我readelf以前是读取ELF文件的信息的。我发现.got节头中节的地址与从动态节中读取的GOT入口点地址不同。.got地址和GOT入口点之间存储的数据是垃圾吗?以下是从readelf.
ELF Header - 此 ELF 在 ARMv7A 上运行。
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: DYN (Shared object file)
Machine: ARM
Version: 0x1
Entry point address: 0x0
Start of program headers: 52 (bytes into file)
Start of section headers: 38412 (bytes into file)
Flags: 0x5000200, Version5 EABI, soft-float ABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 8
Size of section headers: 40 (bytes)
Number of section headers: 26
Section header string table index: 25
节标题-节的地址.got位于0x00008eac
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .note.gnu.build-i NOTE 00000134 000134 000024 00 A 0 0 4
[ 2] .dynsym DYNSYM 00000158 000158 0006a0 10 A 3 1 4
[ 3] .dynstr STRTAB 000007f8 0007f8 000704 00 A 0 0 1
[ 4] .hash HASH 00000efc 000efc 000334 04 A 2 0 4
[ 5] .gnu.version VERSYM 00001230 001230 0000d4 02 A 2 0 2
[ 6] .gnu.version_d VERDEF 00001304 001304 00001c 00 A 3 1 4
[ 7] .gnu.version_r VERNEED 00001320 001320 000020 00 A 3 1 4
[ 8] .rel.dyn REL 00001340 001340 000178 08 A 2 0 4
[ 9] .rel.plt REL 000014b8 0014b8 000250 08 AI 2 10 4
[10] .plt PROGBITS 00001708 001708 00038c 00 AX 0 0 4
[11] .text PROGBITS 00001a94 001a94 0053d4 00 AX 0 0 4
[12] .ARM.extab PROGBITS 00006e68 006e68 000078 00 A 0 0 4
[13] .ARM.exidx ARM_EXIDX 00006ee0 006ee0 000178 08 AL 11 0 4
[14] .rodata PROGBITS 00007058 007058 000038 00 AM 0 0 4
[15] .fini_array FINI_ARRAY 00008cf8 007cf8 000008 00 WA 0 0 4
[16] .data.rel.ro PROGBITS 00008d00 007d00 00007c 00 WA 0 0 4
[17] .init_array INIT_ARRAY 00008d7c 007d7c 000008 00 WA 0 0 4
[18] .dynamic DYNAMIC 00008d84 007d84 000128 08 WA 3 0 4
[19] .got PROGBITS 00008eac 007eac 000154 00 WA 0 0 4
[20] .data PROGBITS 00009000 008000 001450 00 WA 0 0 4
[21] .bss NOBITS 0000a450 009450 000004 00 WA 0 0 4
[22] .comment PROGBITS 00000000 009450 000065 01 MS 0 0 1
[23] .note.gnu.gold-ve NOTE 00000000 0094b8 00001c 00 0 0 4
[24] .ARM.attributes ARM_ATTRIBUTES 00000000 0094d4 000034 00 0 0 1
[25] .shstrtab STRTAB 00000000 009508 000103 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
动态部分的一部分
Dynamic section at offset 0x7d84 contains 32 entries:
Tag Type Name/Value
0x00000003 (PLTGOT) 0x8ecc
0x00000002 (PLTRELSZ) 592 (bytes)
0x00000017 (JMPREL) 0x14b8
0x00000014 (PLTREL) REL
0x00000011 (REL) 0x1340
0x00000012 (RELSZ) 376 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffa (RELCOUNT) 41
0x00000006 (SYMTAB) 0x158
0x0000000b (SYMENT) 16 (bytes)
0x00000005 (STRTAB) 0x7f8
0x0000000a (STRSZ) 1796 (bytes)
0x00000004 (HASH) 0xefc
...
尾部.dynamic和头部.got
...
0x8e84: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
0x8e94: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
0x8ea4: 00 00 00 00 00 00 00 00 00 |......... |
; section: .got
0x8eac: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
0x8ebc: 00 00 00 00 58 70 00 00 e0 6e 00 00 00 00 00 00 |....Xp...n......|
0x8ecc: 00 00 00 00 00 00 00 00 00 00 00 00 08 17 00 00 |................|
0x8edc: 08 17 00 00 08 17 00 00 08 17 00 00 08 17 00 00 |................|
...
Oracle 的规范中提到:
符号 _GLOBAL_OFFSET_TABLE_ 可用于访问该表。这个符号可以位于 .got 部分的中间,允许负和非负下标进入地址数组。
但GOT进入之前的数据,却悄然与其他数据不同。所有其他数据都指向第一个 PLT 地址(0x1708)。GOT的入口点之前的空间是用来存放外部函数地址的,是和其他的一样,还是有其他的使用方式,或者只是无用的垃圾?
更新
我发现0x8eacto块中有两个数字0x8ecb,即GOT入口点之前的块。在0x8ec0,0x7058是.rodata节的地址。而 at 0x8ec4,0x6ee0是.ARM.exidx段的地址。是不是在.gotARM的链式工具和编译器的特定功能中填充这两个地址?
我还没有看到任何 ELF 规范提到这一点。