2013-01-14 11 views
14

Ja eksperymentuje z plików wykonywalnych ELF i gnu toolchain na Linux x86_64:Dlaczego linux/gnu linker wybrał adres 0x400000?

Mam połączone i usuwane (ręcznie) do "Hello World" test.s:

 .global _start 
     .text 
_start: 
     mov  $1, %rax 
     ... 

do 267 bajt ELF64 wykonywalny ...

0000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............ 
0000010: 0200 3e00 0100 0000 d400 4000 0000 0000 ..>[email protected] 
0000020: 4000 0000 0000 0000 0000 0000 0000 0000 @............... 
0000030: 0000 0000 4000 3800 0100 4000 0000 0000 [email protected]@..... 
0000040: 0100 0000 0500 0000 0000 0000 0000 0000 ................ 
0000050: 0000 4000 0000 0000 0000 4000 0000 0000 [email protected]@..... 
0000060: 0b01 0000 0000 0000 0b01 0000 0000 0000 ................ 
0000070: 0000 2000 0000 0000 0000 0000 0000 0000 .. ............. 
0000080: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 
0000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 
00000a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 
00000b0: 0400 0000 1400 0000 0300 0000 474e 5500 ............GNU. 
00000c0: c3b0 cbbd 0abf a73c 26ef e960 fc64 4026 .......<&..`[email protected]& 
00000d0: e242 8bc7 48c7 c001 0000 0048 c7c7 0100 .B..H......H.... 
00000e0: 0000 48c7 c6fe 0040 0048 c7c2 0d00 0000 [email protected] 
00000f0: 0f05 48c7 c03c 0000 0048 31ff 0f05 4865 ..H..<...H1...He 
0000100: 6c6c 6f2c 2057 6f72 6c64 0a    llo, World. 

posiada jedną nagłówek programu (obciążenie) i nie sekcjach:

There are 1 program headers, starting at offset 64 

Program Headers: 
    Type   Offset    VirtAddr   PhysAddr 
       FileSiz   MemSiz    Flags Align 
    LOAD   0x0000000000000000 0x0000000000400000 0x0000000000400000 
       0x000000000000010b 0x000000000000010b R E 200000 

To wydaje się załadować cały plik (przesunięcie pliku 0 do 0x10b - nagłówek elfa i wszystkie) pod adresem 0x400000.

Punkt wejścia jest:

Entry point address:    0x4000d4 

co odpowiada 0xd4 przesunięcie w pliku, a jak widzimy, że adres jest początek kodu maszynowego (mov $1, %rax1)

Moje pytanie brzmi, dlaczego (w jaki sposób) linker gnu wybrał adres 0x400000, aby zmapować plik?

+0

1 megabajta wydaje się ładny okrągły numer do mnie, co byś wybrał? –

+0

'ld' jest sterowany przez skrypty. Domyślny skrypt wspomina o '0x400000', IIRC .... W przeciwnym razie pobierz go i zajrzyj do kodu źródłowego' binutils'. –

+1

@CarlNorum: Czy sugerujesz, że 0x400000 to 1 megabajt? Wypróbuj 4 megabajty. 1 meg = 20 bitów = 5 x 4-bitowe cyfry szesnastkowe = 0x100000 –

Odpowiedz

10

Adres początkowy jest zwykle ustawiany za pomocą skryptu linkera.

Na przykład, GNU/Linux, patrząc na /usr/lib/ldscripts/elf_x86_64.x widzimy:

... 
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); \ 
    . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS; 

Wartość 0x400000 to wartość domyślna dla funkcji SEGMENT_START() na tej platformie.

Możesz dowiedzieć się więcej na temat skryptów linkera przeglądając instrukcję łącznikową:

% info ld Scripts 
+2

https://sourceware.org /binutils/docs/ld/Scripts.html –

Powiązane problemy