skoona
23rd February 2005, 04:48 AM
Folks,
Question: Is there a way to force all statically defined functions to be considered 'local' to the shared library they are contained in? Whats the ld parm to use, or *.c modifier to use?
I am building a plugin or shared library, for gkrellm and I have a code construction or organization problem. Basically, if I organize the code in normal modular fashion I end up with Global or extern references to functions where I don't want them. I have tried several 'ld' options to try and force local references to no avail. So maybe I am missing something that you folks could enlighten me on.
The issue with global references is some functions depend on structures that are a different lengths or size in each mainline. So if the Server.Core.Func(a) is called by Standalone a segfault occurs caused by the different lengths of the base data structures.
This behavour surprised me since I thought 'static int funct (int a);' caused the function to be considered local to the library. Not true it seems if you combine multiple obj files to create a single shared library.
Here the basic code structure;
-- mainline --------utility 1,2,n-----output
Server.c - Core.c = Server.so
Client.c - UI.c = Client.so
Standalone.c - Core.c UI.c = Standalone.so
Three shared libraries is what I want, but the linkage between the utility modules and the mainline need to be locals; there are globals or externs. To overcome this global problem for linkage routines, I am forced to include "core.c", etc in the mainlines. While (includes) solves the problem - it bugs me to have to do this.
I have tried making all functions and .h files 'static' - undefined references was the result. Tried using 'static/extern' combinations - this resolved the undef but left me with the extern'ed function becoming a global reference (source of the segfault). I tried -Bsymbolic, -Bgroup, -start-group...-end-group, and many other combinations in an attempt to force everything local, except for the one routine in each plugin I really do want to be global. I even tried '-s' or strip symbol table; this didn't help because the routines which are called across modules (objs) know the exact name to call and gkrellm as an environment is a single address/name space - collision do happen
Here a look at output from '$ nm Standalone.so' which illustrates the global vs local problem.
Desired outcome (from include"utility.c" style of build)
00004cd0 t nf2_cb_config_idebug_click
00004b60 t nf2_cb_config_pcpu_mode_click
00004d50 t nf2_cb_config_show_sends_click
00006f50 t nf2_cb_panel_click
00004810 t nf2_cb_panel_enter
000046f0 t nf2_cb_panel_expose
00004920 t nf2_cb_panel_leave
Problem outcome (from modular build)
00005fd0 T nf2_cb_config_idebug_click (big T is the undesired global)
00005cf0 T nf2_cb_config_pcpu_mode_click
00006050 T nf2_cb_config_show_sends_click
00009b20 T nf2_cb_panel_click
00005910 t nf2_cb_panel_enter
000057e0 t nf2_cb_panel_expose
00005a30 t nf2_cb_panel_leave
Legend:
uppcase T imples code is in the text segment and the reference is Global.
lowercase t implies code is in the text segment and the reference is local.
Comment: Even if I redid the data structures to include all the values that each mainline needs - this would not solve the problem, only mask it. Example: the server.c does not need the ton of ui.c based GUI values, since it does not require a GUI or even have display capabilities.
%.c files include the gcc cflag of -fPIC on compile, and -shared -Wl on the link step.
I hope someone can help me look at this differently.
Question: Is there a way to force all statically defined functions to be considered 'local' to the shared library they are contained in? Whats the ld parm to use, or *.c modifier to use?
I am building a plugin or shared library, for gkrellm and I have a code construction or organization problem. Basically, if I organize the code in normal modular fashion I end up with Global or extern references to functions where I don't want them. I have tried several 'ld' options to try and force local references to no avail. So maybe I am missing something that you folks could enlighten me on.
The issue with global references is some functions depend on structures that are a different lengths or size in each mainline. So if the Server.Core.Func(a) is called by Standalone a segfault occurs caused by the different lengths of the base data structures.
This behavour surprised me since I thought 'static int funct (int a);' caused the function to be considered local to the library. Not true it seems if you combine multiple obj files to create a single shared library.
Here the basic code structure;
-- mainline --------utility 1,2,n-----output
Server.c - Core.c = Server.so
Client.c - UI.c = Client.so
Standalone.c - Core.c UI.c = Standalone.so
Three shared libraries is what I want, but the linkage between the utility modules and the mainline need to be locals; there are globals or externs. To overcome this global problem for linkage routines, I am forced to include "core.c", etc in the mainlines. While (includes) solves the problem - it bugs me to have to do this.
I have tried making all functions and .h files 'static' - undefined references was the result. Tried using 'static/extern' combinations - this resolved the undef but left me with the extern'ed function becoming a global reference (source of the segfault). I tried -Bsymbolic, -Bgroup, -start-group...-end-group, and many other combinations in an attempt to force everything local, except for the one routine in each plugin I really do want to be global. I even tried '-s' or strip symbol table; this didn't help because the routines which are called across modules (objs) know the exact name to call and gkrellm as an environment is a single address/name space - collision do happen
Here a look at output from '$ nm Standalone.so' which illustrates the global vs local problem.
Desired outcome (from include"utility.c" style of build)
00004cd0 t nf2_cb_config_idebug_click
00004b60 t nf2_cb_config_pcpu_mode_click
00004d50 t nf2_cb_config_show_sends_click
00006f50 t nf2_cb_panel_click
00004810 t nf2_cb_panel_enter
000046f0 t nf2_cb_panel_expose
00004920 t nf2_cb_panel_leave
Problem outcome (from modular build)
00005fd0 T nf2_cb_config_idebug_click (big T is the undesired global)
00005cf0 T nf2_cb_config_pcpu_mode_click
00006050 T nf2_cb_config_show_sends_click
00009b20 T nf2_cb_panel_click
00005910 t nf2_cb_panel_enter
000057e0 t nf2_cb_panel_expose
00005a30 t nf2_cb_panel_leave
Legend:
uppcase T imples code is in the text segment and the reference is Global.
lowercase t implies code is in the text segment and the reference is local.
Comment: Even if I redid the data structures to include all the values that each mainline needs - this would not solve the problem, only mask it. Example: the server.c does not need the ton of ui.c based GUI values, since it does not require a GUI or even have display capabilities.
%.c files include the gcc cflag of -fPIC on compile, and -shared -Wl on the link step.
I hope someone can help me look at this differently.