From b4ba590545b158f6278574fc98fa555562219b42 Mon Sep 17 00:00:00 2001 From: Florian Schmidt Date: Wed, 8 Jan 2025 13:16:42 +0100 Subject: [PATCH 01/21] First draft --- libcob/call.c | 17 +++++++++++++++-- libcob/coblocal.h | 2 ++ libcob/common.c | 3 +++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/libcob/call.c b/libcob/call.c index bae84f135..146b92ac3 100644 --- a/libcob/call.c +++ b/libcob/call.c @@ -60,6 +60,8 @@ FILE *fmemopen (void *buf, size_t size, const char *mode); https://wiki.musl-libc.org/functional-differences-from-glibc.html#Unloading_libraries */ +static cob_settings *cobsetptr = NULL; + #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN @@ -106,7 +108,6 @@ lt_dlerror (void) /* note: only defined in configure when HAVE_DLFCN_H is true and dlopen can be linked */ #include -#define lt_dlopen(x) dlopen(x, RTLD_LAZY | RTLD_GLOBAL) #define lt_dlsym(x,y) dlsym(x, y) #define lt_dlclose(x) dlclose(x) #define lt_dlerror() dlerror() @@ -114,6 +115,19 @@ lt_dlerror (void) #define lt_dlexit() #define lt_dlhandle void * +void* lt_dlopen(const char* filename) { + + if (cobsetptr == NULL || cobsetptr->cob_load_global == NULL) { + // TODO: What to do when cobsetptr is null? + } + + if (cobsetptr->cob_load_global) { + return dlopen(filename, RTLD_LAZY | RTLD_LOCAL); + } else { + return dlopen(filename, RTLD_LAZY | RTLD_GLOBAL); + } +} + #else #include @@ -158,7 +172,6 @@ static struct struct_handle *base_preload_ptr; static struct struct_handle *base_dynload_ptr; static cob_global *cobglobptr = NULL; -static cob_settings *cobsetptr = NULL; static char **resolve_path; static char *resolve_error; diff --git a/libcob/coblocal.h b/libcob/coblocal.h index a8b8e2c6c..7a8cfda45 100644 --- a/libcob/coblocal.h +++ b/libcob/coblocal.h @@ -372,6 +372,8 @@ typedef struct __cob_settings { unsigned int cob_core_on_error; /* signal handling and possible raise of SIGABRT / creation of coredumps on runtime errors */ char *cob_core_filename; /* filename for coredump creation */ + + int cob_load_global; /* Wether dlopen should use the global or local namespace */ } cob_settings; diff --git a/libcob/common.c b/libcob/common.c index 00c5d9a40..77b09a915 100644 --- a/libcob/common.c +++ b/libcob/common.c @@ -521,6 +521,9 @@ static struct config_tbl gc_conf[] = { #ifdef _WIN32 /* checked before configuration load if set from environment in cob_common_init() */ {"COB_UNIX_LF", "unix_lf", "0", NULL, GRP_FILE, ENV_BOOL, SETPOS (cob_unix_lf)}, +#endif +#ifndef _WIN32 + {"COB_LOAD_GLOBAL", "load_global", "1", NULL, GRP_CALL, ENV_BOOL, SETPOS(cob_load_global)}, #endif {"USERNAME", "username", NULL, NULL, GRP_SYSENV, ENV_STR, SETPOS (cob_user_name)}, /* default set in cob_init() */ {"LOGNAME", "logname", NULL, NULL, GRP_HIDE, ENV_STR, SETPOS (cob_user_name)}, From 41e6d95371c0ccd964ec86af438185e6cf5f3ef3 Mon Sep 17 00:00:00 2001 From: Florian Schmidt Date: Wed, 8 Jan 2025 13:41:37 +0000 Subject: [PATCH 02/21] Add documentation --- config/runtime.cfg | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/config/runtime.cfg b/config/runtime.cfg index 6f583f0ee..b84191de9 100644 --- a/config/runtime.cfg +++ b/config/runtime.cfg @@ -306,6 +306,18 @@ # Default: false # Example: PHYSICAL_CANCEL TRUE +# Environment name: COB_LOAD_GLOBAL +# Parameter name: load_global +# Purpose: tell the system loader to provide symbols in CALLed +# programs globally, allowing symbols to be found for linked +# libraries later +# Type: boolean +# Note: COBOL CALLs will always find symbols in already CALLed or +# pre-modules; this setting is mostly an advise to the system, +# not all systems are capable of loading libraries global/local +# Default: false +# Example: load_global true + # ## File I/O # From eab2b749b41f066b83dce48315b722fb8b8f3918 Mon Sep 17 00:00:00 2001 From: Florian Schmidt Date: Wed, 8 Jan 2025 14:48:49 +0000 Subject: [PATCH 03/21] Change default COB_LOAD_GLOBAL to false --- libcob/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcob/common.c b/libcob/common.c index 77b09a915..cc3309dfa 100644 --- a/libcob/common.c +++ b/libcob/common.c @@ -523,7 +523,7 @@ static struct config_tbl gc_conf[] = { {"COB_UNIX_LF", "unix_lf", "0", NULL, GRP_FILE, ENV_BOOL, SETPOS (cob_unix_lf)}, #endif #ifndef _WIN32 - {"COB_LOAD_GLOBAL", "load_global", "1", NULL, GRP_CALL, ENV_BOOL, SETPOS(cob_load_global)}, + {"COB_LOAD_GLOBAL", "load_global", "0", NULL, GRP_CALL, ENV_BOOL, SETPOS(cob_load_global)}, #endif {"USERNAME", "username", NULL, NULL, GRP_SYSENV, ENV_STR, SETPOS (cob_user_name)}, /* default set in cob_init() */ {"LOGNAME", "logname", NULL, NULL, GRP_HIDE, ENV_STR, SETPOS (cob_user_name)}, From 142f7f97b692f38cd6b34e53775b71b9ebfb5aa7 Mon Sep 17 00:00:00 2001 From: Florian Schmidt Date: Wed, 8 Jan 2025 15:19:19 +0000 Subject: [PATCH 04/21] Move option in config_tbl to similar options --- libcob/common.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libcob/common.c b/libcob/common.c index cc3309dfa..3c7c59b46 100644 --- a/libcob/common.c +++ b/libcob/common.c @@ -490,6 +490,9 @@ static struct config_tbl gc_conf[] = { {"LOGICAL_CANCELS", "logical_cancels", NULL, NULL, GRP_HIDE, ENV_BOOL | ENV_NOT, SETPOS (cob_physical_cancel)}, {"COB_LIBRARY_PATH", "library_path", NULL, NULL, GRP_CALL, ENV_PATH, SETPOS (cob_library_path)}, /* default value set in cob_init_call() */ {"COB_PRE_LOAD", "pre_load", NULL, NULL, GRP_CALL, ENV_STR, SETPOS (cob_preload_str)}, +#ifndef _WIN32 + {"COB_LOAD_GLOBAL", "load_global", "0", NULL, GRP_CALL, ENV_BOOL, SETPOS(cob_load_global)}, +#endif {"COB_BELL", "bell", "0", beepopts, GRP_SCREEN, ENV_UINT | ENV_ENUMVAL, SETPOS (cob_beep_value)}, {"COB_DEBUG_LOG", "debug_log", NULL, NULL, GRP_HIDE, ENV_FILE, SETPOS (cob_debug_log)}, {"COB_DISABLE_WARNINGS", "disable_warnings", "0", NULL, GRP_MISC, ENV_BOOL | ENV_NOT, SETPOS (cob_display_warn)}, @@ -521,9 +524,6 @@ static struct config_tbl gc_conf[] = { #ifdef _WIN32 /* checked before configuration load if set from environment in cob_common_init() */ {"COB_UNIX_LF", "unix_lf", "0", NULL, GRP_FILE, ENV_BOOL, SETPOS (cob_unix_lf)}, -#endif -#ifndef _WIN32 - {"COB_LOAD_GLOBAL", "load_global", "0", NULL, GRP_CALL, ENV_BOOL, SETPOS(cob_load_global)}, #endif {"USERNAME", "username", NULL, NULL, GRP_SYSENV, ENV_STR, SETPOS (cob_user_name)}, /* default set in cob_init() */ {"LOGNAME", "logname", NULL, NULL, GRP_HIDE, ENV_STR, SETPOS (cob_user_name)}, From e783e37511833295c97e221a7ae6dbc7ccec70c9 Mon Sep 17 00:00:00 2001 From: Florian Schmidt Date: Wed, 8 Jan 2025 15:22:26 +0000 Subject: [PATCH 05/21] Remove wrong NULL check --- libcob/call.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcob/call.c b/libcob/call.c index 146b92ac3..6c837201a 100644 --- a/libcob/call.c +++ b/libcob/call.c @@ -117,7 +117,7 @@ lt_dlerror (void) void* lt_dlopen(const char* filename) { - if (cobsetptr == NULL || cobsetptr->cob_load_global == NULL) { + if (cobsetptr == NULL) { // TODO: What to do when cobsetptr is null? } From d81423ad995f4f4317c3a0de0efb2cdfbc6774e6 Mon Sep 17 00:00:00 2001 From: Florian Schmidt Date: Wed, 8 Jan 2025 15:46:36 +0000 Subject: [PATCH 06/21] Address review comments --- libcob/call.c | 15 +++++---------- libcob/coblocal.h | 3 +-- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/libcob/call.c b/libcob/call.c index 6c837201a..e605b6f6b 100644 --- a/libcob/call.c +++ b/libcob/call.c @@ -115,17 +115,12 @@ lt_dlerror (void) #define lt_dlexit() #define lt_dlhandle void * -void* lt_dlopen(const char* filename) { - - if (cobsetptr == NULL) { - // TODO: What to do when cobsetptr is null? - } +static void* lt_dlopen(const char* filename) { + int flags = cobsetptr->cob_load_global + ? RTLD_LAZY | RTLD_GLOBAL + : RTLD_LAZY | RTLD_LOCAL; - if (cobsetptr->cob_load_global) { - return dlopen(filename, RTLD_LAZY | RTLD_LOCAL); - } else { - return dlopen(filename, RTLD_LAZY | RTLD_GLOBAL); - } + return dlopen(filename, flags); } #else diff --git a/libcob/coblocal.h b/libcob/coblocal.h index 7a8cfda45..5af6427f3 100644 --- a/libcob/coblocal.h +++ b/libcob/coblocal.h @@ -300,6 +300,7 @@ typedef struct __cob_settings { /* call.c */ int cob_physical_cancel; /* 0 "= "logical only" (default), 1 "also unload", -1 "never unload" */ + unsigned int cob_load_global; /* Wether dlopen should use the global or local namespace */ unsigned int name_convert; char *cob_preload_str; char *cob_library_path; @@ -372,8 +373,6 @@ typedef struct __cob_settings { unsigned int cob_core_on_error; /* signal handling and possible raise of SIGABRT / creation of coredumps on runtime errors */ char *cob_core_filename; /* filename for coredump creation */ - - int cob_load_global; /* Wether dlopen should use the global or local namespace */ } cob_settings; From e7705d26ac50f708e67629bde8d3dbb4fb96eb55 Mon Sep 17 00:00:00 2001 From: Florian Schmidt Date: Wed, 8 Jan 2025 15:54:33 +0000 Subject: [PATCH 07/21] Add entry to ChangeLog --- ChangeLog | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index 2d5ea8a89..f98122cf1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2025-01-08 Simon Sobisch + + * config/runtime.cfg: Add documentation for COB_LOAD_GLOBAL flag + +2025-01-08 Florian Schmidt + + * libcob/call.c, libcob/coblocal.h, libcob/common.c: Introduce a flag + COB_LOAD_GLOBAL (load_global) to toggle if the symbols of CALLed + programs should be made available in the global namespace 2024-12-08 Simon Sobisch From 505f8c98b386fb64d83ad214520e1bc31292e384 Mon Sep 17 00:00:00 2001 From: Florian Schmidt Date: Wed, 8 Jan 2025 16:37:22 +0000 Subject: [PATCH 08/21] refactor and introduce a cob_dlopen function --- libcob/call.c | 108 +++++++++++++++++++++++++++----------------------- 1 file changed, 58 insertions(+), 50 deletions(-) diff --git a/libcob/call.c b/libcob/call.c index e605b6f6b..c5b70ad46 100644 --- a/libcob/call.c +++ b/libcob/call.c @@ -63,71 +63,79 @@ FILE *fmemopen (void *buf, size_t size, const char *mode); static cob_settings *cobsetptr = NULL; #ifdef _WIN32 + #define WIN32_LEAN_AND_MEAN + #include + #include /* for access */ -#define WIN32_LEAN_AND_MEAN -#include -#include /* for access */ + static void * + lt_dlsym (HMODULE hmod, const char *p) + { + union { + FARPROC modaddr; + void *voidptr; + } modun; -static HMODULE -lt_dlopen (const char *x) -{ - if (x == NULL) { - return GetModuleHandle (NULL); + modun.modaddr = GetProcAddress(hmod, p); + return modun.voidptr; } - return LoadLibrary(x); -} - -static void * -lt_dlsym (HMODULE hmod, const char *p) -{ - union { - FARPROC modaddr; - void *voidptr; - } modun; - modun.modaddr = GetProcAddress(hmod, p); - return modun.voidptr; -} - -#define lt_dlclose(x) FreeLibrary(x) -#define lt_dlinit() -#define lt_dlexit() -#define lt_dlhandle HMODULE + #define lt_dlclose(x) FreeLibrary(x) + #define lt_dlinit() + #define lt_dlexit() + #define lt_dlhandle HMODULE -#if 1 /* RXWRXW - dlerror */ -static char errbuf[64]; -static char * -lt_dlerror (void) -{ - sprintf (errbuf, _("LoadLibrary/GetProcAddress error %d"), (int)GetLastError()); - return errbuf; -} + #if 1 /* RXWRXW - dlerror */ + static char errbuf[64]; + static char * + lt_dlerror (void) + { + sprintf (errbuf, _("LoadLibrary/GetProcAddress error %d"), (int)GetLastError()); + return errbuf; + } #endif - #elif defined(USE_LIBDL) -/* note: only defined in configure when HAVE_DLFCN_H is true and dlopen can be linked */ -#include - -#define lt_dlsym(x,y) dlsym(x, y) -#define lt_dlclose(x) dlclose(x) -#define lt_dlerror() dlerror() -#define lt_dlinit() -#define lt_dlexit() -#define lt_dlhandle void * + /* note: only defined in configure when HAVE_DLFCN_H is true and dlopen can be linked */ + #include + + #define lt_dlsym(x,y) dlsym(x, y) + #define lt_dlclose(x) dlclose(x) + #define lt_dlerror() dlerror() + #define lt_dlinit() + #define lt_dlexit() + #define lt_dlhandle void * +#else + #include +#endif -static void* lt_dlopen(const char* filename) { +static void* cob_dlopen(const char* filename) { +#ifdef _WIN32 + if (filename == NULL) { + return GetModuleHandle (NULL); + } + return LoadLibrary(filename); +#elif defined(USE_LIBDL) int flags = cobsetptr->cob_load_global ? RTLD_LAZY | RTLD_GLOBAL : RTLD_LAZY | RTLD_LOCAL; return dlopen(filename, flags); -} - #else - -#include - + lt_dladvise advise; + lt_dladvise_init(&advise); + + if (cobsetptr->cob_load_global) { + lt_dladvise_global(&advise); + } else { + lt_dladvise_local(&advise); + } + + void* handle = lt_dlopenadvise(filename, advise); + lt_dladvise_destroy(&advise); // Clean up advise object + return handle; #endif +} + +#define lt_dlopen(x) cob_dlopen(x) // TODO: Remove this! #define COB_MAX_COBCALL_PARMS 16 #define CALL_BUFF_SIZE 256U From 9dd8c17c8374b6ecd0ec54eb5a15424738991ad3 Mon Sep 17 00:00:00 2001 From: Florian Schmidt Date: Thu, 9 Jan 2025 09:23:57 +0000 Subject: [PATCH 09/21] Restructure according to PR comments --- libcob/call.c | 140 +++++++++++++++++++++++++------------------------- 1 file changed, 69 insertions(+), 71 deletions(-) diff --git a/libcob/call.c b/libcob/call.c index c5b70ad46..e143f2bae 100644 --- a/libcob/call.c +++ b/libcob/call.c @@ -60,82 +60,52 @@ FILE *fmemopen (void *buf, size_t size, const char *mode); https://wiki.musl-libc.org/functional-differences-from-glibc.html#Unloading_libraries */ -static cob_settings *cobsetptr = NULL; + #ifdef _WIN32 - #define WIN32_LEAN_AND_MEAN - #include - #include /* for access */ +#define WIN32_LEAN_AND_MEAN +#include +#include /* for access */ - static void * - lt_dlsym (HMODULE hmod, const char *p) - { - union { - FARPROC modaddr; - void *voidptr; - } modun; +static void * +lt_dlsym (HMODULE hmod, const char *p) +{ + union { + FARPROC modaddr; + void *voidptr; + } modun; - modun.modaddr = GetProcAddress(hmod, p); - return modun.voidptr; - } + modun.modaddr = GetProcAddress(hmod, p); + return modun.voidptr; +} - #define lt_dlclose(x) FreeLibrary(x) - #define lt_dlinit() - #define lt_dlexit() - #define lt_dlhandle HMODULE +#define lt_dlclose(x) FreeLibrary(x) +#define lt_dlinit() +#define lt_dlexit() +#define lt_dlhandle HMODULE - #if 1 /* RXWRXW - dlerror */ - static char errbuf[64]; - static char * - lt_dlerror (void) - { - sprintf (errbuf, _("LoadLibrary/GetProcAddress error %d"), (int)GetLastError()); - return errbuf; - } -#endif -#elif defined(USE_LIBDL) - /* note: only defined in configure when HAVE_DLFCN_H is true and dlopen can be linked */ - #include - - #define lt_dlsym(x,y) dlsym(x, y) - #define lt_dlclose(x) dlclose(x) - #define lt_dlerror() dlerror() - #define lt_dlinit() - #define lt_dlexit() - #define lt_dlhandle void * -#else - #include +#if 1 /* RXWRXW - dlerror */ +static char errbuf[64]; +static char * +lt_dlerror (void) +{ + sprintf (errbuf, _("LoadLibrary/GetProcAddress error %d"), (int)GetLastError()); + return errbuf; +} #endif - -static void* cob_dlopen(const char* filename) { -#ifdef _WIN32 - if (filename == NULL) { - return GetModuleHandle (NULL); - } - return LoadLibrary(filename); #elif defined(USE_LIBDL) - int flags = cobsetptr->cob_load_global - ? RTLD_LAZY | RTLD_GLOBAL - : RTLD_LAZY | RTLD_LOCAL; - - return dlopen(filename, flags); +/* note: only defined in configure when HAVE_DLFCN_H is true and dlopen can be linked */ +#include + +#define lt_dlsym(x,y) dlsym(x, y) +#define lt_dlclose(x) dlclose(x) +#define lt_dlerror() dlerror() +#define lt_dlinit() +#define lt_dlexit() +#define lt_dlhandle void * #else - lt_dladvise advise; - lt_dladvise_init(&advise); - - if (cobsetptr->cob_load_global) { - lt_dladvise_global(&advise); - } else { - lt_dladvise_local(&advise); - } - - void* handle = lt_dlopenadvise(filename, advise); - lt_dladvise_destroy(&advise); // Clean up advise object - return handle; +#include #endif -} - -#define lt_dlopen(x) cob_dlopen(x) // TODO: Remove this! #define COB_MAX_COBCALL_PARMS 16 #define CALL_BUFF_SIZE 256U @@ -175,6 +145,7 @@ static struct struct_handle *base_preload_ptr; static struct struct_handle *base_dynload_ptr; static cob_global *cobglobptr = NULL; +static cob_settings *cobsetptr = NULL; static char **resolve_path; static char *resolve_error; @@ -305,6 +276,33 @@ static int last_entry_is_working_directory (const char *buff, const char *pstr) return 0; } +static void* cob_dlopen(const char* filename) { +#ifdef _WIN32 + if (filename == NULL) { + return GetModuleHandle (NULL); + } + return LoadLibrary(filename); +#elif defined(USE_LIBDL) + int flags = cobsetptr->cob_load_global + ? RTLD_LAZY | RTLD_GLOBAL + : RTLD_LAZY | RTLD_LOCAL; + + return dlopen(filename, flags); +#else + lt_dladvise advise; + lt_dladvise_init(&advise); + + if (cobsetptr->cob_load_global) { + lt_dladvise_global(&advise); + } else { + lt_dladvise_local(&advise); + } + + void* handle = lt_dlopenadvise(filename, advise); + return handle; +#endif +} + /* resolves the actual library path used from * COB_LIBRARY_PATH runtime setting * "." as current working direktory [if not included already: prefixed] @@ -640,7 +638,7 @@ cache_preload (const char *path) return 0; } - libhandle = lt_dlopen (path); + libhandle = cob_dlopen (path); if (!libhandle) { cob_runtime_warning ( _("preloading from existing path '%s' failed; %s"), path, lt_dlerror()); @@ -886,7 +884,7 @@ cob_resolve_internal (const char *name, const char *dirent, for (p = call_filename_buff; *p; ++p) { *p = (cob_u8_t)toupper(*p); } - handle = lt_dlopen (call_filename_buff); + handle = cob_dlopen (call_filename_buff); if (handle != NULL) { /* Candidate for future calls */ cache_dynload (call_filename_buff, handle); @@ -929,7 +927,7 @@ cob_resolve_internal (const char *name, const char *dirent, return NULL; } lt_dlerror (); /* clear last error conditions */ - handle = lt_dlopen (call_filename_buff); + handle = cob_dlopen (call_filename_buff); if (handle != NULL) { /* Candidate for future calls */ cache_dynload (call_filename_buff, handle); @@ -962,7 +960,7 @@ cob_resolve_internal (const char *name, const char *dirent, call_filename_buff[COB_NORMAL_MAX] = 0; if (access (call_filename_buff, R_OK) == 0) { lt_dlerror (); /* clear last error conditions */ - handle = lt_dlopen (call_filename_buff); + handle = cob_dlopen (call_filename_buff); if (handle != NULL) { /* Candidate for future calls */ cache_dynload (call_filename_buff, handle); @@ -1666,7 +1664,7 @@ cob_init_call (cob_global *lptr, cob_settings* sptr, const int check_mainhandle) saves a check for exported functions in every CALL */ if (check_mainhandle) { - mainhandle = lt_dlopen (NULL); + mainhandle = cob_dlopen (NULL); } else { mainhandle = NULL; } From ab26e16c66a85895749da546506359718610818a Mon Sep 17 00:00:00 2001 From: Florian Schmidt Date: Thu, 9 Jan 2025 09:29:56 +0000 Subject: [PATCH 10/21] :Remove unnecessary whitespace changes --- libcob/call.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libcob/call.c b/libcob/call.c index e143f2bae..83e2def80 100644 --- a/libcob/call.c +++ b/libcob/call.c @@ -60,9 +60,8 @@ FILE *fmemopen (void *buf, size_t size, const char *mode); https://wiki.musl-libc.org/functional-differences-from-glibc.html#Unloading_libraries */ - - #ifdef _WIN32 + #define WIN32_LEAN_AND_MEAN #include #include /* for access */ @@ -93,6 +92,7 @@ lt_dlerror (void) return errbuf; } #endif + #elif defined(USE_LIBDL) /* note: only defined in configure when HAVE_DLFCN_H is true and dlopen can be linked */ #include @@ -103,8 +103,11 @@ lt_dlerror (void) #define lt_dlinit() #define lt_dlexit() #define lt_dlhandle void * + #else + #include + #endif #define COB_MAX_COBCALL_PARMS 16 From 2e9315bb5f08a58f35707c228f2e396a097c7c63 Mon Sep 17 00:00:00 2001 From: Florian Schmidt Date: Thu, 9 Jan 2025 09:53:40 +0000 Subject: [PATCH 11/21] Address PR comment --- libcob/coblocal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcob/coblocal.h b/libcob/coblocal.h index 5af6427f3..cf6561f9a 100644 --- a/libcob/coblocal.h +++ b/libcob/coblocal.h @@ -300,7 +300,7 @@ typedef struct __cob_settings { /* call.c */ int cob_physical_cancel; /* 0 "= "logical only" (default), 1 "also unload", -1 "never unload" */ - unsigned int cob_load_global; /* Wether dlopen should use the global or local namespace */ + unsigned int cob_load_global; /* hint for dynamic linker to make symbols available 0=global, 1=local */ unsigned int name_convert; char *cob_preload_str; char *cob_library_path; From 6f11f38851d2a95299ae965c973b6f95e1fe009b Mon Sep 17 00:00:00 2001 From: Florian Schmidt Date: Thu, 9 Jan 2025 10:56:28 +0000 Subject: [PATCH 12/21] Move changelog entries to respective folders --- ChangeLog | 9 --------- config/ChangeLog | 4 ++++ libcob/ChangeLog | 6 ++++++ 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index f98122cf1..2d5ea8a89 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,12 +1,3 @@ -2025-01-08 Simon Sobisch - - * config/runtime.cfg: Add documentation for COB_LOAD_GLOBAL flag - -2025-01-08 Florian Schmidt - - * libcob/call.c, libcob/coblocal.h, libcob/common.c: Introduce a flag - COB_LOAD_GLOBAL (load_global) to toggle if the symbols of CALLed - programs should be made available in the global namespace 2024-12-08 Simon Sobisch diff --git a/config/ChangeLog b/config/ChangeLog index a23c513bb..a8a5800bc 100644 --- a/config/ChangeLog +++ b/config/ChangeLog @@ -1,4 +1,8 @@ +2024-12-16 Simon Sobisch + + * config/runtime.cfg: Add documentation for COB_LOAD_GLOBAL flag + 2024-08-17 Ammar Almoris FR #474: add runtime configuration to hide cursor for extended screenio diff --git a/libcob/ChangeLog b/libcob/ChangeLog index b03c08cb8..b95a9e387 100644 --- a/libcob/ChangeLog +++ b/libcob/ChangeLog @@ -1,4 +1,10 @@ +2025-01-08 Florian Schmidt + + * libcob/call.c, libcob/coblocal.h, libcob/common.c: Introduce a flag + COB_LOAD_GLOBAL (load_global) to toggle if the symbols of CALLed + programs should be made available in the global namespace + 2024-12-11 Emilien Lemaire * fileio.c: fixed Bug #1032 by always using global thread-static variable From bd80e8ce601b1663aa69793f086284c66fd2b463 Mon Sep 17 00:00:00 2001 From: Florian Schmidt Date: Thu, 9 Jan 2025 13:23:48 +0000 Subject: [PATCH 13/21] Improve handling of lt_dladvise --- libcob/call.c | 44 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/libcob/call.c b/libcob/call.c index 83e2def80..9b097021a 100644 --- a/libcob/call.c +++ b/libcob/call.c @@ -161,6 +161,10 @@ static char *call_filename_buff; static lt_dlhandle mainhandle; #endif +#if !defined(_WIN32) && !defined(USE_LIBDL) +static lt_dladvise advise = NULL; +#endif + static size_t call_lastsize; static size_t resolve_size = 0; static unsigned int cob_jmp_primed; @@ -292,14 +296,18 @@ static void* cob_dlopen(const char* filename) { return dlopen(filename, flags); #else - lt_dladvise advise; - lt_dladvise_init(&advise); - - if (cobsetptr->cob_load_global) { - lt_dladvise_global(&advise); - } else { - lt_dladvise_local(&advise); - } + if (advise != NULL) { + int error; + if (cobsetptr->cob_load_global) { + error = lt_dladvise_global(&advise); + } else { + error = lt_dladvise_local(&advise); + } + + if (error) { + cob_runtime_warning("set link loader hint failed; %s", lt_dlerror()); + } + } void* handle = lt_dlopenadvise(filename, advise); return handle; @@ -1575,6 +1583,17 @@ cob_exit_call (void) #endif #endif +#if !defined(_WIN32) && !defined(USE_LIBDL) + if (advise != NULL) { + int error = lt_dladvise_destroy(&advise); + if (error) { + const char * msg = lt_dlerror(); + /* not translated as highly unlikely */ + cob_runtime_warning ( + "destroying link loader advise failed; %s", lt_dlerror()); + } + } +#endif } /* try to load specified module from all entries in COB_LIBRARY_PATH @@ -1662,6 +1681,15 @@ cob_init_call (cob_global *lptr, cob_settings* sptr, const int check_mainhandle) lt_dlinit (); +#if !defined(_WIN32) && !defined(USE_LIBDL) + int error = lt_dladvise_init(&advise); + if (error) { + /* not translated as highly unlikely */ + cob_runtime_warning ( + "init link loader advise failed; %s", lt_dlerror()); + } +#endif + #ifndef COB_BORKED_DLOPEN /* only set main handle if not started by cobcrun as this saves a check for exported functions in every CALL From 1f4d60760e3fb908f9818d68ac0044fae7ee520a Mon Sep 17 00:00:00 2001 From: Florian Schmidt Date: Thu, 9 Jan 2025 15:19:46 +0000 Subject: [PATCH 14/21] Resolve symbol overwrite issue --- libcob/call.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/libcob/call.c b/libcob/call.c index 9b097021a..40c03532c 100644 --- a/libcob/call.c +++ b/libcob/call.c @@ -585,9 +585,20 @@ add_to_preload (const char *path, lt_dlhandle libhandle, struct struct_handle *l base_preload_ptr = preptr; } #else - COB_UNUSED (last_elem); - preptr->next = base_preload_ptr; - base_preload_ptr = preptr; + // Use the same logic as above in case the cob_load_global is set to local + if (!cobsetptr->cob_load_global) { + if (last_elem) { + last_elem->next = preptr; + } else { + preptr->next = NULL; + base_preload_ptr = preptr; + } + } else { + COB_UNUSED (last_elem); + preptr->next = base_preload_ptr; + base_preload_ptr = preptr; + } + #endif if (!cobsetptr->cob_preload_str) { @@ -620,6 +631,9 @@ cache_preload (const char *path) /* Save last element of preload list */ if (!preptr->next) last_elem = preptr; #endif + if(!cobsetptr->cob_load_global) { + if (!preptr->next) last_elem = preptr; + } } /* Check for duplicate in already loaded programs; From 8aed811d4885d655676ad3b8ffe659051ffcd0e8 Mon Sep 17 00:00:00 2001 From: Florian Schmidt Date: Thu, 9 Jan 2025 15:39:11 +0000 Subject: [PATCH 15/21] Add entry to NEWS --- NEWS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/NEWS b/NEWS index 8f0d220fb..177050536 100644 --- a/NEWS +++ b/NEWS @@ -87,6 +87,12 @@ NEWS - user visible changes -*- outline -*- $b for executable basename, $d for date in YYYYMMDD format, $t for time in HHMMSS format (before, only $$ was available for pid) +** introduction of the COB_LOAD_GLOBAL boolean flag, which determines whether + the symbols of dynamically loaded shared libraries are made available + globally to other shared objects or remain confined locally. Previously, + this behavior depended on the underlying platform, where the default was + often "global." The default behavior is now explicitly set to "local." + * New build features ** configure now uses pkg-config/ncurses-config to search for ncurses and From 62de6254d0418b45e142b14f27245b481c1594b1 Mon Sep 17 00:00:00 2001 From: Florian Schmidt Date: Thu, 9 Jan 2025 15:40:17 +0000 Subject: [PATCH 16/21] Add simple testcase --- tests/testsuite.src/run_misc.at | 51 +++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/tests/testsuite.src/run_misc.at b/tests/testsuite.src/run_misc.at index 10df40949..933bbdfce 100644 --- a/tests/testsuite.src/run_misc.at +++ b/tests/testsuite.src/run_misc.at @@ -4285,6 +4285,57 @@ AT_CHECK([COB_LOAD_CASE=UPPER ./caller], [0], [], []) AT_CLEANUP +AT_SETUP([COB_LOAD_GLOBAL=true CALL/CANCEL works]) +AT_KEYWORDS([runmisc CALL CANCEL COB_LOAD_GLOBAL]) + +AT_DATA([CALLEE.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. callee. + PROCEDURE DIVISION. + EXIT PROGRAM. +]) + +AT_DATA([caller.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. caller. + PROCEDURE DIVISION. + CALL "callee" + END-CALL. + CANCEL "callee". + STOP RUN. +]) + +AT_CHECK([$COMPILE_MODULE CALLEE.cob], [0], [], []) +AT_CHECK([$COMPILE caller.cob], [0], [], []) +AT_CHECK([COB_LOAD_GLOBAL=true ./caller], [0], [], []) + +AT_CLEANUP + +AT_SETUP([COB_LOAD_GLOBAL=false CALL/CANCEL still works]) +AT_KEYWORDS([runmisc CALL CANCEL COB_LOAD_GLOBAL]) + +AT_DATA([CALLEE.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. callee. + PROCEDURE DIVISION. + EXIT PROGRAM. +]) + +AT_DATA([caller.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. caller. + PROCEDURE DIVISION. + CALL "callee" + END-CALL. + CANCEL "callee". + STOP RUN. +]) + +AT_CHECK([$COMPILE_MODULE CALLEE.cob], [0], [], []) +AT_CHECK([$COMPILE caller.cob], [0], [], []) +AT_CHECK([COB_LOAD_GLOBAL=false ./caller], [0], [], []) + +AT_CLEANUP AT_SETUP([ALLOCATE / FREE with BASED item (1)]) AT_KEYWORDS([runmisc]) From d109c5995bfdccbc685cb336eb0fee38ca60180c Mon Sep 17 00:00:00 2001 From: Florian Schmidt Date: Mon, 13 Jan 2025 10:09:09 +0000 Subject: [PATCH 17/21] Merge test-cases --- tests/testsuite.src/run_misc.at | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/tests/testsuite.src/run_misc.at b/tests/testsuite.src/run_misc.at index 933bbdfce..c473ec7f4 100644 --- a/tests/testsuite.src/run_misc.at +++ b/tests/testsuite.src/run_misc.at @@ -4285,7 +4285,7 @@ AT_CHECK([COB_LOAD_CASE=UPPER ./caller], [0], [], []) AT_CLEANUP -AT_SETUP([COB_LOAD_GLOBAL=true CALL/CANCEL works]) +AT_SETUP([CALL/CANCEL with COB_LOAD_GLOBAL]) AT_KEYWORDS([runmisc CALL CANCEL COB_LOAD_GLOBAL]) AT_DATA([CALLEE.cob], [ @@ -4308,31 +4308,6 @@ AT_DATA([caller.cob], [ AT_CHECK([$COMPILE_MODULE CALLEE.cob], [0], [], []) AT_CHECK([$COMPILE caller.cob], [0], [], []) AT_CHECK([COB_LOAD_GLOBAL=true ./caller], [0], [], []) - -AT_CLEANUP - -AT_SETUP([COB_LOAD_GLOBAL=false CALL/CANCEL still works]) -AT_KEYWORDS([runmisc CALL CANCEL COB_LOAD_GLOBAL]) - -AT_DATA([CALLEE.cob], [ - IDENTIFICATION DIVISION. - PROGRAM-ID. callee. - PROCEDURE DIVISION. - EXIT PROGRAM. -]) - -AT_DATA([caller.cob], [ - IDENTIFICATION DIVISION. - PROGRAM-ID. caller. - PROCEDURE DIVISION. - CALL "callee" - END-CALL. - CANCEL "callee". - STOP RUN. -]) - -AT_CHECK([$COMPILE_MODULE CALLEE.cob], [0], [], []) -AT_CHECK([$COMPILE caller.cob], [0], [], []) AT_CHECK([COB_LOAD_GLOBAL=false ./caller], [0], [], []) AT_CLEANUP From a5bf8a67409c73ba1adc7595beed5c43d0ac1b5f Mon Sep 17 00:00:00 2001 From: Florian Schmidt Date: Tue, 11 Feb 2025 13:22:07 +0100 Subject: [PATCH 18/21] Fix issue with upper / lower case call --- tests/testsuite.src/run_misc.at | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testsuite.src/run_misc.at b/tests/testsuite.src/run_misc.at index 09d91937a..8ee700dd9 100644 --- a/tests/testsuite.src/run_misc.at +++ b/tests/testsuite.src/run_misc.at @@ -4358,7 +4358,7 @@ AT_CLEANUP AT_SETUP([CALL/CANCEL with COB_LOAD_GLOBAL]) AT_KEYWORDS([runmisc CALL CANCEL COB_LOAD_GLOBAL]) -AT_DATA([CALLEE.cob], [ +AT_DATA([callee.cob], [ IDENTIFICATION DIVISION. PROGRAM-ID. callee. PROCEDURE DIVISION. From 709ca218ef3d8efed5229417bf14cc2b0bc71fd6 Mon Sep 17 00:00:00 2001 From: Florian Schmidt Date: Tue, 11 Feb 2025 13:27:27 +0100 Subject: [PATCH 19/21] Fix another case issue --- tests/testsuite.src/run_misc.at | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testsuite.src/run_misc.at b/tests/testsuite.src/run_misc.at index 8ee700dd9..7e5a54bbb 100644 --- a/tests/testsuite.src/run_misc.at +++ b/tests/testsuite.src/run_misc.at @@ -4375,7 +4375,7 @@ AT_DATA([caller.cob], [ STOP RUN. ]) -AT_CHECK([$COMPILE_MODULE CALLEE.cob], [0], [], []) +AT_CHECK([$COMPILE_MODULE callee.cob], [0], [], []) AT_CHECK([$COMPILE caller.cob], [0], [], []) AT_CHECK([COB_LOAD_GLOBAL=true ./caller], [0], [], []) AT_CHECK([COB_LOAD_GLOBAL=false ./caller], [0], [], []) From 14232c6c25e3b0c93271f52dc8074fcdda432b73 Mon Sep 17 00:00:00 2001 From: Florian Schmidt Date: Tue, 11 Feb 2025 13:36:08 +0100 Subject: [PATCH 20/21] Remove C++ style comment --- libcob/call.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcob/call.c b/libcob/call.c index 40c03532c..d7d6ab70b 100644 --- a/libcob/call.c +++ b/libcob/call.c @@ -585,7 +585,7 @@ add_to_preload (const char *path, lt_dlhandle libhandle, struct struct_handle *l base_preload_ptr = preptr; } #else - // Use the same logic as above in case the cob_load_global is set to local + /* Use the same logic as above in case the cob_load_global is set to local */ if (!cobsetptr->cob_load_global) { if (last_elem) { last_elem->next = preptr; From ea0a8bfb8b6d69fb244b4875e936a663aa4da581 Mon Sep 17 00:00:00 2001 From: Simon Sobisch Date: Tue, 11 Feb 2025 19:52:47 +0100 Subject: [PATCH 21/21] Update ChangeLog using the more important part "default changed" first, more explanation --- libcob/ChangeLog | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libcob/ChangeLog b/libcob/ChangeLog index 5435f1df3..2bd4ab42a 100644 --- a/libcob/ChangeLog +++ b/libcob/ChangeLog @@ -1,9 +1,14 @@ 2025-01-08 Florian Schmidt - * libcob/call.c, libcob/coblocal.h, libcob/common.c: Introduce a flag - COB_LOAD_GLOBAL (load_global) to toggle if the symbols of CALLed - programs should be made available in the global namespace + * call.c (cob_dlopen): new function used instead of partially re-defining + lt_dlopen; changed default to not load symbols to the global namespace + any more but locally (was always the case for _WIN32) + * common.c, coblocal.h (cob_settings): added boolean COB_LOAD_GLOBAL + to toggle into which namespace the symbols of CALLed programs should be + made available + * call.c (cob_dlopen, add_to_preload, cache_preload, cob_exit_call): + handle COB_LOAD_GLOBAL (load_global) 2024-12-31 Simon Sobisch