2

My intent is to place the text section at a specific location in memory (0x00100000).

SECTIONS
{
    . = 0x00100000;
    .text :
    {   
        *(.text*)
    }
}    

Although the linker does do this (note the 0x01000000 Addr field):

$ readelf -S file.elf 
There are 12 section headers, starting at offset 0x104edc:

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        00100000 100000 000e66 00  AX  0   0  4
  [ 2] .eh_frame         PROGBITS        00100e68 100e68 000628 00   A  0   0  4
...

it also places ~1MB of zeros before the .text section in the ELF file (note the .text section's offset is 1MB). Shown another way:

$ hexdump -C file.elf
00000000  7f 45 4c 46 01 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  02 00 03 00 01 00 00 00  0c 00 10 00 34 00 00 00  |............4...|
00000020  dc 4e 10 00 00 00 00 00  34 00 20 00 02 00 28 00  |.N......4. ...(.|
00000030  0c 00 0b 00 01 00 00 00  00 00 00 00 00 00 00 00  |................|
00000040  00 00 00 00 90 14 10 00  96 04 4f 00 07 00 00 00  |..........O.....|
00000050  00 00 20 00 51 e5 74 64  00 00 00 00 00 00 00 00  |.. .Q.td........|
00000060  00 00 00 00 00 00 00 00  00 00 00 00 07 00 00 00  |................|
00000070  10 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000080  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00100000  02 b0 ad 1b 03 00 00 00  fb 4f 52 e4 8b 25 90 04  |.........OR..%..|
00100010  4f 00 50 53 e8 88 00 00  00 fa f4 eb fc 55 89 e5  |O.PS.........U..|
00100020  83 ec 10 c7 45 f8 00 80  0b 00 c7 45 fc 00 00 00  |....E......E....|
00100030  00 eb 24 8b 45 fc 8d 14  00 8b 45 f8 01 d0 8b 4d  |..$.E.....E....M|

How can this be prevented? Am I improperly using the location counter ("dot" notation) syntax?

  • Why do you care? The layout in the file doesn't correspond to how it gets loaded into memory. – Barmar May 23 '17 at 21:02
  • @Barmar, Because GRUB's multiboot specification requires certain data to be within the first 8192 bytes of the file being loaded. – sherrellbc May 23 '17 at 21:10
  • Did you use ld -n to stop alignment, as I've seen this in some examples. – meuh May 24 '17 at 7:18
2

It turns out that telling the linker to emulate elf_i386 produced the output that I was looking for, though I do not understand why. Namely, invoke the linker with:

$ ld -melf_i386 [...]

Files produced with and without -melf_i386 appear to be mostly similar:

with.elf:    ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, not stripped, with debug_info
without.elf: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, not stripped, with debug_info

Except their sizes are vastly different:

$ ls -l *.elf
-rwxr-xr-x 1 user user   10948 May 24 11:56 with.elf
-rwxr-xr-x 1 user user 1055428 May 24 11:56 without.elf

As far as I can tell, the output files are otherwise exactly the same:

$ readelf -S with.elf
There are 12 section headers, starting at offset 0x28e4:

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        00100000 001000 000205 00  AX  0   0  4
  [ 2] .eh_frame         PROGBITS        00100208 001208 0000b8 00   A  0   0  4
  [ 3] .bss              NOBITS          001002c0 0012c0 3ef000 00  WA  0   0  4
  [ 4] .debug_info       PROGBITS        00000000 0012c0 0007bf 00      0   0  1
  [ 5] .debug_abbrev     PROGBITS        00000000 001a7f 0002c9 00      0   0  1
  [ 6] .debug_aranges    PROGBITS        00000000 001d48 000060 00      0   0  1
  [ 7] .debug_line       PROGBITS        00000000 001da8 00023c 00      0   0  1
  [ 8] .debug_str        PROGBITS        00000000 001fe4 0004bd 01  MS  0   0  1
  [ 9] .symtab           SYMTAB          00000000 0024a4 000280 10     10  22  4
  [10] .strtab           STRTAB          00000000 002724 00014e 00      0   0  1
  [11] .shstrtab         STRTAB          00000000 002872 000070 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  p (processor specific)

Just note the "offset" field is slightly different

$ readelf -S without.elf
There are 12 section headers, starting at offset 0x1018e4:

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        00100000 100000 000205 00  AX  0   0  4
  [ 2] .eh_frame         PROGBITS        00100208 100208 0000b8 00   A  0   0  4
  [ 3] .bss              NOBITS          001002c0 1002c0 3ef000 00  WA  0   0  4
  [ 4] .debug_info       PROGBITS        00000000 1002c0 0007bf 00      0   0  1
  [ 5] .debug_abbrev     PROGBITS        00000000 100a7f 0002c9 00      0   0  1
  [ 6] .debug_aranges    PROGBITS        00000000 100d48 000060 00      0   0  1
  [ 7] .debug_line       PROGBITS        00000000 100da8 00023c 00      0   0  1
  [ 8] .debug_str        PROGBITS        00000000 100fe4 0004bd 01  MS  0   0  1
  [ 9] .symtab           SYMTAB          00000000 1014a4 000280 10     10  22  4
  [10] .strtab           STRTAB          00000000 101724 00014e 00      0   0  1
  [11] .shstrtab         STRTAB          00000000 101872 000070 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  p (processor specific)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.