2016-07-04 30 views
4

es ist sehr einfach zu finden, wie dlsym() und andere Funktionen aus dieser Familie verwenden, aber wie funktioniert es intern arbeiten? Ist es möglich, eigene, einfache Implementierung von dlsym() zu schreiben?Wie funktioniert das DLSym?

Ich frage mich, ob es möglich ist, ähnliches Verhalten zu erreichen, aber ohne Verknüpfung mit -ldl (lässt sagen, dass ich das nicht tun kann).

Antwort

9

Wie funktioniert es intern?

this answer Wie erläutert, in GLIBC der erste Parameter tatsächlich ein Zeiger auf struct link_map ist, der genug Informationen enthält, die dynamische Symboltabelle der gemeinsam benutzten Bibliothek zu lokalisieren. Sobald die Symboltabelle und DT_HASH oder DT_GNU_HASH lokalisiert sind, verwendet dlsym die eine oder andere Hash-Tabelle, um den angegebenen Symbolnamen zu finden.

Ist es möglich, eigene, einfache Implementierung von dlsym() zu schreiben?

Ja. Wenn Ihnen die Suchgeschwindigkeit nicht wichtig ist, können Sie einfach die dynamische Symboltabelle linear durchsuchen. Der Code, um dies zu tun ist ziemlich einfach, vor allem, wenn die gemeinsame Bibliothek (optional) Abschnitt Kopfzeile hat: alles, was Sie tun müssen, ist Ort der .dynsym und .dynstr Abschnitte im Speicher finden, und dann (vorausgesetzt, Sie suchen nach Symbol

)
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; 

Wenn Sie über Lookup-Geschwindigkeit ist egal (dlsym sicherlich der Fall ist), müssen Sie .hash oder .gnu_hash, dekodieren, die etwas komplizierter ist. Sie könnten here starten.