Next: , Previous: , Up: Top   [Contents][Index]


6 ELF File

The Poke types provided to denote ELF64 and ELF32 files are Elf64_File and Elf32_File respectively.

6.1 Overview

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;
  };

6.2 Fields

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.

6.3 Methods

6.3.1 Methods related to sections

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.

6.3.2 Methods related to string tables

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.

6.3.3 Methods related to section groups

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.

6.3.4 Methods related to loaded contents

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.

6.4 Usage

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

6.4.1 Working with sections

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.

6.4.2 Working with string tables

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.

6.4.3 Working with section groups

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:


Footnotes

(2)

The first section in an ELF file is the “null” section and has an empty name.


Next: , Previous: , Up: Top   [Contents][Index]