2013-12-11 23 views
14

Ich versuche, ein Linker-Problem zu debuggen, das ich habe, wenn ich einen Kernel schreibe.Linker-Skripte: Strategien zum Debuggen?

Das Problem ist, dass ich eine Variable SCAN_CODE_MAPPING habe, die ich nicht verwenden kann - es scheint leer zu sein oder so. Ich kann das beheben, indem ich die Art ändere, wie ich mein Programm verknüpfe, aber ich weiß nicht warum.

Wenn ich in die generierte Binärdatei mit objdump schaue, sind die Daten für die Variable definitiv da, also ist nur etwas kaputt mit dem Verweis darauf.

Here's a gist mit den beiden Linker-Skripten und dem Teil der Symboltabelle, die zwischen den beiden Dateien unterscheidet.

Was mich verwirrt ist, dass beide Symboltabellen alle die gleichen Symbole haben, sie sind alle gleich lang, und sie scheinen die richtigen Daten zu enthalten. Der einzige Unterschied, den ich sehen kann, ist, dass sie nicht in der gleichen Reihenfolge sind.

Bisher habe ich versucht,

  • die SCAN_CODE_MAPPING Speicherplatz Inspektion sicherstellen, dass es die Daten erwarte ich und wurde nicht auf Null gesetzt
  • Überprüfung, dass alle Symbole die gleichen
  • die Überprüfung alle Symbol Inhalt die gleiche Länge
  • bei .data.rel.ro.local suchen, um sicherzustellen, dass es die Adresse der Daten hat

Ein möglicher Hinweis ist diese Warnung:

warning: uninitialized space declared in non-BSS section `.text': zeroing

, die ich sowohl in den gebrochenen und dem richtigen Fall erhalten.

Was soll ich als nächstes versuchen?

+0

Voting als Debug-Hilfe zu schließen. –

Antwort

3

Sie können eine Tonne mehr Informationen mit "readelf" erhalten.

Insbesondere werfen Sie einen Blick auf den Programm-Header:

readelf -l Programm

Ihr BSS Abschnitt als den Standard ganz anders ist, was wohl die Warnung verursacht. Hier ist, was der Standard wie auf meinem System aussieht:

.bss   : 
    { 
    *(.dynbss) 
    *(.bss .bss.* .gnu.linkonce.b.*) 
    *(COMMON) 
    /* Align here to ensure that the .bss section occupies space up to 
     _end. Align after .bss to ensure correct alignment even if the 
     .bss section disappears because there are no input sections. 
     FIXME: Why do we need it? When there is no .bss section, we don't 
     pad the .data section. */ 
    . = ALIGN(. != 0 ? 64/8 : 1); 
    } 

Wenn ein Eingabeabschnitt nicht etwas in Ihrem Linker-Skript übereinstimmt, der Linker hat es immer noch irgendwo zu platzieren. Stellen Sie sicher, dass Sie alle Eingabebereiche abdecken.

Beachten Sie, dass zwischen Abschnitten und Segmenten ein Unterschied besteht. Abschnitte werden vom Linker verwendet, aber das einzige, was der Programmlader betrachtet, sind die Segmente. Das Textsegment enthält den Textabschnitt, aber es enthält auch andere Abschnitte. Abschnitte, die in dasselbe Segment gehören, müssen benachbart sein. Also ist Ordnung wichtig.

Der Rodata-Abschnitt folgt normalerweise dem Textabschnitt. Diese sind während der Ausführung schreibgeschützt und werden einmal in Ihren Programmheadern als LOAD-Eintrag mit den Berechtigungen & ausführen angezeigt. Dieser LOAD-Eintrag ist das Textsegment.

Der BSS-Abschnitt geht normalerweise nach dem Datenabschnitt. Diese sind während der Ausführung beschreibbar und werden einmal in Ihren Programmheadern als LOAD-Eintrag mit den Schreibrechten & angezeigt. Dieser LOAD-Eintrag ist das Datensegment.

Wenn Sie die Reihenfolge ändern, beeinflusst es, wie der Linker die Programmheader generiert. Die Programmkopfzeilen und nicht die Abschnittsüberschriften werden beim Laden des Programms vor dessen Ausführung verwendet. Überprüfen Sie die Programmheader, wenn Sie ein benutzerdefiniertes Linker-Skript verwenden.

Wenn Sie genauer angeben können, was Ihre tatsächlichen Symptome sind, dann wird es einfacher zu helfen.

+0

Das war nicht das Problem, das ich hatte (ich schrieb einen Kernel, also spielte die Struktur der endgültigen ausführbaren Datei keine Rolle). Nützliche Informationen sowieso. – jvns

5

Das Problem hier stellte sich heraus, dass ich ein Betriebssystem schrieb, und nur 12k davon wurde geladen, anstatt der ganzen Sache. Also das Linker-Skript funktionierte wirklich gut.

Die wichtigsten Werkzeuge, die ich verwendet, Binärdateien zu verstehen waren:

  • nm
  • objdump
  • readelf