-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[lld-macho][NFC] Refactor ObjCSelRefsSection out of ObjCStubsSection #83878
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-lld-macho @llvm/pr-subscribers-lld Author: None (alx32) ChangesCurrently ObjCStubsSection is handling both the logic for the "__objc_stubs" section, as well as the logic for the "__objc_selrefs" section. Full diff: https://github.com/llvm/llvm-project/pull/83878.diff 3 Files Affected:
diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index a5d66bb4ea0801..c8a0b29581eed3 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -806,26 +806,13 @@ void StubHelperSection::setUp() {
dyldPrivate->used = true;
}
-ObjCStubsSection::ObjCStubsSection()
- : SyntheticSection(segment_names::text, section_names::objcStubs) {
- flags = S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS;
- align = config->objcStubsMode == ObjCStubsMode::fast
- ? target->objcStubsFastAlignment
- : target->objcStubsSmallAlignment;
-}
-
-bool ObjCStubsSection::isObjCStubSymbol(Symbol *sym) {
- return sym->getName().starts_with(symbolPrefix);
-}
-
-StringRef ObjCStubsSection::getMethname(Symbol *sym) {
- assert(isObjCStubSymbol(sym) && "not an objc stub");
- auto name = sym->getName();
- StringRef methname = name.drop_front(symbolPrefix.size());
- return methname;
+ObjCSelRefsSection::ObjCSelRefsSection()
+ : SyntheticSection(segment_names::data, section_names::objcSelrefs) {
+ flags = S_ATTR_NO_DEAD_STRIP;
+ align = target->wordSize;
}
-void ObjCStubsSection::initialize() {
+void ObjCSelRefsSection::initialize() {
// Do not fold selrefs without ICF.
if (config->icfLevel == ICFLevel::none)
return;
@@ -852,32 +839,63 @@ void ObjCStubsSection::initialize() {
}
}
+ConcatInputSection *ObjCSelRefsSection::makeSelRef(StringRef methName) {
+ auto methnameOffset =
+ in.objcMethnameSection->getStringOffset(methName).outSecOff;
+
+ size_t wordSize = target->wordSize;
+ uint8_t *selrefData = bAlloc().Allocate<uint8_t>(wordSize);
+ write64le(selrefData, methnameOffset);
+ ConcatInputSection *objcSelref =
+ makeSyntheticInputSection(segment_names::data, section_names::objcSelrefs,
+ S_LITERAL_POINTERS | S_ATTR_NO_DEAD_STRIP,
+ ArrayRef<uint8_t>{selrefData, wordSize},
+ /*align=*/wordSize);
+ objcSelref->live = true;
+ objcSelref->relocs.push_back({/*type=*/target->unsignedRelocType,
+ /*pcrel=*/false, /*length=*/3,
+ /*offset=*/0,
+ /*addend=*/static_cast<int64_t>(methnameOffset),
+ /*referent=*/in.objcMethnameSection->isec});
+ objcSelref->parent = ConcatOutputSection::getOrCreateForInput(objcSelref);
+ inputSections.push_back(objcSelref);
+ objcSelref->isFinal = true;
+ methnameToSelref[CachedHashStringRef(methName)] = objcSelref;
+ return objcSelref;
+}
+
+ConcatInputSection *
+ObjCSelRefsSection::getSelRefForMethName(StringRef methName) {
+ auto it = methnameToSelref.find(CachedHashStringRef(methName));
+ if (it == methnameToSelref.end())
+ return nullptr;
+ return it->second;
+}
+
+ObjCStubsSection::ObjCStubsSection()
+ : SyntheticSection(segment_names::text, section_names::objcStubs) {
+ flags = S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS;
+ align = config->objcStubsMode == ObjCStubsMode::fast
+ ? target->objcStubsFastAlignment
+ : target->objcStubsSmallAlignment;
+}
+
+bool ObjCStubsSection::isObjCStubSymbol(Symbol *sym) {
+ return sym->getName().starts_with(symbolPrefix);
+}
+
+StringRef ObjCStubsSection::getMethname(Symbol *sym) {
+ assert(isObjCStubSymbol(sym) && "not an objc stub");
+ auto name = sym->getName();
+ StringRef methname = name.drop_front(symbolPrefix.size());
+ return methname;
+}
+
void ObjCStubsSection::addEntry(Symbol *sym) {
StringRef methname = getMethname(sym);
// We create a selref entry for each unique methname.
- if (!methnameToSelref.count(CachedHashStringRef(methname))) {
- auto methnameOffset =
- in.objcMethnameSection->getStringOffset(methname).outSecOff;
-
- size_t wordSize = target->wordSize;
- uint8_t *selrefData = bAlloc().Allocate<uint8_t>(wordSize);
- write64le(selrefData, methnameOffset);
- auto *objcSelref = makeSyntheticInputSection(
- segment_names::data, section_names::objcSelrefs,
- S_LITERAL_POINTERS | S_ATTR_NO_DEAD_STRIP,
- ArrayRef<uint8_t>{selrefData, wordSize},
- /*align=*/wordSize);
- objcSelref->live = true;
- objcSelref->relocs.push_back(
- {/*type=*/target->unsignedRelocType,
- /*pcrel=*/false, /*length=*/3,
- /*offset=*/0,
- /*addend=*/static_cast<int64_t>(methnameOffset),
- /*referent=*/in.objcMethnameSection->isec});
- objcSelref->parent = ConcatOutputSection::getOrCreateForInput(objcSelref);
- inputSections.push_back(objcSelref);
- objcSelref->isFinal = true;
- methnameToSelref[CachedHashStringRef(methname)] = objcSelref;
+ if (!in.objcSelRefs->getSelRefForMethName(methname)) {
+ in.objcSelRefs->makeSelRef(methname);
}
auto stubSize = config->objcStubsMode == ObjCStubsMode::fast
@@ -927,9 +945,9 @@ void ObjCStubsSection::writeTo(uint8_t *buf) const {
Defined *sym = symbols[i];
auto methname = getMethname(sym);
- auto j = methnameToSelref.find(CachedHashStringRef(methname));
- assert(j != methnameToSelref.end());
- auto selrefAddr = j->second->getVA(0);
+ InputSection *selRef = in.objcSelRefs->getSelRefForMethName(methname);
+ assert(selRef != nullptr && "no selref for methname");
+ auto selrefAddr = selRef->getVA(0);
target->writeObjCMsgSendStub(buf + stubOffset, sym, in.objcStubs->addr,
stubOffset, selrefAddr, objcMsgSend);
}
diff --git a/lld/MachO/SyntheticSections.h b/lld/MachO/SyntheticSections.h
index 8d54cacc8d756a..794ed332f109f1 100644
--- a/lld/MachO/SyntheticSections.h
+++ b/lld/MachO/SyntheticSections.h
@@ -315,6 +315,25 @@ class StubHelperSection final : public SyntheticSection {
Defined *dyldPrivate = nullptr;
};
+class ObjCSelRefsSection final : public SyntheticSection {
+public:
+ ObjCSelRefsSection();
+ void initialize();
+
+ // This SyntheticSection does not do its own writing, but instead uses the
+ // creates SyntheticInputSection's and inserts them into inputSections
+ uint64_t getSize() const override { return 0; }
+ bool isNeeded() const override { return false; }
+ void writeTo(uint8_t *buf) const override {}
+
+ ConcatInputSection *getSelRefForMethName(StringRef methName);
+ ConcatInputSection *makeSelRef(StringRef methName);
+
+private:
+ llvm::DenseMap<llvm::CachedHashStringRef, ConcatInputSection *>
+ methnameToSelref;
+};
+
// Objective-C stubs are hoisted objc_msgSend calls per selector called in the
// program. Apple Clang produces undefined symbols to each stub, such as
// '_objc_msgSend$foo', which are then synthesized by the linker. The stubs
@@ -324,7 +343,6 @@ class StubHelperSection final : public SyntheticSection {
class ObjCStubsSection final : public SyntheticSection {
public:
ObjCStubsSection();
- void initialize();
void addEntry(Symbol *sym);
uint64_t getSize() const override;
bool isNeeded() const override { return !symbols.empty(); }
@@ -338,7 +356,6 @@ class ObjCStubsSection final : public SyntheticSection {
private:
std::vector<Defined *> symbols;
- llvm::DenseMap<llvm::CachedHashStringRef, InputSection *> methnameToSelref;
Symbol *objcMsgSend = nullptr;
};
@@ -794,6 +811,7 @@ struct InStruct {
LazyPointerSection *lazyPointers = nullptr;
StubsSection *stubs = nullptr;
StubHelperSection *stubHelper = nullptr;
+ ObjCSelRefsSection *objcSelRefs = nullptr;
ObjCStubsSection *objcStubs = nullptr;
UnwindInfoSection *unwindInfo = nullptr;
ObjCImageInfoSection *objCImageInfo = nullptr;
diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index 65b598d1d7c422..d66c5091143209 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -720,7 +720,7 @@ static void addNonWeakDefinition(const Defined *defined) {
void Writer::scanSymbols() {
TimeTraceScope timeScope("Scan symbols");
- in.objcStubs->initialize();
+ in.objcSelRefs->initialize();
for (Symbol *sym : symtab->getSymbols()) {
if (auto *defined = dyn_cast<Defined>(sym)) {
if (!defined->isLive())
@@ -1359,6 +1359,7 @@ void macho::createSyntheticSections() {
in.got = make<GotSection>();
in.tlvPointers = make<TlvPointerSection>();
in.stubs = make<StubsSection>();
+ in.objcSelRefs = make<ObjCSelRefsSection>();
in.objcStubs = make<ObjCStubsSection>();
in.unwindInfo = makeUnwindInfoSection();
in.objCImageInfo = make<ObjCImageInfoSection>();
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
cdbc35c
to
e0c056b
Compare
LGTM. Suggest waiting for others' reviews or comments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
e0c056b
to
e692db0
Compare
…6456) In a previous PR: #83878, the intent was to make no functional changes, just refactor out the code for reuse. However, by creating `ObjCSelRefsSection` as a `SyntheticSection` - this slightly changed the functionality of the application as the `SyntheticSection` constructor registers the `SyntheticSection` as a functional one - with an associated `SyntheticInputSection`. With this change we remove this unintended consequence by making the code not use a `SyntheticSection` as base, but just by having it be a static helper.
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".