Why are nonstatic global variables defined in shared objects referenced using GOT? - linux

I mean nonstatic global variables that are defined in the module, not externally.
Why does it have to be referenced through GOT? Why no use relative address?(since the distance between the global variable in the .data section and the reference in the .text section is a constant, it's also position-independent)

Since your variable isn't static, on ELF it can be interposed (think of LD_PRELOAD).

I also have the same confusion.
If there is one global variable with same name defined in both two DSOs and they are dynamically linked into one executable, will both libraries access the same copy of the variable?
And which library(library's data section) the variable locates depends on the order of libraries loading?

Related

How do I find a variable in NODEJS

Good day,
I am trying to read a variable from a process. With javascript, I know, you can use console.log(window['variable-name']) to find a variable's contents using a string.
However, for NodeJs, I know you can use console.log(global['variable-name']), but the variable needs to be global, how can I read module local variables?
Short answer: only by exporting them (module.exports.your_var = your_var) or by setting the variable on global (global.your_var = your_var).
Longer answer:
Modules, when loaded by Node.js, are being wrapped within a Javascript function and then called when required the first time. Function variables belong to the function's scope and they are unaccessible from outside.

how to create global nanoc variable between preprocessor and rule

I create variable #foo in preprocessor block. It is global for the time of preprocessing, i.e. different methods can access it. However, in compilation time, i.e. in Rules, this variable is not available.
Currently, I use #config map to store such variables. How to create global variable that will be shared without using the #config map?

ELF Dynamic loader symbol lookup ordering

What is the search order for symbol lookup when resolving dynamic relocations?
When resolving symbols for a shared library does the loader first search in the 'main executable' (to let the main executable override definitions...) or what?
Per my understanding, each executable object has its own "lookup scope":
The main executable is usually the first object in the "global" lookup scope. This means that symbols defined in the main executable would override those in dependent shared libraries. Shared objects that are added using the LD_PRELOAD facility are added to the global lookup scope, right after the main executable.
However, if the shared object being loaded uses the DF_SYMBOLIC flag, then symbol references that originate within that object will look for definitions within the object before searching in the global lookup scope.
Shared objects opened using dlopen() may have their own dependencies. If the RTLD_GLOBAL flag was not set during the call to dlopen(), these dependencies are added to the lookup scope for that object, but do not affect the global lookup scope. If the RTLD_GLOBAL flag was passed to dlopen(), then the shared object (and its dependencies) will be added to the "global" lookup scope, changing the behavior of subsequent symbol lookups.
Ulrich Drepper's guide "How to Write Shared Libraries" is recommended reading on this topic.
When resolving symbols for a shared library does the loader first search in the 'main executable' (to let the main executable override definitions...) or what?
Yes, exactly. The dynamic loader has a linked list of loaded ELF objects (the head of the list is _r_dynamic.r_map) and searches dynamic symbol tables of objects in that list linearly, until it finds the symbol definition it is looking for.
The head of the list always points to the main executable. If a given symbol is exported from the main executable, then it (almost) always "wins" (overrides other definitions).
However, note that -Bsymbolic linker flag changes the picture a bit.

Global Static Pointer Issue

This is a rather a problem from a convoluted situation. I have a static pointer sitting in one of my header files. Which is being included everywhere, this is why I put it as a static pointer. So that I can quickly initilize it in my main function so that other files can use it.
The problem is this, even after I initialize it and put stuff into it. Other files only find it NULL. It is like every file that includes the header with the static pointer makes a copy of it for itself and even when others initialize it, each file has their own separate copy. Negating ofcourse, the purpose of having a global variable.
How can I cope up with this?. Maybe I am understanding a static variable wrong, or maybe is it because its a pointer?
Should i be declaring it as: &variable = 5; or just as variable = 5; or &variable = (int)5?
It is like every file that includes the header with the static pointer makes a copy of it for itself and even when others initialize it, each file has their own separate copy.
That's what static means when applied to a variable at namespace scope: the variable is given internal linkage, making it "local" to a given translation unit (source file).
If you have a static variable at namespace scope in a header file and you include that header file in multiple .cpp files, there will be multiple instances of that variable: one for each of the .cpp files that include the header file.
If you want a global variable that is shared across multiple source files, you need to make it extern. Declare the variable as extern in the header file, then define the extern variable in exactly one of your .cpp files.
Yes, you are understanding the static keyword wrong. Static keyword at namespace and file scope declares a variable that is only visible inside the translation unit (basically a single .cpp file plus all of its includes) where it is declared. By declaring a static variable in header that you use in multiple .cpp files you are effectively defining multiple variables.
If you want a global pointer then declare it extern without static in the single header and define it without extern or static in a single .cpp file. E.g.:
In foo.h:
extern int * p;
and in main.cpp:
int * p = something;
Defining the global pointer static results in the C++ compiler creating a separate pointer for every translation unit, the definition is included in. I'm pretty sure it's not what you want and it's the cause of your problems.
You should declare it extern in a header and define once in one cpp file.
I can imagine the confusion came from the way, static keyword works inside a class or a struct definition. Indeed, it works differently there and it creates one variable, common for all instances of the class or struct.
Btw. In case you actually want a variable to be visible only in one translation unit the recommended way is to put ii into an anonymous namespace. static works too, but it's use is discouraged as deprecated.

Main Program and Shared Library initializes same static variable in __static_initialization_and_destruction_0

Does anyone know why a library initialized within dlopen() would initialize a static variable owned by the main program. Both the main program and shared library have a copy of the static variable, but for some reason the shared library re-initializes the main program's copy of the static variable and destructs it, causing a segfault when the main program attempts to destruct it.
Is this a case of bad name mangling in the symbol table?
This is a case where the runtime linker only wants a single active copy of a symbol in a process. If both a shared object and the executable have a copy of the symbol, the runtime linker will resolve all references to one of those.
What you can do to solve this problem is to use symbol reduction using the version command of the link editor when building the shared object. Make sure the symbol for the static variable is not global and you will get the behavior you are looking for.

Resources