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 offset 0x300.

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 and R_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 and R_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 of 0x00400580.

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.