Binutils causes abnormally large, non-working binaries since 2.43

Dimitry Andric dimitry@andric.com
Mon Feb 17 12:56:31 GMT 2025


On 17 Feb 2025, at 12:55, Bastiaan Timmer <basjetimmer@yahoo.com> wrote:
> On 17-02-2025 11:58, Julian Waters wrote:
>> Unfortunately even binutils 2.42 still yields a Java Virtual Machine bloated to extreme sizes. It seems the 2 issues are unrelated.
...
> 
> I just realized: it is of course possible that just downgrading binutils is not enough.
> 
> For example in my case, I noticed the size increase in a program I was linking against openssl. Just downgrading binutils would not fix this, unless I also recompiled openssl _after_ that downgrade. So, I of course don't know anything about that JVM, but maybe it is possible its size increase is due to one of its dependencies having bloated in size, and that needs to be rebuilt with the old binutils version first.

Looking at libcrypto.a, I see that with your binutils 2.42 it is 8,145,216 bytes, while with binutils 2.43 it is 26,922,052 bytes. This difference is explained by the size of the contained object files:

  $ ls -l libcrypto-with-2.42
  total 9640
  -rw-r--r-- 1 dim dim   2421 2025-02-17 13:33:29 libcommon-lib-ciphercommon_block.obj
  -rw-r--r-- 1 dim dim   1893 2025-02-17 13:33:29 libcommon-lib-ciphercommon_ccm_hw.obj
  -rw-r--r-- 1 dim dim   6923 2025-02-17 13:33:29 libcommon-lib-ciphercommon_ccm.obj
  -rw-r--r-- 1 dim dim   1667 2025-02-17 13:33:29 libcommon-lib-ciphercommon_gcm_hw.obj
  -rw-r--r-- 1 dim dim   8479 2025-02-17 13:33:29 libcommon-lib-ciphercommon_gcm.obj
  -rw-r--r-- 1 dim dim   4506 2025-02-17 13:33:29 libcommon-lib-ciphercommon_hw.obj
  -rw-r--r-- 1 dim dim  15663 2025-02-17 13:33:29 libcommon-lib-ciphercommon.obj
  -rw-r--r-- 1 dim dim   1640 2025-02-17 13:33:29 libcommon-lib-der_digests_gen.obj
  -rw-r--r-- 1 dim dim   1112 2025-02-17 13:33:29 libcommon-lib-der_dsa_gen.obj
  ...

  $ ls -l libcrypto-with-2.43
  total 27048
  -rw-r--r-- 1 dim dim  21929 2025-02-17 13:33:35 libcommon-lib-ciphercommon_block.obj
  -rw-r--r-- 1 dim dim  17733 2025-02-17 13:33:35 libcommon-lib-ciphercommon_ccm_hw.obj
  -rw-r--r-- 1 dim dim  23523 2025-02-17 13:33:35 libcommon-lib-ciphercommon_ccm.obj
  -rw-r--r-- 1 dim dim  17531 2025-02-17 13:33:35 libcommon-lib-ciphercommon_gcm_hw.obj
  -rw-r--r-- 1 dim dim  24283 2025-02-17 13:33:35 libcommon-lib-ciphercommon_gcm.obj
  -rw-r--r-- 1 dim dim  18234 2025-02-17 13:33:35 libcommon-lib-ciphercommon_hw.obj
  -rw-r--r-- 1 dim dim  31279 2025-02-17 13:33:35 libcommon-lib-ciphercommon.obj
  -rw-r--r-- 1 dim dim   9480 2025-02-17 13:33:35 libcommon-lib-der_digests_gen.obj
  -rw-r--r-- 1 dim dim   9112 2025-02-17 13:33:35 libcommon-lib-der_dsa_gen.obj
  ...

All the individual object files are increased a lot in size. Added together, the sizes mostly match what the .a files have:

  $ du -hs libcrypto-with-2.42
  9.5M    libcrypto-with-2.42

  $ du -hs libcrypto-with-2.43/
  27M     libcrypto-with-2.43/

