4

I understand that due to shared libraries not knowing where they will be placed by the dynamic loader, they have to rely on the GOT to resolve all references to global data. For example, a shared library has a global variable named globe, a possible way to access such variable will be something like this mov eax,DWORD PTR [ecx-0x10], assuming that ecx contains the address of the GOT and the offset of globe is 0x10. Now, lets say that process A uses this shared library, immediately followed by process B. I know that the code of a shared library can be shared between processes, but data cannot since each process could potentially change the data depending on its execution. Therefore, each process will get it's own GOT, which means that, thanks to virtual memory, the address ecx + 0x10 will point to completely two different GOTs depending on what process is running that piece of code. But then say one of the processes loads a second shared library with a different global data member at offset 0x10 in its GOT. How exactly can the process using the two libraries access each libraries' global data if they are both at the same virtual address?

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
GamefanA
  • 1,555
  • 2
  • 16
  • 23
  • Dynamic loading and shared objects are quite complicated beasts. You just have to take it on faith that The Right Thing Will Happen[tm]. How? Unless someone's purpose is to write their own dynamic loader, I see no reason why anyone care. C++ specifies how things work. As long as the code meets all requirements and does not introduce undefined behavior, things like shared libraries will work as advertised, without anyone have to worry how CPU register mapping. Another thing you haven't mentioned at all is virtual memory and the MMU, which plays a big part in this. – Sam Varshavchik Feb 23 '19 at 00:57
  • 1
    If I wanted someone to tell me to have faith, I would've waited until Sunday service. – GamefanA Feb 23 '19 at 10:21
  • I think the answer for what you're getting at might be "copy-on-write". See [this answer](https://stackoverflow.com/a/23051178/488095). – jamieguinan Feb 24 '19 at 18:01

1 Answers1

0

But then say one of the processes loads a second shared library with a different global data member at offset 0x10 in its GOT. How exactly can the process using the two libraries access each libraries' global data if they are both at the same virtual address?

There are three parts to the answer:

  1. How does each library access its own globals?
  2. How does each library access the other libraries's globals?
  3. How does main executable access globals from either library?

The best way to understand this is to compile two trivial libraries, and a main binary, and then examine various GOT sections and observe when they change and in what way.

The root of your confusion appears to be that assume that there is only one GOT. That is not the case: each library will have its own .got section, and the compiler and the runtime loader will arrange it so that ecx points to the right .got.

For main executable, the answer is "copy relocations".

Here is a good article on the subject.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • Hmm, I thought that the main executable also used PIC and not load time relocation? (I mean it has to use load time relocation to put the address of the global variable in the GOT but that's about it) – GamefanA Feb 27 '19 at 06:20