Next: ELF Header, Previous: ELF Basic Types, Up: Top [Contents][Index]
The Poke types provided to denote ELF64 and ELF32 files are
Elf64_File
and Elf32_File
respectively.
type Elf32_File = struct { Elf32_Ehdr ehdr; if (ehdr.e_shnum > 0) Elf32_Shdr[ehdr.e_shnum] shdr ehdr.e_shoff; if (ehdr.e_phnum > 0) Elf32_Phdr[ehdr.e_phnum] phdr ehdr.e_phoff; };
type Elf64_File = struct { Elf64_Ehdr ehdr; if (ehdr.e_shnum > 0) Elf64_Shdr[ehdr.e_shnum] shdr ehdr.e_shoff; if (ehdr.e_phnum > 0) Elf64_Phdr[ehdr.e_phnum] phdr ehdr.e_phoff; };
ehdr
Is the header of the ELF file, of type Elf64_File
. This always
exists and is always located at the beginning of the ELF file.
shdr
Is the optional section header table of the ELF file. This is an
optional field that is an array of Elf64_Shdr
(or
Elf32_Shdr
) values, describing the ELF sections present in the
file.
This table, if it exists, can be located anywhere in the ELF file. The ELF header determines the size and location of the table.
phdr
Is the optional program section header table of the ELF file. This is
an optional field that is an array of Elf64_Phdr
(or
Elf32_Phdr
) describing ELF segments present in the file.
This table, if it exists, can be located anywhere in the ELF file. The ELF header determines the size and location of the table.
File_Elf64.section_name_p = (string name) int<32>
File_Elf32.section_name_p = (string name) int<32>
Given a section name, return whether a section with that name exists in the ELF file.
File_Elf64.get_sections_by_name = (string name) Elf64_Shdr[]
File_Elf32.get_sections_by_name = (string name) Elf32_Shdr[]
Given the name of a section, return an array of section headers in the ELF file having that name. The returned array may of course be empty.
For example, this is how you can get an array of all the sections in
the file with name .text
:
(poke) elf.get_sections_by_name (".text") [Elf64_Shdr { sh_name=141U#B, sh_type=#<progbits>, sh_flags=#<alloc,execinstr>, sh_addr=18144UL#B, sh_offset=18144UL#B, sh_size=80574UL#B, sh_link=0U, sh_info=0U, sh_addralign=16UL, sh_entsize=0UL#B }]
File_Elf64.get_sections_by_type = (Elf_Word stype) Elf64_Shdr[]
File_Elf32.get_sections_by_type = (Elf_Word stype) Elf32_Shdr[]
Given a section type (one of the ELF_SHT_*
value) return an
array of section headers in the ELF file with that type. The returned
array may be empty.
Elf64_File.get_section_name = (offset<Elf_Word,B> offset) string
Elf32_File.get_section_name = (offset<Elf_Word,B> offset) string
Given an offset into the ELF file’s section string table, return the
string starting at that offset. This uses one particular string
table that is linked from the ELF header via the e_shstrndx
field.
For example, this is how we would print the name of the second section in an ELF file2:
(poke) elf.get_section_name (elf.shdr[1].sh_name) ".interp"
Elf64_File.get_symbol_name = (Elf64_Shdr symtab, offset<Elf_Word,B> offset) string
Elf64_File.get_symbol_name = (Elf32_Shdr symtab, offset<Elf_Word,B> offset) string
Given the section header of a section that contains a symbol table symtab, and an offset, return the corresponding string stored at the symbol table associated string table.
Elf64_File.get_string = (offset<Elf_Word,B> offset) string
Elf32_File.get_string = (offset<Elf_Word,B> offset) string
Given an offset, return the string stored at that offset in the “default” string table of the ELF file.
The default string table is contained in a section named
.strtab
. If such a section doesn’t exist, or if it exists but
it doesn’t contain a string table, then this function raises
E_inval
.
Elf64_File.get_group_signature = (Elf64_Shdr section) string
Elf32_File.get_group_signature = (Elf32_Shdr section) string
Return the signature corresponding to a given group section,
characterized by its entry in the section header table. If the given
section header doesn’t correspond to a group section then raise
E_inval
.
Elf64_File.get_group_signatures = string[]
Elf32_File.get_group_signatures = string[]
Return an array of strings with the signatures of the section groups present in this ELF file.
Elf64_File.get_section_group = (string name) Elf64_Shdr[]
Elf32_File.get_section_group = (string name) Elf32_Shdr[]
Given the name of a section group, return an array with the section headers corresponding to all the sections in that group. If the given name doesn’t identify a section group in the ELF file then return an empty array.
Elf64_File.get_load_base = Elf64_Addr
Determine the base where the contents of the ELF file are loaded,
understood as the lower virtual address where segments get loaded. If
there are no loadable segments in the ELF file then this method raises
E_inval
.
Elf64_File.vaddr_to_sec = (Elf64_Addr vaddr) Elf64_Addr
Given a virtual address, return the index in the section header table of the section whose loaded contents cover the given address. If no such section is found this method returns -1.
Consider for example a relocation which points to some content that is
stored in some section in a loadable ELF file. The corresponding
r_offset
field in the relocation will not contain a file
offset, but a loaded address. This method can be then used to
determine the section the relocation is applied to.
Elf64_File.vaddr_to_file_offset = (Elf64_Addr vaddr) Elf64_Addr
If some of the contents of the file sections are to be loaded in vaddr, this method returns the file offset to these contents.
Poking at an ELF file usually starts by opening some IO space and
mapping a Elf64_File
(or Elf32_File
):
(poke) .file /bin/ls (poke) var elf = Elf64_File @ 0#B
Once mapped, we can access any of the above fields. For example, let’s see how many sections and segments this file has:
(poke) elf.shdr'length 30UL (poke) elf.phdr'length 11UL
In case the file didn’t have a program header table, which always
happens with object files, we would have got an exception if we tried
to access the absent field phdr
:
$ echo '' | gcc -c -xc -o foo.o - $ poke foo.o (poke) load elf (poke) (Elf64_File @ 0#B).phdr unhandled invalid element exception
Unlike in older object formats (like a.out for example) the sections present in ELF files are not fixed nor they have fixed pre-defined names: there can be any number of them (including none) and they can have any arbitrary name. Also, more than one section in the file can have the same name.
So when it comes to ELF files, the process to determine whether one or more section with a given name exists in the file is a bit laborious: one has to traverse the section header table, fetch the section names from whatever appropriate string table, etc.
The following methods, that you can use in your own pickles, scripts, or at the prompt, are handy to look at particular sections in the file.
The names of several entities in ELF files are stored in different string table, which are themselves stored in different sections. There are different rules establishing where exactly the name of certain entities (sections, symbols, ...) are to be found.
These rules are not trivial and require traversing several data
structures. Therefore the Elf64_File
(and File32_File
)
type provides several methods in order to easily determine the name of
these entities.
ELF supports grouping several sections in a section group. This is useful when several sections have to go together, because they rely on each other somehow.
A section of type SHT_GROUP
defines a section group. Groups
are univocally identified by a group signature, which is the
name associated with a symbol that is stored in a particular symbol
table, linked from the section header of the group defining section.
Again, it is not exactly trivial to determine, for example, which of the sections in the ELF file pertain to which group. Therefore the pickle provides the methods below:
Next: ELF Header, Previous: ELF Basic Types, Up: Top [Contents][Index]