LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 44824 - Linking Linux kernel aspeed_g5_defconfig fails
Summary: Linking Linux kernel aspeed_g5_defconfig fails
Status: RESOLVED FIXED
Alias: None
Product: lld
Classification: Unclassified
Component: ELF (show other bugs)
Version: unspecified
Hardware: Other All
: P enhancement
Assignee: Unassigned LLVM Bugs
URL:
Keywords:
: 44825 (view as bug list)
Depends on:
Blocks:
 
Reported: 2020-02-07 06:37 PST by Nathan Chancellor
Modified: 2020-05-11 09:13 PDT (History)
4 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nathan Chancellor 2020-02-07 06:37:41 PST
On mainline Linux:

$ make -j$(nproc) -s ARCH=arm CC=clang CROSS_COMPILE=arm-linux-gnueabi- LD=ld.lld O=out.arm32 distclean aspeed_g5_defconfig vmlinux
...
ld.lld: error: .tmp_vmlinux1:(.ARM.exidx+0x30AB0): relocation R_ARM_PREL31 out of range: 2136743560 is not in [-1073741824, 1073741823]
ld.lld: error: .tmp_vmlinux1:(.ARM.exidx+0x32E1C): relocation R_ARM_PREL31 out of range: 2136800028 is not in [-1073741824, 1073741823]
ld.lld: error: .tmp_vmlinux1:(.ARM.exidx+0x32E64): relocation R_ARM_PREL31 out of range: 2136799956 is not in [-1073741824, 1073741823]
ld.lld: error: .tmp_vmlinux1:(.ARM.exidx+0x32E94): relocation R_ARM_PREL31 out of range: 2136799908 is not in [-1073741824, 1073741823]
ld.lld: error: .tmp_vmlinux1:(.ARM.exidx+0x32EC4): relocation R_ARM_PREL31 out of range: 2136799860 is not in [-1073741824, 1073741823]
ld.lld: error: .tmp_vmlinux1:(.ARM.exidx+0x32EDC): relocation R_ARM_PREL31 out of range: 2136799836 is not in [-1073741824, 1073741823]
ld.lld: error: .tmp_vmlinux1:(.ARM.exidx+0x32EF4): relocation R_ARM_PREL31 out of range: 2136799812 is not in [-1073741824, 1073741823]
ld.lld: error: .tmp_vmlinux1:(.ARM.exidx+0x32F04): relocation R_ARM_PREL31 out of range: 2136799796 is not in [-1073741824, 1073741823]
ld.lld: error: .tmp_vmlinux1:(.ARM.exidx+0x32F54): relocation R_ARM_PREL31 out of range: 2136799716 is not in [-1073741824, 1073741823]
ld.lld: error: .tmp_vmlinux1:(.ARM.exidx+0x32F64): relocation R_ARM_PREL31 out of range: 2136799700 is not in [-1073741824, 1073741823]
ld.lld: error: .tmp_vmlinux1:(.ARM.exidx+0x33004): relocation R_ARM_PREL31 out of range: 2136799540 is not in [-1073741824, 1073741823]
...
$ make -j$(nproc) -s ARCH=arm CC=clang CROSS_COMPILE=arm-linux-gnueabi- O=out.arm32 distclean aspeed_g5_defconfig vmlinux
...
Comment 1 Dmitry Golovin 2020-02-07 06:40:31 PST
*** Bug 44825 has been marked as a duplicate of this bug. ***
Comment 2 Peter Smith 2020-04-10 03:15:22 PDT
The example shows up three nasty problems:
1.) The linker script has a /DISCARD/ entry that identifies .ARM.exidx.text.exit.* and .ARM.exidx.text.extab.* for discard, but not .text.exit. As .ARM.exidx is a Synthetic container for all .ARM.exidx.* InputSections the /DISCARD/ code marks the .ARM.extab.text.exit as non-live but does not mark .ARM.exidx.text.exit as non-live. This leaves dangling references from the .ARM.exidx.text.exit to discarded .ARM.extab.text.exit sections.

Unfortunately there is no clean way of finding out how to mark the .ARM.exidx.text.exit section as non-live with the current code base. My current thoughts are that we add a function to LinkerScript to say something like onMatchDiscard(InputSections, callback) so that we could take the list of ExidxSections that the ARMExidxSyntheticSection contains can be filtered against the /DISCARD/ patterns.

2.) The linker script has a non-monotonic order of OutputSection address, in particular 0xffff0000 for the .vectors section. This breaks the assumption that OuputSection::sectionIndex is sufficient to order the .ARM.exidx synthetic table. We will have to do it after the first call to assignAddresses() to be correct.

