Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

NOLOAD attribute of output section seems to be ignored #44540

Closed Quuxplusone closed 4 years ago

Quuxplusone commented 4 years ago
Bugzilla Link PR45570
Status RESOLVED DUPLICATE of bug 45336
Importance P normal
Reported by Emmanuel Blot (eblot.ml@gmail.com)
Reported on 2020-04-16 01:22:40 -0700
Last modified on 2020-04-16 05:08:42 -0700
Version unspecified
Hardware Other All
CC eblot.ml@gmail.com, llvm-bugs@lists.llvm.org, smithp352@googlemail.com
Fixed by commit(s)
Attachments blink_gnu.elf (227876 bytes, application/x-executable)
blink_lld.elf (96028 bytes, application/x-executable)
Blocks
Blocked by
See also
Hi,

Using LLVM v10.0 final, host: macOS 10.14.6, target: baremetal ARMv6m, ARMv7em
ELF EABI.

It seems the behavior of I believe ld.lld has been modified with release 10.0.
I'm not 100% sure the issue is with lld, but it looks like so:

`(NOLOAD)` section attribute in linker script is commonly used to prevent a
section from being "loaded into memory when the program is run.", according to
GNU LD.

This attribute is used with ARM embedded targets so that stack, heap and other
RAM sections have assigned, reserved space in the target memory, but have no
associated data in the ELF image.

ld.lld used to behave the same as GNU ld up to 9.0 and development versions but
starting with release 10.0, ld.lld seems to ignore this attribute - or may be
it always has but some other changes made it behave differently.

When the ELF image is converted to a raw binary image, things start to go
crazy: for example a 4KB bin image now inflates to 384MB. With this example ARM
ELF file, text and data sections are stored @ 0x08000000, while RAM is mapped @
0x20000000. It seems ld.ldd generates NOLOAD section into the ELF file so that
some sections appear at 0x20000000, hence generating a large bin file padded
from 0x08000000 to 0x20000000.

I've build a small text example with clang 10.0, and linked it with the same
linker script with GNU ld and ld.lld

GNU ld ELF sections:

arm-none-eabi-readelf -S blink_gnu.elf
There are 25 section headers, starting at offset 0x3763c:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .mstack           NOBITS          20000000 030000 000200 00  WA  0   0  1
  [ 2] .pstack           NOBITS          20000200 030000 000400 00  WA  0   0  1
  [ 3] .vectors          PROGBITS        08000000 010000 0000c0 00  AX  0   0 16
  [ 4] .text             PROGBITS        080000c0 0100c0 0010f6 00  AX  0   0 16
  [ 5] .rodata           PROGBITS        080011b8 0111b8 000060 00   A  0   0  4
  [ 6] .ARM.exidx        ARM_EXIDX       08001218 011218 000008 00  AL  4   0  4
  [ 7] .data             PROGBITS        20000600 020600 000010 00  WA  0   0  4
  [ 8] .bss              NOBITS          20000610 020610 0000a0 00  WA  0   0  4
  [ 9] .ram0_init        PROGBITS        200006b0 020610 000000 00   W  0   0  4
  [10] .ram0             PROGBITS        200006b0 020610 000000 00   W  0   0  4
  [11] .heap             NOBITS          200006b0 0206b0 000150 00  WA  0   0  1
  [12] .debug_str        PROGBITS        00000000 020610 001710 01  MS  0   0  1
  [13] .debug_loc        PROGBITS        00000000 021d20 002325 00      0   0  1
  [14] .debug_abbrev     PROGBITS        00000000 024045 001a91 00      0   0  1
  [15] .debug_info       PROGBITS        00000000 025ad6 006101 00      0   0  1
  [16] .comment          PROGBITS        00000000 02bbd7 000016 01  MS  0   0  1
  [17] .ARM.attributes   ARM_ATTRIBUTES  00000000 02bbed 000031 00      0   0  1
  [18] .debug_frame      PROGBITS        00000000 02bc20 000d34 00      0   0  4
  [19] .debug_line       PROGBITS        00000000 02c954 00450d 00      0   0  1
  [20] .debug_aranges    PROGBITS        00000000 030e61 000060 00      0   0  1
  [21] .debug_ranges     PROGBITS        00000000 030ec1 000450 00      0   0  1
  [22] .symtab           SYMTAB          00000000 031314 0058e0 10     23 1284  4
  [23] .strtab           STRTAB          00000000 036bf4 000958 00      0   0  1
  [24] .shstrtab         STRTAB          00000000 03754c 0000ee 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),
  y (purecode), p (processor specific)

