2012-08-29 11 views
6

Ich baue ein Projekt, das mehrere gemeinsame Bibliotheken und ausführbare Dateien erstellt. Alle Quelldateien, die zum Erstellen dieser Binärdateien verwendet werden, befinden sich in einem einzelnen/src-Verzeichnis. Daher ist es nicht offensichtlich, herauszufinden, welche Quelldateien zum Erstellen der einzelnen Binärdateien verwendet wurden (es gibt eine Viele-zu-Viele-Beziehung).Wie finden Sie * .c und * .h Dateien, die zum Erstellen einer Binärdatei verwendet wurden?

Mein Ziel ist es, ein Skript zu schreiben, das eine Reihe von C-Dateien für jede Binärdatei analysiert und sicherstellt, dass nur die richtigen Funktionen von ihnen aufgerufen werden.

Eine Option scheint zu versuchen, diese Informationen aus Makefile zu extrahieren. Dies funktioniert jedoch nicht gut mit generierten Dateien und Headern (aufgrund der Abhängigkeit von Includes).

Eine andere Option könnte sein, einfach Call Graphen zu durchsuchen, aber das würde kompliziert werden, weil viele Funktionen mit Funktionszeigern aufgerufen werden.

Irgendwelche anderen Ideen?

+1

Nur aus Neugier: Warum versuchst du das? – stefan

+0

Der Distributionspaket-Mechanismus kennt alle Abhängigkeiten ... –

+0

Haben Sie eine genaue Definition, was "die richtigen Funktionen heißen" bedeutet? Es ist nicht offensichtlich und ist nicht einfach. –

Antwort

6

Sie können zuerst Ihr Projekt mit Debug-Informationen (gcc-g) kompilieren und objdump verwenden, um die Quelldateien zu erhalten.

objdump -W <some_compiled_binary> 

Das Zwergformat sollte die Informationen enthalten, die Sie suchen.

<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit) 
    < c> DW_AT_producer : (indirect string, offset: 0x5f): GNU C 4.4.3 
    <10> DW_AT_language : 1 (ANSI C) 
    <11> DW_AT_name  : (indirect string, offset: 0x28): test_3.c  
    <15> DW_AT_comp_dir : (indirect string, offset: 0x36): /home/auselen/trials  
    <19> DW_AT_low_pc  : 0x82f0 
    <1d> DW_AT_high_pc  : 0x8408 
    <21> DW_AT_stmt_list : 0x0 

In diesem Beispiel habe ich von test_3 kompilierten Objektdatei, und es wurde in sich .../Studien-Verzeichnis. Dann müssen Sie natürlich ein Skript schreiben, um verwandte Quelldateinamen zu sammeln.

2

Hier ist eine Idee, müssen basierend auf Ihrem spezifischen Build verfeinern. Erstellen Sie einen Build, protokollieren Sie ihn mithilfe des Skripts (z. B. script log.txt make clean all). Der letzte (oder einer der letzten) Schritt sollte die Verknüpfung von Objektdateien sein. (Tipp: Suchen Sie nach cc -o <your_binary_name>). Diese Zeile sollte alle .o Dateien verknüpfen, die entsprechende .c Dateien in Ihrem Baum haben sollten. Dann grep diese .c Dateien für alle enthaltenen Header-Dateien.

Wenn Sie doppelte Namen in Ihren .c Dateien in Ihrem Baum haben, dann müssen wir den vollständigen Pfad in der Linker-Zeile oder arbeiten von der Makefile.

Was Mahmood unten schlägt, sollte auch funktionieren. Wenn Sie ein Bild mit Symbolen haben, sollte strings <debug_image> | grep <full_path_of_src_directory> Ihnen eine Liste von C-Dateien geben.

+0

Gute Idee auch. Aber ich bin nicht vertraut mit den Makefiles für GCC, aber ich mit VS und VS wird nicht zeigen, dass Schritt in vielen Details wird einfach die Bibliothek Dateien auflisten, die Sie gegen verlinken. –

2

Zuerst müssen Sie die Debug-Symbole von der gerade kompilierten Binärdatei trennen. Überprüfen Sie diese Frage, wie Sie dies tun: How to generate gcc debug symbol outside the build target?

Dann können Sie versuchen, diese Datei auf eigene Faust zu analysieren. Ich weiß, wie man das für Visual Studio macht, aber da Sie GCC verwenden, kann ich Ihnen nicht weiterhelfen.

+0

Das sollte auch funktionieren! – jman

1

Sie können Unix nm Werkzeug verwenden. Es zeigt alle Symbole an, die im Objekt definiert sind. Sie müssen also:

  1. Run nm auf binäre und greifen alle undefinierte Symbole
  2. Run ldd auf binäre Liste aller seiner dynamischen Abhängigkeiten greifen (.so-Dateien Ihre binäre verknüpft ist)
  3. Führen Sie nm auf jeder .so Datei Youf in Schritt 2.

, die Ihnen die vollständige Liste der dynamischen Symbole, die Ihre binäre Verwendung gefunden.

Beispiel:

nm -C --dynamic /bin/ls 
....skipping..... 
00000000006186d0 A _edata 
0000000000618c70 A _end 
       U _exit 
0000000000410e34 T _fini 
0000000000401d88 T _init 
       U _obstack_begin 
       U _obstack_newchunk 
       U _setjmp 
       U abort 
       U acl_extended_file 
       U bindtextdomain 
       U calloc 
       U clock_gettime 
       U closedir 
       U dcgettext 
       U dirfd 

All diese Symbole mit Kapital "U" durch ls Befehl verwendet werden.

1

Wenn Ihr Ziel ist C-Quelldateien zu analysieren, können Sie das tun, indem Sie den GCC-Compiler anpassen. Sie könnten MELT zu diesem Zweck verwenden (MELT ist eine High-Level-Domain spezifische Sprache GCC zu erweitern) -Hinzufügen Ihre eigene Analyse in MELT innerhalb GCC-Pässe codieren, aber Sie sollen zuerst über GCC Mitte-End-interne Darstellungen (Gimple, Baum lernen , ...).

Customizing GCC dauert mehrere Tage Arbeit (vor allem, weil GCC Einbauten in den Details sehr komplex sind).

Fühlen Sie sich frei, mich zu fragen mehr über MELT.

Verwandte Themen