ELF toolchain

Serge Vakulenko edited this page Dec 5, 2015 · 1 revision

Tutorial on using ELF toolchain

ELF Tool Chain contains linker, archiver and a set of basic utilities for manipulating ELF object files.

Let's consider a simple example of using these utilities.

Create a trivial application

Let's create a trivial application consisting of one C file, and one assembler file, linked together.

File start.c:

void exit(int status);

void start()
{
    exit(0);
}

File exit.s:

	.set	noreorder
        .type   exit, @function
exit:	.global	exit
	.text
        syscall 0
	b	exit
	nop

Linker script:

OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips")
OUTPUT_ARCH(mips)
ENTRY(start)
SECTIONS {
    .text       0x9d000000  : AT(0x9d000000)    { *(.text)      }
    .rdata      ALIGN(4096) :                   { *(.rdata)     }
    .rodata     ALIGN(4096) :                   { *(.rodata)    }
    .data       ALIGN(4096) :                   { *(.data)      }
    .bss        ALIGN(4096) :                   { *(.bss)       }
}

Compile the sources into object files and link them together. Here I use the GCC compiler/assembler/linker from Mentor Sourcery CodeBench Lite toolchain.

mips-sde-elf-gcc -EL -mips32r2 -Wall -Werror -O -c start.c -o start.o
mips-sde-elf-gcc -EL -mips32r2 -Wall -Werror -O -c exit.s -o exit.o
mips-sde-elf-ld -EL -mips32r2 -nostdlib -Tlinker-script.ld start.o exit.o  -o test.elf
mips-sde-elf-objdump -S test.elf > test.dis

The resulting disassembled file looks like this:

test.elf:     file format elf32-tradlittlemips

Disassembly of section .text:

9d000000 <start>:
9d000000:	27bdffe8 	addiu	sp,sp,-24
9d000004:	afbf0014 	sw	ra,20(sp)
9d000008:	0f400004 	jal	9d000010 <exit>
9d00000c:	00002021 	move	a0,zero

9d000010 <exit>:
9d000010:	0000000c 	syscall
9d000014:	1000fffe 	b	9d000010 <exit>
9d000018:	00000000 	nop

nm

NM utility display symbolic information from ELF file.

$ nm -a exit.o
00000000 b .bss
00000000 d .data
00000000 n .pdr
00000000 n .reginfo
00000000 t .text
00000000 T exit
$ nm -a start.o
00000000 b .bss
00000000 n .comment
00000000 d .data
00000000 n .gnu.attributes
00000000 n .mdebug.abi32
00000000 n .pdr
00000000 n .reginfo
00000000 t .text
         U exit
00000000 T start
00000000 a start.c
$ nm -a test.elf
00000000 a
00000000 n .comment
00000000 n .gnu.attributes
00000000 n .pdr
00000000 n .reginfo
9d000000 t .text
9d000010 T exit
9d000000 T start
00000000 a start.c

size

SIZE utility displays sizes of ELF sections.

$ size *.o *.elf
  text   data   bss   dec    hex   filename
    12      0     0    12    0xc   exit.o
    16      0     0    16   0x10   start.o
    28      0     0    28   0x1c   test.elf

strings

STRINGS utility scans the binary file and finds all contiguous sequences of printable characters.

$ strings -a *.elf
GCC: (Sourcery CodeBench Lite 2013.11-37) 4.8.1
.symtab
.strtab
.shstrtab
.text
.reginfo
.pdr
.comment
.gnu.attributes
start.c
exit
start

elfdump

ELFDUMP utility displays information about ELF objects. Though, I would recommend to use another utility 'readelf' (see below), as it provides more comprehensive information.

readelf

READELF utility displays information about ELF objects.

$ readelf -a exit.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:                            NONE
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           MIPS R3000 Big-Endian only
  Version:                           0x1
  Entry point address:               0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          152 (bytes into file)
  Flags:                             0x70001001, mips32r2, o32, noreorder
  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:         10
  Section header string table index: 7

There are no program headers in this file.
There are 10 section headers, starting at offset 0x98:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0] (null)            NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00000000 000034 00000c 00  AX  0   0  4
  [ 2] .rel.text         REL             00000000 0002a0 000008 08      8   1  4
  [ 3] .data             PROGBITS        00000000 000040 000000 00  WA  0   0  1
  [ 4] .bss              NOBITS          00000000 000040 000000 00  WA  0   0  1
  [ 5] .reginfo          MIPS_REGINFO    00000000 000040 000018 18      0   0  4
  [ 6] .pdr              PROGBITS        00000000 000058 000000 00      0   0  4
  [ 7] .shstrtab         STRTAB          00000000 000058 00003e 00      0   0  1
  [ 8] .symtab           SYMTAB          00000000 000228 000070 10      9   6  4
  [ 9] .strtab           STRTAB          00000000 000298 000006 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

There is no dynamic section in this file.

Relocation section (.rel.text):
r_offset r_info   r_type              st_value st_name
00000004 0000060a R_MIPS_PC16         00000000 exit
Symbol table (.symtab) contains 7 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 SECTION LOCAL  DEFAULT    1
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    3
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    4
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    5
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    6
     6: 0000000000000000     0 FUNC    GLOBAL DEFAULT    1 exit

