Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions lld/MachO/ConcatOutputSection.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ class Defined;
// in the final binary.
class ConcatOutputSection : public OutputSection {
public:
explicit ConcatOutputSection(StringRef name)
: OutputSection(ConcatKind, name) {}
explicit ConcatOutputSection(StringRef name,
OutputSection::Kind kind = ConcatKind)
: OutputSection(kind, name) {}

const ConcatInputSection *firstSection() const { return inputs.front(); }
const ConcatInputSection *lastSection() const { return inputs.back(); }
Expand All @@ -46,7 +47,7 @@ class ConcatOutputSection : public OutputSection {
void writeTo(uint8_t *buf) const override;

static bool classof(const OutputSection *sec) {
return sec->kind() == ConcatKind;
return sec->kind() == ConcatKind || sec->kind() == TextKind;
}

static ConcatOutputSection *getOrCreateForInput(const InputSection *);
Expand All @@ -66,12 +67,18 @@ class ConcatOutputSection : public OutputSection {
// support thunk insertion.
class TextOutputSection : public ConcatOutputSection {
public:
explicit TextOutputSection(StringRef name) : ConcatOutputSection(name) {}
explicit TextOutputSection(StringRef name)
: ConcatOutputSection(name, TextKind) {}
void finalizeContents() override {}
void finalize() override;
bool needsThunks() const;
const std::vector<ConcatInputSection *> &getThunks() const { return thunks; }
void writeTo(uint8_t *buf) const override;

static bool classof(const OutputSection *sec) {
return sec->kind() == TextKind;
}

private:
uint64_t estimateStubsInRangeVA(size_t callIdx) const;

Expand Down
29 changes: 28 additions & 1 deletion lld/MachO/MapFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,28 @@ static uint64_t getSymSizeForMap(Defined *sym) {
return sym->size;
}

// Merges two vectors of input sections in order of their outSecOff values.
// This approach creates a new (temporary) vector which is not ideal but the
// ideal approach leads to a lot of code duplication.
static std::vector<ConcatInputSection *>
mergeOrderedInputs(const std::vector<ConcatInputSection *> &inputs1,
const std::vector<ConcatInputSection *> &inputs2) {
std::vector<ConcatInputSection *> vec;
size_t i = 0, ie = inputs1.size();
size_t t = 0, te = inputs2.size();
while (i < ie || t < te) {
while (i < ie &&
(t == te || inputs1[i]->outSecOff <= inputs2[t]->outSecOff)) {
vec.push_back(inputs1[i++]);
}
while (t < te &&
(i == ie || inputs2[t]->outSecOff < inputs1[i]->outSecOff)) {
vec.push_back(inputs2[t++]);
}
}
return vec;
}

void macho::writeMapFile() {
if (config->mapFile.empty())
return;
Expand Down Expand Up @@ -220,7 +242,12 @@ void macho::writeMapFile() {
os << "# Address\tSize \tFile Name\n";
for (const OutputSegment *seg : outputSegments) {
for (const OutputSection *osec : seg->getSections()) {
if (auto *concatOsec = dyn_cast<ConcatOutputSection>(osec)) {
const TextOutputSection *textOsec = dyn_cast<TextOutputSection>(osec);
if (textOsec && textOsec->getThunks().size()) {
auto inputsAndThunks =
mergeOrderedInputs(textOsec->inputs, textOsec->getThunks());
printIsecArrSyms(inputsAndThunks);
} else if (auto *concatOsec = dyn_cast<ConcatOutputSection>(osec)) {
printIsecArrSyms(concatOsec->inputs);
} else if (osec == in.cStringSection || osec == in.objcMethnameSection) {
const auto &liveCStrings = info.liveCStringsForSection.lookup(osec);
Expand Down
1 change: 1 addition & 0 deletions lld/MachO/OutputSection.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class OutputSection {
enum Kind {
ConcatKind,
SyntheticKind,
TextKind,
};

OutputSection(Kind kind, StringRef name) : name(name), sectionKind(kind) {}
Expand Down
26 changes: 25 additions & 1 deletion lld/test/MachO/arm64-thunks.s
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,38 @@
## (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.
## (6) Thunks are in the linker map file.
## Notes:
## 0x4000000 = 64 Mi = half the magnitude of the forward-branch range

# RUN: rm -rf %t; mkdir %t
# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin %s -o %t/input.o
# RUN: %lld -arch arm64 -dead_strip -lSystem -U _extern_sym -o %t/thunk %t/input.o
# RUN: %lld -arch arm64 -dead_strip -lSystem -U _extern_sym -map %t/thunk.map -o %t/thunk %t/input.o
# RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn %t/thunk | FileCheck %s

## Check that the thunks appear in the map file and that everything is sorted by address
# MAP: [[0x[0-9A-Fa-f]+]] 0x[0-9A-Fa-f]+ \[[0-9]+\] _b
# MAP: [[0x[0-9A-Fa-f]+]] 0x[0-9A-Fa-f]+ \[[0-9]+\] _c
# MAP: [[0x[0-9A-Fa-f]+]] 0x[0-9A-Fa-f]+ \[[0-9]+\] _d.thunk.0
# MAP: [[0x[0-9A-Fa-f]+]] 0x[0-9A-Fa-f]+ \[[0-9]+\] _e.thunk.0
# MAP: [[0x[0-9A-Fa-f]+]] 0x[0-9A-Fa-f]+ \[[0-9]+\] _f.thunk.0
# MAP: [[0x[0-9A-Fa-f]+]] 0x[0-9A-Fa-f]+ \[[0-9]+\] _g.thunk.0
# MAP: [[0x[0-9A-Fa-f]+]] 0x[0-9A-Fa-f]+ \[[0-9]+\] _h.thunk.0
# MAP: [[0x[0-9A-Fa-f]+]] 0x[0-9A-Fa-f]+ \[[0-9]+\] ___nan.thunk.0
# MAP: [[0x[0-9A-Fa-f]+]] 0x[0-9A-Fa-f]+ \[[0-9]+\] _d
# MAP: [[0x[0-9A-Fa-f]+]] 0x[0-9A-Fa-f]+ \[[0-9]+\] _e
# MAP: [[0x[0-9A-Fa-f]+]] 0x[0-9A-Fa-f]+ \[[0-9]+\] _f
# MAP: [[0x[0-9A-Fa-f]+]] 0x[0-9A-Fa-f]+ \[[0-9]+\] _g
# MAP: [[0x[0-9A-Fa-f]+]] 0x[0-9A-Fa-f]+ \[[0-9]+\] _a.thunk.0
# MAP: [[0x[0-9A-Fa-f]+]] 0x[0-9A-Fa-f]+ \[[0-9]+\] _b.thunk.0
# MAP: [[0x[0-9A-Fa-f]+]] 0x[0-9A-Fa-f]+ \[[0-9]+\] _h
# MAP: [[0x[0-9A-Fa-f]+]] 0x[0-9A-Fa-f]+ \[[0-9]+\] _main
# MAP: [[0x[0-9A-Fa-f]+]] 0x[0-9A-Fa-f]+ \[[0-9]+\] _c.thunk.0
# MAP: [[0x[0-9A-Fa-f]+]] 0x[0-9A-Fa-f]+ \[[0-9]+\] _d.thunk.1
# MAP: [[0x[0-9A-Fa-f]+]] 0x[0-9A-Fa-f]+ \[[0-9]+\] _e.thunk.1
# MAP: [[0x[0-9A-Fa-f]+]] 0x[0-9A-Fa-f]+ \[[0-9]+\] _f.thunk.1
# MAP: [[0x[0-9A-Fa-f]+]] 0x[0-9A-Fa-f]+ \[[0-9]+\] _z

# CHECK: Disassembly of section __TEXT,__text:

# CHECK: [[#%.13x, A_PAGE:]][[#%.3x, A_OFFSET:]] <_a>:
Expand Down
Loading