Page 1 of 1

Why does ld pad 4kb of nulls?

Posted: Sun Aug 09, 2009 3:13 pm
by m35
I'm trying to get the size of my kernel down and I've noticed that there is 4kb of nulls in my elf binary.

Code: Select all

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:               0xff50000c
  Start of program headers:          52 (bytes into file)
  Start of section headers:          4436 (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:         3
  Section header string table index: 2
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        ff500000 001000 000140 00  AX  0   0  4
  [ 2] .shstrtab         STRTAB          00000000 001140 000011 00      0   0  1

Basically it's:

Elf header
followed directly by the program header
~4kb of nulls
.text
followed directly by a null section header then by the .text s_header.

I've altered the binary to remove the .shstrtab and the kernel still boots.

I'm now trying to alter the binary so that the .text occurs directly after the program header, followed directly by the section headers. This renders the kernel unbootable by grub.

I'm not sure if I'm updating the header correctly or if there's actually a reason the .text is aligned at 0x1000. I would think that grub would load the .text to the physical address given and not need any alignment in the file itself?

Also, can I remove the null section header without causing problems? Ideally I just want a text section for my kernel.

Thanks

EDIT: I have now been able to relocate the .text section to occur right after the program header and still boot. The null section can also be removed. It turns out grub does need .shstrtab. I had only decreased the number of section headers before. When I actually remove the section's header and entry the kernel doesn't boot. This is a pain because it means to remove those 4kb of nulls, the entire file has to be restructured because of that worthless string table. :?

Does anyone know why ld puts all those nulls there in the first place? It's aparently not an issue of having to have the .text aligned in the file itself.

Re: Why does ld pad 4kb of nulls?

Posted: Mon Aug 10, 2009 12:21 pm
by DeleteMe
so you can map the hole ELF file into memory, and still have your .text page alinged.

maybe???

Re: Why does ld pad 4kb of nulls?

Posted: Tue Aug 11, 2009 1:16 am
by m35
so you can map the hole ELF file into memory, and still have your .text page alinged.
I guess that makes sense if the code were relocatable or if there was more than just a .text section. In such a case the file could be read directly to memory and possibly run as is. But I can't see how this would make sense if the code is going to mapped to a fixed address with only one section.

In such a case the elf file still could be loaded directly into memory and run as is but would have to be loaded in a slightly lower address so that the .text section would line up with the start address. The thing is, this it would have to be loaded at a lower address space regardless if there is alignment within the file.

Maybe this is too obscure a case for the ld developers to have considered or maybe the developers thought no one would care about 4kb- it's certainly not enough for anyone anyways :roll:

Re: Why does ld pad 4kb of nulls?

Posted: Tue Aug 11, 2009 1:53 am
by qw
m35 wrote:Does anyone know why ld puts all those nulls there in the first place? It's aparently not an issue of having to have the .text aligned in the file itself.
Does your linker script contain something like

Code: Select all

.text : AT(4096)
That may be the reason.

Re: Why does ld pad 4kb of nulls?

Posted: Tue Aug 11, 2009 5:01 pm
by m35
No, it's loaded at 1mb:

Code: Select all

ENTRY(start)
SECTIONS{
	.text 0xFF500000 : AT(0x100000) {*(.text)}
}

Re: Why does ld pad 4kb of nulls?

Posted: Tue Aug 11, 2009 6:25 pm
by KurtGollhardt
.text has a default ALIGN of 4096 unless you override it (as do .data and .bss, if I recall correctly).

(Actually, I think it's technically based on the program segments, not the individual sections, but in a simple file, it's the same thing. I wasn't able to find the spec for these defaults in a quick web search, but I remember reading them "way back when".)

This is for the case where .text is loaded (paged) without the ELF header, not the other way round. It ensures that .text, which would typically be mapped read-only in a paged executable, doesn't end up in the same page as writeable data or other sections that may have different paging properties.
m35 wrote:I guess that makes sense if the code were relocatable or if there was more than just a .text section. In such a case the file could be read directly to memory and possibly run as is. But I can't see how this would make sense if the code is going to mapped to a fixed address with only one section.
You're right that it only makes sense with multiple sections (segments), but they chose not to make a special case for single-section files. After all, pretty much any normal executable is going to have some global data.

Re: Why does ld pad 4kb of nulls?

Posted: Tue Aug 11, 2009 10:27 pm
by m35
KurtGollhardt, thanks for the information.