Skip to content

Commit 80a9e0e

Browse files
author
Alex B
committed
[lld-macho][NFC] Refactor ObjCSelRefsSection out of ObjCStubsSection
1 parent dbca8aa commit 80a9e0e

File tree

3 files changed

+84
-47
lines changed

3 files changed

+84
-47
lines changed

lld/MachO/SyntheticSections.cpp

Lines changed: 62 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -806,26 +806,13 @@ void StubHelperSection::setUp() {
806806
dyldPrivate->used = true;
807807
}
808808

809-
ObjCStubsSection::ObjCStubsSection()
810-
: SyntheticSection(segment_names::text, section_names::objcStubs) {
811-
flags = S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS;
812-
align = config->objcStubsMode == ObjCStubsMode::fast
813-
? target->objcStubsFastAlignment
814-
: target->objcStubsSmallAlignment;
815-
}
816-
817-
bool ObjCStubsSection::isObjCStubSymbol(Symbol *sym) {
818-
return sym->getName().starts_with(symbolPrefix);
819-
}
820-
821-
StringRef ObjCStubsSection::getMethname(Symbol *sym) {
822-
assert(isObjCStubSymbol(sym) && "not an objc stub");
823-
auto name = sym->getName();
824-
StringRef methname = name.drop_front(symbolPrefix.size());
825-
return methname;
809+
ObjCSelRefsSection::ObjCSelRefsSection()
810+
: SyntheticSection(segment_names::data, section_names::objcSelrefs) {
811+
flags = S_ATTR_NO_DEAD_STRIP;
812+
align = target->wordSize;
826813
}
827814

828-
void ObjCStubsSection::initialize() {
815+
void ObjCSelRefsSection::initialize() {
829816
// Do not fold selrefs without ICF.
830817
if (config->icfLevel == ICFLevel::none)
831818
return;
@@ -852,32 +839,63 @@ void ObjCStubsSection::initialize() {
852839
}
853840
}
854841

842+
ConcatInputSection *ObjCSelRefsSection::makeSelRef(StringRef methName) {
843+
auto methnameOffset =
844+
in.objcMethnameSection->getStringOffset(methName).outSecOff;
845+
846+
size_t wordSize = target->wordSize;
847+
uint8_t *selrefData = bAlloc().Allocate<uint8_t>(wordSize);
848+
write64le(selrefData, methnameOffset);
849+
ConcatInputSection *objcSelref =
850+
makeSyntheticInputSection(segment_names::data, section_names::objcSelrefs,
851+
S_LITERAL_POINTERS | S_ATTR_NO_DEAD_STRIP,
852+
ArrayRef<uint8_t>{selrefData, wordSize},
853+
/*align=*/wordSize);
854+
objcSelref->live = true;
855+
objcSelref->relocs.push_back({/*type=*/target->unsignedRelocType,
856+
/*pcrel=*/false, /*length=*/3,
857+
/*offset=*/0,
858+
/*addend=*/static_cast<int64_t>(methnameOffset),
859+
/*referent=*/in.objcMethnameSection->isec});
860+
objcSelref->parent = ConcatOutputSection::getOrCreateForInput(objcSelref);
861+
inputSections.push_back(objcSelref);
862+
objcSelref->isFinal = true;
863+
methnameToSelref[CachedHashStringRef(methName)] = objcSelref;
864+
return objcSelref;
865+
}
866+
867+
ConcatInputSection *
868+
ObjCSelRefsSection::getSelRefForMethName(StringRef methName) {
869+
auto it = methnameToSelref.find(CachedHashStringRef(methName));
870+
if (it == methnameToSelref.end())
871+
return nullptr;
872+
return it->second;
873+
}
874+
875+
ObjCStubsSection::ObjCStubsSection()
876+
: SyntheticSection(segment_names::text, section_names::objcStubs) {
877+
flags = S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS;
878+
align = config->objcStubsMode == ObjCStubsMode::fast
879+
? target->objcStubsFastAlignment
880+
: target->objcStubsSmallAlignment;
881+
}
882+
883+
bool ObjCStubsSection::isObjCStubSymbol(Symbol *sym) {
884+
return sym->getName().starts_with(symbolPrefix);
885+
}
886+
887+
StringRef ObjCStubsSection::getMethname(Symbol *sym) {
888+
assert(isObjCStubSymbol(sym) && "not an objc stub");
889+
auto name = sym->getName();
890+
StringRef methname = name.drop_front(symbolPrefix.size());
891+
return methname;
892+
}
893+
855894
void ObjCStubsSection::addEntry(Symbol *sym) {
856895
StringRef methname = getMethname(sym);
857896
// We create a selref entry for each unique methname.
858-
if (!methnameToSelref.count(CachedHashStringRef(methname))) {
859-
auto methnameOffset =
860-
in.objcMethnameSection->getStringOffset(methname).outSecOff;
861-
862-
size_t wordSize = target->wordSize;
863-
uint8_t *selrefData = bAlloc().Allocate<uint8_t>(wordSize);
864-
write64le(selrefData, methnameOffset);
865-
auto *objcSelref = makeSyntheticInputSection(
866-
segment_names::data, section_names::objcSelrefs,
867-
S_LITERAL_POINTERS | S_ATTR_NO_DEAD_STRIP,
868-
ArrayRef<uint8_t>{selrefData, wordSize},
869-
/*align=*/wordSize);
870-
objcSelref->live = true;
871-
objcSelref->relocs.push_back(
872-
{/*type=*/target->unsignedRelocType,
873-
/*pcrel=*/false, /*length=*/3,
874-
/*offset=*/0,
875-
/*addend=*/static_cast<int64_t>(methnameOffset),
876-
/*referent=*/in.objcMethnameSection->isec});
877-
objcSelref->parent = ConcatOutputSection::getOrCreateForInput(objcSelref);
878-
inputSections.push_back(objcSelref);
879-
objcSelref->isFinal = true;
880-
methnameToSelref[CachedHashStringRef(methname)] = objcSelref;
897+
if (!in.objcSelRefs->getSelRefForMethName(methname)) {
898+
in.objcSelRefs->makeSelRef(methname);
881899
}
882900

883901
auto stubSize = config->objcStubsMode == ObjCStubsMode::fast
@@ -927,9 +945,9 @@ void ObjCStubsSection::writeTo(uint8_t *buf) const {
927945
Defined *sym = symbols[i];
928946

929947
auto methname = getMethname(sym);
930-
auto j = methnameToSelref.find(CachedHashStringRef(methname));
931-
assert(j != methnameToSelref.end());
932-
auto selrefAddr = j->second->getVA(0);
948+
InputSection *selRef = in.objcSelRefs->getSelRefForMethName(methname);
949+
assert(selRef != nullptr && "no selref for methname");
950+
auto selrefAddr = selRef->getVA(0);
933951
target->writeObjCMsgSendStub(buf + stubOffset, sym, in.objcStubs->addr,
934952
stubOffset, selrefAddr, objcMsgSend);
935953
}

lld/MachO/SyntheticSections.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,25 @@ class StubHelperSection final : public SyntheticSection {
315315
Defined *dyldPrivate = nullptr;
316316
};
317317

318+
class ObjCSelRefsSection final : public SyntheticSection {
319+
public:
320+
ObjCSelRefsSection();
321+
void initialize();
322+
323+
// This SyntheticSection does not do its own writing, but instead uses the
324+
// creates SyntheticInputSection's and inserts them into inputSections
325+
uint64_t getSize() const override { return 0; }
326+
bool isNeeded() const override { return false; }
327+
void writeTo(uint8_t *buf) const override {}
328+
329+
ConcatInputSection *getSelRefForMethName(StringRef methName);
330+
ConcatInputSection *makeSelRef(StringRef methName);
331+
332+
private:
333+
llvm::DenseMap<llvm::CachedHashStringRef, ConcatInputSection *>
334+
methnameToSelref;
335+
};
336+
318337
// Objective-C stubs are hoisted objc_msgSend calls per selector called in the
319338
// program. Apple Clang produces undefined symbols to each stub, such as
320339
// '_objc_msgSend$foo', which are then synthesized by the linker. The stubs
@@ -324,7 +343,6 @@ class StubHelperSection final : public SyntheticSection {
324343
class ObjCStubsSection final : public SyntheticSection {
325344
public:
326345
ObjCStubsSection();
327-
void initialize();
328346
void addEntry(Symbol *sym);
329347
uint64_t getSize() const override;
330348
bool isNeeded() const override { return !symbols.empty(); }
@@ -338,7 +356,6 @@ class ObjCStubsSection final : public SyntheticSection {
338356

339357
private:
340358
std::vector<Defined *> symbols;
341-
llvm::DenseMap<llvm::CachedHashStringRef, InputSection *> methnameToSelref;
342359
Symbol *objcMsgSend = nullptr;
343360
};
344361

@@ -794,6 +811,7 @@ struct InStruct {
794811
LazyPointerSection *lazyPointers = nullptr;
795812
StubsSection *stubs = nullptr;
796813
StubHelperSection *stubHelper = nullptr;
814+
ObjCSelRefsSection *objcSelRefs = nullptr;
797815
ObjCStubsSection *objcStubs = nullptr;
798816
UnwindInfoSection *unwindInfo = nullptr;
799817
ObjCImageInfoSection *objCImageInfo = nullptr;

lld/MachO/Writer.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ static void addNonWeakDefinition(const Defined *defined) {
720720

721721
void Writer::scanSymbols() {
722722
TimeTraceScope timeScope("Scan symbols");
723-
in.objcStubs->initialize();
723+
in.objcSelRefs->initialize();
724724
for (Symbol *sym : symtab->getSymbols()) {
725725
if (auto *defined = dyn_cast<Defined>(sym)) {
726726
if (!defined->isLive())
@@ -1359,6 +1359,7 @@ void macho::createSyntheticSections() {
13591359
in.got = make<GotSection>();
13601360
in.tlvPointers = make<TlvPointerSection>();
13611361
in.stubs = make<StubsSection>();
1362+
in.objcSelRefs = make<ObjCSelRefsSection>();
13621363
in.objcStubs = make<ObjCStubsSection>();
13631364
in.unwindInfo = makeUnwindInfoSection();
13641365
in.objCImageInfo = make<ObjCImageInfoSection>();

0 commit comments

Comments
 (0)