Ich versuche, die Ausgabe eines nm oder readelf -s auf einer ausführbaren Datei zu verarbeiten. Ich habe jedoch Probleme, statische Funktionen in der Ausgabe voneinander zu unterscheiden.
Hier ist, woran ich arbeite:
test.c
%Vor%sonstiges.c
%Vor%Ich kompiliere diese wie folgt:
%Vor%Und dann einen nm-Befehl ausführen, um alle Symbole zu erhalten:
%Vor%Darunter erscheinen die folgenden zwei Symbole (für meine statischen Funktionen):
%Vor%Gibt es eine Methode, um unterscheiden zu können, aus welcher Datei die spezifische foo-Funktion stammt? Oder muss ich etwas Magie vor dem Kompilieren machen, um das zum Laufen zu bringen?
Ich sollte hinzufügen, dass ich für meinen Anwendungsfall Zugriff auf die endgültige Binärdatei und die von ihm verwendeten Objektdateien habe, aber ich kann es nicht selbst erstellen, um sicherzustellen, dass es eine Symboltabelle hat.
Danke!
Ihre Frage geht davon aus, dass Sie bei einer ausführbaren Datei immer feststellen können
die Namen der static
(lokalen) Funktionen, die darin kompiliert wurden,
mit nm
oder einem anderen Werkzeug. So können Sie sehen, wenn zwei oder
mehr solche Namen sind gleich und werfen die Frage auf, wie man entdeckt
aus welchen Quelldateien sie kompiliert wurden.
Diese Annahme ist jedoch falsch. Im Fall von gcc, wenn Dateien kompiliert werden
Mit Optimierung -O0
werden dann lokale Symbole im Objekt ausgegeben
Dateisymbol Tabelle. -O0
ist der Standardwert, also gilt es im Fall von:
Aber wenn Dateien auf einer höheren Optimierungsebene kompiliert werden - wie sie sicherlich sind
wird für einen Release-Build sein - dann werden lokale Symbole aus dem Objekt weggelassen
Dateien Symboltabelle. Der Linker sieht sie also nie. Du kannst dich also nicht erholen
sie aus der ausführbaren Datei mit nm
oder irgendetwas anderem.
Kompilieren Sie Ihre Beispieldateien mit:
%Vor% dann nm test
erneut, und Sie werden feststellen, dass die:
ist zusammen mit allen anderen statischen Funktionsnamen verschwunden.
Wenn Sie in diesem Fall nicht steuern können, wie die ausführbare Datei erstellt wird, dann können Sie nicht sicherstellen, dass es überhaupt möglich ist, dass Ihre Frage auftaucht .
Wenn Sie können steuern, wie die ausführbare Datei erstellt wird, um sicherzustellen, dass es sich um Dateien handelt
kompiliert mit -O0
, dann gibt es mehrere Möglichkeiten, wie Sie die
statische Funktionsnamen für Quelldateien. Zwei ebenso einfache wären:
und
%Vor%jeder von ihnen wird einen Quelldateinamen an der Spitze jedes Stücks von auflisten Symbole, die von ihm kommen.
(Und wenn es nötig ist, entgeht der von @Amol vorgeschlagene gdb
-Ansatz nicht der Einschränkung, dass die ausführbare Datei mit der Optimierung -O0
kompiliert worden sein muss)
Ich habe die folgende Sequenz ausprobiert.
Wenn Sie die Ausgabedatei ohne Debugging-Symbole entfernt haben, können Sie mit gdb
eine Objektdatei erstellen.
Befolgen Sie die folgenden Befehle:
gibt folgendes als Ausgabe
%Vor% Dann
(gdb)
wird in Terminal
Geben Sie die folgenden Befehle nacheinander ein (die Eingabeaufforderung (gdb)
wird standardmäßig bei der Eingabe von Befehlen angezeigt)
Jetzt können Sie in Ihrem Ordner eine Datei mit dem Namen Dateiname sehen. Öffnen Sie diese Datei im Texteditor, dann können Sie Informationen wie folgt sehen:
%Vor% Hier können Sie deutlich sehen, welche foo()
Funktion von welcher .c
Datei kommt. Hoffe, das hilft dir.
Sie müssen möglicherweise die ELF-Symboltabelle lesen und den ELF32_ST_BIND-Wert extrahieren.
Gemäß der ELF-Spezifikation (siehe Ссылка ) können die Werte für ELF32_ST_BIND sein:
%Vor%Dabei ist STB_LOCAL definiert als "Lokale Symbole sind außerhalb der Objektdatei, die ihre Definition enthält, nicht sichtbar. Lokale Symbole mit demselben Namen können in mehreren Dateien vorhanden sein, ohne sich gegenseitig zu stören." die scheinen ziemlich gut mit statischen C-Funktionen übereinzustimmen.
Nehmen Sie zum Beispiel eine Probe und ändern Sie sie leicht:
%Vor% und kompilieren mit gcc -o test test.c other.c
und Blick auf die Symboltabelle (viele Einträge entfernt):
Wir können sehen, dass die beiden statischen Funktionen als LOCAL und die eine "normale" Funktion als GLOBAL
angezeigt wirdHinweis: Während diese Methode mit Nicht-Debug-Dateien funktioniert, können wir diese Methode nicht verwenden, wenn die letzte Datei entfernt wird.
Tags und Links c static nm symbol-table