Readelf指令&可执行目标文件与可重定位目标文件的比较

Readelf -h XXX.o

读ELF头

读可重定位目标文件的ELF头:

lsy@lsy-VirtualBox:~/Documents$ readelf -h Hello.o
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00   #魔数,代表ELF
  Class:                             ELF64                                         #64位ELF
  Data:                              2's complement, little endian     #二进制补码,小端法
  Version:                           1 (current)                              
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)             #类型为可重定位文件
  Machine:                           Advanced Micro Devices X86-64#在64位机器上运行
  Version:                           0x1
  Entry point address:               0x0                               #起始地址(虚拟空间)
  Start of program headers:          0 (bytes into file)      #程序头表起始地址为0(可重定目   标文件没有程序表头
  Start of section headers:          680 (bytes into file)   
  Flags:                             0x0
  Size of this header:               64 (bytes)                    #ELF头共64B
  Size of program headers:           0 (bytes)                 #ELF头大小为0未存放数据,不是可执行程序,所以为0
  Number of program headers:         0                        
  Size of section headers:           64 (bytes)
  Number of section headers:         13
  Section header string table index: 10                          #节头部表在表中的位置索引

对比读可执行文件的ELF头:

lsy@lsy-VirtualBox:~/Documents$ readelf -h Hello
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)#可执行文件
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x400430#可执行文件加载入内存,所以有起始地址
  Start of program headers:          64 (bytes into file)#可执行文件有程序表头
  Start of section headers:          6624 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         9
  Size of section headers:           64 (bytes)
  Number of section headers:         31
  Section header string table index: 28

readelf -l XXX

读程序头表(program header)
程序表头(program header):描述了可执行文件中的节与虚拟空间中的存储段之间的映射关系。可重定位文件中的节经过链接生成可执行文件时会组合为对应的段,程序表头就是描述了这些段与节的关系。所以程序表头也只有可执行文件里有而可重定位文件是没有的

lsy@lsy-VirtualBox:~/Documents$ readelf -l Hello
Elf file type is EXEC (Executable file)
Entry point 0x400430
There are 9 program headers, starting at offset 64
Program Headers: 
  Type            偏移位置           虚拟空间地址       物理地址
                 FileSiz            MemSiz              操作标志 对齐     
  PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040
                 0x00000000000001f8 0x00000000000001f8  R E    8
  INTERP         0x0000000000000238 0x0000000000400238 0x0000000000400238
                 0x000000000000001c 0x000000000000001c  R      1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x00000000000006fc 0x00000000000006fc  R E    200000
  LOAD           0x0000000000000e10 0x0000000000600e10 0x0000000000600e10
                 0x0000000000000228 0x0000000000000230  RW     200000
  DYNAMIC        0x0000000000000e28 0x0000000000600e28 0x0000000000600e28
                 0x00000000000001d0 0x00000000000001d0  RW     8
  NOTE           0x0000000000000254 0x0000000000400254 0x0000000000400254
                 0x0000000000000044 0x0000000000000044  R      4
  GNU_EH_FRAME   0x00000000000005d0 0x00000000004005d0 0x00000000004005d0
                 0x0000000000000034 0x0000000000000034  R      4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     10
  GNU_RELRO      0x0000000000000e10 0x0000000000600e10 0x0000000000600e10
                 0x00000000000001f0 0x00000000000001f0  R 
                 
Section to Segment mapping:
  Segment Sections...
   00     
   01     .interp 
   02     .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .plt.got .text .fini .rodata .eh_frame_hdr .eh_frame 
   03     .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss 
   04     .dynamic 
   05     .note.ABI-tag .note.gnu.build-id 
   06     .eh_frame_hdr 
   07     
   08     .init_array .fini_array .jcr .dynamic .got

读可重定位文件时,无程序头表:

lsy@lsy-VirtualBox:~/Documents$ readelf -l Hello.o
There are no program headers in this file.
readelf -s XXX.o

读符号表(.symbols)

root@lsy-VirtualBox:/mnt/Wshare/chap7_code# readelf -s Symbols.o
Symbol table '.symtab' contains 13 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS symbols.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    5 
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    8 
     8: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
     #####前9个是链接器内部使用的局部符号####################
     9: 0000000000000000     4 FUNC    GLOBAL DEFAULT    1 foo
    10: 0000000000000004    41 FUNC    GLOBAL DEFAULT    1 main
    11: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND printf
    12: 0000000000000004     4 OBJECT  GLOBAL DEFAULT  COM time
Ndx:1~8为ELF头中的位置索引,比如1表示存放在.text节;ABS表示不该被重定位;UND表示未定义,一般是外部引用;COM表示未初始化数据

symbols.c的代码:

#include <stdio.h>
int time;
int foo(int a) {
    int b = a + 1;
    return b;
}
int main(int argc, char *argv[])
{
    printf("%d\n", foo(5));
    return 0;
}
readelf -S XXX

读节头部表
节头部表(Section header):描述了每个节的节名,在文件中的偏移,大小,访问属性 ,对齐方式等

读可重定位文件:

