Giter Club home page Giter Club logo

Comments (2)

sayon avatar sayon commented on August 22, 2024

Sorry to have missed this issue for a long time, let me make this a bit more clear.

  1. If any variable is global to the process (is used by multiple objects), it has to be accessed through GOT. The reason is that the dynamic loader will select only one of its copies so that when one object modifies it, the other objects will see the change. It is important if the said variable is modified.

  2. Which object will host the variable in run time depends on which libraries are loaded and in which order. The libraries and their dependencies are first loaded in depth-first-order (for each library, its dependencies are loaded before itself), then the dynamic linker performs symbol resolution.

For each GOT (unique per object) the dynamic linker crawls the libraries in a breadth-first-order. It is building the 'global lookup scope' this way. The first object containing the said variable will be its host. The GOT will be

  1. An optimization occurs: If a variable is declared in both shared library AND main executable file, we are going to select the instance in the main executable file. It is happening for two reasons:
  • The executable file is always first in the global lookup scope, so we can guarantee that this is the good place to store the variable.
  • This allows to bypass GOT usage and use absolute addresses inside the executable when addressing the said variable AND the executable is non-PIC. It is faster (GOT introduces overhead) and, in this context, it is safe. But in the dynamic library compiled with PIC enabled, you should always use GOT to address global-global variables because you can never know, where does this variable belong in run time.

You can check the said facts by declaring a variable in both executable file and a shared library. Then print its address and hang. Something like:
Library:

int g = 10;
void f(void) {
printf("%p\n", &g);
}

Executable:

int g;
int main(void) {
g++;
f();
while (1);
return 0;
}

Then compile it, link and launch in background. Use /proc/<PID>/maps file to check where does this address belong: you are going to see that it belongs to the executable's .data section; moreover, in the disassembly, you are going to see that during the increment this variable is going to be addressed by its absolute address rather than through GOT.

from low-level-programming.

yeah-boi avatar yeah-boi commented on August 22, 2024

Thanks for your detailed explanation.

from low-level-programming.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.