2017-11-27 16 views
1

Ich arbeite mit einer eingebetteten OS-ähnlichen Umgebung, und daher sollte die Größe der Binärdateien so klein wie möglich sein. Ich hatte einfache flache Binärdateien als eine ausführbare Datei verwendet, aber jetzt versuche ich, ELF zu verwenden. Ich benutze nur Assembler-Code, aber Verknüpfung mit ld. Assembler-Code:Warum führt das Kompilieren dieses einfachen Assembly-Codes und das Verknüpfen mit ELF zu einer so großen Größe als die Flat-Binärdatei?

CPU i386 
BITS 32 
SECTION .text progbits alloc exec nowrite 
GLOBAL start 


start: 
mov eax, 0 
add eax, 1 
inc eax 
mov eax, 0x12345678 
mov dword [0x100000], eax 
mov ebx, dword [0x100000] 
mov eax, ebx 

out 0xF3, al ;dump memory API call 

out 0xF0, ax 
cli 
hlt 

Build-Befehle:

yasm -o testbench/test.o testbench/test.asm -f elf32 
i386-elf-gcc -T testbench/linker.ld -o test.elf -ffreestanding -nostdlib testbench/test.o -Wl,--gc-sections -dead_strip -fdata-sections -ffunction-sections -Os -nostartfiles -nodefaultlibs 
strip --strip-all test.elf 

Und schließlich Linker-Skript:

OUTPUT_FORMAT("elf32-i386") 
ENTRY(start) 
phys = 0x1000; 
scratch = 0x100000; 
MEMORY 
{ 
    coderom (rx) : ORIGIN = phys, LENGTH = 128K 
    scratchram (!rx) : ORIGIN = scratch, LENGTH = 1024K 
} 
SECTIONS 
{ 
    .text phys : AT(phys) { 
    code = .; 
    *(.text.start); 
    *(.text*) 
    *(.rodata) 
    . = ALIGN(4); 
    } > coderom 
    __text_end=.; 
    .data : AT(scratch) 
    { 
    data = .; 
    *(.data) 
    . = ALIGN(4); 
    } > scratchram 
    __data_end=.; 
    __binary_end = .; 
    .bss : AT(scratch + (bss - data)) 
    { 
    bss = .; 
    *(.bss) 
    . = ALIGN(4); 
    } > scratchram 
} 

, die in dieser readelf Farmacia:

[email protected]:~/x86LibSC$ readelf -a test.elf 
ELF Header: 
    Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
    Class:        ELF32 
    Data:        2's complement, little endian 
    Version:       1 (current) 
    OS/ABI:       UNIX - System V 
    ABI Version:      0 
    Type:        EXEC (Executable file) 
    Machine:       Intel 80386 
    Version:       0x1 
    Entry point address:    0x1000 
    Start of program headers:   52 (bytes into file) 
    Start of section headers:   4160 (bytes into file) 
    Flags:        0x0 
    Size of this header:    52 (bytes) 
    Size of program headers:   32 (bytes) 
    Number of program headers:   1 
    Size of section headers:   40 (bytes) 
    Number of section headers:   5 
    Section header string table index: 4 

Section Headers: 
    [Nr] Name    Type   Addr  Off Size ES Flg Lk Inf Al 
    [ 0]     NULL   00000000 000000 000000 00  0 0 0 
    [ 1] .text    PROGBITS  00001000 001000 000024 00 AX 0 0 16 
    [ 2] .data    PROGBITS  00100000 001024 000000 00 WA 0 0 1 
    [ 3] .bss    NOBITS   00100000 000000 000000 00 WA 0 0 1 
    [ 4] .shstrtab   STRTAB   00000000 001024 00001c 00  0 0 1 
Key to Flags: 
    W (write), A (alloc), X (execute), M (merge), S (strings) 
    I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) 
    O (extra OS processing required) o (OS specific), p (processor specific) 

There are no section groups in this file. 

Program Headers: 
    Type   Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align 
    LOAD   0x001000 0x00001000 0x00001000 0x00024 0x00024 R E 0x1000 

Section to Segment mapping: 
    Segment Sections... 
    00  .text 

There is no dynamic section in this file. 

There are no relocations in this file. 

The decoding of unwind sections for machine type Intel 80386 is not currently supported. 

No version information found in this file. 

Wie Sie können sieh, das sollte kompilieren zu 100 oder 200 Bytes maximal (und tat bei der Verwendung von flachen binären Format) .. aber aus irgendeinem Grund dauert dies mehr als 4 KB.

Wie kann ich die ELF-Programmgröße so weit wie möglich reduzieren, ohne die ELF-Datei manuell im Assembler zu erstellen?

Als Referenz gibt es in dieser Betriebssystemumgebung keine Umlagerungen oder dynamischen Code. Es lädt nur flache Programmabschnitte.

+0

Sieht aus wie '.text' Ausrichtung auf 4k festgelegt. – Jester

+0

Ich bemerkte, dass für das Programm-Header-Bit, ist es auf 4K in der Datei selbst ausgerichtet ... aber ich sehe keine Möglichkeit, LD zu sagen, dies nicht zu tun @ Jester – Earlz

+0

Die 4kb-Ausrichtung stammt möglicherweise aus den Eingabeabschnitten von die Objektdateien und an die Ausgabeabschnitte in der endgültigen ausführbaren Datei weitergegeben. Sie können das möglicherweise mit der Anweisung SUBALIGN für die Zeilen ".text" und ".data" verfälschen. Das könnte also überschrieben werden '.text phys: AT (phys) SUBALIGN (64)' und '.data: AT (scratch) SUBALIGN (64)' die 64 kann der Wert der Ausrichtung sein, die Sie verwenden möchten (Null wird als unterstützt Gut). –

Antwort

2

Ich endete mit dem Lösen der Link-Option "-n" (auch bekannt als "-nmagic"). Das sagt im Grunde, dass es sich nicht darum kümmern muss, Programmabschnitte auf Seitengrenzen auszurichten. Das brachte mich von 4K auf etwa 700 (400 nach dem Strip). Und dann habe ich sstrip verwendet, um das weiter auf nur etwa 150 Bytes zu reduzieren. Dies ist die Art von Größe, die ich für diesen Anwendungsfall erreichen wollte.

Verwandte Themen