-
Notifications
You must be signed in to change notification settings - Fork 0
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.
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
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.
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 ELFSectionHeader
s 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
.
.
.
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