4
很容易找到使用 dlsym()和这个系列的其他功能,但如何在内部工作?是否有可能编写自己的,简单的dlsym()实现?dlsym如何工作?
我想知道是否可以实现类似的行为,但不与连接-ldl(可以说,我不能这样做)。
很容易找到使用 dlsym()和这个系列的其他功能,但如何在内部工作?是否有可能编写自己的,简单的dlsym()实现?dlsym如何工作?
我想知道是否可以实现类似的行为,但不与连接-ldl(可以说,我不能这样做)。
它是如何在内部工作的?
作为this answer解释,在GLIBC第一参数实际上是指向struct link_map
,它包含足够的信息来找到共享库的动态符号表。一旦符号表和DT_HASH
或DT_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。