ld.lld ELF output sections:

$ arm-none-eabi-readelf -S blink_lld.elf
There are 26 section headers, starting at offset 0x1730c:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .mstack           PROGBITS        20000000 0000f4 000200 00   A  0   0  1
  [ 2] .pstack           PROGBITS        20000200 0002f4 000400 00   A  0   0  1
  [ 3] .vectors          PROGBITS        08000000 001000 0000c0 00  AX  0   0 16
  [ 4] .xtors            PROGBITS        080000c0 0010c0 000000 00  AX  0   0  4
  [ 5] .text             PROGBITS        080000c0 0010c0 0010f4 00  AX  0   0 16
  [ 6] .rodata           PROGBITS        080011b4 0021b4 00005c 00 AMS  0   0  4
  [ 7] .ARM.exidx        ARM_EXIDX       08001210 002210 000010 00  AL  3   0  4
  [ 8] .data             PROGBITS        20000600 002600 000010 00  WA  0   0  4
  [ 9] .bss              NOBITS          20000610 002610 0000a0 00  WA  0   0  4
  [10] .ram0_init        PROGBITS        200006b0 0026b0 000000 00  WA  0   0  4
  [11] .ram0             PROGBITS        200006b0 0026b0 000000 00  WA  0   0  4
  [12] .heap             PROGBITS        200006b0 0026b0 000150 00  WA  0   0  1
  [13] .debug_str        PROGBITS        00000000 002800 002090 01  MS  0   0  1
  [14] .debug_loc        PROGBITS        00000000 004890 0023b0 00      0   0  1
  [15] .debug_abbrev     PROGBITS        00000000 006c40 001daf 00      0   0  1
  [16] .debug_info       PROGBITS        00000000 0089ef 006c31 00      0   0  1
  [17] .comment          PROGBITS        00000000 00f620 00002a 01  MS  0   0  1
  [18] .ARM.attributes   ARM_ATTRIBUTES  00000000 00f64a 000041 00      0   0  1
  [19] .debug_frame      PROGBITS        00000000 00f68c 000e00 00      0   0  4
  [20] .debug_line       PROGBITS        00000000 01048c 004cea 00      0   0  1
  [21] .debug_ranges     PROGBITS        00000000 015176 000478 00      0   0  1
  [22] .debug_aranges    PROGBITS        00000000 0155ee 000080 00      0   0  1
  [23] .symtab           SYMTAB          00000000 015670 001210 10     25 155  4
  [24] .shstrtab         STRTAB          00000000 016880 0000f5 00      0   0  1
  [25] .strtab           STRTAB          00000000 016975 000996 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),
  y (purecode), p (processor specific)

The .mstack, .pstack and .heap sections are marked as PROGBITS and loaded with
ld.lld, while they are marked as NOBITS with GNU LD and not loaded.

Using objcopy to generate the RAW binary file from the ELF file, if these 3
sections are removed from the destination file (-R <section>), the binary file
generated by ld.ldd matches the one generated by GNU ld with all sections kept.

I'm attaching both ELF files to this ticket.
Quuxplusone commented 4 years ago

Attached blink_gnu.elf (227876 bytes, application/x-executable): Test example, linked with GNU LD

Quuxplusone commented 4 years ago

Attached blink_lld.elf (96028 bytes, application/x-executable): Test example, linked with ld.lld

Quuxplusone commented 4 years ago

There was a recent fix (March 28) involving NOLOAD in https://bugs.llvm.org/show_bug.cgi?id=45336 https://reviews.llvm.org/D76981

Can you check if this has resolved the problem? If it doesn't it would help if we could have a small reproducer including a linker script rather the output ELF file.

Quuxplusone commented 4 years ago

It is indeed a duplicate of 45336.

Applying the patch fixes the issue. The patch does not directly apply to the 10.0 tag (as the test file has been heavily modified since), but the lld fix does and the generated lld works at expected, with NOLOAD sections flags as NOBITS.

Thanks for the pointer.

_This bug has been marked as a duplicate of bug 45336_