pts
pts

Reputation: 87201

Binutils objdump reports incorrect section sizes in COFF object

It looks like that the objdump tool (part of GNU Binutils) on Linux displays the section sizes of a COFF object file incorrectly. For example, the size of the .bss section should be 0x130, but objdump displays 0x40.

I have the following COFF object file (hex dump):

       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.

Just by looking at the hex dump, I can see the hex bytes 30 01 00 00 (indicating that the section size is 0x130 bytes) shortly after .bss. I've double checked both the DJGPP documentation and the OSDev COFF page that I'm looking at the correct offsets. First there is the ".bss\0\0\0\0" (8 bytes), then the physical address (4 bytes), then the virtual address (4 bytes), and then comes the size (4 bytes). Everything looks correct.

However, in the output of objdump -h file.o on my Linux system with GNU Binutils 2.30, I can't see the correct section size (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

Also the flags are weird. There shouldn't be any NOREAD flags.

How can I make objdump parse this COFF object file correctly? Ultimately I care about Binutils ld (rather than objdump), because I want to link such object files to my programs. But since objdump and ld use the same library (libbfd) for parsing object files, maybe fixing one will fix the other.

If it's impossible to fix objdump, how do I convert my COFF object file to a format objdump understands correctly?

Upvotes: 1

Views: 47

Answers (1)

pts
pts

Reputation: 87201

It looks there are multiple variations of the COFF object file format, and the file I have is of a different kind than what GNU Binutils ld(1) and objdump(1) understand. The most important difference is that the Binutils tools work correctly only if the s_vaddr field in the section header is zero.

I've written the converter fixcoff.pl which fixes this. After the conversion ld(1) and objdump(1) works.

Upvotes: 1

Related Questions