Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the dlsym work?

it's very easy to find how to use dlsym() and other functions from this family, but how does it work internally? Is it possible to write own, easy implementation of dlsym()?

I'm wondering if it is possible to achieve similar behavior but without linking with -ldl (lets say I can't do this).

like image 524
kashpersky Avatar asked Jul 04 '16 20:07

kashpersky


1 Answers

how does it work internally?

As this answer explains, in GLIBC the first parameter is actually a pointer to struct link_map, which contains enough info to locate the dynamic symbol table of the shared library. Once the symbol table and DT_HASH or DT_GNU_HASH are located, dlsym uses one or the other hash table to find the given symbol name.

Is it possible to write own, easy implementation of dlsym()?

Yes. If you don't care about the speed of lookup, you can simply do linear search of the dynamic symbol table. The code to do so is quite simple, especially if the shared library has (optional) section header: all you need to do is find location of .dynsym and .dynstr sections in memory, and then (assuming you are looking for symbol "foo")

const char *strtab = ... /* locate .dynstr */
const ElfW(Sym) *sym = ... /* locate .dynsym */

for (; sym < end_of_dynsym; ++sym) {
  if (strcmp(strtab + sym->st_name, "foo") == 0) {
    /* found it */
    return load_address + sym->st_value;
  }
}
/* symbol not found */
return NULL;

If you do care about lookup speed (dlsym certainly does), you'll need to decode .hash or .gnu_hash, which is a bit more complicated. You could start here.

like image 189
Employed Russian Avatar answered Sep 17 '22 20:09

Employed Russian