diff options
Diffstat (limited to 'llvm/tools/llvm-objcopy')
-rw-r--r-- | llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp | 45 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/MachO/Object.cpp | 12 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/MachO/Object.h | 9 |
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) {} }; |