glibc - dlsym如何工作?

标签 glibc dlopen dlsym

从该系列中很容易找到如何使用 dlsym()和其他函数,但是在内部如何工作呢?是否可以编写自己的,容易实现的dlsym()?

我想知道是否有可能实现类似的行为,但在不将与-ldl链接的情况下实现(可以说我无法做到这一点)。

最佳答案

how does it work internally?



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

Is it possible to write own, easy implementation of 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

关于glibc - dlsym如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38191776/

相关文章:

cmake - 如何通过CMake交叉编译CMake for ARM

c - dlopen 无法使用代码覆盖工具 (lcov/gcov)

c - 写入关闭的本地 TCP 套接字不会失败

shared-libraries - 主程序和共享库在 __static_initialization_and_destruction_0 中初始化相同的静态变量

c++ - 如何防止插件崩溃影响主程序 (dlopen)

c++ - 错误 : void value not ignored as it ought to be

c++ - 在共享库中定义抽象类的接口(interface)

c - 如何将 dlsym 返回的指针正确赋值给函数指针类型的变量?

linux - 如何链接到特定的 glibc 版本?

c - 需要一种优化堆使用的方法 C - Freebsd/glibc