Reverse-engineering part 3: introspecting with the toolchain
Previously in this series of articles, we generated a number of binary artifacts when building a program with a toolchain (namely, three relocatable object files and an executable file). In this part, we will analyze one object file and the executable file with the toolchain.
Just like in part 1, this is a simplified explanation intended to give a basic, high-level overview of the ELF file structures and associated tooling for the purposes of reverse-engineering. For an in-depth explanation, please refer to Fabien Sanglard’s Driving Compilers series of articles, especially part 3 and part 4.
Tools of the toolchain
Like in part 2, we will be using the Debian Bullseye operating system as a building environment. We’ll assume we have already installed the toolchain for our target:
$ sudo apt-get install \
build-essential \
binutils-mips-linux-gnu \
gcc-mips-linux-gnu
We will use the following tools to introspect the ascii-table.o
and ascii-table.elf
artifacts:
readelf
: a low-level, standalone ELF file data dumper ;objdump
: the generic Unix object file data dumper ;nm
: the generic Unix symbolic information dumper.
Since we are working with the GNU toolchain for the MIPS architecture, the actual names for the generic tools will be mips-linux-gnu-objdump
and mips-linux-gnu-nm
.
Note that while the output of these tools may differ, they nevertheless display the same basic data for a given file, which is why the results of equivalent commands are grouped into tabs.
Relocatable object file
$ readelf --wide --file-header ascii-table.o
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: MIPS R3000
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 7860 (bytes into file)
Flags: 0x70001001, noreorder, o32, mips32r2
Size of this header: 52 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)
Number of section headers: 34
Section header string table index: 33
$ mips-linux-gnu-objdump --wide --file-headers ascii-table.o
ascii-table.o: file format elf32-tradlittlemips
architecture: mips:isa32r2, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x00000000
ascii-table.o
is a relocatable object file for the 32-bit MIPS architecture.
Since it is not an executable file, its entry point address is left uninitialized (0x00000000
).
We know what type of file ascii-table.o
is, but we do not yet know what it contains.
Sections
ELF files are made up of sections, which can be thought of as byte arrays with names.
We will limit our analysis to the .text
, .text.startup
and .rodata
sections, since they contain the functions and data defined in our original source code files.
$ readelf --wide --section-headers ascii-table.o
There are 34 section headers, starting at offset 0x1eb4:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000040 000190 00 AX 0 0 16
[ 2] .rel.text REL 00000000 0014d0 000038 08 I 31 1 4
[ 3] .data PROGBITS 00000000 0001d0 000000 00 WA 0 0 16
[ 4] .bss NOBITS 00000000 0001d0 000000 00 WA 0 0 16
[ 5] .reginfo MIPS_REGINFO 00000000 0001d0 000018 18 A 0 0 4
[ 6] .MIPS.abiflags MIPS_ABIFLAGS 00000000 0001e8 000018 18 A 0 0 8
[ 7] .pdr PROGBITS 00000000 000200 000060 00 0 0 4
[ 8] .rel.pdr REL 00000000 001508 000018 08 I 31 7 4
[ 9] .mdebug.abi32 PROGBITS 00000000 000260 000000 00 0 0 1
[10] .text.startup PROGBITS 00000000 000260 0000a0 00 AX 0 0 4
[11] .rel.text.startup REL 00000000 001520 000020 08 I 31 10 4
[12] .rodata PROGBITS 00000000 000300 000060 00 A 0 0 16
[13] .rel.rodata REL 00000000 001540 000050 08 I 31 12 4
[14] .debug_info MIPS_DWARF 00000000 000360 000426 00 0 0 1
[15] .rel.debug_info REL 00000000 001590 0002d8 08 I 31 14 4
[16] .debug_abbrev MIPS_DWARF 00000000 000786 000194 00 0 0 1
[17] .debug_loc MIPS_DWARF 00000000 00091a 000272 00 0 0 1
[18] .rel.debug_loc REL 00000000 001868 000240 08 I 31 17 4
[19] .debug_aranges MIPS_DWARF 00000000 000b8c 000028 00 0 0 1
[20] .rel.debug_aranges REL 00000000 001aa8 000018 08 I 31 19 4
[21] .debug_ranges MIPS_DWARF 00000000 000bb4 0001b0 00 0 0 1
[22] .rel.debug_ranges REL 00000000 001ac0 000290 08 I 31 21 4
[23] .debug_line MIPS_DWARF 00000000 000d64 0001a8 00 0 0 1
[24] .rel.debug_line REL 00000000 001d50 000010 08 I 31 23 4
[25] .debug_str MIPS_DWARF 00000000 000f0c 0001be 01 MS 0 0 1
[26] .comment PROGBITS 00000000 0010ca 000028 01 MS 0 0 1
[27] .note.GNU-stack PROGBITS 00000000 0010f2 000000 00 0 0 1
[28] .debug_frame MIPS_DWARF 00000000 0010f4 0000a0 00 0 0 4
[29] .rel.debug_frame REL 00000000 001d60 000030 08 I 31 28 4
[30] .gnu.attributes GNU_ATTRIBUTES 00000000 001194 000010 00 0 0 1
[31] .symtab SYMTAB 00000000 0011a4 000270 10 32 22 4
[32] .strtab STRTAB 00000000 001414 0000b9 00 0 0 1
[33] .shstrtab STRTAB 00000000 001d90 000124 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
p (processor specific)
$ mips-linux-gnu-objdump --wide --section-headers ascii-table.o
ascii-table.o: file format elf32-tradlittlemips
Sections:
Idx Name Size VMA LMA File off Algn Flags
0 .text 00000190 00000000 00000000 00000040 2**4 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 00000000 00000000 00000000 000001d0 2**4 CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 000001d0 2**4 ALLOC
3 .reginfo 00000018 00000000 00000000 000001d0 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA, LINK_ONCE_SAME_SIZE
4 .MIPS.abiflags 00000018 00000000 00000000 000001e8 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA, LINK_ONCE_SAME_SIZE
5 .pdr 00000060 00000000 00000000 00000200 2**2 CONTENTS, RELOC, READONLY
6 .mdebug.abi32 00000000 00000000 00000000 00000260 2**0 CONTENTS, READONLY
7 .text.startup 000000a0 00000000 00000000 00000260 2**2 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
8 .rodata 00000060 00000000 00000000 00000300 2**4 CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
9 .debug_info 00000426 00000000 00000000 00000360 2**0 CONTENTS, RELOC, READONLY, DEBUGGING, OCTETS
10 .debug_abbrev 00000194 00000000 00000000 00000786 2**0 CONTENTS, READONLY, DEBUGGING, OCTETS
11 .debug_loc 00000272 00000000 00000000 0000091a 2**0 CONTENTS, RELOC, READONLY, DEBUGGING, OCTETS
12 .debug_aranges 00000028 00000000 00000000 00000b8c 2**0 CONTENTS, RELOC, READONLY, DEBUGGING, OCTETS
13 .debug_ranges 000001b0 00000000 00000000 00000bb4 2**0 CONTENTS, RELOC, READONLY, DEBUGGING, OCTETS
14 .debug_line 000001a8 00000000 00000000 00000d64 2**0 CONTENTS, RELOC, READONLY, DEBUGGING, OCTETS
15 .debug_str 000001be 00000000 00000000 00000f0c 2**0 CONTENTS, READONLY, DEBUGGING, OCTETS
16 .comment 00000028 00000000 00000000 000010ca 2**0 CONTENTS, READONLY
17 .note.GNU-stack 00000000 00000000 00000000 000010f2 2**0 CONTENTS, READONLY
18 .debug_frame 000000a0 00000000 00000000 000010f4 2**2 CONTENTS, RELOC, READONLY, DEBUGGING, OCTETS
19 .gnu.attributes 00000010 00000000 00000000 00001194 2**0 CONTENTS, READONLY
$ mips-linux-gnu-objdump --wide --disassemble --reloc --section .text ascii-table.o
ascii-table.o: file format elf32-tradlittlemips
Disassembly of section .text:
00000000 <print_number>:
0: 27bdffd0 addiu sp,sp,-48
4: afb30028 sw s3,40(sp)
8: 2413000c li s3,12
c: afb20024 sw s2,36(sp)
10: 2412fffc li s2,-4
14: afb10020 sw s1,32(sp)
18: 24110010 li s1,16
1c: afb0001c sw s0,28(sp)
20: 00808025 move s0,a0
24: afbf002c sw ra,44(sp)
28: 02701007 srav v0,s0,s3
2c: 0051001a div zero,v0,s1
30: 00001010 mfhi v0
34: 304300ff andi v1,v0,0xff
38: 2842000a slti v0,v0,10
3c: 10400011 beqz v0,84 <print_number+0x84>
40: 00000000 nop
44: 24630030 addiu v1,v1,48
48: 24060001 li a2,1
4c: a3a30010 sb v1,16(sp)
50: 27a50010 addiu a1,sp,16
54: 24040001 li a0,1
58: 0c000000 jal 0 <print_number> 58: R_MIPS_26 write
5c: 2673fffc addiu s3,s3,-4
60: 1672fff2 bne s3,s2,2c <print_number+0x2c>
64: 02701007 srav v0,s0,s3
68: 8fbf002c lw ra,44(sp)
6c: 8fb30028 lw s3,40(sp)
70: 8fb20024 lw s2,36(sp)
74: 8fb10020 lw s1,32(sp)
78: 8fb0001c lw s0,28(sp)
7c: 03e00008 jr ra
80: 27bd0030 addiu sp,sp,48
84: 1000fff0 b 48 <print_number+0x48>
88: 24630057 addiu v1,v1,87
0000008c <print_ascii_entry>:
8c: 27bdffd0 addiu sp,sp,-48
90: afbf002c sw ra,44(sp)
94: afb30024 sw s3,36(sp)
98: 24130020 li s3,32
9c: afb20020 sw s2,32(sp)
a0: 00c09025 move s2,a2
a4: afb1001c sw s1,28(sp)
a8: 00808825 move s1,a0
ac: afb00018 sw s0,24(sp)
b0: 00a08025 move s0,a1
b4: 0c000000 jal 0 <print_number> b4: R_MIPS_26 print_number
b8: afb40028 sw s4,40(sp)
bc: 24040001 li a0,1
c0: 24060001 li a2,1
c4: a3b30010 sb s3,16(sp)
c8: 0c000000 jal 0 <print_number> c8: R_MIPS_26 write
cc: 27a50010 addiu a1,sp,16
d0: 0c000000 jal 0 <print_number> d0: R_MIPS_26 isgraph
d4: 02202025 move a0,s1
d8: 10400018 beqz v0,13c <print_ascii_entry+0xb0>
dc: 00000000 nop
e0: a3b10010 sb s1,16(sp)
e4: 24060001 li a2,1
e8: 27a50010 addiu a1,sp,16
ec: 24040001 li a0,1
f0: 0c000000 jal 0 <print_number> f0: R_MIPS_26 write
f4: 00009825 move s3,zero
f8: 24020020 li v0,32
fc: 24060001 li a2,1
100: 27a50010 addiu a1,sp,16
104: a3a20010 sb v0,16(sp)
108: 24040001 li a0,1
10c: 0c000000 jal 0 <print_number> 10c: R_MIPS_26 write
110: 24140020 li s4,32
114: 0272102a slt v0,s3,s2
118: 1440000a bnez v0,144 <print_ascii_entry+0xb8>
11c: 8fbf002c lw ra,44(sp)
120: 8fb40028 lw s4,40(sp)
124: 8fb30024 lw s3,36(sp)
128: 8fb20020 lw s2,32(sp)
12c: 8fb1001c lw s1,28(sp)
130: 8fb00018 lw s0,24(sp)
134: 03e00008 jr ra
138: 27bd0030 addiu sp,sp,48
13c: 1000ffe9 b e4 <print_ascii_entry+0x58>
140: a3b30010 sb s3,16(sp)
144: 8e020000 lw v0,0(s0)
148: 0040f809 jalr v0
14c: 02202025 move a0,s1
150: 1040000b beqz v0,180 <print_ascii_entry+0xf4>
154: 00000000 nop
158: 92020004 lbu v0,4(s0)
15c: a3a20010 sb v0,16(sp)
160: 24060001 li a2,1
164: 27a50010 addiu a1,sp,16
168: 24040001 li a0,1
16c: 26730001 addiu s3,s3,1
170: 0c000000 jal 0 <print_number> 170: R_MIPS_26 write
174: 26100008 addiu s0,s0,8
178: 1000ffe7 b 118 <print_ascii_entry+0x8c>
17c: 0272102a slt v0,s3,s2
180: 1000fff7 b 160 <print_ascii_entry+0xd4>
184: a3b40010 sb s4,16(sp)
...
Every section has the following main properties:
- a name ;
- a file offset and a file size, specifying where in the file is that section’s data stored ;
- a virtual address.
Each section in the relocatable object file has virtual address 0x0
: this is because sections are not yet laid out in memory by the linker, so they do not have a predefined base virtual address.
Nevertheless, .text
, .text.startup
and .rodata
all have a file offset and a file size because these sections do have contents.
We now know what sections ascii-table.o
does contain and where they are located in the file, but we do not know what’s inside those sections.
Symbols
Section contains symbols, which are like labels for addresses.
In the case of relocatable object files, these addresses are relative to the section, so here if a symbol has an address of 0x4
for example, it means it is located at the 4th byte of the section.
$ readelf --wide --symbols ascii-table.o
Symbol table '.symtab' contains 39 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FILE LOCAL DEFAULT ABS ascii-table.c
2: 00000000 0 SECTION LOCAL DEFAULT 1
3: 00000000 0 SECTION LOCAL DEFAULT 3
4: 00000000 0 SECTION LOCAL DEFAULT 4
5: 00000000 0 SECTION LOCAL DEFAULT 9
6: 00000000 0 SECTION LOCAL DEFAULT 10
7: 00000000 0 SECTION LOCAL DEFAULT 14
8: 00000000 0 SECTION LOCAL DEFAULT 16
9: 00000000 0 SECTION LOCAL DEFAULT 17
10: 00000000 0 SECTION LOCAL DEFAULT 19
11: 00000000 0 SECTION LOCAL DEFAULT 21
12: 00000000 0 SECTION LOCAL DEFAULT 23
13: 00000000 0 SECTION LOCAL DEFAULT 25
14: 00000000 0 SECTION LOCAL DEFAULT 27
15: 00000000 0 SECTION LOCAL DEFAULT 28
16: 00000000 0 SECTION LOCAL DEFAULT 5
17: 00000000 0 SECTION LOCAL DEFAULT 6
18: 00000000 0 SECTION LOCAL DEFAULT 7
19: 00000000 0 SECTION LOCAL DEFAULT 12
20: 00000000 0 SECTION LOCAL DEFAULT 26
21: 00000000 0 SECTION LOCAL DEFAULT 30
22: 00000000 140 FUNC GLOBAL DEFAULT 1 print_number
23: 00000000 0 NOTYPE GLOBAL DEFAULT UND write
24: 0000008c 252 FUNC GLOBAL DEFAULT 1 print_ascii_entry
25: 00000000 0 NOTYPE GLOBAL DEFAULT UND isgraph
26: 00000000 160 FUNC GLOBAL DEFAULT 10 main
27: 00000004 80 OBJECT GLOBAL DEFAULT 12 s_ascii_properties
28: 00000000 4 OBJECT GLOBAL DEFAULT 12 COLUMNS
29: 00000000 0 NOTYPE GLOBAL DEFAULT UND isprint
30: 00000000 0 NOTYPE GLOBAL DEFAULT UND iscntrl
31: 00000000 0 NOTYPE GLOBAL DEFAULT UND isspace
32: 00000000 0 NOTYPE GLOBAL DEFAULT UND ispunct
33: 00000000 0 NOTYPE GLOBAL DEFAULT UND isalnum
34: 00000000 0 NOTYPE GLOBAL DEFAULT UND isalpha
35: 00000000 0 NOTYPE GLOBAL DEFAULT UND isdigit
36: 00000000 0 NOTYPE GLOBAL DEFAULT UND isupper
37: 00000000 0 NOTYPE GLOBAL DEFAULT UND islower
38: 00000054 4 OBJECT GLOBAL DEFAULT 12 NUM_ASCII_PROPERTIES
$ mips-linux-gnu-objdump --wide --syms ascii-table.o
ascii-table.o: file format elf32-tradlittlemips
SYMBOL TABLE:
00000000 l df *ABS* 00000000 ascii-table.c
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 l d .mdebug.abi32 00000000 .mdebug.abi32
00000000 l d .text.startup 00000000 .text.startup
00000000 l d .debug_info 00000000 .debug_info
00000000 l d .debug_abbrev 00000000 .debug_abbrev
00000000 l d .debug_loc 00000000 .debug_loc
00000000 l d .debug_aranges 00000000 .debug_aranges
00000000 l d .debug_ranges 00000000 .debug_ranges
00000000 l d .debug_line 00000000 .debug_line
00000000 l d .debug_str 00000000 .debug_str
00000000 l d .note.GNU-stack 00000000 .note.GNU-stack
00000000 l d .debug_frame 00000000 .debug_frame
00000000 l d .reginfo 00000000 .reginfo
00000000 l d .MIPS.abiflags 00000000 .MIPS.abiflags
00000000 l d .pdr 00000000 .pdr
00000000 l d .rodata 00000000 .rodata
00000000 l d .comment 00000000 .comment
00000000 l d .gnu.attributes 00000000 .gnu.attributes
00000000 g F .text 0000008c print_number
00000000 *UND* 00000000 write
0000008c g F .text 000000fc print_ascii_entry
00000000 *UND* 00000000 isgraph
00000000 g F .text.startup 000000a0 main
00000004 g O .rodata 00000050 s_ascii_properties
00000000 g O .rodata 00000004 COLUMNS
00000000 *UND* 00000000 isprint
00000000 *UND* 00000000 iscntrl
00000000 *UND* 00000000 isspace
00000000 *UND* 00000000 ispunct
00000000 *UND* 00000000 isalnum
00000000 *UND* 00000000 isalpha
00000000 *UND* 00000000 isdigit
00000000 *UND* 00000000 isupper
00000000 *UND* 00000000 islower
00000054 g O .rodata 00000004 NUM_ASCII_PROPERTIES
$ mips-linux-gnu-nm --format sysv --line-numbers --no-sort ascii-table.o
Symbols from ascii-table.o:
Name Value Class Type Size Line Section
print_number |00000000| T | FUNC|0000008c| |.text /home/jblbeurope/Documents/samples/ascii-table.c:26
write | | U | NOTYPE| | |*UND* /home/jblbeurope/Documents/samples/ascii-table.c:33
print_ascii_entry |0000008c| T | FUNC|000000fc| |.text /home/jblbeurope/Documents/samples/ascii-table.c:37
isgraph | | U | NOTYPE| | |*UND* /home/jblbeurope/Documents/samples/ascii-table.c:41
main |00000000| T | FUNC|000000a0| |.text.startup /home/jblbeurope/Documents/samples/ascii-table.c:57
s_ascii_properties |00000004| R | OBJECT|00000050| |.rodata /home/jblbeurope/Documents/samples/ascii-table.c:11
COLUMNS |00000000| R | OBJECT|00000004| |.rodata /home/jblbeurope/Documents/samples/ascii-table.c:24
isprint | | U | NOTYPE| | |*UND*
iscntrl | | U | NOTYPE| | |*UND*
isspace | | U | NOTYPE| | |*UND*
ispunct | | U | NOTYPE| | |*UND*
isalnum | | U | NOTYPE| | |*UND*
isalpha | | U | NOTYPE| | |*UND*
isdigit | | U | NOTYPE| | |*UND*
isupper | | U | NOTYPE| | |*UND*
islower | | U | NOTYPE| | |*UND*
NUM_ASCII_PROPERTIES|00000054| R | OBJECT|00000004| |.rodata /home/jblbeurope/Documents/samples/ascii-table.c:10
Relocatable object files can have two types of symbols:
- defined symbols, which are provided by this object file and are located within a section at a given offset ;
- undefined symbols, which are not provided by this object file and therefore do not belong to any section.
Since defined symbols have an offset within a section and sections have a file offset, we can compute the file offset of a defined symbol by adding its section’s offset and its offset within the section.
Taking s_ascii_properties
as an example:
- the symbol is located at offset 4 of the
.rodata
section ; - the
.rodata
is located at file offset0x300
.
We can calculate that the symbol s_ascii_properties
starts at file offset 0x304
.
We now know what symbols are defined within the sections of ascii-table.o
, but these sections are relocatable.
We therefore need a way to relocate the contents of the sections to a given virtual base address as part of the linking procedure.
Relocations
Note: for readability reasons, the relocations for debugging sections have been removed.
Only the relocations for sections .text
, .text.startup
and .rodata
are displayed here.
$ readelf --wide --relocs ascii-table.o
Relocation section '.rel.text' at offset 0x14d0 contains 7 entries:
Offset Info Type Sym. Value Symbol's Name
00000058 00001704 R_MIPS_26 00000000 write
000000b4 00001604 R_MIPS_26 00000000 print_number
000000c8 00001704 R_MIPS_26 00000000 write
000000d0 00001904 R_MIPS_26 00000000 isgraph
000000f0 00001704 R_MIPS_26 00000000 write
0000010c 00001704 R_MIPS_26 00000000 write
00000170 00001704 R_MIPS_26 00000000 write
Relocation section '.rel.text.startup' at offset 0x1520 contains 4 entries:
Offset Info Type Sym. Value Symbol's Name
00000008 00001b05 R_MIPS_HI16 00000004 s_ascii_properties
00000018 00001b06 R_MIPS_LO16 00000004 s_ascii_properties
00000048 00001804 R_MIPS_26 0000008c print_ascii_entry
0000006c 00001704 R_MIPS_26 00000000 write
Relocation section '.rel.rodata' at offset 0x1540 contains 10 entries:
Offset Info Type Sym. Value Symbol's Name
00000004 00001902 R_MIPS_32 00000000 isgraph
0000000c 00001d02 R_MIPS_32 00000000 isprint
00000014 00001e02 R_MIPS_32 00000000 iscntrl
0000001c 00001f02 R_MIPS_32 00000000 isspace
00000024 00002002 R_MIPS_32 00000000 ispunct
0000002c 00002102 R_MIPS_32 00000000 isalnum
00000034 00002202 R_MIPS_32 00000000 isalpha
0000003c 00002302 R_MIPS_32 00000000 isdigit
00000044 00002402 R_MIPS_32 00000000 isupper
0000004c 00002502 R_MIPS_32 00000000 islower
$ mips-linux-gnu-objdump --wide --reloc ascii-table.o
ascii-table.o: file format elf32-tradlittlemips
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
00000058 R_MIPS_26 write
000000b4 R_MIPS_26 print_number
000000c8 R_MIPS_26 write
000000d0 R_MIPS_26 isgraph
000000f0 R_MIPS_26 write
0000010c R_MIPS_26 write
00000170 R_MIPS_26 write
RELOCATION RECORDS FOR [.text.startup]:
OFFSET TYPE VALUE
00000008 R_MIPS_HI16 s_ascii_properties
00000018 R_MIPS_LO16 s_ascii_properties
00000048 R_MIPS_26 print_ascii_entry
0000006c R_MIPS_26 write
RELOCATION RECORDS FOR [.rodata]:
OFFSET TYPE VALUE
00000004 R_MIPS_32 isgraph
0000000c R_MIPS_32 isprint
00000014 R_MIPS_32 iscntrl
0000001c R_MIPS_32 isspace
00000024 R_MIPS_32 ispunct
0000002c R_MIPS_32 isalnum
00000034 R_MIPS_32 isalpha
0000003c R_MIPS_32 isdigit
00000044 R_MIPS_32 isupper
0000004c R_MIPS_32 islower
A relocation is a request to patch a spot in a section with the final address of a symbol. As such, it is composed of:
- the offset within a section to patch ;
- the type of patching to perform ;
- the symbol to use as part of the patching.
This object file contains four different types of relocations:
R_MIPS_32
: this relocation fixes a 32-bit absolute address as-is, typically used in data sections ;R_MIPS_26
: this relocation fixes an address to fit within a MIPS J-Format instruction, typically used in jump instructions for function calls ;R_MIPS_HI16
andR_MIPS_LO16
: these relocations work in tandem to fix a 32-bit absolute address across two MIPS I-Format instructions (R_MIPS_HI16
for the high 16 bits andR_MIPS_LO16
for the low 16 bits).
Executable file
$ readelf --wide --file-header ascii-table.elf
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: MIPS R3000
Version: 0x1
Entry point address: 0x400568
Start of program headers: 52 (bytes into file)
Start of section headers: 10320 (bytes into file)
Flags: 0x70001001, noreorder, o32, mips32r2
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 5
Size of section headers: 40 (bytes)
Number of section headers: 21
Section header string table index: 20
$ mips-linux-gnu-objdump --wide --file-headers ascii-table.elf
ascii-table.elf: file format elf32-tradlittlemips
architecture: mips:isa32r2, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x00400568
ascii-table.elf
is an executable file for the 32-bit MIPS architecture.
Since it is an executable file, it has a valid entry point address (0x00400568
) from which execution will begin.
Sections
As with object files, executable files are made up of sections:
$ readelf --wide --section-headers ascii-table.elf
There are 21 section headers, starting at offset 0x2850:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .MIPS.abiflags MIPS_ABIFLAGS 004000d8 0000d8 000018 18 A 0 0 8
[ 2] .reginfo MIPS_REGINFO 004000f0 0000f0 000018 18 A 0 0 4
[ 3] .note.gnu.build-id NOTE 00400108 000108 000024 00 A 0 0 4
[ 4] .text PROGBITS 00400130 000130 000450 00 AX 0 0 16
[ 5] .rodata PROGBITS 00400580 000580 000170 00 A 0 0 16
[ 6] .comment PROGBITS 00000000 0006f0 000027 01 MS 0 0 1
[ 7] .pdr PROGBITS 00000000 000718 000220 00 0 0 4
[ 8] .debug_aranges MIPS_DWARF 00000000 000938 000068 00 0 0 1
[ 9] .debug_info MIPS_DWARF 00000000 0009a0 000805 00 0 0 1
[10] .debug_abbrev MIPS_DWARF 00000000 0011a5 00033f 00 0 0 1
[11] .debug_line MIPS_DWARF 00000000 0014e4 00040d 00 0 0 1
[12] .debug_frame MIPS_DWARF 00000000 0018f4 0001a8 00 0 0 4
[13] .debug_str MIPS_DWARF 00000000 001a9c 000244 01 MS 0 0 1
[14] .debug_loc MIPS_DWARF 00000000 001ce0 00048d 00 0 0 1
[15] .debug_ranges MIPS_DWARF 00000000 00216d 0001b0 00 0 0 1
[16] .gnu.attributes GNU_ATTRIBUTES 00000000 00231d 000010 00 0 0 1
[17] .mdebug.abi32 PROGBITS 00000000 00232d 000000 00 0 0 1
[18] .symtab SYMTAB 00000000 002330 000320 10 19 23 4
[19] .strtab STRTAB 00000000 002650 000118 00 0 0 1
[20] .shstrtab STRTAB 00000000 002768 0000e6 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
p (processor specific)
$ mips-linux-gnu-objdump --wide --section-headers ascii-table.elf
ascii-table.elf: file format elf32-tradlittlemips
Sections:
Idx Name Size VMA LMA File off Algn Flags
0 .MIPS.abiflags 00000018 004000d8 004000d8 000000d8 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA, LINK_ONCE_SAME_SIZE
1 .reginfo 00000018 004000f0 004000f0 000000f0 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA, LINK_ONCE_SAME_SIZE
2 .note.gnu.build-id 00000024 00400108 00400108 00000108 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .text 00000450 00400130 00400130 00000130 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE
4 .rodata 00000170 00400580 00400580 00000580 2**4 CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .comment 00000027 00000000 00000000 000006f0 2**0 CONTENTS, READONLY
6 .pdr 00000220 00000000 00000000 00000718 2**2 CONTENTS, READONLY
7 .debug_aranges 00000068 00000000 00000000 00000938 2**0 CONTENTS, READONLY, DEBUGGING, OCTETS
8 .debug_info 00000805 00000000 00000000 000009a0 2**0 CONTENTS, READONLY, DEBUGGING, OCTETS
9 .debug_abbrev 0000033f 00000000 00000000 000011a5 2**0 CONTENTS, READONLY, DEBUGGING, OCTETS
10 .debug_line 0000040d 00000000 00000000 000014e4 2**0 CONTENTS, READONLY, DEBUGGING, OCTETS
11 .debug_frame 000001a8 00000000 00000000 000018f4 2**2 CONTENTS, READONLY, DEBUGGING, OCTETS
12 .debug_str 00000244 00000000 00000000 00001a9c 2**0 CONTENTS, READONLY, DEBUGGING, OCTETS
13 .debug_loc 0000048d 00000000 00000000 00001ce0 2**0 CONTENTS, READONLY, DEBUGGING, OCTETS
14 .debug_ranges 000001b0 00000000 00000000 0000216d 2**0 CONTENTS, READONLY, DEBUGGING, OCTETS
15 .gnu.attributes 00000010 00000000 00000000 0000231d 2**0 CONTENTS, READONLY
16 .mdebug.abi32 00000000 00000000 00000000 0000232d 2**0 CONTENTS, READONLY
$ mips-linux-gnu-objdump --wide --disassemble --reloc --section .text ascii-table.elf
ascii-table.elf: file format elf32-tradlittlemips
Disassembly of section .text:
00400130 <main>:
400130: 27bdffd0 addiu sp,sp,-48
400134: afb20020 sw s2,32(sp)
400138: 3c120040 lui s2,0x40
40013c: afb40028 sw s4,40(sp)
400140: 24140080 li s4,128
400144: afb30024 sw s3,36(sp)
400148: 26520584 addiu s2,s2,1412
40014c: afb00018 sw s0,24(sp)
400150: 24130009 li s3,9
400154: 00008025 move s0,zero
400158: afbf002c sw ra,44(sp)
40015c: afb1001c sw s1,28(sp)
400160: 32110003 andi s1,s0,0x3
400164: 00101083 sra v0,s0,0x2
400168: 00112140 sll a0,s1,0x5
40016c: 2406000a li a2,10
400170: 00822021 addu a0,a0,v0
400174: 02402825 move a1,s2
400178: 0c100097 jal 40025c <print_ascii_entry>
40017c: 7c042420 seb a0,a0
400180: 2402000a li v0,10
400184: 3a310003 xori s1,s1,0x3
400188: 0271100b movn v0,s3,s1
40018c: 24060001 li a2,1
400190: 27a50010 addiu a1,sp,16
400194: 24040001 li a0,1
400198: 26100001 addiu s0,s0,1
40019c: 0c100154 jal 400550 <write>
4001a0: a3a20010 sb v0,16(sp)
4001a4: 1614ffef bne s0,s4,400164 <main+0x34>
4001a8: 32110003 andi s1,s0,0x3
4001ac: 8fbf002c lw ra,44(sp)
4001b0: 00001025 move v0,zero
4001b4: 8fb40028 lw s4,40(sp)
4001b8: 8fb30024 lw s3,36(sp)
4001bc: 8fb20020 lw s2,32(sp)
4001c0: 8fb1001c lw s1,28(sp)
4001c4: 8fb00018 lw s0,24(sp)
4001c8: 03e00008 jr ra
4001cc: 27bd0030 addiu sp,sp,48
004001d0 <print_number>:
4001d0: 27bdffd0 addiu sp,sp,-48
4001d4: afb30028 sw s3,40(sp)
4001d8: 2413000c li s3,12
4001dc: afb20024 sw s2,36(sp)
4001e0: 2412fffc li s2,-4
4001e4: afb10020 sw s1,32(sp)
4001e8: 24110010 li s1,16
4001ec: afb0001c sw s0,28(sp)
4001f0: 00808025 move s0,a0
4001f4: afbf002c sw ra,44(sp)
4001f8: 02701007 srav v0,s0,s3
4001fc: 0051001a div zero,v0,s1
400200: 00001010 mfhi v0
400204: 304300ff andi v1,v0,0xff
400208: 2842000a slti v0,v0,10
40020c: 10400011 beqz v0,400254 <print_number+0x84>
400210: 00000000 nop
400214: 24630030 addiu v1,v1,48
400218: 24060001 li a2,1
40021c: a3a30010 sb v1,16(sp)
400220: 27a50010 addiu a1,sp,16
400224: 24040001 li a0,1
400228: 0c100154 jal 400550 <write>
40022c: 2673fffc addiu s3,s3,-4
400230: 1672fff2 bne s3,s2,4001fc <print_number+0x2c>
400234: 02701007 srav v0,s0,s3
400238: 8fbf002c lw ra,44(sp)
40023c: 8fb30028 lw s3,40(sp)
400240: 8fb20024 lw s2,36(sp)
400244: 8fb10020 lw s1,32(sp)
400248: 8fb0001c lw s0,28(sp)
40024c: 03e00008 jr ra
400250: 27bd0030 addiu sp,sp,48
400254: 1000fff0 b 400218 <print_number+0x48>
400258: 24630057 addiu v1,v1,87
0040025c <print_ascii_entry>:
40025c: 27bdffd0 addiu sp,sp,-48
400260: afbf002c sw ra,44(sp)
400264: afb30024 sw s3,36(sp)
400268: 24130020 li s3,32
40026c: afb20020 sw s2,32(sp)
400270: 00c09025 move s2,a2
400274: afb1001c sw s1,28(sp)
400278: 00808825 move s1,a0
40027c: afb00018 sw s0,24(sp)
400280: 00a08025 move s0,a1
400284: 0c100074 jal 4001d0 <print_number>
400288: afb40028 sw s4,40(sp)
40028c: 24040001 li a0,1
400290: 24060001 li a2,1
400294: a3b30010 sb s3,16(sp)
400298: 0c100154 jal 400550 <write>
40029c: 27a50010 addiu a1,sp,16
4002a0: 0c100104 jal 400410 <isgraph>
4002a4: 02202025 move a0,s1
4002a8: 10400018 beqz v0,40030c <print_ascii_entry+0xb0>
4002ac: 00000000 nop
4002b0: a3b10010 sb s1,16(sp)
4002b4: 24060001 li a2,1
4002b8: 27a50010 addiu a1,sp,16
4002bc: 24040001 li a0,1
4002c0: 0c100154 jal 400550 <write>
4002c4: 00009825 move s3,zero
4002c8: 24020020 li v0,32
4002cc: 24060001 li a2,1
4002d0: 27a50010 addiu a1,sp,16
4002d4: a3a20010 sb v0,16(sp)
4002d8: 24040001 li a0,1
4002dc: 0c100154 jal 400550 <write>
4002e0: 24140020 li s4,32
4002e4: 0272102a slt v0,s3,s2
4002e8: 1440000a bnez v0,400314 <print_ascii_entry+0xb8>
4002ec: 8fbf002c lw ra,44(sp)
4002f0: 8fb40028 lw s4,40(sp)
4002f4: 8fb30024 lw s3,36(sp)
4002f8: 8fb20020 lw s2,32(sp)
4002fc: 8fb1001c lw s1,28(sp)
400300: 8fb00018 lw s0,24(sp)
400304: 03e00008 jr ra
400308: 27bd0030 addiu sp,sp,48
40030c: 1000ffe9 b 4002b4 <print_ascii_entry+0x58>
400310: a3b30010 sb s3,16(sp)
400314: 8e020000 lw v0,0(s0)
400318: 0040f809 jalr v0
40031c: 02202025 move a0,s1
400320: 1040000b beqz v0,400350 <print_ascii_entry+0xf4>
400324: 00000000 nop
400328: 92020004 lbu v0,4(s0)
40032c: a3a20010 sb v0,16(sp)
400330: 24060001 li a2,1
400334: 27a50010 addiu a1,sp,16
400338: 24040001 li a0,1
40033c: 26730001 addiu s3,s3,1
400340: 0c100154 jal 400550 <write>
400344: 26100008 addiu s0,s0,8
400348: 1000ffe7 b 4002e8 <print_ascii_entry+0x8c>
40034c: 0272102a slt v0,s3,s2
400350: 1000fff7 b 400330 <print_ascii_entry+0xd4>
400354: a3b40010 sb s4,16(sp)
...
00400360 <isalnum>:
400360: 2403ffff li v1,-1
400364: 10830007 beq a0,v1,400384 <isalnum+0x24>
400368: 00001025 move v0,zero
40036c: 3c020040 lui v0,0x40
400370: 308400ff andi a0,a0,0xff
400374: 244205e1 addiu v0,v0,1505
400378: 00822021 addu a0,a0,v0
40037c: 90820000 lbu v0,0(a0)
400380: 30420007 andi v0,v0,0x7
400384: 03e00008 jr ra
400388: 00000000 nop
0040038c <isalpha>:
40038c: 2403ffff li v1,-1
400390: 10830007 beq a0,v1,4003b0 <isalpha+0x24>
400394: 00001025 move v0,zero
400398: 3c020040 lui v0,0x40
40039c: 308400ff andi a0,a0,0xff
4003a0: 244205e1 addiu v0,v0,1505
4003a4: 00822021 addu a0,a0,v0
4003a8: 90820000 lbu v0,0(a0)
4003ac: 30420003 andi v0,v0,0x3
4003b0: 03e00008 jr ra
4003b4: 00000000 nop
004003b8 <iscntrl>:
4003b8: 2403ffff li v1,-1
4003bc: 10830007 beq a0,v1,4003dc <iscntrl+0x24>
4003c0: 00001025 move v0,zero
4003c4: 3c020040 lui v0,0x40
4003c8: 308400ff andi a0,a0,0xff
4003cc: 244205e1 addiu v0,v0,1505
4003d0: 00822021 addu a0,a0,v0
4003d4: 90820000 lbu v0,0(a0)
4003d8: 30420020 andi v0,v0,0x20
4003dc: 03e00008 jr ra
4003e0: 00000000 nop
004003e4 <isdigit>:
4003e4: 2403ffff li v1,-1
4003e8: 10830007 beq a0,v1,400408 <isdigit+0x24>
4003ec: 00001025 move v0,zero
4003f0: 3c020040 lui v0,0x40
4003f4: 308400ff andi a0,a0,0xff
4003f8: 244205e1 addiu v0,v0,1505
4003fc: 00822021 addu a0,a0,v0
400400: 90820000 lbu v0,0(a0)
400404: 30420004 andi v0,v0,0x4
400408: 03e00008 jr ra
40040c: 00000000 nop
00400410 <isgraph>:
400410: 2403ffff li v1,-1
400414: 10830007 beq a0,v1,400434 <isgraph+0x24>
400418: 00001025 move v0,zero
40041c: 3c020040 lui v0,0x40
400420: 308400ff andi a0,a0,0xff
400424: 244205e1 addiu v0,v0,1505
400428: 00822021 addu a0,a0,v0
40042c: 90820000 lbu v0,0(a0)
400430: 30420017 andi v0,v0,0x17
400434: 03e00008 jr ra
400438: 00000000 nop
0040043c <islower>:
40043c: 2403ffff li v1,-1
400440: 10830007 beq a0,v1,400460 <islower+0x24>
400444: 00001025 move v0,zero
400448: 3c020040 lui v0,0x40
40044c: 308400ff andi a0,a0,0xff
400450: 244205e1 addiu v0,v0,1505
400454: 00822021 addu a0,a0,v0
400458: 90820000 lbu v0,0(a0)
40045c: 30420002 andi v0,v0,0x2
400460: 03e00008 jr ra
400464: 00000000 nop
00400468 <isprint>:
400468: 2403ffff li v1,-1
40046c: 10830007 beq a0,v1,40048c <isprint+0x24>
400470: 00001025 move v0,zero
400474: 3c020040 lui v0,0x40
400478: 308400ff andi a0,a0,0xff
40047c: 244205e1 addiu v0,v0,1505
400480: 00822021 addu a0,a0,v0
400484: 80820000 lb v0,0(a0)
400488: 30420097 andi v0,v0,0x97
40048c: 03e00008 jr ra
400490: 00000000 nop
00400494 <ispunct>:
400494: 2403ffff li v1,-1
400498: 10830007 beq a0,v1,4004b8 <ispunct+0x24>
40049c: 00001025 move v0,zero
4004a0: 3c020040 lui v0,0x40
4004a4: 308400ff andi a0,a0,0xff
4004a8: 244205e1 addiu v0,v0,1505
4004ac: 00822021 addu a0,a0,v0
4004b0: 90820000 lbu v0,0(a0)
4004b4: 30420010 andi v0,v0,0x10
4004b8: 03e00008 jr ra
4004bc: 00000000 nop
004004c0 <isspace>:
4004c0: 2403ffff li v1,-1
4004c4: 10830007 beq a0,v1,4004e4 <isspace+0x24>
4004c8: 00001025 move v0,zero
4004cc: 3c020040 lui v0,0x40
4004d0: 308400ff andi a0,a0,0xff
4004d4: 244205e1 addiu v0,v0,1505
4004d8: 00822021 addu a0,a0,v0
4004dc: 90820000 lbu v0,0(a0)
4004e0: 30420008 andi v0,v0,0x8
4004e4: 03e00008 jr ra
4004e8: 00000000 nop
004004ec <isupper>:
4004ec: 2403ffff li v1,-1
4004f0: 10830007 beq a0,v1,400510 <isupper+0x24>
4004f4: 00001025 move v0,zero
4004f8: 3c020040 lui v0,0x40
4004fc: 308400ff andi a0,a0,0xff
400500: 244205e1 addiu v0,v0,1505
400504: 00822021 addu a0,a0,v0
400508: 90820000 lbu v0,0(a0)
40050c: 30420001 andi v0,v0,0x1
400510: 03e00008 jr ra
400514: 00000000 nop
00400518 <isxdigit>:
400518: 2403ffff li v1,-1
40051c: 10830007 beq a0,v1,40053c <isxdigit+0x24>
400520: 00001025 move v0,zero
400524: 3c020040 lui v0,0x40
400528: 308400ff andi a0,a0,0xff
40052c: 244205e1 addiu v0,v0,1505
400530: 00822021 addu a0,a0,v0
400534: 90820000 lbu v0,0(a0)
400538: 30420044 andi v0,v0,0x44
40053c: 03e00008 jr ra
400540: 00000000 nop
...
00400550 <write>:
400550: 24020fa4 li v0,4004
400554: 0000000c syscall
400558: 03e00008 jr ra
40055c: 00000000 nop
00400560 <exit>:
400560: 24020fa1 li v0,4001
400564: 0000000c syscall
00400568 <__start>:
400568: 27bdffe8 addiu sp,sp,-24
40056c: afbf0014 sw ra,20(sp)
400570: 0c10004c jal 400130 <main>
400574: 00000000 nop
400578: 0c100158 jal 400560 <exit>
40057c: 00402025 move a0,v0
This time, the .text
, .text.startup
and .rodata
sections all have a non-zero virtual base address.
This is because the linker laid these out in memory as part of the linking process.
The sections still have a file offset and a file size as before.
Symbols
$ readelf --wide --symbols ascii-table.elf
Symbol table '.symtab' contains 50 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 004000d8 0 SECTION LOCAL DEFAULT 1
2: 004000f0 0 SECTION LOCAL DEFAULT 2
3: 00400108 0 SECTION LOCAL DEFAULT 3
4: 00400130 0 SECTION LOCAL DEFAULT 4
5: 00400580 0 SECTION LOCAL DEFAULT 5
6: 00000000 0 SECTION LOCAL DEFAULT 6
7: 00000000 0 SECTION LOCAL DEFAULT 7
8: 00000000 0 SECTION LOCAL DEFAULT 8
9: 00000000 0 SECTION LOCAL DEFAULT 9
10: 00000000 0 SECTION LOCAL DEFAULT 10
11: 00000000 0 SECTION LOCAL DEFAULT 11
12: 00000000 0 SECTION LOCAL DEFAULT 12
13: 00000000 0 SECTION LOCAL DEFAULT 13
14: 00000000 0 SECTION LOCAL DEFAULT 14
15: 00000000 0 SECTION LOCAL DEFAULT 15
16: 00000000 0 SECTION LOCAL DEFAULT 16
17: 00000000 0 SECTION LOCAL DEFAULT 17
18: 00000000 0 FILE LOCAL DEFAULT ABS ascii-table.c
19: 00000000 0 FILE LOCAL DEFAULT ABS ctype.c
20: 00000000 0 FILE LOCAL DEFAULT ABS libstd.c
21: 00000000 0 FILE LOCAL DEFAULT ABS
22: 004186e0 0 NOTYPE LOCAL DEFAULT 5 _gp
23: 00400584 80 OBJECT GLOBAL DEFAULT 5 s_ascii_properties
24: 004106f0 0 NOTYPE GLOBAL DEFAULT 5 _fdata
25: 004005d4 4 OBJECT GLOBAL DEFAULT 5 NUM_ASCII_PROPERTIES
26: 0040043c 44 FUNC GLOBAL DEFAULT 4 islower
27: 00400494 44 FUNC GLOBAL DEFAULT 4 ispunct
28: 004004c0 44 FUNC GLOBAL DEFAULT 4 isspace
29: 00400518 44 FUNC GLOBAL DEFAULT 4 isxdigit
30: 00400550 16 FUNC GLOBAL DEFAULT 4 write
31: 00400568 24 FUNC GLOBAL DEFAULT 4 __start
32: 004001d0 140 FUNC GLOBAL DEFAULT 4 print_number
33: 00400130 0 NOTYPE GLOBAL DEFAULT 4 _ftext
34: 004004ec 44 FUNC GLOBAL DEFAULT 4 isupper
35: 0040038c 44 FUNC GLOBAL DEFAULT 4 isalpha
36: 004106f0 0 NOTYPE GLOBAL DEFAULT 5 __bss_start
37: 00400130 160 FUNC GLOBAL DEFAULT 4 main
38: 00400410 44 FUNC GLOBAL DEFAULT 4 isgraph
39: 00400360 44 FUNC GLOBAL DEFAULT 4 isalnum
40: 00400468 44 FUNC GLOBAL DEFAULT 4 isprint
41: 0040025c 252 FUNC GLOBAL DEFAULT 4 print_ascii_entry
42: 00400580 4 OBJECT GLOBAL DEFAULT 5 COLUMNS
43: 004003e4 44 FUNC GLOBAL DEFAULT 4 isdigit
44: 004106f0 0 NOTYPE GLOBAL DEFAULT 5 _edata
45: 004106f0 0 NOTYPE GLOBAL DEFAULT 5 _end
46: 00400560 8 FUNC GLOBAL DEFAULT 4 exit
47: 004003b8 44 FUNC GLOBAL DEFAULT 4 iscntrl
48: 004005e0 257 OBJECT GLOBAL DEFAULT 5 _ctype_
49: 004106f0 0 NOTYPE GLOBAL DEFAULT 5 _fbss
$ mips-linux-gnu-objdump --wide --syms ascii-table.elf
ascii-table.elf: file format elf32-tradlittlemips
SYMBOL TABLE:
004000d8 l d .MIPS.abiflags 00000000 .MIPS.abiflags
004000f0 l d .reginfo 00000000 .reginfo
00400108 l d .note.gnu.build-id 00000000 .note.gnu.build-id
00400130 l d .text 00000000 .text
00400580 l d .rodata 00000000 .rodata
00000000 l d .comment 00000000 .comment
00000000 l d .pdr 00000000 .pdr
00000000 l d .debug_aranges 00000000 .debug_aranges
00000000 l d .debug_info 00000000 .debug_info
00000000 l d .debug_abbrev 00000000 .debug_abbrev
00000000 l d .debug_line 00000000 .debug_line
00000000 l d .debug_frame 00000000 .debug_frame
00000000 l d .debug_str 00000000 .debug_str
00000000 l d .debug_loc 00000000 .debug_loc
00000000 l d .debug_ranges 00000000 .debug_ranges
00000000 l d .gnu.attributes 00000000 .gnu.attributes
00000000 l d .mdebug.abi32 00000000 .mdebug.abi32
00000000 l df *ABS* 00000000 ascii-table.c
00000000 l df *ABS* 00000000 ctype.c
00000000 l df *ABS* 00000000 libstd.c
00000000 l df *ABS* 00000000
004186e0 l .rodata 00000000 _gp
00400584 g O .rodata 00000050 s_ascii_properties
004106f0 g .rodata 00000000 _fdata
004005d4 g O .rodata 00000004 NUM_ASCII_PROPERTIES
0040043c g F .text 0000002c islower
00400494 g F .text 0000002c ispunct
004004c0 g F .text 0000002c isspace
00400518 g F .text 0000002c isxdigit
00400550 g F .text 00000010 write
00400568 g F .text 00000018 __start
004001d0 g F .text 0000008c print_number
00400130 g .text 00000000 _ftext
004004ec g F .text 0000002c isupper
0040038c g F .text 0000002c isalpha
004106f0 g .rodata 00000000 __bss_start
00400130 g F .text 000000a0 main
00400410 g F .text 0000002c isgraph
00400360 g F .text 0000002c isalnum
00400468 g F .text 0000002c isprint
0040025c g F .text 000000fc print_ascii_entry
00400580 g O .rodata 00000004 COLUMNS
004003e4 g F .text 0000002c isdigit
004106f0 g .rodata 00000000 _edata
004106f0 g .rodata 00000000 _end
00400560 g F .text 00000008 exit
004003b8 g F .text 0000002c iscntrl
004005e0 g O .rodata 00000101 _ctype_
004106f0 g .rodata 00000000 _fbss
$ mips-linux-gnu-nm --format sysv --line-numbers --no-sort ascii-table.elf
Symbols from ascii-table.elf:
Name Value Class Type Size Line Section
_gp |004186e0| r | NOTYPE| | |.rodata
s_ascii_properties |00400584| R | OBJECT|00000050| |.rodata /home/jblbeurope/Documents/samples/ascii-table.c:11
_fdata |004106f0| R | NOTYPE| | |.rodata
NUM_ASCII_PROPERTIES|004005d4| R | OBJECT|00000004| |.rodata /home/jblbeurope/Documents/samples/ascii-table.c:10
islower |0040043c| T | FUNC|0000002c| |.text /home/jblbeurope/Documents/samples/ctype.c:111
ispunct |00400494| T | FUNC|0000002c| |.text /home/jblbeurope/Documents/samples/ctype.c:121
isspace |004004c0| T | FUNC|0000002c| |.text /home/jblbeurope/Documents/samples/ctype.c:126
isxdigit |00400518| T | FUNC|0000002c| |.text /home/jblbeurope/Documents/samples/ctype.c:136
write |00400550| T | FUNC|00000010| |.text /home/jblbeurope/Documents/samples/libstd.c:12
__start |00400568| T | FUNC|00000018| |.text /home/jblbeurope/Documents/samples/libstd.c:44
print_number |004001d0| T | FUNC|0000008c| |.text /home/jblbeurope/Documents/samples/ascii-table.c:26
_ftext |00400130| T | NOTYPE| | |.text /home/jblbeurope/Documents/samples/ascii-table.c:57
isupper |004004ec| T | FUNC|0000002c| |.text /home/jblbeurope/Documents/samples/ctype.c:131
isalpha |0040038c| T | FUNC|0000002c| |.text /home/jblbeurope/Documents/samples/ctype.c:91
__bss_start |004106f0| R | NOTYPE| | |.rodata
main |00400130| T | FUNC|000000a0| |.text /home/jblbeurope/Documents/samples/ascii-table.c:57
isgraph |00400410| T | FUNC|0000002c| |.text /home/jblbeurope/Documents/samples/ctype.c:106
isalnum |00400360| T | FUNC|0000002c| |.text /home/jblbeurope/Documents/samples/ctype.c:86
isprint |00400468| T | FUNC|0000002c| |.text /home/jblbeurope/Documents/samples/ctype.c:116
print_ascii_entry |0040025c| T | FUNC|000000fc| |.text /home/jblbeurope/Documents/samples/ascii-table.c:37
COLUMNS |00400580| R | OBJECT|00000004| |.rodata /home/jblbeurope/Documents/samples/ascii-table.c:24
isdigit |004003e4| T | FUNC|0000002c| |.text /home/jblbeurope/Documents/samples/ctype.c:101
_edata |004106f0| R | NOTYPE| | |.rodata
_end |004106f0| R | NOTYPE| | |.rodata
exit |00400560| T | FUNC|00000008| |.text /home/jblbeurope/Documents/samples/libstd.c:27
iscntrl |004003b8| T | FUNC|0000002c| |.text /home/jblbeurope/Documents/samples/ctype.c:96
_ctype_ |004005e0| R | OBJECT|00000101| |.rodata /home/jblbeurope/Documents/samples/ctype.c:49
_fbss |004106f0| R | NOTYPE| | |.rodata
Unlike the relocatable object file, every symbol in the executable is defined. Furthermore, because every defined symbol is located within a section and every section has a virtual address, every symbol therefore also has an absolute virtual address. Therefore, non-relocatable files use absolute virtual addresses for their symbols ; they are not relative to a section.
With the section and symbol data, we can compute the file addresses of symbols.
Taking once again s_ascii_properties
as an example:
- the symbol is located at virtual address
0x00400584
within the.rodata
section ; - the
.rodata
section has a virtual base address of0x00400580
.
We can calculate that the symbol s_ascii_properties
has an offset from the start of the .rodata
section of 0x4
.
Furthermore, the .rodata
section has a file offset of 0x580
, so the file offset of this symbol is 0x584
.
Relocations
$ readelf --wide --relocs ascii-table.elf
There are no relocations in this file.
$ mips-linux-gnu-objdump --wide --reloc ascii-table.elf
ascii-table.elf: file format elf32-tradlittlemips
As noted previously, executables do not have relocations. They are no longer useful once all symbols have an address and every relocation has been processed by the linker.
The files for this case study can be found here: case-study.tar.gz
Conclusion
We have analyzed the binary artifacts of our case study created by the toolchain with the toolchain. Next time, we will analyze the run-time behavior of our case study by running and debugging our program.