2016-07-04 31 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