root@lsy-VirtualBox:/mnt/Wshare/chap7_code# readelf -S Symbols.o
There are 13 section headers, starting at offset 0x320:
Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         0000000000000000  00000040
       000000000000002d  0000000000000000  AX       0     0     1
  [ 2] .rela.text        RELA             0000000000000000  00000240
       0000000000000048  0000000000000018   I      10     1     8
  [ 3] .data             PROGBITS         0000000000000000  0000006d
       0000000000000000  0000000000000000  WA       0     0     1
  [ 4] .bss              NOBITS           0000000000000000  0000006d
       0000000000000000  0000000000000000  WA       0     0     1
  [ 5] .rodata.str1.1    PROGBITS         0000000000000000  0000006d
       0000000000000004  0000000000000001 AMS       0     0     1
  [ 6] .comment          PROGBITS         0000000000000000  00000071
       000000000000002e  0000000000000001  MS       0     0     1
  [ 7] .note.GNU-stack   PROGBITS         0000000000000000  0000009f
       0000000000000000  0000000000000000           0     0     1
  [ 8] .eh_frame         PROGBITS         0000000000000000  000000a0
       0000000000000048  0000000000000000   A       0     0     8
  [ 9] .rela.eh_frame    RELA             0000000000000000  00000288
       0000000000000030  0000000000000018   I      10     8     8
  [10] .symtab           SYMTAB           0000000000000000  000000e8
       0000000000000138  0000000000000018          11     9     8
  [11] .strtab           STRTAB           0000000000000000  00000220
       0000000000000020  0000000000000000           0     0     1
  [12] .shstrtab         STRTAB           0000000000000000  000002b8
       0000000000000068  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific
可以观察到,在可重定位目标文件中.bss是没有分配空间的,它不占据实际空间,仅仅是一个占位符

读可执行文件:

root@lsy-VirtualBox:/mnt/Wshare/chap7_code# readelf -S Symbols
There are 31 section headers, starting at offset 0x1a18:
Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .interp           PROGBITS         0000000000400238  00000238
       000000000000001c  0000000000000000   A       0     0     1
  [ 2] .note.ABI-tag     NOTE             0000000000400254  00000254
       0000000000000020  0000000000000000   A       0     0     4
  [ 3] .note.gnu.build-i NOTE             0000000000400274  00000274
       0000000000000024  0000000000000000   A       0     0     4
  [ 4] .gnu.hash         GNU_HASH         0000000000400298  00000298
       000000000000001c  0000000000000000   A       5     0     8
  [ 5] .dynsym           DYNSYM           00000000004002b8  000002b8
       0000000000000060  0000000000000018   A       6     1     8
  [ 6] .dynstr           STRTAB           0000000000400318  00000318
       000000000000003f  0000000000000000   A       0     0     1
  [ 7] .gnu.version      VERSYM           0000000000400358  00000358
       0000000000000008  0000000000000002   A       5     0     2
  [ 8] .gnu.version_r    VERNEED          0000000000400360  00000360
       0000000000000020  0000000000000000   A       6     1     8
  [ 9] .rela.dyn         RELA             0000000000400380  00000380
       0000000000000018  0000000000000018   A       5     0     8
  [10] .rela.plt         RELA             0000000000400398  00000398
       0000000000000030  0000000000000018  AI       5    24     8
  [11] .init             PROGBITS         00000000004003c8  000003c8
       000000000000001a  0000000000000000  AX       0     0     4
  [12] .plt              PROGBITS         00000000004003f0  000003f0
       0000000000000030  0000000000000010  AX       0     0     16
  [13] .plt.got          PROGBITS         0000000000400420  00000420
       0000000000000008  0000000000000000  AX       0     0     8
  [14] .text             PROGBITS         0000000000400430  00000430
       00000000000001b2  0000000000000000  AX       0     0     16
  [15] .fini             PROGBITS         00000000004005e4  000005e4
       0000000000000009  0000000000000000  AX       0     0     4
  [16] .rodata           PROGBITS         00000000004005f0  000005f0
       0000000000000008  0000000000000000   A       0     0     4
  [17] .eh_frame_hdr     PROGBITS         00000000004005f8  000005f8
       000000000000003c  0000000000000000   A       0     0     4
  [18] .eh_frame         PROGBITS         0000000000400638  00000638
       0000000000000114  0000000000000000   A       0     0     8
  [19] .init_array       INIT_ARRAY       0000000000600e10  00000e10
       0000000000000008  0000000000000000  WA       0     0     8
  [20] .fini_array       FINI_ARRAY       0000000000600e18  00000e18
       0000000000000008  0000000000000000  WA       0     0     8
  [21] .jcr              PROGBITS         0000000000600e20  00000e20
       0000000000000008  0000000000000000  WA       0     0     8
  [22] .dynamic          DYNAMIC          0000000000600e28  00000e28
       00000000000001d0  0000000000000010  WA       6     0     8
  [23] .got              PROGBITS         0000000000600ff8  00000ff8
       0000000000000008  0000000000000008  WA       0     0     8
  [24] .got.plt          PROGBITS         0000000000601000  00001000
       0000000000000028  0000000000000008  WA       0     0     8
  [25] .data             PROGBITS         0000000000601028  00001028
       0000000000000010  0000000000000000  WA       0     0     8
  [26] .bss              NOBITS           0000000000601038  00001038
       0000000000000008  0000000000000000  WA       0     0     4
  [27] .comment          PROGBITS         0000000000000000  00001038
       0000000000000035  0000000000000001  MS       0     0     1
  [28] .shstrtab         STRTAB           0000000000000000  00001909
       000000000000010c  0000000000000000           0     0     1
  [29] .symtab           SYMTAB           0000000000000000  00001070
       0000000000000678  0000000000000018          30    47     8
  [30] .strtab           STRTAB           0000000000000000  000016e8
       0000000000000221  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)
  观察到可执行目标文件中.bss有了实际空间,是因为运行时将这些未初始化的变量加载入内存并赋初值为0.
  另外我们可以观察到可执行目标文件比可重定位文件多了一个程序头表和init节,少了rel.text,rel.data。事实上,可执行目标文件只留下了ELF头, .text, .rodata, .data, .bss。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值