llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.11k stars 12.01k forks source link

NOLOAD attribute of output section seems to be ignored #44915

Closed 7f1138a3-b229-4707-9203-bbc9684dbd73 closed 4 years ago

7f1138a3-b229-4707-9203-bbc9684dbd73 commented 4 years ago
Bugzilla Link 45570
Resolution DUPLICATE
Resolved on Apr 16, 2020 05:08
Version unspecified
OS All
Attachments Test example, linked with GNU LD, Test example, linked with ld.lld
CC @eblot,@smithp35

Extended Description

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

), 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.

7f1138a3-b229-4707-9203-bbc9684dbd73 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 llvm/llvm-project#44681

smithp35 commented 4 years ago

There was a recent fix (March 28) involving NOLOAD in llvm/llvm-project#44681 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.