3.) The .vectors placed at 0xffff0000 (On ArmV5 the vector table can be at either 0x0 or 0xffff0000) are too far away from the .ARM.exidx table (close to 0x80000000) to generate a synthetic table entry. There is no point in generating a table entry when the destination is out of range. Unfortunately we won't know that until after the initial address allocation what the ranges are.

It is likely that 2 and 3 can be fixed as they both dependent on address allocation. 1 is independent.
Comment 3 Peter Smith 2020-04-18 03:32:12 PDT
I've submitted https://reviews.llvm.org/D78422 to move the location of .ARM.exidx sorting. This won't fix anything yet, but it will enable the vector table out of range to be solved as address information will be available.

Reproducers in LLD test form for the problems:

Vector table synthesised .ARM.exidx section out of range

// RUN: llvm-mc --arm-add-build-attributes --triple=armv7a-linux-gnueabihf -filetype=obj %s -o %t.o
// RUN: echo "SECTIONS { \
// RUN:         . = 0x80000000; \
// RUN:         .text : { *(.text) } \
// RUN:         .vectors 0xffff0000 : AT(0xffff0000) { *(.vectors) } \
// RUN: } " > %t.script
// RUN: ld.lld --script %t.script %t.o -o %t
/// Adapted from Linux kernel linker script failing due to out of range
/// relocation. The .vectors at 0xffff0000 (one of two places the vector table
/// can go, the other is 0x0) in earlier Arm CPUs.
/// In the example the .vectors won't have an exception table so if LLD creates
/// one then we'll get a relocation out of range error. Check that we don't
/// synthesise a table entry or place a sentinel out of range.
 .text
 .global _start
 .type _start, %function
_start:
 .fnstart
 bx lr
 .cantunwind
 .fnend

 .section .vectors, "ax", %progbits
 .global vecs
 .type vecs, %function
vecs:
 bx lr

// REQUIRES: arm
// RUN: llvm-mc -filetype=obj -triple arm-gnu-linux-eabi -mcpu cortex-a7 -arm-add-build-attributes %s -o %t.o
// RUN: echo "SECTIONS { . = 0x10000; .text : { *(.text) } /DISCARD/ : { *(.exit.text) } }" > %t.script
// RUN: ld.lld -T %t.script %t.o -o %t.elf
// RUN: llvm-readobj -x .ARM.exidx --sections %t.elf | FileCheck %s

// CHECK-NOT: .exit.text
/// Expect 2 entries both CANTUNWIND as the .ARM.exidx.exit.text
// should have been removed.
// CHECK: Hex dump of section '.ARM.exidx':
// CHECK-NEXT: 0x00010000 10000000 01000000 10000000 01000000


Discarding of .ARM.exidx but not the executable section with a link to it.

/// The /DISCARD/ is evaluated after sections have been assigned to the
/// .ARM.exidx synthetic section. We must account for the /DISCARD/
 .section .exit.text, "ax", %progbits
 .globl foo
 .type foo, %function
foo:
 .fnstart
 bx lr
 .save {r7, lr}
 .setfp r7, sp, #0
 .fnend

 .text
 .globl _start
 .type _start, %function
_start:
 .fnstart
 bx lr
 .cantunwind
 .fnend

 .section .text.__aeabi_unwind_cpp_pr0, "ax", %progbits
 .global __aeabi_unwind_cpp_pr0
__aeabi_unwind_cpp_pr0:
 bx lr
Comment 4 Peter Smith 2020-05-02 05:05:47 PDT
I've started https://reviews.llvm.org/D79289 to fix one part of the problem. This prevents LLD from generating a.ARM.exidx if it is too far away.

Still ToDo, the /DISCARD/ causing the majority of the errors.
Comment 5 Peter Smith 2020-05-10 04:09:09 PDT
Submitted https://reviews.llvm.org/D79687 to fix the /DISCARD/ of a subset of the .ARM.exidx sections.

https://reviews.llvm.org/D79289 landed with rG48aebfc908ba: [ELF][ARM] Do not create .ARM.exidx sections for out of range inputs

master with D79687 should permit this particular configuration to succeed.
Comment 6 Peter Smith 2020-05-11 09:13:08 PDT
committed https://reviews.llvm.org/D79289

I think that this should resolve at least the R_ARM_PREL31 link errors. I'll mark this as resolved for now, it can be reopened if there are any more problems.

Commits required:
3b1622d63a9c2e0a63a5796f94a7f4218a9a4cad D78422
48aebfc908ba7b9372aaa478a9c200789491096e D79289
0ae7990b6071b941995183d872b928bba3a5d3b8 D79687