[lld] [lld-macho][NFC] Refactor ObjCSelRefsSection out of ObjCStubsSection (PR #83878)

via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 5 23:26:45 PST 2024


https://github.com/alx32 updated https://github.com/llvm/llvm-project/pull/83878

>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 1/2] [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>();

>From e0c056b66e6a40f5d6a7eb399b9d7c0f8838e347 Mon Sep 17 00:00:00 2001
From: Alex B <alexborcan at meta.com>
Date: Tue, 5 Mar 2024 23:16:55 -0800
Subject: [PATCH 2/2] [lld-macho] Address Feedback #1

---
 lld/MachO/SyntheticSections.cpp | 13 ++++---------
 lld/MachO/SyntheticSections.h   |  2 +-
 2 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index c8a0b29581eed3..9cb4756f6d75b0 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -807,10 +807,7 @@ void StubHelperSection::setUp() {
 }
 
 ObjCSelRefsSection::ObjCSelRefsSection()
-    : SyntheticSection(segment_names::data, section_names::objcSelrefs) {
-  flags = S_ATTR_NO_DEAD_STRIP;
-  align = target->wordSize;
-}
+    : SyntheticSection(segment_names::data, section_names::objcSelrefs) {}
 
 void ObjCSelRefsSection::initialize() {
   // Do not fold selrefs without ICF.
@@ -864,8 +861,7 @@ ConcatInputSection *ObjCSelRefsSection::makeSelRef(StringRef methName) {
   return objcSelref;
 }
 
-ConcatInputSection *
-ObjCSelRefsSection::getSelRefForMethName(StringRef methName) {
+ConcatInputSection *ObjCSelRefsSection::getSelRef(StringRef methName) {
   auto it = methnameToSelref.find(CachedHashStringRef(methName));
   if (it == methnameToSelref.end())
     return nullptr;
@@ -894,9 +890,8 @@ StringRef ObjCStubsSection::getMethname(Symbol *sym) {
 void ObjCStubsSection::addEntry(Symbol *sym) {
   StringRef methname = getMethname(sym);
   // We create a selref entry for each unique methname.
-  if (!in.objcSelRefs->getSelRefForMethName(methname)) {
+  if (!in.objcSelRefs->getSelRef(methname))
     in.objcSelRefs->makeSelRef(methname);
-  }
 
   auto stubSize = config->objcStubsMode == ObjCStubsMode::fast
                       ? target->objcStubsFastSize
@@ -945,7 +940,7 @@ void ObjCStubsSection::writeTo(uint8_t *buf) const {
     Defined *sym = symbols[i];
 
     auto methname = getMethname(sym);
-    InputSection *selRef = in.objcSelRefs->getSelRefForMethName(methname);
+    InputSection *selRef = in.objcSelRefs->getSelRef(methname);
     assert(selRef != nullptr && "no selref for methname");
     auto selrefAddr = selRef->getVA(0);
     target->writeObjCMsgSendStub(buf + stubOffset, sym, in.objcStubs->addr,
diff --git a/lld/MachO/SyntheticSections.h b/lld/MachO/SyntheticSections.h
index 794ed332f109f1..397b008200fce5 100644
--- a/lld/MachO/SyntheticSections.h
+++ b/lld/MachO/SyntheticSections.h
@@ -326,7 +326,7 @@ class ObjCSelRefsSection final : public SyntheticSection {
   bool isNeeded() const override { return false; }
   void writeTo(uint8_t *buf) const override {}
 
-  ConcatInputSection *getSelRefForMethName(StringRef methName);
+  ConcatInputSection *getSelRef(StringRef methName);
   ConcatInputSection *makeSelRef(StringRef methName);
 
 private:



More information about the llvm-commits mailing list