My question is about static variable (static void*) created inside shared library (let's call this library 'S'), but it's an internal variable not shown outside, but every call of API depends on it. Now let's think about a case, when a program (let's call it main program) links to another two shared libraries and every one of them is linked with library S. Now what happens to this static variable for our main program? Does it have one instance? Two?
Suma's answer is correct. There will only be a single instance of the static variable. This is also why having static globals in shared libraries can be a huge problem. One real-world example where this can happen:
Apache webserver which loads the following modules:
mod_php which is linked against
libxml2
mod_perl which loads
libxml2
Now if some PHP code modifies a global setting like a parser option in libxml2, the Perl code will also see these changes. This can lead to bugs that are extremely hard to diagnose. So you should avoid global state in your shared libraries at all cost.
(With libxml2 you can make most settings locally these days.)
Assuming your static variable is only defined in one translation unit, it will exist only once, as the shared library is loaded only once into the process.
This would get more difficult if a mixture of shared and static linking was used.
The compiler creates a different instance for every global static variable, even when you have several such variables with identical names.
In fact, the compiler (or possibly, the preprocessor) implicitly changes the name of every such variable, according to the name of the source file which declares it.
You can prove this to yourself by declaring a global static variable in a header file, and then include this header file in several different source files. Try to set it to a different value in each source file, and you'll see that this variable retains its different value in each source file.
Related
Let's say, in my C executable project, I use a C library to which I have source access - in fact, the .c files of the library get built as part of the build process for my C executable.
Then, let's say in some of the library .c files, let's say exotic.c, there is something like:
static struct exotic_type all_exotic_array[NUM_EXOTIC_ITEMS][8];
... which the author of the library believes should remain hidden (ergo static) - but which, it turns out, I need a reference to in my code; therefore I'd like to make this variable's symbol publicly accessible.
So, in principle I could just erase the static keyword there and recompile - and I'd get the all_exotic_array as global. However, let's say I also do not want to change the source code of the library.
So in this context, I can intervene in the Makefile, when the individual library .c files get compiled. So:
Is there a compilation switch, with which I could tell the compiler gcc (or linker ld?), while compiling exotic.c, something like: "please ignore the static storage class specifier of the symbol all_exotic_array, and make it available globally"?
If not - is there any other action I could take (maybe after compilation of exotic.c but before linking my executable), to make the symbol all_exotic_array globally available?
I have seen
Access of static variable from one file to another file
Renaming symbols at compile time without changing the code in a cross platform way
Access a global static variable from a .so file without modifying library
Keep all exported symbols when creating a shared library from a static library
... which hint that there may be a possibility to do what I want, however I couldn't find exactly what to do in my use case.
In my code (game engine code) there are multiple source (.c) files which maintain the status of the game, status like
START
CONFIGURE
STOP
END
DEFAULT
RUNNING
for maintaining state, one global variable gameStatus used which shared between multiple source files using extern keyword. now I have read that the global variable is bad to use and it allows the outside module to change it and as the number of components using global variable increases, the complexity of the interactions can also increase.
So I have limited scope that variable to one file using static keyword and added accessor methods like get or set APIs in the same file. So other files only access that variable using accessor APIs.
I have removed the global variable that is good but now every other file which used that global variable have to call accessor APIs which seems to add the overhead of function calls,
so now I am confused which is better? any C standard about how efficiently share the data between different source files?
The fact that global variables are "bad practice" is entirely opinion based and 100% dependent on the context. It is impossible to say whether you are applying such "bad practice" or not without looking at your code. Global variables are not bad practice per se, using them in the wrong way is. Global variables are often necessary in C. Take as an example the C standard library: errno is a global variable that is used basically everywhere in both library code and user code to check for errors. Is that bad practice? Could they have defined a function get_errno() instead (well to be honest they actually did it's just hidden... but that's for complex concurrency reasons)? I'll let you decide.
In your specific case, changing a globally visible variable to static and then creating two functions only to get and set its value is totally unnecessary. Any part of the code can still modify the variable, but now it's just more annoying to do so, and it could also lead to slower code if not optimized correctly. All in all, by creating those functions you just stripped the variable of the static qualifier.
I am reading this article on PLT (Process Linkage Table) and GOT (Global Offset Table). While the purpose of PLT is clear to me, I'm still confused about GOT. What I've understood from the article is that GOT is only necessary for variables declared as extern in a shared library. For global variables declared as static in a shared library code, it is not required.
Is my understanding right, or am I completely missing the point.
Perhaps your confusion is with the meaning of extern. Since the default linkage is extern, any variable declared outside function scope without the static keyword is extern.
The reason the GOT is necessary is because the address of variables accessed by the shared library code is not known at the time the shared library is generated. It depends either on the load address the library gets loaded at (if the definition is in the library itself) or the third-party code the variable is defined in (if the definition is elsewhere). So rather than putting the address inline in the code, the compiler generates code to read the shared library's GOT and then loads the address from the GOT at runtime.
If the variable is known to be defined within the same shared library (either because it's static or the hidden or protected visibility attribute it used) then the address relative to the code in the library can be fixed at the time the shared library file is generated. In this case, rather than performing a lookup through the GOT, the compiler just generates code to access the variable with program-counter-relative addressing. This is less expensive both at runtime and at load time (because the whole symbol lookup and relocation process can be skipped at load time).
I've got a worked binary used in embeded system. Now i want to write a some kind of patch for it. The patch will be loaded into a RAM bellow the main program and then will be called from main program. The question is how to tell gcc to use manually setted addresses of some function which will be used from patch. in other words:
Old code has function sin() and i could use nm to find out the address of sin() in old code. My patched code will use sin() (or something else from main programm) and i want to tell the gcc (or maybe ld or maybe something else) for it to use the static address of function sin() while it linking the patched code. is it possible?
The problem is that you would gave to replace all references to the original sin() function for the patched code. That would require the runtime system to contain all the object code data used to resolve references, and for the original code to be modifiable (i.e. not in ROM for example).
Windriver's RTOS VxWorks can do something close to what you are suggesting; the way it does it is you use "partial linking" (GNU linker option -r) to generate an object file with links that will be resolved at runtime - this allows an object file to be created with unresolved links - i.e. an incomplete executable. VxWorks itself contains a loader and runtime "linker" that can dynamically load partially linked object files and resolve references. A loaded object file however must be resolvable entirely using already loaded object code - so no circular dependencies, and in your example you would have to reload/restart the system so that the object file containing the sin() were loaded before those that reference it, otherwise only those loaded after would use the new implementation.
So if you were to use VxWorks (or an OS with similar capabilities), the solution is perhaps simple, if not you would have to implement your own loader/linker, which is of course possible, but not trivial.
Another, perhaps simpler possibility is to have all your code call functions through pointers that you hold in variables, so that all calls (or at least all calls you might want to replace) are resolved at runtime. You would have to load the patch and then modify the sin() function's pointer so that all calls thereafter are made to the new function. The problem with this approach is that you would either have to know a priori which functions you might later want to replace, or have all functions called that way (which may be prohibitively expensive in memory terms. It would perhaps be useful for this solution to have some sort of preprocessor or code generator that would allow you to mark functions that would be "dynamic" in this way and could automatically generate the pointers and calling code. So for example you might write code thus:
__dynamic void myFunction( void ) ;
...
myFunction() ;
and your custom preprocessor would generate:
void myFunction( void ) ;
void (*__dynamic_myFunction)(void) = myFunction() ;
...
__dynamic_myFunction() ;
then your patch/loader code would reassign myFunctionDyn with the address of the replacement function.
You could generate a "dynamic symbol table" containing just the names and addresses of the __dynamic_xxxxx symbols and include that in your application so that a loader could change the __dynamic_xxxxx variables by matching the xxxxx name with the symbols in the loaded object file - if you load a plain binary however you would have to provide the link information to the loader - i.e. which __dynamic_xxxxx variable to be reasssigned and teh address to assign to it.
I am reading this article on PLT (Process Linkage Table) and GOT (Global Offset Table). While the purpose of PLT is clear to me, I'm still confused about GOT. What I've understood from the article is that GOT is only necessary for variables declared as extern in a shared library. For global variables declared as static in a shared library code, it is not required.
Is my understanding right, or am I completely missing the point.
Perhaps your confusion is with the meaning of extern. Since the default linkage is extern, any variable declared outside function scope without the static keyword is extern.
The reason the GOT is necessary is because the address of variables accessed by the shared library code is not known at the time the shared library is generated. It depends either on the load address the library gets loaded at (if the definition is in the library itself) or the third-party code the variable is defined in (if the definition is elsewhere). So rather than putting the address inline in the code, the compiler generates code to read the shared library's GOT and then loads the address from the GOT at runtime.
If the variable is known to be defined within the same shared library (either because it's static or the hidden or protected visibility attribute it used) then the address relative to the code in the library can be fixed at the time the shared library file is generated. In this case, rather than performing a lookup through the GOT, the compiler just generates code to access the variable with program-counter-relative addressing. This is less expensive both at runtime and at load time (because the whole symbol lookup and relocation process can be skipped at load time).