Re: About ELF format

"Tim Bauer" <tbauer@cadrc.calpoly.edu>
6 Jun 2004 15:25:50 -0400

          From comp.compilers

Related articles
About ELF format vinaynkaranth@yahoo.com (2004-05-30)
Re: About ELF format kharmon@optonline.net (George Huber) (2004-06-06)
Re: About ELF format zhangjie@magima.com.cn (Jie Zhang) (2004-06-06)
Re: About ELF format tbauer@cadrc.calpoly.edu (Tim Bauer) (2004-06-06)
Re: About ELF format vinaynkaranth@yahoo.com (2004-06-11)
Re: About ELF format lod@egobolinu.xorg (Lode) (2004-09-21)
| List of all articles for this month |

From: "Tim Bauer" <tbauer@cadrc.calpoly.edu>
Newsgroups: comp.compilers
Date: 6 Jun 2004 15:25:50 -0400
Organization: Cal Poly, SLO
References: 04-05-098
Keywords: linker
Posted-Date: 06 Jun 2004 15:25:50 EDT

Yay. I just spent several weeks pulling apart ELF files for a C stack trace
program I am writing / wrote. I think I can really help. Additionally, I was
doing this
on Linux (x86).


I am operating under the assumption you are using the "elf.h" constructs
mentioned in the documents.


You are correct, the creature you want is the "e_shoff" field of the
Elf32_Ehdr structure starting at offset 0. It is at offset 20h (32 dec).
> I have a little doubt regarding the ELF file. Here is a Hex snap shot
> of an ELF file compiled using GCC on RH linux 9.0 (X86).
>
> 00000000h: 7F 45 4C 46 01 01 01 00 00 00 00 00 00 00 00 00
> 00000010h: 02 00 03 00 01 00 00 00 C0 83 04 08 34 00 00 00
> 00000020h: 08 4F 00 00 00 00 00 00 34 00 20 00 06 00 28 00
> 00000030h: 1E 00 1B 00 06 00 00 00 34 00 00 00 34 80 04 08
> 00000040h: 34 80 04 08 C0 00 00 00 C0 00 00 00 05 00 00 00


Byte 5 is the byte ordering which is 1 == ELFDATALSB as expected on x86.
The word at 20h is 0x4F08 (reading little endian), this is the same thing
you got.
So far, all is well.


> From the ELF document I understand that at the offset 0x20 0x21
> contains the section header table's file offset in bytes.
> In the above snap shot it shows, "0x4F08". But the offset "0x4F08", it
> looks as though it is not the section table
> start address. Here is the snap shot of offset "0x4F08".


Its actually suppose to be 4 bytes wide since it is an "Elf32_Off".
Neverthless, that does not change your computation in this case.


> 00004ee0h: 2E 64 79 6E 61 6D 69 63 00 2E 73 62 73 73 00 2E
> 00004ef0h: 62 73 73 00 2E 73 74 61 62 00 2E 73 74 61 62 73
> 00004f00h: 74 72 00 2E 63 6F 6D 6D 65 6E 74 00 2E 6E 6F 74
> 00004f10h: 65 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 00004f20h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 00004f30h: 00 00 00 00 00 00 00 00 00 00 00 00 1B 00 00 00
> 00004f40h: 01 00 00 00 02 00 00 00 F4 80 04 08 F4 00 00 00
> 00004f50h: 13 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00
> 00004f60h: 00 00 00 00 23 00 00 00 07 00 00 00 02 00 00 00


The first section header should be a dummy entry. It is this way so
when other sections have a field that refers to a section index and
they don't want that to point to anything, they just point it at section
index 0 (the dummy index).
Now, the only requirement for the section 0 header is that the field
"sh_type"
is of type SHT_NULL == 0. All other fields are undefined.
However, on the Slackware machine I am using every ELF file I have
looked at has filled these bytes with 0's. I looked at many files in
this, most gcc generated, others from an unknown origin. So I highly
doubt the random bytes at 0x4F08 are correct. If you are generating a
file with undefined entries, it is no faster to put random garbage
that it is to put explicit 0's.


So I assume that address is off. If we look foward we see 40
contiguous zero bytes, I would suspect the real header starts at
offset 0x4F14. That gives you the necessary 40 zero bytes for the
dummy section header. Better than that, if we keep reading forward
under this assumption. We find valid contents for the next
section. Section 1 in all my files is the ".interp" section. So I am
assuming this for your file too. I hand parsed this section and then
ran my test program and dumped the ".interp" section.


sh_name = 0x0000001B (27) this is a valid "looking" string offset.
sh_type = 0x00000001 (1) SHT_PROGBITS (same as my file)
sh_flags = 0x00000002 (2) SHF_ALLOC (same as my file)
sh_addr = 0x080480F4 (A good looking gcc-generated virtual address for a
main module
                                                                                  Same address as my file )
sh_offset = 0x000000F4 (The offset matches my ".interp")
sh_size = 0x00000013 ( The size of the entry same for mine)
sh_link = 0x00000000 (same as my test file)
sh_info = 0x00000000 (same)
sh_addralign = 0x00000001 (same)
sh_entsize = 0x00000000 (same)


Here is the output of my program with on itself.
im142:/home/tbauer/elf> elfview -l .interp elfview
Elf32_Shdr[1]{
    sh_name: 0x00000001 ".interp"
    sh_type: SHT_PROGBITS
    sh_flags: 0x00000002 (-A-)
    sh_addr: 0x080480F4
    sh_offset: 0x000000F4 (244)
    sh_size: 0x00000013 (19)
    sh_link: 0x00000000 (0)
            ( undefined )
    sh_info: 0x00000000 (0)
            ( no meaning )
    sh_addralign: 0x00000001 (1)
    sh_entsize: 0x00000000 (0)
}


Everything matches, except for the string index, and that is
reasonable. The string tables are doubtlessly layed out differently.


From all this, I would bet my life that the section headers of your
file start at 0x4F14 and not 0x4F08. Now, why on earth is it off by
12 bytes? The file had to be corrupted somehow, or gcc miscalculated
something or...


  - Did any tool or utility touch the file?
  - How did you generate the hex dump? It is doubtful that it is off, but I
am at a loss
  - Does the executable function?
  - Try running "readelf" on it. Expect an immediate fatal.
Do you have the source file used to generate this?
Which gcc version?


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.