Skip to content

Commit

Permalink
[lld-macho] Ensure all sections in __TEXT get thunks if necessary
Browse files Browse the repository at this point in the history
  • Loading branch information
speednoisemovement committed Apr 5, 2024
1 parent e915b7d commit d92a3fb
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 2 deletions.
14 changes: 12 additions & 2 deletions lld/MachO/ConcatOutputSection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,20 @@ bool TextOutputSection::needsThunks() const {
uint64_t isecAddr = addr;
for (ConcatInputSection *isec : inputs)
isecAddr = alignToPowerOf2(isecAddr, isec->align) + isec->getSize();
if (isecAddr - addr + in.stubs->getSize() <=
std::min(target->backwardBranchRange, target->forwardBranchRange))
// Other sections besides __text might be small enough to pass this
// test but nevertheless need thunks for calling into oher sections.
// An imperfect heuristic to use in this case is that if a section
// we've already processed in this segment needs thunks, so do the
// rest.
bool needsThunks = parent && parent->needsThunks;
if (!needsThunks &&
isecAddr - addr + in.stubs->getSize() <=
std::min(target->backwardBranchRange, target->forwardBranchRange))
return false;
// Yes, this program is large enough to need thunks.
if (parent) {
parent->needsThunks = true;
}
for (ConcatInputSection *isec : inputs) {
for (Reloc &r : isec->relocs) {
if (!target->hasAttr(r.type, RelocAttrBits::BRANCH))
Expand Down
1 change: 1 addition & 0 deletions lld/MachO/OutputSegment.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class OutputSegment {
uint32_t initProt = 0;
uint32_t flags = 0;
uint8_t index;
bool needsThunks = false;

llvm::TinyPtrVector<Defined *> segmentStartSymbols;
llvm::TinyPtrVector<Defined *> segmentEndSymbols;
Expand Down
14 changes: 14 additions & 0 deletions lld/test/MachO/arm64-thunks.s
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
## (3) a second thunk is created when the first one goes out of range
## (4) early calls to a dylib stub use a thunk, and later calls the stub
## directly
## (5) Thunks are created for all sections in the text segment with branches.
## Notes:
## 0x4000000 = 64 Mi = half the magnitude of the forward-branch range

Expand Down Expand Up @@ -168,6 +169,10 @@

# CHECK: [[#%x, NAN_PAGE + NAN_OFFSET]] <__stubs>:

# CHECK: Disassembly of section __TEXT,__lcxx_override:
# CHECK: <_z>:
# CHECK: bl 0x[[#%x, A_THUNK_0]] <_a.thunk.0>

.subsections_via_symbols
.text

Expand Down Expand Up @@ -300,3 +305,12 @@ _main:
bl _h
bl ___nan
ret

.section __TEXT,__lcxx_override,regular,pure_instructions

.globl _z
.no_dead_strip _z
.p2align 2
_z:
bl _a
ret

0 comments on commit d92a3fb

Please sign in to comment.