Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linking Linux kernel aspeed_g5_defconfig fails #44169

Closed
nathanchance opened this issue Feb 7, 2020 · 7 comments
Closed

Linking Linux kernel aspeed_g5_defconfig fails #44169

nathanchance opened this issue Feb 7, 2020 · 7 comments
Labels
bugzilla Issues migrated from bugzilla lld:ELF

Comments

@nathanchance
Copy link
Member

Bugzilla Link 44824
Resolution FIXED
Resolved on May 11, 2020 09:13
Version unspecified
OS All
CC @MaskRay,@smithp35

Extended Description

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

@llvmbot
Copy link
Member

llvmbot commented Feb 7, 2020

*** Bug llvm/llvm-bugzilla-archive#44825 has been marked as a duplicate of this bug. ***

@smithp35
Copy link
Collaborator

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.

@smithp35
Copy link
Collaborator

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

@smithp35
Copy link
Collaborator

smithp35 commented May 2, 2020

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.

@smithp35
Copy link
Collaborator

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.

@smithp35
Copy link
Collaborator

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:
3b1622d D78422
48aebfc D79289
0ae7990 D79687

@llvmbot
Copy link
Member

llvmbot commented Nov 27, 2021

mentioned in issue llvm/llvm-bugzilla-archive#44825

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 10, 2021
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla lld:ELF
Projects
None yet
Development

No branches or pull requests

3 participants