question about link_map data structure in elf on 64-bit Linux systems

Hi all,

I’m trying to determine if some code in DynamicLoaderPOSIXDYLD is correct and I could use some confirmation:

The code in question reads the module id of a module as part of finding the TLS block associated with that module, by determining its location and then reading with a hardcoded 32-bit unsigned read. (The code in question is source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp, in DynamicLoaderPOSIXDYLD::GetThreadLocalData).

I’ve read http://dev.gentoo.org/~dberkholz/articles/toolchain/tls.pdf , which describes a number of architectures and in all cases the value seems to be either size_t or “unsigned long int”. Thus the code appears to be wrong in at least some cases, in that it should be reading 64 bits when debugging 64-bit runtimes. The code presumably works today for 64-bit LSB (little-endian) systems (which is most of the 64-bit Linuxes) because it’s reading the right 32-bits out of the 64-bit location.

But I’m not 100% sure, because

  • I’m not sure that the referenced pdf is definitive
  • I don’t have an MSB 64-bit system to test on to verify that it’s a bug.

Can anyone with any familiarity with this issue comment on this?

Thanks,
Steve

The definitive document is here: I just had a look through and I guess it probably is a bug. Technically the code in DLYDRendezvous::GetThreadInfo() should query not only the location, but also the size of modid (using the same API), and then later issue the appropriately-sized read. It’s not really “wrong” for little-endian systems right now, unless you have 4 billion modules loaded. Steve Pucci wrote:

Great, thanks a lot, Richard. I’ll make the change you suggest to the code I’m working on.

  • Steve

Hi Richard,

I’m looking at this now. I’m having trouble finding the symbol name I need to query to get the modid size in DYLDRendezvous::GetThreadInfo(). Is there a document somewhere that describes those symbols (like _thread_db_link_map_l_tls_modid)? I’m not finding them with Google.

If it’s not readily available, I guess I could just use the size of a pointer on the target?

Thanks again for your help here,

Steve

If it’s not readily available, I guess I could just use the size of a pointer on the target?

Or somewhat safer (but hackier), we could just continue to read 32 bits on little-endian machines and read pointer-sized ints on big-endian targets.