I am writing a compiler and am just starting to generate ELF executables from scratch. I am creating a .text
section (although it doesn't have a name because I am not creating a string table yet), and trying to put it within a PT_LOAD
segment. However, readelf
isn't reporting that the section is mapped into the segment and objdump
refuses to disassemble the code in the .text
section. This is the readout of readelf
, with some bits omitted for brevity:
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x0
Start of program headers: 64 (bytes into file)
Start of section headers: 122 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 1
Size of section headers: 64 (bytes)
Number of section headers: 2
Section header string table index: 0
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] <no-name> NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] <no-name> PROGBITS 0000000008048000 00000078
0000000000000002 0000000000000000 AX 0 0 16
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.
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000078 0x0000000008048000 0x0000000008048000
0x0000000000000002 0x0000000000000002 R E 1000
At offset 0x78
, I am just emitting two push ebx
s (opcode 0x53
) for testing. Here is the hex dump:
00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
00000010 02 00 3e 00 01 00 00 00 00 00 00 00 00 00 00 00 |..>.............|
00000020 40 00 00 00 00 00 00 00 7a 00 00 00 00 00 00 00 |@.......z.......|
00000030 00 00 00 00 40 00 38 00 01 00 40 00 02 00 00 00 |[email protected]...@.....|
00000040 01 00 00 00 05 00 00 00 78 00 00 00 00 00 00 00 |........x.......|
00000050 00 80 04 08 00 00 00 00 00 80 04 08 00 00 00 00 |................|
00000060 02 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 |................|
00000070 00 10 00 00 00 00 00 00 53 53 00 00 00 00 00 00 |........SS......|
00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000000b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 |................|
000000c0 00 00 06 00 00 00 00 00 00 00 00 80 04 08 00 00 |................|
000000d0 00 00 78 00 00 00 00 00 00 00 02 00 00 00 00 00 |..x.............|
000000e0 00 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00 |................|
*
000000fa
Edit: Question - Why isn't a section to segment mapping shown between the two, and why is no disassembly shown by objdump
?
Even though sections are not required for the executable part of ELF lifetime, a lot of tools depend on sections being present. For example, the lone segment you have in your executable contains both code and the ELF header, and the program header. Generally you don't want to disassemble the header.
The ELF data format explicitly provides two views of the same data. The difference between segments and sections is thus not what data they contain, but how they index the same data. The specification goes a step further: A program header table tells the system how to create a process image.
Perhaps one of the fields in the ELF header having to do with sections has been edited/corrupted to slow down automatic analysis, since section information cannot be displayed. if the section header table is still present in the binary, the ELF header can be repaired so that this information is properly parsed.
Amongst these files are normal executable files, relocatable object files, core files, and shared objects. An executable file using the ELF file format consists of an ELF header, followed by a program header table or a section header table, or both. The ELF header is always at offset zero of the file.
Why isn't a section to segment mapping shown between the two
Because there are no valid sections (as far as readelf
can tell).
and why is no disassembly shown by objdump?
objdump
also uses sections.
Even though sections are not required for the executable part of ELF
lifetime, a lot of tools depend on sections being present. For example, the lone segment you have in your executable contains both code and the ELF
header, and the program header. Generally you don't want to disassemble the header. Without sections, objdump
doesn't know where to start disassembly from.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With