2009-03-31 9 views
2

Ich kompiliere ein C-Programm mit dem SPARC RTEMS C-Compiler.Wie bekomme ich Speicherorte von Bibliotheksfunktionen?

Mit der Xlinker -M-Option kann ich eine große Speicherkarte mit vielen Dingen, die ich nicht erkenne, erhalten.

Ich habe auch versucht, das RCC nm-Dienstprogramm, das eine etwas besser lesbare Symboltabelle zurückgibt. Ich nehme an, dass der Speicherort, der von diesem Dienstprogramm für beispielsweise printf angegeben wird, der Speicherort ist, in dem sich printf befindet, und dass jedes Programm, das printf aufruft, diesen Speicherort während der Ausführung erreicht. Ist das eine gültige Annahme?

Gibt es eine Möglichkeit, eine Liste von Standorten für alle Bibliothek/Systemfunktionen zu erhalten? Wenn die Verknüpfung abgeschlossen ist, werden dann nur die Funktionen verknüpft, die die ausführbare Datei aufruft, oder sind es alle Funktionen in der Bibliothek? Es scheint mir Letzteres zu sein, angesichts der Anzahl von Dingen, die ich in der Symboltabelle und der Speicherkarte gefunden habe. Kann ich dafür sorgen, dass nur die benötigten Funktionen verknüpft werden?

Danke für Ihre Hilfe.

Antwort

4

Wenn Sie eine dynamische Bibliothek verwenden, kann das nm-Dienstprogramm meistens nicht die genaue Antwort geben. Binaries verwenden heutzutage sogenannte verschiebbare Adressen. Diese Adressen ändern sich, wenn sie dem Adressraum des Prozesses zugeordnet werden.

Mit der Option Xlinker -M kann ich eine große Speicherkarte mit vielen Dingen, die ich nicht erkenne, erhalten.

Die Karte Linker wird in der Regel alle Symbole - bei Ihnen, die Standard-Bibliotheken, Laufzeit Haken usw.

Gibt es eine Möglichkeit, eine Liste von Standorten für alle Bibliothek/Systemfunktionen zu bekommen?

Die Header sind ein guter Ort, um zu schauen.

Auch, wenn die Verknüpfung erfolgt ist, verbindet es nur die Funktionen, die die ausführbare Datei aufruft, oder sind es alle Funktionen in der Bibliothek?

Verknüpfen bedeutet nicht unbedingt, dass alle Symbole aufgelöst werden (d. H. Eine Adresse erhalten). Dies hängt vom Typ der Binärdatei ab, die Sie erstellen.

Einige Compiler wie gcc erlauben Ihnen jedoch, ob Sie eine nicht verschiebbare Binärdatei erstellen oder nicht. (Für gcc können Sie exp-Dateien, dlltool usw. auschecken.) Überprüfen Sie mit der entsprechenden Dokumentation.

+0

Wenn ich die Option -static für den Linker verwende, um die Verwendung von gemeinsam genutzten Bibliotheken zu vermeiden, werden dadurch die mit dynamischen Bibliotheken verbundenen Probleme vermieden? – mandaleeka

+0

Welche Probleme? Ich nehme an, Sie haben doppelte Symboldefinition. In diesem Fall nein. Sie müssen sich verstecken/umbenennen, um den Namenskonflikt zu vermeiden. – dirkgently

+0

Sorry, ich meinte würde nm mir die genaue Antwort geben oder ist die Adresse noch umsetzbar? – mandaleeka

1

Mit dynamischer Verknüpfung, 1. Ihre ausführbare Datei hat einen besonderen Platz für alle externen Anrufe (PLT-Tabelle). 2. Ihre ausführbare Datei hat eine Liste von Bibliotheken, die davon abhängt,

Diese beiden Dinge sind unabhängig. Es ist unmöglich zu sagen, welche externe Funktion in welcher Bibliothek lebt.

Wenn ein Programm einen externen Funktionsaufruf ausführt, ruft es tatsächlich einen Eintrag in der PLT-Tabelle auf, der in den dynamischen Lader springt. Der dynamische Loader prüft, welche Funktion aufgerufen wurde (über PLT), sieht seinen Namen (über die Symboltabelle in der ausführbaren Datei) und sucht diesen Namen in ALLEN Bibliotheken, die zugeordnet sind (abhängig davon, welche ausführbare Datei davon abhängig ist).Sobald der Name gefunden ist, wird die Adresse der entsprechenden Funktion in den PLT zurückgeschrieben, so dass der nächste Anruf direkt unter Umgehung des dynamischen Linkers erfolgt.

Um Ihre Frage zu beantworten, sollten Sie die gleiche Aufgabe wie Dynamic Linker tun: Holen Sie sich eine Liste der abhängigen Bibliotheken und suchen Sie alle Namen in ihnen. Dies könnte mit dem Dienstprogramm 'nm' oder 'readelf' geschehen.

Wie bei der statischen Verknüpfung, denke ich, dass alle Symbole in der angegebenen Objektdatei in libXXX.a verknüpft werden. Zum Beispiel besteht die statische Bibliothek libXXX.a aus den Objektdateien a.o, b.o und c.o. Wenn Sie eine Funktion foo() benötigen, die sich in a.o befindet, wird a.o mit Ihrer App verknüpft - zusammen mit der Funktion foo() und allen anderen darin definierten Daten. Aus diesem Grund werden beispielsweise C-Bibliotheksfunktionen pro Datei aufgeteilt.

1

Wenn Sie dynamisch verknüpfen möchten, verwenden Sie dlopen/dlsym, um UNIX .so freigegebene Bibliothekseinstiegspunkte aufzulösen.

http://www.opengroup.org/onlinepubs/009695399/functions/dlsym.html

Vorausgesetzt, dass Sie die Namen der Funktionen kennen, die Sie anrufen möchten, und die .so sie sind in. Es ist ziemlich einfach.

void *handle; 
int  *iptr, (*fptr)(int); 

/* open the needed object */ 
handle = dlopen("/usr/home/me/libfoo.so", RTLD_LOCAL | RTLD_LAZY); 

/* find the address of function and data objects */ 
*(void **)(&fptr) = dlsym(handle, "my_function"); 
iptr = (int *)dlsym(handle, "my_object"); 

/* invoke function, passing value of integer as a parameter */ 
(*fptr)(*iptr); 

Wenn Sie eine Liste aller dynamischen Symbole zu bekommen, objdump -T file.so ist die beste Wahl. (objdump -t file.a wenn Sie nach statisch gebundenen Funktionen suchen). Objdump ist plattformübergreifend, Teil von binutils, also können Sie im Notfall Ihre Binärdateien in ein anderes System kopieren und sie mit objdump auf einer anderen Plattform interrorstellen.

Wenn dynamische Verknüpfung optimal sein soll, sollten Sie sich Ihre ld.so.conf anschauen, die die Suchreihenfolge für die ld.so.cache angibt (so.cache right;).