forked from OSchip/llvm-project
ELF: Don't reuse a thunk in a different loadable partition.
There's no guarantee that the other partition will be loaded, so it can't be reused. Differential Revision: https://reviews.llvm.org/D62365 llvm-svn: 361926
This commit is contained in:
parent
ba2816be82
commit
87575f6501
|
@ -1607,12 +1607,22 @@ ThunkSection *ThunkCreator::addThunkSection(OutputSection *OS,
|
||||||
InputSectionDescription *ISD,
|
InputSectionDescription *ISD,
|
||||||
uint64_t Off) {
|
uint64_t Off) {
|
||||||
auto *TS = make<ThunkSection>(OS, Off);
|
auto *TS = make<ThunkSection>(OS, Off);
|
||||||
|
TS->Partition = OS->Partition;
|
||||||
ISD->ThunkSections.push_back({TS, Pass});
|
ISD->ThunkSections.push_back({TS, Pass});
|
||||||
return TS;
|
return TS;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<Thunk *, bool> ThunkCreator::getThunk(Symbol &Sym, RelType Type,
|
static bool isThunkSectionCompatible(InputSection *Source,
|
||||||
uint64_t Src) {
|
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<Thunk *, bool> ThunkCreator::getThunk(InputSection *IS, Symbol &Sym,
|
||||||
|
RelType Type, uint64_t Src) {
|
||||||
std::vector<Thunk *> *ThunkVec = nullptr;
|
std::vector<Thunk *> *ThunkVec = nullptr;
|
||||||
|
|
||||||
// We use (section, offset) pair to find the thunk position if possible so
|
// We use (section, offset) pair to find the thunk position if possible so
|
||||||
|
@ -1625,7 +1635,8 @@ std::pair<Thunk *, bool> ThunkCreator::getThunk(Symbol &Sym, RelType Type,
|
||||||
|
|
||||||
// Check existing Thunks for Sym to see if they can be reused
|
// Check existing Thunks for Sym to see if they can be reused
|
||||||
for (Thunk *T : *ThunkVec)
|
for (Thunk *T : *ThunkVec)
|
||||||
if (T->isCompatibleWith(Type) &&
|
if (isThunkSectionCompatible(IS, T->getThunkTargetSym()->Section) &&
|
||||||
|
T->isCompatibleWith(Type) &&
|
||||||
Target->inBranchRange(Type, Src, T->getThunkTargetSym()->getVA()))
|
Target->inBranchRange(Type, Src, T->getThunkTargetSym()->getVA()))
|
||||||
return std::make_pair(T, false);
|
return std::make_pair(T, false);
|
||||||
|
|
||||||
|
@ -1709,7 +1720,7 @@ bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) {
|
||||||
|
|
||||||
Thunk *T;
|
Thunk *T;
|
||||||
bool IsNew;
|
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) {
|
if (IsNew) {
|
||||||
// Find or create a ThunkSection for the new Thunk
|
// Find or create a ThunkSection for the new Thunk
|
||||||
|
|
|
@ -136,7 +136,8 @@ private:
|
||||||
|
|
||||||
void createInitialThunkSections(ArrayRef<OutputSection *> OutputSections);
|
void createInitialThunkSections(ArrayRef<OutputSection *> OutputSections);
|
||||||
|
|
||||||
std::pair<Thunk *, bool> getThunk(Symbol &Sym, RelType Type, uint64_t Src);
|
std::pair<Thunk *, bool> getThunk(InputSection *IS, Symbol &Sym, RelType Type,
|
||||||
|
uint64_t Src);
|
||||||
|
|
||||||
ThunkSection *addThunkSection(OutputSection *OS, InputSectionDescription *,
|
ThunkSection *addThunkSection(OutputSection *OS, InputSectionDescription *,
|
||||||
uint64_t Off);
|
uint64_t Off);
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue