Index: lld/trunk/ELF/Relocations.h =================================================================== --- lld/trunk/ELF/Relocations.h +++ lld/trunk/ELF/Relocations.h @@ -136,7 +136,8 @@ void createInitialThunkSections(ArrayRef OutputSections); - std::pair getThunk(Symbol &Sym, RelType Type, uint64_t Src); + std::pair getThunk(InputSection *IS, Symbol &Sym, RelType Type, + uint64_t Src); ThunkSection *addThunkSection(OutputSection *OS, InputSectionDescription *, uint64_t Off); Index: lld/trunk/ELF/Relocations.cpp =================================================================== --- lld/trunk/ELF/Relocations.cpp +++ lld/trunk/ELF/Relocations.cpp @@ -1607,12 +1607,22 @@ InputSectionDescription *ISD, uint64_t Off) { auto *TS = make(OS, Off); + TS->Partition = OS->Partition; ISD->ThunkSections.push_back({TS, Pass}); return TS; } -std::pair ThunkCreator::getThunk(Symbol &Sym, RelType Type, - uint64_t Src) { +static bool isThunkSectionCompatible(InputSection *Source, + SectionBase *Target) { + // We can't reuse thunks in different loadable partitions because they might + // not be loaded. But partition 1 (the main partition) will always be loaded. + if (Source->Partition != Target->Partition) + return Target->Partition == 1; + return true; +} + +std::pair ThunkCreator::getThunk(InputSection *IS, Symbol &Sym, + RelType Type, uint64_t Src) { std::vector *ThunkVec = nullptr; // We use (section, offset) pair to find the thunk position if possible so @@ -1625,7 +1635,8 @@ // Check existing Thunks for Sym to see if they can be reused for (Thunk *T : *ThunkVec) - if (T->isCompatibleWith(Type) && + if (isThunkSectionCompatible(IS, T->getThunkTargetSym()->Section) && + T->isCompatibleWith(Type) && Target->inBranchRange(Type, Src, T->getThunkTargetSym()->getVA())) return std::make_pair(T, false); @@ -1709,7 +1720,7 @@ Thunk *T; bool IsNew; - std::tie(T, IsNew) = getThunk(*Rel.Sym, Rel.Type, Src); + std::tie(T, IsNew) = getThunk(IS, *Rel.Sym, Rel.Type, Src); if (IsNew) { // Find or create a ThunkSection for the new Thunk Index: lld/trunk/test/ELF/partition-thunk-reuse.s =================================================================== --- lld/trunk/test/ELF/partition-thunk-reuse.s +++ lld/trunk/test/ELF/partition-thunk-reuse.s @@ -0,0 +1,45 @@ +// REQUIRES: arm +// RUN: llvm-mc %s -o %t.o -filetype=obj --triple=armv7-unknown-linux -arm-add-build-attributes +// RUN: ld.lld %t.o -o %t --export-dynamic --gc-sections +// RUN: llvm-nm %t | FileCheck %s + +// CHECK: __Thumbv7ABSLongThunk__start +// CHECK: __Thumbv7ABSLongThunk__start + +// CHECK: __Thumbv7ABSLongThunk_foo +// CHECK-NOT: __Thumbv7ABSLongThunk_foo + +.thumb + +.section .llvm_sympart.g1,"",%llvm_sympart +.asciz "part1" +.4byte f1 + +.section .llvm_sympart.g2,"",%llvm_sympart +.asciz "part2" +.4byte f2 + +.section .text._start,"ax",%progbits +.globl _start +_start: +bx lr +foo: +b f0 +.zero 17*1048576 + +.section .text.f0,"ax",%progbits +.globl f0 +f0: +b foo + +.section .text.f1,"aw",%progbits +.globl f1 +f1: +b _start +b foo + +.section .text.f2,"ax",%progbits +.globl f2 +f2: +b _start +b foo