[lld] [lld-macho][NFC] Refactor ObjCSelRefsSection out of ObjCStubsSection (PR #83878)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 4 09:47:37 PST 2024
https://github.com/alx32 created https://github.com/llvm/llvm-project/pull/83878
Currently ObjCStubsSection is handling both the logic for stubs as well as 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 - 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"
>From f50448553add238d482fdc348ad534386c09f4f1 Mon Sep 17 00:00:00 2001
From: Alex B <alexborcan at meta.com>
Date: Mon, 4 Mar 2024 09:40:01 -0800
Subject: [PATCH] [lld-macho][NFC] Refactor ObjCSelRefsSection out of
ObjCStubsSection
---
lld/MachO/SyntheticSections.cpp | 106 +++++++++++++++++++-------------
lld/MachO/SyntheticSections.h | 22 ++++++-
lld/MachO/Writer.cpp | 3 +-
3 files changed, 84 insertions(+), 47 deletions(-)
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>();
More information about the llvm-commits
mailing list