summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-objcopy
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-objcopy')
-rw-r--r--llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp45
-rw-r--r--llvm/tools/llvm-objcopy/MachO/Object.cpp12
-rw-r--r--llvm/tools/llvm-objcopy/MachO/Object.h9
3 files changed, 60 insertions, 6 deletions
diff --git a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
index 73983a175a9..d14354e8d06 100644
--- a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
+++ b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
@@ -23,6 +23,16 @@ using SectionPred = std::function<bool(const Section &Sec)>;
static void removeSections(const CopyConfig &Config, Object &Obj) {
SectionPred RemovePred = [](const Section &) { return false; };
+ if (Config.StripAll) {
+ // Remove all debug sections.
+ RemovePred = [RemovePred](const Section &Sec) {
+ if (Sec.Segname == "__DWARF")
+ return true;
+
+ return RemovePred(Sec);
+ };
+ }
+
if (!Config.OnlySection.empty()) {
RemovePred = [&Config, RemovePred](const Section &Sec) {
return !Config.OnlySection.matches(Sec.CanonicalName);
@@ -32,6 +42,23 @@ static void removeSections(const CopyConfig &Config, Object &Obj) {
return Obj.removeSections(RemovePred);
}
+static void markSymbols(const CopyConfig &Config, Object &Obj) {
+ // Symbols referenced from the indirect symbol table must not be removed.
+ for (IndirectSymbolEntry &ISE : Obj.IndirectSymTable.Symbols)
+ if (ISE.Symbol)
+ (*ISE.Symbol)->Referenced = true;
+}
+
+static void removeSymbols(const CopyConfig &Config, Object &Obj) {
+ auto RemovePred = [Config](const std::unique_ptr<SymbolEntry> &N) {
+ if (N->Referenced)
+ return false;
+ return Config.StripAll;
+ };
+
+ Obj.SymTable.removeSymbols(RemovePred);
+}
+
static Error handleArgs(const CopyConfig &Config, Object &Obj) {
if (Config.AllowBrokenLinks || !Config.BuildIdLinkDir.empty() ||
Config.BuildIdLinkInput || Config.BuildIdLinkOutput ||
@@ -45,9 +72,9 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
!Config.UnneededSymbolsToRemove.empty() ||
!Config.SetSectionAlignment.empty() || !Config.SetSectionFlags.empty() ||
!Config.ToRemove.empty() || Config.ExtractDWO || Config.KeepFileSymbols ||
- Config.LocalizeHidden || Config.PreserveDates || Config.StripDWO ||
- Config.StripNonAlloc || Config.StripSections || Config.Weaken ||
- Config.DecompressDebugSections || Config.StripDebug ||
+ Config.LocalizeHidden || Config.PreserveDates || Config.StripAllGNU ||
+ Config.StripDWO || Config.StripNonAlloc || Config.StripSections ||
+ Config.Weaken || Config.DecompressDebugSections || Config.StripDebug ||
Config.StripNonAlloc || Config.StripSections || Config.StripUnneeded ||
Config.DiscardMode != DiscardType::None || !Config.SymbolsToAdd.empty() ||
Config.EntryExpr) {
@@ -56,6 +83,18 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
}
removeSections(Config, Obj);
+
+ // Mark symbols to determine which symbols are still needed.
+ if (Config.StripAll)
+ markSymbols(Config, Obj);
+
+ removeSymbols(Config, Obj);
+
+ if (Config.StripAll)
+ for (LoadCommand &LC : Obj.LoadCommands)
+ for (Section &Sec : LC.Sections)
+ Sec.Relocations.clear();
+
return Error::success();
}
diff --git a/llvm/tools/llvm-objcopy/MachO/Object.cpp b/llvm/tools/llvm-objcopy/MachO/Object.cpp
index ba3e2ef8ba4..5626782d7d6 100644
--- a/llvm/tools/llvm-objcopy/MachO/Object.cpp
+++ b/llvm/tools/llvm-objcopy/MachO/Object.cpp
@@ -10,6 +10,18 @@ const SymbolEntry *SymbolTable::getSymbolByIndex(uint32_t Index) const {
return Symbols[Index].get();
}
+SymbolEntry *SymbolTable::getSymbolByIndex(uint32_t Index) {
+ return const_cast<SymbolEntry *>(
+ static_cast<const SymbolTable *>(this)->getSymbolByIndex(Index));
+}
+
+void SymbolTable::removeSymbols(
+ function_ref<bool(const std::unique_ptr<SymbolEntry> &)> ToRemove) {
+ Symbols.erase(
+ std::remove_if(std::begin(Symbols), std::end(Symbols), ToRemove),
+ std::end(Symbols));
+}
+
void Object::removeSections(function_ref<bool(const Section &)> ToRemove) {
for (LoadCommand &LC : LoadCommands)
LC.Sections.erase(std::remove_if(std::begin(LC.Sections),
diff --git a/llvm/tools/llvm-objcopy/MachO/Object.h b/llvm/tools/llvm-objcopy/MachO/Object.h
index bf802531a4f..8642ce3c0d9 100644
--- a/llvm/tools/llvm-objcopy/MachO/Object.h
+++ b/llvm/tools/llvm-objcopy/MachO/Object.h
@@ -87,6 +87,7 @@ struct LoadCommand {
// nlist.
struct SymbolEntry {
std::string Name;
+ bool Referenced = false;
uint32_t Index;
uint8_t n_type;
uint8_t n_sect;
@@ -110,6 +111,9 @@ struct SymbolTable {
std::vector<std::unique_ptr<SymbolEntry>> Symbols;
const SymbolEntry *getSymbolByIndex(uint32_t Index) const;
+ SymbolEntry *getSymbolByIndex(uint32_t Index);
+ void removeSymbols(
+ function_ref<bool(const std::unique_ptr<SymbolEntry> &)> ToRemove);
};
struct IndirectSymbolEntry {
@@ -118,10 +122,9 @@ struct IndirectSymbolEntry {
uint32_t OriginalIndex;
/// The Symbol referenced by this entry. It's None if the index is
/// INDIRECT_SYMBOL_LOCAL or INDIRECT_SYMBOL_ABS.
- Optional<const SymbolEntry *> Symbol;
+ Optional<SymbolEntry *> Symbol;
- IndirectSymbolEntry(uint32_t OriginalIndex,
- Optional<const SymbolEntry *> Symbol)
+ IndirectSymbolEntry(uint32_t OriginalIndex, Optional<SymbolEntry *> Symbol)
: OriginalIndex(OriginalIndex), Symbol(Symbol) {}
};
OpenPOWER on IntegriCloud