从该系列中很容易找到如何使用 dlsym()和其他函数,但是在内部如何工作呢?是否可以编写自己的,容易实现的dlsym()?
我想知道是否有可能实现类似的行为,但在不将与-ldl链接的情况下实现(可以说我无法做到这一点)。
最佳答案
how does it work internally?
正如this answer解释的那样,在GLIBC中,第一个参数实际上是指向
struct link_map
的指针,它包含足够的信息来定位共享库的动态符号表。找到符号表和DT_HASH
或DT_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/