aboutsummaryrefslogtreecommitdiff
path: root/lld/MachO
diff options
context:
space:
mode:
authorKyungwoo Lee <kyulee@meta.com>2024-01-29 23:29:57 -0800
committerGitHub <noreply@github.com>2024-01-29 23:29:57 -0800
commitcb46c6181770dabad59cc738ad1d26ad78b5f885 (patch)
tree543fde62b9463c24d3277868ee0a485cb9c452bf /lld/MachO
parent67f0a6917c07df6a21580adb567b1a8964818d92 (diff)
downloadllvm-cb46c6181770dabad59cc738ad1d26ad78b5f885.zip
llvm-cb46c6181770dabad59cc738ad1d26ad78b5f885.tar.gz
llvm-cb46c6181770dabad59cc738ad1d26ad78b5f885.tar.bz2
[lld-macho] dead-strip objc stubs (#79726)
This supports dead-strip for objc stubs.
Diffstat (limited to 'lld/MachO')
-rw-r--r--lld/MachO/Driver.cpp5
-rw-r--r--lld/MachO/SyntheticSections.cpp14
-rw-r--r--lld/MachO/SyntheticSections.h2
-rw-r--r--lld/MachO/Writer.cpp10
4 files changed, 25 insertions, 6 deletions
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 411fbcf..a57f60c 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -1275,11 +1275,10 @@ static void foldIdenticalLiterals() {
static void addSynthenticMethnames() {
std::string &data = *make<std::string>();
llvm::raw_string_ostream os(data);
- const int prefixLength = ObjCStubsSection::symbolPrefix.size();
for (Symbol *sym : symtab->getSymbols())
if (isa<Undefined>(sym))
- if (sym->getName().starts_with(ObjCStubsSection::symbolPrefix))
- os << sym->getName().drop_front(prefixLength) << '\0';
+ if (ObjCStubsSection::isObjCStubSymbol(sym))
+ os << ObjCStubsSection::getMethname(sym) << '\0';
if (data.empty())
return;
diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index 53220ad04..d3c8cb0 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -814,9 +814,19 @@ ObjCStubsSection::ObjCStubsSection()
: 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) {
- assert(sym->getName().starts_with(symbolPrefix) && "not an objc stub");
- StringRef methname = sym->getName().drop_front(symbolPrefix.size());
+ StringRef methname = getMethname(sym);
offsets.push_back(
in.objcMethnameSection->getStringOffset(methname).outSecOff);
diff --git a/lld/MachO/SyntheticSections.h b/lld/MachO/SyntheticSections.h
index 5fb7b6e..5ae9795 100644
--- a/lld/MachO/SyntheticSections.h
+++ b/lld/MachO/SyntheticSections.h
@@ -332,6 +332,8 @@ public:
void setUp();
static constexpr llvm::StringLiteral symbolPrefix = "_objc_msgSend$";
+ static bool isObjCStubSymbol(Symbol *sym);
+ static StringRef getMethname(Symbol *sym);
private:
std::vector<Defined *> symbols;
diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index 1b0e64a..3634c626 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -736,8 +736,16 @@ void Writer::scanSymbols() {
dysym->getFile()->refState =
std::max(dysym->getFile()->refState, dysym->getRefState());
} else if (isa<Undefined>(sym)) {
- if (sym->getName().starts_with(ObjCStubsSection::symbolPrefix))
+ if (ObjCStubsSection::isObjCStubSymbol(sym)) {
+ // When -dead_strip is enabled, we don't want to emit any dead stubs.
+ // Although this stub symbol is yet undefined, addSym() was called
+ // during MarkLive.
+ if (config->deadStrip) {
+ if (!sym->isLive())
+ continue;
+ }
in.objcStubs->addEntry(sym);
+ }
}
}