Section '.reginfo' contains 1 entries:
 REGINFO    ri_gprmask:    0x00000000
            ri_cprmask[0]: 0x00000000
            ri_cprmask[1]: 0x00000000
            ri_cprmask[2]: 0x00000000
            ri_cprmask[3]: 0x00000000
            ri_gp_value:   0

$ readelf -a start.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:                            NONE
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           MIPS R3000 Big-Endian only
  Version:                           0x1
  Entry point address:               0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          296 (bytes into file)
  Flags:                             0x70001001, mips32r2, o32, noreorder
  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:         14
  Section header string table index: 11

There are no program headers in this file.
There are 14 section headers, starting at offset 0x128:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0] (null)            NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00000000 000034 000010 00  AX  0   0  4
  [ 2] .rel.text         REL             00000000 00042c 000008 08     12   1  4
  [ 3] .data             PROGBITS        00000000 000044 000000 00  WA  0   0  1
  [ 4] .bss              NOBITS          00000000 000044 000000 00  WA  0   0  1
  [ 5] .reginfo          MIPS_REGINFO    00000000 000044 000018 18      0   0  4
  [ 6] .pdr              PROGBITS        00000000 00005c 000020 00      0   0  4
  [ 7] .rel.pdr          REL             00000000 000434 000008 08     12   6  4
  [ 8] .mdebug.abi32     PROGBITS        00000000 00007c 000000 00      0   0  1
  [ 9] .comment          PROGBITS        00000000 00007c 000031 01  MS  0   0  1
  [10] .gnu.attributes   SUNW_cap        00000000 0000ad 000010 00      0   0  1
  [11] .shstrtab         STRTAB          00000000 0000bd 000069 00      0   0  1
  [12] .symtab           SYMTAB          00000000 000358 0000c0 10     13  10  4
  [13] .strtab           STRTAB          00000000 000418 000014 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

There is no dynamic section in this file.

Relocation section (.rel.text):
r_offset r_info   r_type              st_value st_name
00000008 00000b04 R_MIPS_26           00000000 exit

Relocation section (.rel.pdr):
r_offset r_info   r_type              st_value st_name
00000000 00000a02 R_MIPS_32           00000000 start
Symbol table (.symtab) contains 12 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS start.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    8
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    5
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    6
     8: 0000000000000000     0 SECTION LOCAL  DEFAULT    9
     9: 0000000000000000     0 SECTION LOCAL  DEFAULT   10
    10: 0000000000000000    16 FUNC    GLOBAL DEFAULT    1 start
    11: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND exit
Attribute Section: gnu
File Attributes
  Tag_GNU_MIPS_ABI_FP: Hard float (double precision)

Section '.reginfo' contains 1 entries:
 REGINFO    ri_gprmask:    0xa0000010
            ri_cprmask[0]: 0x00000000
            ri_cprmask[1]: 0x00000000
            ri_cprmask[2]: 0x00000000
            ri_cprmask[3]: 0x00000000
            ri_gp_value:   0

$ readelf -a test.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:                            NONE
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           MIPS R3000 Big-Endian only
  Version:                           0x1
  Entry point address:               0x9d000000
  Start of program headers:          52 (bytes into file)
  Start of section headers:          65756 (bytes into file)
  Flags:                             0x70001001, mips32r2, o32, noreorder
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         1
  Size of section headers:           40 (bytes)
  Number of section headers:         9
  Section header string table index: 6

Elf file type is EXEC (Executable file)
Entry point 0x9d000000
There are 1 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x010000 0x9d000000 0x9d000000 0x0001c 0x0001c R E 0x10000

 Section to Segment mapping:
  Segment Sections...
   00     .text
There are 9 section headers, starting at offset 0x100dc:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0] (null)            NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        9d000000 010000 00001c 00  AX  0   0  4
  [ 2] .reginfo          MIPS_REGINFO    00000000 01001c 000018 18      0   0  4
  [ 3] .pdr              PROGBITS        00000000 010034 000020 00      0   0  4
  [ 4] .comment          PROGBITS        00000000 010054 000030 01  MS  0   0  1
  [ 5] .gnu.attributes   SUNW_cap        00000000 010084 000010 00      0   0  1
  [ 6] .shstrtab         STRTAB          00000000 010094 000048 00      0   0  1
  [ 7] .symtab           SYMTAB          00000000 010244 0000a0 10      8   8  4
  [ 8] .strtab           STRTAB          00000000 0102e4 000014 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

There is no dynamic section in this file.
Symbol table (.symtab) contains 10 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 000000009d000000     0 SECTION LOCAL  DEFAULT    1
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    2
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    5
     6: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS start.c
     7: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS
     8: 000000009d000010     0 FUNC    GLOBAL DEFAULT    1 exit
     9: 000000009d000000    16 FUNC    GLOBAL DEFAULT    1 start
Attribute Section: gnu
File Attributes
  Tag_GNU_MIPS_ABI_FP: Hard float (double precision)

Section '.reginfo' contains 1 entries:
 REGINFO    ri_gprmask:    0xa0000010
            ri_cprmask[0]: 0x00000000
            ri_cprmask[1]: 0x00000000
            ri_cprmask[2]: 0x00000000
            ri_cprmask[3]: 0x00000000
            ri_gp_value:   0