Linux 上的 objdump 工具(GNU Binutils 的一部分)似乎无法正确显示 COFF 目标文件的部分大小。例如,.bss部分的大小应为0x130,但objdump显示0x40。
我有以下 COFF 目标文件(十六进制转储):
0 4c 01 04 00 dd ec 3f 00 18 01 00 00 09 00 00 00 L.....?.........
10 00 00 04 00 2e 74 65 78 74 00 00 00 00 00 00 00 .....text.......
20 00 00 00 00 38 00 00 00 b4 00 00 00 04 01 00 00 ....8...........
30 00 00 00 00 02 00 00 00 20 00 00 00 2e 64 61 74 ........ ....dat
40 61 00 00 00 38 00 00 00 38 00 00 00 08 00 00 00 a...8...8.......
50 ec 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
60 40 00 00 00 2e 62 73 73 00 00 00 00 40 00 00 00 @....bss....@...
70 40 00 00 00 30 01 00 00 00 00 00 00 00 00 00 00 @...0...........
80 00 00 00 00 00 00 00 00 80 00 00 00 2e 72 6f 64 .............rod
90 61 74 61 00 70 01 00 00 70 01 00 00 10 00 00 00 ata.p...p.......
a0 f4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
b0 40 00 00 00 b8 04 00 00 00 bb 01 00 00 00 b9 70 @..............p
c0 01 00 00 ba 0e 00 00 00 cd 80 b8 04 00 00 00 bb ................
d0 01 00 00 00 b9 38 00 00 00 ba 07 00 00 00 cd 80 .....8..........
e0 b8 01 00 00 00 33 db cd 80 90 90 90 57 6f 72 6c .....3......Worl
f0 64 21 0a 00 48 65 6c 6c 6f 2c 20 57 6f 72 6c 64 d!..Hello, World
100 21 0a 00 00 0b 00 00 00 05 00 00 00 06 00 21 00 !.............!.
110 00 00 01 00 00 00 06 00 2e 74 65 78 74 00 00 00 .........text...
120 00 00 00 00 01 00 00 00 03 00 2e 64 61 74 61 00 ...........data.
130 00 00 38 00 00 00 02 00 00 00 03 00 2e 62 73 73 ..8..........bss
140 00 00 00 00 40 00 00 00 03 00 00 00 03 00 2e 72 [email protected]
150 6f 64 61 74 61 00 70 01 00 00 06 00 00 00 03 00 odata.p.........
160 00 00 00 00 04 00 00 00 7f 01 00 00 06 00 00 00 ................
170 03 00 5f 73 74 61 72 74 00 00 00 00 00 00 01 00 .._start........
180 00 00 02 00 6d 73 67 62 00 00 00 00 38 00 00 00 ....msgb....8...
190 02 00 00 00 03 00 6d 73 67 61 00 00 00 00 70 01 ......msga....p.
1a0 00 00 06 00 00 00 03 00 00 00 00 00 0e 00 00 00 ................
1b0 40 00 00 00 02 00 00 00 03 00 18 00 00 00 6d 73 @.............ms
1c0 67 61 5f 65 6e 64 31 00 6d 73 67 62 5f 65 6e 64 ga_end1.msgb_end
1d0 31 00 1.
只需查看十六进制转储,我就可以在
30 01 00 00
之后不久看到十六进制字节 .bss
(表示节大小为 0x130 字节)。我仔细检查了 DJGPP 文档 和 OSDev COFF 页面,我正在查看正确的偏移量。首先是 ".bss\0\0\0\0"
(8 字节),然后是物理地址(4 字节),然后是虚拟地址(4 字节),最后是大小(4 字节)。一切看起来都正确。
但是,在我的使用 GNU Binutils 2.30 的 Linux 系统上的
objdump -h file.o
的输出中,我看不到正确的节大小 (0x130):
file.o: file format pe-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000038 00000000 00000000 000000b4 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE, NOREAD
1 .data 00000008 00000038 00000038 000000ec 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA, NOREAD
2 .bss 00000040 00000040 00000040 00000000 2**2
ALLOC, READONLY, NOREAD
3 .rodata 00000010 00000170 00000170 000000f4 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA, NOREAD
旗帜也很奇怪。不应该有任何
NOREAD
标志。
如何让 objdump 正确解析这个 COFF 目标文件?最终我关心 Binutils ld (而不是 objdump),因为我想将此类对象文件链接到我的程序。但由于 objdump 和 ld 使用相同的库 (libbfd) 来解析目标文件,也许修复一个就能修复另一个。
如果无法修复 objdump,如何将我的 COFF 目标文件转换为 objdump 可以正确理解的格式?
看起来 COFF 目标文件格式有多种变体,并且我拥有的文件与 GNU Binutils ld(1) 和 objdump(1) 理解的文件类型不同。最重要的区别是,仅当节标题中的 s_vaddr 字段为零时,Binutils 工具才能正常工作。
我已经编写了转换器 fixcoff.pl 来解决这个问题。转换后 ld(1) 和 objdump(1) 起作用。