Skip to content

llvm-objcopy missing padding between sections #55246

@Kimplul

Description

@Kimplul

I have an elf file that I would like to turn into a raw binary, and I'm trying to allocate the .bss section directly in the binary. For some reason, there is a small gap between my .text and .bss, which is padded with some bytes when using GNU objcopy, but seemingly ignored when using llvm-objcopy.

To illustrate:
riscv64-unknown-elf-objcopy -Obinary --set-section-flags .bss=alloc,load,contents --gap-fill 255 example.elf example.bin

produces a raw binary ending in

...
00000240: ef00 e000 0100 e270 4274 2161 8280 2a86  .......pBt!a..*.
00000250: 2e85 0286 ffff ffff 0000 0000 0000 0000  ................

where ffff ffff is padding. (The actual value of the padding is irrelevant, I just used ff for demonstration purposes). The equivalent command with llvm-objcopy
llvm-objcopy -Obinary --set-section-flags .bss=alloc,load,contents example.elf example.bin

produces

...
00000240: ef00 e000 0100 e270 4274 2161 8280 2a86  .......pBt!a..*.
00000250: 2e85 0286 0000 0000 0000 0000            ............

For context, here's the readelf output for example.elf:

readelf -SW example.elf
There are 15 section headers, starting at offset 0x20d0:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        0000000080080000 001000 000254 00  AX  0   0  2
  [ 2] .bss              NOBITS          0000000080080258 001254 000008 00  WA  0   0  8
  [ 3] .debug_info       PROGBITS        0000000000000000 001254 00030e 00      0   0  1
  [ 4] .debug_abbrev     PROGBITS        0000000000000000 001562 000187 00      0   0  1
  [ 5] .debug_aranges    PROGBITS        0000000000000000 0016f0 000060 00      0   0 16
  [ 6] .debug_line       PROGBITS        0000000000000000 001750 000292 00      0   0  1
  [ 7] .debug_str        PROGBITS        0000000000000000 0019e2 0001aa 01  MS  0   0  1
  [ 8] .debug_line_str   PROGBITS        0000000000000000 001b8c 000098 01  MS  0   0  1
  [ 9] .comment          PROGBITS        0000000000000000 001c24 000012 01  MS  0   0  1
  [10] .riscv.attributes RISCV_ATTRIBUTES 0000000000000000 001c36 000039 00      0   0  1
  [11] .debug_frame      PROGBITS        0000000000000000 001c70 0000d0 00      0   0  8
  [12] .symtab           SYMTAB          0000000000000000 001d40 000270 18     13  17  8
  [13] .strtab           STRTAB          0000000000000000 001fb0 000080 00      0   0  1
  [14] .shstrtab         STRTAB          0000000000000000 002030 00009e 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  D (mbind), p (processor specific)

I'm assuming the bug is on LLVM's side in this case, because the start address of .bss matches when using GNU objcopy, whereas its four bytes short when using LLVM.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions