ELF(Executable and Linking Format)格式教學文件, #1: ELF 簡介

jollen 發表於 November 19, 2006 10:12 PM

ELF(Executable and Linking Format)是 object file 的檔案格式,其主要結構是以 section(節區)為主,我們可以利用 GNU binutils 套件的 objdump 工具來列出執行檔的 section 與其內容。例如,我想把 ls 命令的 ELF section 列印出來:

# objdump -x /bin/ls |more
...
Idx Name          Size      VMA       LMA       File off  Algn
  0 .interp       00000013  08048114  08048114  00000114  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .note.ABI-tag 00000020  08048128  08048128  00000128  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .hash         0000028c  08048148  08048148  00000148  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .dynsym       000005e0  080483d4  080483d4  000003d4  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .dynstr       000003ea  080489b4  080489b4  000009b4  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .gnu.version  000000bc  08048d9e  08048d9e  00000d9e  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .gnu.version_r 00000070  08048e5c  08048e5c  00000e5c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .rel.dyn      00000028  08048ecc  08048ecc  00000ecc  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  8 .rel.plt      00000278  08048ef4  08048ef4  00000ef4  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  9 .init         00000017  0804916c  0804916c  0000116c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 10 .plt          00000500  08049184  08049184  00001184  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 11 .text         0000ab4c  08049690  08049690  00001690  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 12 .fini         0000001b  080541dc  080541dc  0000c1dc  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 13 .rodata       00003760  08054200  08054200  0000c200  2**5
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 14 .eh_frame_hdr 0000002c  08057960  08057960  0000f960  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 15 .eh_frame     0000010c  0805798c  0805798c  0000f98c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 16 .data         00000114  08058000  08058000  00010000  2**5
                  CONTENTS, ALLOC, LOAD, DATA
 17 .dynamic      000000d0  08058114  08058114  00010114  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 18 .ctors        00000008  080581e4  080581e4  000101e4  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 19 .dtors        00000008  080581ec  080581ec  000101ec  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 20 .jcr          00000004  080581f4  080581f4  000101f4  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 21 .got          00000150  080581f8  080581f8  000101f8  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 22 .bss          00000368  08058360  08058360  00010360  2**5
                  ALLOC
...

如果要印出指定 section 的內容,例如 .data section:

# objdump -j .data -s /bin/ls

/bin/ls: file format elf32-i386
Contents of section .data: 8058000 00000000 00000000 f0810508 00000000 ................ 8058010 00000000 00000000 00000000 00000000 ................ 8058020 00000080 ffffffff 01000000 01000000 ................ 8058030 00000000 00000000 00000000 00000000 ................ 8058040 02000000 5c420508 01000000 5f420508 ....\B......_B.. 8058050 00000000 00000000 01000000 53720508 ............Sr.. 8058060 01000000 53720508 05000000 61420508 ....Sr......aB.. 8058070 05000000 67420508 02000000 76420508 ....gB......vB.. 8058080 05000000 6d420508 05000000 73420508 ....mB......sB.. 8058090 05000000 73420508 00000000 00000000 ....sB.......... 80580a0 00000000 00000000 05000000 79420508 ............yB.. 80580b0 05000000 6d420508 05000000 7f420508 ....mB.......B.. 80580c0 05000000 85420508 05000000 8b420508 .....B.......B.. 80580d0 05000000 91420508 00000000 97420508 .....B.......B.. 80580e0 a1420508 01000000 ffffffff 01000000 .B.............. 80580f0 90110508 01000000 01000000 00010000 ................ 8058100 a0850508 fc800508 e0750508 01000000 .........u...... 8058110 00000000 ....

Object file 主要有 3 種類別:

1. relocatable file
2. executable file
3. shared object file

relocatable file 即副檔名為 .o 的檔案、executable file 為一般的執行檔、shared object file 則是 *.so(shared libraries)檔案。ELF 是 object file 的檔案格式,其檔案格式如下圖。

jollen_blog-ELF_View.jpg
圖:ELF View(Execution View v.s. Linking View)

Linking view 指的是經由 assembler 或 linkage editor 編譯過,可被 CPU 執行的檔案格式,也就是儲存在儲存裝置上的程式格式(stored programs)。Execution view 指的是由 loader 載入後,程式執行時的格式,也就是存在於記憶體上的程式格式(process)。

當載入器(loader)將程式載入記憶體後,object file 就會是 execution view 的格式。了解 ELF 格式與學會如何讀取 ELF 內容,對於深入研究 Linux 內部的程式實作相當有幫助。例如,未來我們將會討論的 sys_init_module 實作,便需要對「如何讀取 ELF object」有一定程度的了解。

Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue

您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw