ELF section and program headers
-
- Member
- Posts: 127
- Joined: Sat Sep 29, 2007 5:43 pm
- Location: Amsterdam, The Netherlands
ELF section and program headers
Hello,
I am programming my bootsector and I am busy with the ELF parsing, at the wiki they say that only the program headers are important, so my question is are the section headers needed for the ELF parsing in a bootsector or can I leave that part out? They also talk about the program headers but there's only one offset in the ELF header, here my question is? Are the program headers after each other like this:
| Program header 1 |
| Program header 2 |
| Program header 3 |
Or are they all spread around over the ELF file? I was thinking the first but I am not sure...
Thanks already,
Stephan van Schaik.
I am programming my bootsector and I am busy with the ELF parsing, at the wiki they say that only the program headers are important, so my question is are the section headers needed for the ELF parsing in a bootsector or can I leave that part out? They also talk about the program headers but there's only one offset in the ELF header, here my question is? Are the program headers after each other like this:
| Program header 1 |
| Program header 2 |
| Program header 3 |
Or are they all spread around over the ELF file? I was thinking the first but I am not sure...
Thanks already,
Stephan van Schaik.
-
- Member
- Posts: 127
- Joined: Sat Sep 29, 2007 5:43 pm
- Location: Amsterdam, The Netherlands
You need the program header to know where the section headers are. Unless you use GRUB, which doesn't give you the program header, but instead the fields from the program header that indicate where to find the section headers.StephanVanSchaik wrote:Thanks, James.
Yesterday I was confused because they keep talking about sections on the wiki and at the end they say that you need to use the program headers. Anyway thanks for clearing it up.
JAL
Possibly a nomenclature clash here - the "one true header", the one at the start of the ELF file, I referred to as the "ELF header". The "program headers" he referred to were, I assumed, the "process headers" detailed in the ELF man pages.jal wrote:You need the program header to know where the section headers are. Unless you use GRUB, which doesn't give you the program header, but instead the fields from the program header that indicate where to find the section headers.StephanVanSchaik wrote:Thanks, James.
Yesterday I was confused because they keep talking about sections on the wiki and at the end they say that you need to use the program headers. Anyway thanks for clearing it up.
JAL
-
- Member
- Posts: 127
- Joined: Sat Sep 29, 2007 5:43 pm
- Location: Amsterdam, The Netherlands
In the ELF specification I got, they don't talk about process headers . I so far know how to handle the ELF header, where in you can find how much program headers you have, how big they are and where they start in the file, the same with section headers.
Program header table entry:
The only problem I've got is that I don't know if I need to use the program header(s) or/and the section header(s).typedef struct {
unsigned char e_ident[EI_NIDENT];
Elf32_Half e_type;
Elf32_Half e_machine;
Elf32_Word e_version;
Elf32_Addr e_entry;
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
} Elf32_Ehdr;
Program header table entry:
Section header table entry:typedef struct {
Elf32_Word p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
Elf32_Word p_filesz;
Elf32_Word p_memsz;
Elf32_Word p_flags;
Elf32_Word p_align;
} Elf32_Phdr;
Hopefully this clears up a few things about the headers...typedef struct {
Elf32_Word sh_name;
Elf32_Word sh_type;
Elf32_Word sh_flags;
Elf32_Addr sh_addr;
Elf32_Off sh_offset;
Elf32_Word sh_size;
Elf32_Word sh_link;
Elf32_Word sh_info;
Elf32_Word sh_addralign;
Elf32_Word sh_entsize;
} Elf32_Shdr;
-
- Member
- Posts: 127
- Joined: Sat Sep 29, 2007 5:43 pm
- Location: Amsterdam, The Netherlands
Using readelf, I see that there are 3 program headers. I also found this back in elf.h of GeekOS as stated in the wiki. If I am right this is the max. possible... The first is then text, the second data but I don't know what the third is. Is this bss? If so, does it need to be even handled then since it's just empty.
If I am right, I just should read out the program header, reallocate them in memory and then just execute it. Correct me if I am wrong.
If I am right, I just should read out the program header, reallocate them in memory and then just execute it. Correct me if I am wrong.
Hi,
I believe that it will be a .bss. In this case, it needs to be zeroed as this is what your program will expect. There is also a chance that uninitialised data can appear in any of the sections. In this case, you will find that p_memsz is greater than p_filesz. In this case, you copy over p_filesz bytes and then zero a range of (p_memsz - p_filesz) bytes.
Is your third section marked with PT_LOAD? I suggest looking through the elf reference and implement the proper relocation method for all possible program header types (there aren't many!).
Cheers,
Adam
I believe that it will be a .bss. In this case, it needs to be zeroed as this is what your program will expect. There is also a chance that uninitialised data can appear in any of the sections. In this case, you will find that p_memsz is greater than p_filesz. In this case, you copy over p_filesz bytes and then zero a range of (p_memsz - p_filesz) bytes.
Is your third section marked with PT_LOAD? I suggest looking through the elf reference and implement the proper relocation method for all possible program header types (there aren't many!).
Cheers,
Adam
-
- Member
- Posts: 127
- Joined: Sat Sep 29, 2007 5:43 pm
- Location: Amsterdam, The Netherlands
What?! .bss, .text, et al. Are sections. They therefore are defined by section headers!AJ wrote:Hi,
I believe that it will be a .bss. In this case, it needs to be zeroed as this is what your program will expect. There is also a chance that uninitialised data can appear in any of the sections. In this case, you will find that p_memsz is greater than p_filesz. In this case, you copy over p_filesz bytes and then zero a range of (p_memsz - p_filesz) bytes.
Is your third section marked with PT_LOAD? I suggest looking through the elf reference and implement the proper relocation method for all possible program header types (there aren't many!).
Cheers,
Adam
Pull the section headers list out, find the section header string table index (sh_shstrndx), use that to look up the names of all the sections. You'll end up with things like .text, .bss, .symtab, .strtab etc. Then use the flags field in the section header of each of those to discover if they need memory allocating, and where, and if they need that memory zeroing (like .bss) or copying from the file (like .text).
PS: AJ: Sorry if what you said was correct, I've never really used process headers, but .text et al are definately sections
Sorry, JamesM, I was being ambiguous in my use of the word sections. Once I started talking about program headers, I then started referring to each program header as a 'section' - this is clearly wrong and I should have avoided that nomenclature!
My ELF relocation code runs like this, for what it's worth:
Which is fairly simple, really. Obviously you also need to do checks to ensure that this is a valid ELF file, you need to page in any RAM needed initially and you need to read the entry point from the ELF header.
[EDIT]
Oh, and what I meant about the BSS:
In the program headers, the BSS will not be identified as such, but it may appear in one of two ways. Either it will appear as a separate program header with p_filesz == 0 and p_memsz == bss size, OR it will appear
as an over sized code / data program header (p_memsz > p_filesz).
[/EDIT]
Cheers,
Adam
My ELF relocation code runs like this, for what it's worth:
Code: Select all
void exe_relocate_elf(void *elfstart)
{
Elf32_Ehdr *ehead = (Elf32_Ehdr *)elfstart;
Elf32_Phdr *phead = (Elf32_Phdr*)((u32)ehead + ehead->e_phoff);
for(u32 i=0;i<ehead->e_phnum;i++)
{
if(phead[i].p_type == PT_LOAD)
{
memcpy((void*)phead[i].p_vaddr, (void*)(mod->mod_start + phead[i].p_offset), phead[i].p_filesz);
memset((void*)(phead[i].p_vaddr + phead[i].p_filesz), 0, phead[i].p_memsz - phead[i].p_filesz);
}
}
}
[EDIT]
Oh, and what I meant about the BSS:
In the program headers, the BSS will not be identified as such, but it may appear in one of two ways. Either it will appear as a separate program header with p_filesz == 0 and p_memsz == bss size, OR it will appear
as an over sized code / data program header (p_memsz > p_filesz).
[/EDIT]
Cheers,
Adam
So what exactly are the rules for zeroing? I noticed that Grub zeroes any section with type SHT_NOBITS and flags SHF_ALLOC, which I find rather annoying (I'd like initial sections for stack and heap so I don't need to determine myself where to put them, but it takes quite some time to zero the memory).JamesM wrote:Then use the flags field in the section header of each of those to discover if they need memory allocating, and where, and if they need that memory zeroing (like .bss) or copying from the file (like .text).
JAL