Skip to content
Nazim Bhuiyan edited this page Mar 6, 2018 · 1 revision

Documentation draft

ELFGenerator

This document aims to assist anyone dealing with the ELFGenerator class, whether it is to augment, write tests, or just to understand how it works.

Introduction

The class ELFGenerator is an abstract base class that provides a mechanism to share code between different kinds of ELF file generators. Currently, 2 implementations exist: ELFExecutableGenerator and ELFRelocatableGenerator. Both of these classes inherit from ELFGenerator and implement the pure virtual functions that contain code specific to the type of ELF file being built.

As their names imply, ELFExecutableGenerator generates executable ELF, and ELFRelocatableGenerator generates relocatable ELF.

TODO (perhaps not very important): write up and link a jump to a section that summarizes the difference between the 2 elf formats

Initialization

The ELFRelocatableGenerator and ELFExecutableGenerator should be initialized only after the code cache has been set up. ELFRelocatableGenerator and ELFExecutable generator both share the same constructor, and require the TR::RawAllocator _rawAllocator, the code cache segment base, and the size of the code cache segment.

When either of the generators are initialized, the header for the ELF file specific to the target platform, the type of ELF (ET_REL or ET_EXEC), the program header (in the case of executable ELF), etc. are set up. Platform-specific initializations are the same across both relocatable and executable ELF, for which the function TR::ELFGenerator::initializeHeaderForPlatform() takes care of that.

Generating the file

When the JIT compiler is being shut down, the compiled methods and static relocations should be written to ELF files. Both relocatable and executable ELF generator classes would need a call to emitELF(...). The function signature of emitELF is not the same across both the derived classes, as relocatable ELF files will need CodeCacheRelocationInfo.

For both relocatable and executable generators, emitELF(...) first initializes the various section headers relevant to the type of ELF file being built. Many of the values assigned to the members of the ELFSectionHeader structs depend on the variable offset resulting from the varying number of CodeCacheSymbols, CodeCacheRelocationInfo, etc.

After the ELFSectionHeaders have been initialized, it is now time to begin writing to file. The file name that was passed to emitELF(...) is opened in writing binary mode. First the ELFEHeader is written, followed by the ELFProgramHeader (in the case of executable ELF), the code segment, the section headers, the section header names, the CodeCacheSymbols converted to ELFSymbols, and ELFRela entries (in the case of RelocatableELF).

TODO: More in-depth explanation regarding the purpose of each of the section headers and what is required vs optional .
.
.

Sample ELF file

Here is an example of how an ELF file generated by ELFRelocatableGenerator looks like, which can be viewed on Linux by the command readelf -a <elfFileName>.o:

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - GNU
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          16777256 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           64 (bytes)
  Number of section headers:         6
  Section header string table index: 4

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         0000000000000000  00000040
       0000000000ffffe8  0000000000000000  AX       0     0     32
  [ 2] .rela.text        RELA             0000000000000000  010002e8
       0000000000000078  0000000000000018           3     1     8
  [ 3] .symtab           SYMTAB           0000000000000000  010001d8
       00000000000000c0  0000000000000018           5     1     8
  [ 4] .shstrtab         STRTAB           0000000000000000  010001a8
       000000000000002c  0000000000000000           0     0     1
  [ 5] .strtab           STRTAB           0000000000000000  01000298
       0000000000000050  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

There are no section groups in this file.

There are no program headers in this file.

Relocation section '.rela.text' at offset 0x10002e8 contains 5 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000081  000200000001 R_X86_64_64       0000000000000000 doublesum + 0
00000000009b  000300000001 R_X86_64_64       0000000000000000 doublesum + 0
0000000000b5  000400000001 R_X86_64_64       0000000000000000 doublesum + 0
0000000000d5  000500000001 R_X86_64_64       0000000000000000 doublesum + 0
0000000000ff  000600000001 R_X86_64_64       0000000000000000 doublesum + 0

The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.

Symbol table '.symtab' contains 8 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000034   286 FUNC    GLOBAL DEFAULT    1 test_calls
     2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND doublesum
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND doublesum
     4: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND doublesum
     5: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND doublesum
     6: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND doublesum
     7: 0000000000000174   262 FUNC    GLOBAL DEFAULT    1 test_computed_call

No version information found in this file.

TODO: Explanation for each of the parts of this file and what their different functions are