2016-07-04 32 views
4

很容易找到使用 dlsym()和这个系列的其他功能,但如何在内部工作?是否有可能编写自己的,简单的dlsym()实现?dlsym如何工作?

我想知道是否可以实现类似的行为,但不连接-ldl(可以说,我不能这样做)。

回答

9

它是如何在内部工作的?

作为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