dlsym是如何工作的?

时间:2016-07-04 20:24:01

标签: glibc dlopen dlsym

很容易找到如何使用 dlsym()以及此系列中的其他功能,但内部如何工作?是否有可能编写自己的,易于实现的dlsym()?

我想知道是否有可能实现类似的行为,但没有链接-ldl(假设我不能这样做)。

1 个答案:

答案 0 :(得分:10)

  

它在内部如何运作?

正如this answer所解释的那样,在GLIBC中,第一个参数实际上是指向struct link_map的指针,它包含足够的信息来定位共享库的动态符号表。找到符号表DT_HASHDT_GNU_HASH后,dlsym会使用一个或另一个哈希表来查找给定的符号名称。

  

是否有可能编写自己的,易于实现的dlsym()?

是。如果您不关心查找速度,则可以简单地对动态符号表进行线性搜索。这样做的代码非常简单,特别是如果共享库有(可选)部分标题:您需要做的就是在内存中找到.dynsym.dynstr部分的位置,然后(假设您正在寻找符号"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;

如果您确实关心查找速度(dlsym当然可以),则需要解码.hash.gnu_hash,这有点复杂。你可以开始here