2016-07-30 48 views
0

Dies weist einige BSS Variablen:Warum bewirkt das Ausrichten einer .bss-Variablen einen massiven Anstieg der Binärgröße?

.lcomm page_table_l2, 4096 
.lcomm page_table_l3, 4096 
.lcomm page_table_l4, 4096 

Die binäre Ich bin Gebäude endet 4792 Bytes ist, so dass Sie, dass die BSS Variablen nicht direkt enthalten (oder die binäre wäre> 12 KiB) sehen kann.

Allerdings müssen diese drei 4 KiB ausgerichtet sein, so dass ich ändern Sie den Abschnitt:

.section .bss 
.align 4096 
.lcomm page_table_l2, 4096 
.lcomm page_table_l3, 4096 
.lcomm page_table_l4, 4096 

... und das binäre wächst auf 8760! Vorausgesetzt, dass BSS nur eine Notiz in einem ELF binäre Sprichwort an den Linker sein soll, hey, zuteilen n Bytes Nullspeicher, Warum bewirkt Ausrichtung einer BSS-Variablen überhaupt Wachstum der Binärdatei?

du in C sehen kann, auch:

char x[4096] __attribute__ ((aligned (8192))) = {0}; 

Wenn Sie die Ausrichtung variieren, ändert sich die Ausgangsobjekt Datei Größe mit. (obwohl ich in meinem ursprünglichen Beispiel die Größe des endgültigen Binärcodes betrachte.)

Beachten Sie, dass diese Ausgabedatei ein Betriebssystemkern ist; Ich folge dem Tutorial here. Ich bin mit der folgenden Linker-Skript:

ENTRY(start) 

SECTIONS { 
    . = 1M; 

    .boot ALIGN(8) : AT(ADDR(.boot)) 
    { 
     /* ensure that the multiboot header is at the beginning */ 
     KEEP(*(.multiboot_header)) 
    } 

    .text : 
    { 
     *(.text) 
    } 
} 

Nach objdump, es ist eine Art sieht aus wie das gesamte Programm bekommt 4 KiB ausgerichtet in der Elf selbst, die ein bisschen komisch ist.

Ohne .align:

Sections: 
Idx Name   Size  VMA    LMA    File off Algn 
    0 .boot   00000018 0000000000100000 0000000000100000 00000078 2**0 
        CONTENTS, ALLOC, LOAD, READONLY, DATA 

Mit .align:

Sections: 
Idx Name   Size  VMA    LMA    File off Algn 
    0 .boot   00000018 0000000000100000 0000000000100000 00001000 2**0 
        CONTENTS, ALLOC, LOAD, READONLY, DATA 

Hinweis File off oder der Abschnitt in der Datei versetzt. Warum ändert sich das?

+1

Mit welchen Befehlen bauen Sie? 'gcc -nostdlib'? Eine einfache ELF-Binärdatei erstellen? Außerdem wusste ich nicht, dass Multiboot-Kernel Text/Daten/BSS-Segmente haben; das ist ziemlich schick. Das Tutorial, das Sie verfolgen, verwendet NASM, daher ist es nicht schwer sich vorzustellen, dass Gas etwas anders funktioniert. Dinge im BSS ausrichten. Wie auch immer, wenn man das zu einem [mcve] machen würde, würde es nur ein paar Zeilen mehr Befehle und Notizen darüber geben, welcher Codeblock unter welchem ​​Dateinamen steht, oder? Das ist interessant und bringt mich dazu, es auszuprobieren, aber nicht schlecht genug, um zu erraten, was genau du getan hast: P –

+0

@MichaelPetch: Ja, ich stimme zu, es ist klar, dass dies eine ELF-Binärdatei ist. Ich weiß einfach nicht genug über das Erstellen von Multiboot-Kernel-Images, um zu wissen, ob etwas Besonderes für Sie relevant wäre, oder ob Sie dasselbe Verhalten erwarten würden, wenn Sie eine '.o' oder normale Linux-Datei erstellen. Ich zweifelte nicht daran, dass GRUBs Multi-Boot-Loader ein BSS für Sie auf null setzen wird. Ich habe nur gesagt, dass ich nicht wusste, dass das unterstützt wird, bis ich es gerade gelesen habe. : P –

Antwort

0

Getestet habe ich diese einige (mit nur dieser Code und einem _start, die eine exit_group syscall macht), gebaut mit gcc -c oder gcc -nostdlib).

Es scheint wie die .o Größe skaliert mit der größten Ausrichtung in der .S verwendet. In der ELF-Datei sind nullte Bytes. (Schauen Sie sich zum Beispiel den Hexdump an).

Die verknüpfte Binärdatei scheint jedoch keine zusätzliche Auffüllung zu haben. Es ist also kein Problem nach der Verknüpfung, nur für den Speicherplatzverbrauch von temporären Dateien während des Builds.


habe ich das gleiche Ergebnis von .space Verwendung genullten Bytes in den .bss zu montieren, wie ich aus der Verwendung .lcomm tat Platz im .bss zuzuweisen, ohne auf sie umzuschalten.

.section .bss 
    .balign 4096    # .balign or .p2align are preferable, to avoid ambiguity between power-of-2 or exponent 

page_table_l2: .space 4096 
.balign 1024 
page_table_l3: .space 4096 
page_table_l4: .space 4096 
foo:  .space 17 
    .balign 4096    # This doesn't make the .o any bigger if a .align 4096 is already present 
bar: .space 1 

# .lcomm page_table_l2, 4096 
# .lcomm page_table_l3, 4096 
# .lcomm page_table_l4, 4096 


    .text 
.global _start 
_start: 
    xor %edi, %edi 

    mov $231, %eax # exit_group(0) 
    syscall 

# the .o is big 
$ gcc -c align-bss.S && ll align-bss.o && objdump -haf align-bss.o 
-rw-rw-r-- 1 peter peter 4.8K Jul 30 11:05 align-bss.o 
... 
Idx Name   Size  VMA    LMA    File off Algn 
... 
    2 .bss   00004001 0000000000000000 0000000000000000 00001000 2**12 

# the binary doesn't care 
$ gcc -nostdlib align-bss.S -o align-bss && ll align-bss && objdump -haf align-bss 
-rwxrwxr-x 1 peter peter 1.2K Jul 30 11:08 align-bss 
    ... 
Idx Name   Size  VMA    LMA    File off Algn 
... 
    2 .bss   00004008 0000000000601000 0000000000601000 00001000 2**12 

Mit den Richtlinien .balign kommentierte die .o 872b ist, und der verbundene statische binäre noch 1.2K (unstripped).