2016-08-02 33 views
0

Bei der Arbeit an einem kleinen 32-Bit-Kernel für die x86-Architektur entdeckte ich etwas seltsam mit wie ld behandelt Nobits Abschnitte.ld ignoriert Größe von Nobits Eingabeabschnitt

In meinem Kernel definiere ich einen .bootstrap_stack Abschnitt, der einen temporären Stapel für den Initialisierungsteil des Systems enthält. Ich halte auch Symbole für den Anfang und das Ende des Stapels. Dieser Eingabebereich wird zum Ausgabebereich .bss umgeleitet. Jeder Ausgabeabschnitt meines Kernels hat ein Symbol für den Anfang und das Ende des Abschnitts.

Das Problem ist, dass in der endgültigen ausführbaren Datei das Symbol für das Ende des Stapels ist nach das Ende der .bss Abschnitt. In den folgenden Beispielen haben die Symbole stack_top und _kernel_ebss (und _kernel_end) den gleichen Wert, was ich nicht wollte.

Ich erwartete _kernel_ebss gleich stack_bottom.

Jedoch einmal ich .bootstrap_stack zu .bss umbenennen, geschieht dies nicht. Entfernen nobits funktioniert auch, aber die resultierende Binärdatei ist erheblich größer.

Hier sind die abgestreiften Dateien, die mein Problem zu reproduzieren:

boot.s

section .bootstrap_stack, nobits ; this does not work 
;section .bootstrap_stack  ; this works 
;section .bss     ; this also works 

stack_top: 
resb 8096 
stack_bottom: 

section .text 
global _start 
_start: 
    hlt 
    jmp _start 

linker.ld

ENTRY(_start) 

SECTIONS 
{ 
    . = 0xC0100000; 

    _kernel_start = .; 

    .text ALIGN(4K) : AT(ADDR(.text) - 0xC0000000) 
    { 
     _kernel_text = .; 
     *(.multiboot) 
     *(.text) 
     _kernel_etext = .; 
    } 

    .bss ALIGN(4K) : AT(ADDR(.bss) - 0xC0000000) 
    { 
     _kernel_bss = .; 
     *(COMMON) 
     *(.bss) 
     *(.bootstrap_stack) 
     _kernel_ebss = .; 
    } 
    _kernel_end = .; 
} 

Hier werden die Symbole:

$ objdump -t kernel | sort 
00000000 l df *ABS*    00000000 boot.s 
c0100000 g  .text    00000000 _kernel_start 
c0100000 g  .text    00000000 _kernel_text 
c0100000 g  .text    00000000 _start 
c0100000 l d .text    00000000 .text 
c0100003 g  .text    00000000 _kernel_etext 
c0101000 g  .text    00000000 _kernel_bss 
c0101000 g  .text    00000000 _kernel_ebss 
c0101000 g  .text    00000000 _kernel_end 
c0101000 l  .bootstrap_stack, 00000000 stack_top 
c0101000 l d .bootstrap_stack, 00000000 .bootstrap_stack, 
c0102fa0 l  .bootstrap_stack, 00000000 stack_bottom 

Durch Umbenennen von .bootstrap_stack zu .bss Ich bekomme, was ich erwartet habe.

00000000 l df *ABS* 00000000 boot.s 
c0100000 g  .text 00000000 _kernel_start 
c0100000 g  .text 00000000 _kernel_text 
c0100000 g  .text 00000000 _start 
c0100000 l d .text 00000000 .text 
c0100003 g  .text 00000000 _kernel_etext 
c0101000 g  .bss 00000000 _kernel_bss 
c0101000 l  .bss 00000000 stack_top 
c0101000 l d .bss 00000000 .bss 
c0102fa0 g  .bss 00000000 _kernel_ebss 
c0102fa0 g  .bss 00000000 _kernel_end 
c0102fa0 l  .bss 00000000 stack_bottom 

Meine Frage ist, ob dies das erwartete Verhalten von ld ist. Wenn ja, was ist das Problem mit meinem Beispiel, denn soweit ich weiß .bss ist auch ein Nobits-Abschnitt, aber es produziert das erwartete Ergebnis?

Antwort

0

Okay, ich habe es herausgefunden.

Anscheinend sollen Sie nicht gleich nach dem Namen des Abschnitts ein Komma haben. objdump enthält das Komma im Namen des Abschnitts, so dass deutlich zeigt, dass das der Fehler ist.

So

section .bootstrap_stack, nobits 

sollte

section .bootstrap_stack nobits