Looking at one individual object file, for example libcommon-lib-ciphercommon_block.obj with Microsoft's dumpbin tool, I can see that the "size of raw data" seems to have been page-aligned in 2.43 output.

With the object file produced by 2.42:

  Dump of file libcommon-lib-ciphercommon_block-2.42.obj
  ...
  SECTION HEADER #1
     .text name
         0 physical address
         0 virtual address
       2C0 size of raw data
       12C file pointer to raw data (0000012C to 000003EB)
  ...
       4F8 file pointer to relocation table
         0 file pointer to line numbers
        16 number of relocations
         0 number of line numbers
  ...
  SECTION HEADER #4
    .xdata name
         0 physical address
         0 virtual address
        30 size of raw data
       3EC file pointer to raw data (000003EC to 0000041B)
  ...
  SECTION HEADER #5
    .pdata name
         0 physical address
         0 virtual address
        3C size of raw data
       41C file pointer to raw data (0000041C to 00000457)
       5D4 file pointer to relocation table
  ...
  SECTION HEADER #6
    .rdata name
         0 physical address
         0 virtual address
        80 size of raw data
       458 file pointer to raw data (00000458 to 000004D7)
  ...
  SECTION HEADER #7
        /4 name (.rdata$zzz)
         0 physical address
         0 virtual address
        20 size of raw data
       4D8 file pointer to raw data (000004D8 to 000004F7)
  ...
    Summary

             0 .bss
             0 .data
            3C .pdata
            80 .rdata
            20 .rdata$zzz
           2C0 .text
            30 .xdata

Compare to the object file produced by 2.43:

  Dump of file libcommon-lib-ciphercommon_block-2.43.obj
  ...
  SECTION HEADER #1
     .text name
         0 physical address
         0 virtual address
      1000 size of raw data
       12C file pointer to raw data (0000012C to 0000112B)
      512C file pointer to relocation table
  ...
  SECTION HEADER #4
    .xdata name
         0 physical address
         0 virtual address
      1000 size of raw data
      112C file pointer to raw data (0000112C to 0000212B)
  ...
  SECTION HEADER #5
    .pdata name
         0 physical address
         0 virtual address
      1000 size of raw data
      212C file pointer to raw data (0000212C to 0000312B)
      5208 file pointer to relocation table
  ...
  SECTION HEADER #6
    .rdata name
         0 physical address
         0 virtual address
      1000 size of raw data
      312C file pointer to raw data (0000312C to 0000412B)
  ...
  SECTION HEADER #7
        /4 name (.rdata$zzz)
         0 physical address
         0 virtual address
      1000 size of raw data
      412C file pointer to raw data (0000412C to 0000512B)
  ...
    Summary

             0 .bss
             0 .data
          1000 .pdata
          1000 .rdata
          1000 .rdata$zzz
          1000 .text
          1000 .xdata

Hence, it looks like the compiler/assembler in 2.43 now outputs aligned sections, filling them with zero bytes.

  $ objdump -j .xdata -s libcommon-lib-ciphercommon_block.obj

  libcommon-lib-ciphercommon_block.obj:     file format pe-x86-64

  Contents of section .xdata:
   0000 010e0600 0e320a30 09600870 075006c0  .....2.0.`.p.P..
   0010 010a0300 0a420630 05600000 01040000  .....B.0.`......
   0020 01080100 08420000 01060200 06300560  .....B.......0.`
   0030 00000000 00000000 00000000 00000000  ................
   0040 00000000 00000000 00000000 00000000  ................
   0050 00000000 00000000 00000000 00000000  ................
   ... lots more zeros ...
   0fe0 00000000 00000000 00000000 00000000  ................
   0ff0 00000000 00000000 00000000 00000000  ................

Bisecting might help to find where this behavior change occurred.

-Dimitry



More information about the Binutils mailing list