[ELF][MIPS] Fix crash in LLD when linking code that needs PIC thunks

Summary:
The bug triggers when the following conditions are met:
    - A thunk is created in a given input section S
    - A linker script is specified
    - There is at least one matcher in the linker script .text section output
      that does not match any of the sections in the input files, before the matcher
      that matches section S.

The issue was found when linking the FreeBSD kernel for MIPS when built
with -fPIC. Patch by Alfredo Mazzinghi.

Reviewers: ruiu, psmith, atanasyan

Reviewed By: ruiu

Subscribers: peter.smith, emaste, sdardis, krytarowski, llvm-commits

Differential Revision: https://reviews.llvm.org/D40174

llvm-svn: 318653
This commit is contained in:
Alexander Richardson 2017-11-20 15:37:19 +00:00
parent 12e3a58842
commit f463042312
2 changed files with 42 additions and 0 deletions

View File

@ -1224,6 +1224,8 @@ ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS) {
OutputSection *TOS = IS->getParent(); OutputSection *TOS = IS->getParent();
for (BaseCommand *BC : TOS->SectionCommands) for (BaseCommand *BC : TOS->SectionCommands)
if (auto *ISD = dyn_cast<InputSectionDescription>(BC)) { if (auto *ISD = dyn_cast<InputSectionDescription>(BC)) {
if (ISD->Sections.empty())
continue;
InputSection *first = ISD->Sections.front(); InputSection *first = ISD->Sections.front();
InputSection *last = ISD->Sections.back(); InputSection *last = ISD->Sections.back();
if (IS->OutSecOff >= first->OutSecOff && if (IS->OutSecOff >= first->OutSecOff &&

View File

@ -0,0 +1,40 @@
# REQUIRES: mips
# RUN: llvm-mc -filetype=obj -defsym=MAIN=1 -triple=mips-unknown-freebsd %s -o %t
# RUN: llvm-mc -filetype=obj -defsym=TARGET=1 -triple=mips-unknown-freebsd %s -o %t1
# SECTIONS command with the first pattern that does not match.
# Linking a PIC and non-PIC object files triggers the LA25 thunk generation.
# RUN: echo "SECTIONS { \
# RUN: .text : { \
# RUN: *(.nomatch) \
# RUN: %t(.text) \
# RUN: . = . + 0x100000 ; \
# RUN: %t1(.text) \
# RUN: } \
# RUN: }" > %t.script
# RUN: ld.lld -o %t.exe --script %t.script %t %t1
# RUN: llvm-objdump -t %t.exe | FileCheck %s
# CHECK: SYMBOL TABLE:
# CHECK-ANY: 00000000 .text 00000000 _start
# CHECK-ANY: 0010000c l F .text 00000010 __LA25Thunk_too_far
# CHECK-ANY: 00100020 g F .text 00000024 too_far
.ifdef MAIN
.global _start
_start:
j too_far
nop
.endif
.ifdef TARGET
.text
.abicalls
.set noreorder
.globl too_far
.ent too_far
too_far:
nop
jr $ra
nop
.end too_far
.endif