Skip to content

Commit a53401e

Browse files
alx32Alex B
andauthored
[lld-macho][NFC] Refactor ObjCSelRefsSection out of ObjCStubsSection (#83878)
Currently ObjCStubsSection is handling both the logic for the "__objc_stubs" section, as well as the logic for the "__objc_selrefs" section. While this is OK for now, it will be an issue for other features that want to interact with the "__objc_selrefs" section, such as upcoming relative method lists feature - which will also want to create / reference entries in the "__objc_selrefs" section. In this PR we split the logic relating to handling the "__objc_selrefs" section into a new SyntheticSection (ObjCSelRefsSection). Non-functional change - neither the behavior nor implementation changes, the interface is just made more friendly to not have "__objc_selrefs" so bound to "__objc_stubs". --------- Co-authored-by: Alex B <[email protected]>
1 parent 193b3d6 commit a53401e

File tree

3 files changed

+83
-49
lines changed

3 files changed

+83
-49
lines changed

lld/MachO/SyntheticSections.cpp

Lines changed: 59 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -806,26 +806,10 @@ 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-
}
809+
ObjCSelRefsSection::ObjCSelRefsSection()
810+
: SyntheticSection(segment_names::data, section_names::objcSelrefs) {}
820811

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;
826-
}
827-
828-
void ObjCStubsSection::initialize() {
812+
void ObjCSelRefsSection::initialize() {
829813
// Do not fold selrefs without ICF.
830814
if (config->icfLevel == ICFLevel::none)
831815
return;
@@ -852,33 +836,62 @@ void ObjCStubsSection::initialize() {
852836
}
853837
}
854838

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

883896
auto stubSize = config->objcStubsMode == ObjCStubsMode::fast
884897
? target->objcStubsFastSize
@@ -927,9 +940,9 @@ void ObjCStubsSection::writeTo(uint8_t *buf) const {
927940
Defined *sym = symbols[i];
928941

929942
auto methname = getMethname(sym);
930-
auto j = methnameToSelref.find(CachedHashStringRef(methname));
931-
assert(j != methnameToSelref.end());
932-
auto selrefAddr = j->second->getVA(0);
943+
InputSection *selRef = in.objcSelRefs->getSelRef(methname);
944+
assert(selRef != nullptr && "no selref for methname");
945+
auto selrefAddr = selRef->getVA(0);
933946
target->writeObjCMsgSendStub(buf + stubOffset, sym, in.objcStubs->addr,
934947
stubOffset, selrefAddr, objcMsgSend);
935948
}

lld/MachO/SyntheticSections.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,27 @@ 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 directly write data to the output, it is
324+
// just a placeholder for easily creating SyntheticInputSection's which will
325+
// be inserted into inputSections and handeled by the default writing
326+
// mechanism.
327+
uint64_t getSize() const override { return 0; }
328+
bool isNeeded() const override { return false; }
329+
void writeTo(uint8_t *buf) const override {}
330+
331+
ConcatInputSection *getSelRef(StringRef methname);
332+
ConcatInputSection *makeSelRef(StringRef methname);
333+
334+
private:
335+
llvm::DenseMap<llvm::CachedHashStringRef, ConcatInputSection *>
336+
methnameToSelref;
337+
};
338+
318339
// Objective-C stubs are hoisted objc_msgSend calls per selector called in the
319340
// program. Apple Clang produces undefined symbols to each stub, such as
320341
// '_objc_msgSend$foo', which are then synthesized by the linker. The stubs
@@ -324,7 +345,6 @@ class StubHelperSection final : public SyntheticSection {
324345
class ObjCStubsSection final : public SyntheticSection {
325346
public:
326347
ObjCStubsSection();
327-
void initialize();
328348
void addEntry(Symbol *sym);
329349
uint64_t getSize() const override;
330350
bool isNeeded() const override { return !symbols.empty(); }
@@ -338,7 +358,6 @@ class ObjCStubsSection final : public SyntheticSection {
338358

339359
private:
340360
std::vector<Defined *> symbols;
341-
llvm::DenseMap<llvm::CachedHashStringRef, InputSection *> methnameToSelref;
342361
Symbol *objcMsgSend = nullptr;
343362
};
344363

@@ -794,6 +813,7 @@ struct InStruct {
794813
LazyPointerSection *lazyPointers = nullptr;
795814
StubsSection *stubs = nullptr;
796815
StubHelperSection *stubHelper = nullptr;
816+
ObjCSelRefsSection *objcSelRefs = nullptr;
797817
ObjCStubsSection *objcStubs = nullptr;
798818
UnwindInfoSection *unwindInfo = nullptr;
799819
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)