diff --git a/llvm/tools/llvm-objcopy/CommonConfig.h b/llvm/tools/llvm-objcopy/CommonConfig.h --- a/llvm/tools/llvm-objcopy/CommonConfig.h +++ b/llvm/tools/llvm-objcopy/CommonConfig.h @@ -210,14 +210,6 @@ // Repeated options std::vector AddSection; std::vector DumpSection; - std::vector RPathToAdd; - std::vector RPathToPrepend; - DenseMap RPathsToUpdate; - DenseMap InstallNamesToUpdate; - DenseSet RPathsToRemove; - - // install-name-tool's id option - Optional SharedLibId; // Section matchers NameMatcher KeepSection; @@ -239,23 +231,13 @@ StringMap SetSectionFlags; StringMap SymbolsToRename; - // ELF entry point address expression. The input parameter is an entry point - // address in the input ELF file. The entry address in the output file is - // calculated with EntryExpr(input_address), when either --set-start or - // --change-start is used. - std::function EntryExpr; - // Symbol info specified by --add-symbol option. std::vector SymbolsToAdd; // Boolean options - bool AllowBrokenLinks = false; bool DeterministicArchives = true; bool ExtractDWO = false; bool ExtractMainPartition = false; - bool KeepFileSymbols = false; - bool KeepUndefined = false; - bool LocalizeHidden = false; bool OnlyKeepDebug = false; bool PreserveDates = false; bool StripAll = false; @@ -264,12 +246,9 @@ bool StripDebug = false; bool StripNonAlloc = false; bool StripSections = false; - bool StripSwiftSymbols = false; bool StripUnneeded = false; bool Weaken = false; bool DecompressDebugSections = false; - // install-name-tool's --delete_all_rpaths - bool RemoveAllRpaths = false; DebugCompressionType CompressionType = DebugCompressionType::None; }; diff --git a/llvm/tools/llvm-objcopy/ConfigManager.cpp b/llvm/tools/llvm-objcopy/ConfigManager.cpp --- a/llvm/tools/llvm-objcopy/ConfigManager.cpp +++ b/llvm/tools/llvm-objcopy/ConfigManager.cpp @@ -559,27 +559,21 @@ } Expected ConfigManager::getELFConfig() const { - if (Common.StripSwiftSymbols || Common.KeepUndefined) - return createStringError(llvm::errc::invalid_argument, - "option not supported by llvm-objcopy for ELF"); - return ELF; } Expected ConfigManager::getCOFFConfig() const { - if (Common.AllowBrokenLinks || !Common.SplitDWO.empty() || - !Common.SymbolsPrefix.empty() || !Common.AllocSectionsPrefix.empty() || - !Common.DumpSection.empty() || !Common.KeepSection.empty() || - ELF.NewSymbolVisibility || !Common.SymbolsToGlobalize.empty() || + if (!Common.SplitDWO.empty() || !Common.SymbolsPrefix.empty() || + !Common.AllocSectionsPrefix.empty() || !Common.DumpSection.empty() || + !Common.KeepSection.empty() || !Common.SymbolsToGlobalize.empty() || !Common.SymbolsToKeep.empty() || !Common.SymbolsToLocalize.empty() || !Common.SymbolsToWeaken.empty() || !Common.SymbolsToKeepGlobal.empty() || !Common.SectionsToRename.empty() || !Common.SetSectionAlignment.empty() || - Common.ExtractDWO || Common.LocalizeHidden || Common.PreserveDates || - Common.StripDWO || Common.StripNonAlloc || Common.StripSections || - Common.StripSwiftSymbols || Common.KeepUndefined || Common.Weaken || + Common.ExtractDWO || Common.PreserveDates || Common.StripDWO || + Common.StripNonAlloc || Common.StripSections || Common.Weaken || Common.DecompressDebugSections || Common.DiscardMode == DiscardType::Locals || - !Common.SymbolsToAdd.empty() || Common.EntryExpr) { + !Common.SymbolsToAdd.empty()) { return createStringError(llvm::errc::invalid_argument, "option not supported by llvm-objcopy for COFF"); } @@ -588,19 +582,18 @@ } Expected ConfigManager::getMachOConfig() const { - if (Common.AllowBrokenLinks || !Common.SplitDWO.empty() || - !Common.SymbolsPrefix.empty() || !Common.AllocSectionsPrefix.empty() || - !Common.KeepSection.empty() || ELF.NewSymbolVisibility || + if (!Common.SplitDWO.empty() || !Common.SymbolsPrefix.empty() || + !Common.AllocSectionsPrefix.empty() || !Common.KeepSection.empty() || !Common.SymbolsToGlobalize.empty() || !Common.SymbolsToKeep.empty() || !Common.SymbolsToLocalize.empty() || !Common.SymbolsToWeaken.empty() || !Common.SymbolsToKeepGlobal.empty() || !Common.SectionsToRename.empty() || !Common.UnneededSymbolsToRemove.empty() || !Common.SetSectionAlignment.empty() || !Common.SetSectionFlags.empty() || - Common.ExtractDWO || Common.LocalizeHidden || Common.PreserveDates || - Common.StripAllGNU || Common.StripDWO || Common.StripNonAlloc || - Common.StripSections || Common.Weaken || Common.DecompressDebugSections || - Common.StripUnneeded || Common.DiscardMode == DiscardType::Locals || - !Common.SymbolsToAdd.empty() || Common.EntryExpr) { + Common.ExtractDWO || Common.PreserveDates || Common.StripAllGNU || + Common.StripDWO || Common.StripNonAlloc || Common.StripSections || + Common.Weaken || Common.DecompressDebugSections || Common.StripUnneeded || + Common.DiscardMode == DiscardType::Locals || + !Common.SymbolsToAdd.empty()) { return createStringError(llvm::errc::invalid_argument, "option not supported by llvm-objcopy for MachO"); } @@ -612,8 +605,7 @@ if (!Common.AddGnuDebugLink.empty() || Common.ExtractPartition || !Common.SplitDWO.empty() || !Common.SymbolsPrefix.empty() || !Common.AllocSectionsPrefix.empty() || - Common.DiscardMode != DiscardType::None || ELF.NewSymbolVisibility || - !Common.SymbolsToAdd.empty() || !Common.RPathToAdd.empty() || + Common.DiscardMode != DiscardType::None || !Common.SymbolsToAdd.empty() || !Common.SymbolsToGlobalize.empty() || !Common.SymbolsToLocalize.empty() || !Common.SymbolsToKeep.empty() || !Common.SymbolsToRemove.empty() || !Common.UnneededSymbolsToRemove.empty() || @@ -684,6 +676,7 @@ ConfigManager ConfigMgr; CommonConfig &Config = ConfigMgr.Common; ELFConfig &ELFConfig = ConfigMgr.ELF; + MachOConfig &MachOConfig = ConfigMgr.MachO; Config.InputFilename = Positional[0]; Config.OutputFilename = Positional[Positional.size() == 1 ? 0 : 1]; if (InputArgs.hasArg(OBJCOPY_target) && @@ -905,7 +898,7 @@ Config.ExtractDWO = InputArgs.hasArg(OBJCOPY_extract_dwo); Config.ExtractMainPartition = InputArgs.hasArg(OBJCOPY_extract_main_partition); - Config.LocalizeHidden = InputArgs.hasArg(OBJCOPY_localize_hidden); + ELFConfig.LocalizeHidden = InputArgs.hasArg(OBJCOPY_localize_hidden); Config.Weaken = InputArgs.hasArg(OBJCOPY_weaken); if (InputArgs.hasArg(OBJCOPY_discard_all, OBJCOPY_discard_locals)) Config.DiscardMode = @@ -913,13 +906,13 @@ ? DiscardType::All : DiscardType::Locals; Config.OnlyKeepDebug = InputArgs.hasArg(OBJCOPY_only_keep_debug); - Config.KeepFileSymbols = InputArgs.hasArg(OBJCOPY_keep_file_symbols); - Config.KeepUndefined = InputArgs.hasArg(OBJCOPY_keep_undefined); + ELFConfig.KeepFileSymbols = InputArgs.hasArg(OBJCOPY_keep_file_symbols); + MachOConfig.KeepUndefined = InputArgs.hasArg(OBJCOPY_keep_undefined); Config.DecompressDebugSections = InputArgs.hasArg(OBJCOPY_decompress_debug_sections); if (Config.DiscardMode == DiscardType::All) { Config.StripDebug = true; - Config.KeepFileSymbols = true; + ELFConfig.KeepFileSymbols = true; } for (auto Arg : InputArgs.filtered(OBJCOPY_localize_symbol)) if (Error E = Config.SymbolsToLocalize.addMatcher(NameOrPattern::create( @@ -993,7 +986,7 @@ Config.SymbolsToAdd.push_back(*SymInfo); } - Config.AllowBrokenLinks = InputArgs.hasArg(OBJCOPY_allow_broken_links); + ELFConfig.AllowBrokenLinks = InputArgs.hasArg(OBJCOPY_allow_broken_links); Config.DeterministicArchives = InputArgs.hasFlag( OBJCOPY_enable_deterministic_archives, @@ -1013,16 +1006,16 @@ return createStringError( EAddr.getError(), "bad entry point address: '%s'", Arg->getValue()); - Config.EntryExpr = [EAddr](uint64_t) { return *EAddr; }; + ELFConfig.EntryExpr = [EAddr](uint64_t) { return *EAddr; }; } else if (Arg->getOption().matches(OBJCOPY_change_start)) { auto EIncr = getAsInteger(Arg->getValue()); if (!EIncr) return createStringError(EIncr.getError(), "bad entry point increment: '%s'", Arg->getValue()); - auto Expr = Config.EntryExpr ? std::move(Config.EntryExpr) - : [](uint64_t A) { return A; }; - Config.EntryExpr = [Expr, EIncr](uint64_t EAddr) { + auto Expr = ELFConfig.EntryExpr ? std::move(ELFConfig.EntryExpr) + : [](uint64_t A) { return A; }; + ELFConfig.EntryExpr = [Expr, EIncr](uint64_t EAddr) { return Expr(EAddr) + *EIncr; }; } @@ -1057,6 +1050,7 @@ DriverConfig DC; ConfigManager ConfigMgr; CommonConfig &Config = ConfigMgr.Common; + MachOConfig &MachOConfig = ConfigMgr.MachO; InstallNameToolOptTable T; unsigned MissingArgumentIndex, MissingArgumentCount; llvm::opt::InputArgList InputArgs = @@ -1087,27 +1081,27 @@ } for (auto Arg : InputArgs.filtered(INSTALL_NAME_TOOL_add_rpath)) - Config.RPathToAdd.push_back(Arg->getValue()); + MachOConfig.RPathToAdd.push_back(Arg->getValue()); for (auto *Arg : InputArgs.filtered(INSTALL_NAME_TOOL_prepend_rpath)) - Config.RPathToPrepend.push_back(Arg->getValue()); + MachOConfig.RPathToPrepend.push_back(Arg->getValue()); for (auto Arg : InputArgs.filtered(INSTALL_NAME_TOOL_delete_rpath)) { StringRef RPath = Arg->getValue(); // Cannot add and delete the same rpath at the same time. - if (is_contained(Config.RPathToAdd, RPath)) + if (is_contained(MachOConfig.RPathToAdd, RPath)) return createStringError( errc::invalid_argument, "cannot specify both -add_rpath '%s' and -delete_rpath '%s'", RPath.str().c_str(), RPath.str().c_str()); - if (is_contained(Config.RPathToPrepend, RPath)) + if (is_contained(MachOConfig.RPathToPrepend, RPath)) return createStringError( errc::invalid_argument, "cannot specify both -prepend_rpath '%s' and -delete_rpath '%s'", RPath.str().c_str(), RPath.str().c_str()); - Config.RPathsToRemove.insert(RPath); + MachOConfig.RPathsToRemove.insert(RPath); } for (auto *Arg : InputArgs.filtered(INSTALL_NAME_TOOL_rpath)) { @@ -1118,51 +1112,52 @@ // Cannot specify duplicate -rpath entries auto It1 = find_if( - Config.RPathsToUpdate, + MachOConfig.RPathsToUpdate, [&Match](const DenseMap::value_type &OldNew) { return Match(OldNew.getFirst()) || Match(OldNew.getSecond()); }); - if (It1 != Config.RPathsToUpdate.end()) + if (It1 != MachOConfig.RPathsToUpdate.end()) return createStringError(errc::invalid_argument, "cannot specify both -rpath '" + It1->getFirst() + "' '" + It1->getSecond() + "' and -rpath '" + Old + "' '" + New + "'"); // Cannot specify the same rpath under both -delete_rpath and -rpath - auto It2 = find_if(Config.RPathsToRemove, Match); - if (It2 != Config.RPathsToRemove.end()) + auto It2 = find_if(MachOConfig.RPathsToRemove, Match); + if (It2 != MachOConfig.RPathsToRemove.end()) return createStringError(errc::invalid_argument, "cannot specify both -delete_rpath '" + *It2 + "' and -rpath '" + Old + "' '" + New + "'"); // Cannot specify the same rpath under both -add_rpath and -rpath - auto It3 = find_if(Config.RPathToAdd, Match); - if (It3 != Config.RPathToAdd.end()) + auto It3 = find_if(MachOConfig.RPathToAdd, Match); + if (It3 != MachOConfig.RPathToAdd.end()) return createStringError(errc::invalid_argument, "cannot specify both -add_rpath '" + *It3 + "' and -rpath '" + Old + "' '" + New + "'"); // Cannot specify the same rpath under both -prepend_rpath and -rpath. - auto It4 = find_if(Config.RPathToPrepend, Match); - if (It4 != Config.RPathToPrepend.end()) + auto It4 = find_if(MachOConfig.RPathToPrepend, Match); + if (It4 != MachOConfig.RPathToPrepend.end()) return createStringError(errc::invalid_argument, "cannot specify both -prepend_rpath '" + *It4 + "' and -rpath '" + Old + "' '" + New + "'"); - Config.RPathsToUpdate.insert({Old, New}); + MachOConfig.RPathsToUpdate.insert({Old, New}); } if (auto *Arg = InputArgs.getLastArg(INSTALL_NAME_TOOL_id)) { - Config.SharedLibId = Arg->getValue(); - if (Config.SharedLibId->empty()) + MachOConfig.SharedLibId = Arg->getValue(); + if (MachOConfig.SharedLibId->empty()) return createStringError(errc::invalid_argument, "cannot specify an empty id"); } for (auto *Arg : InputArgs.filtered(INSTALL_NAME_TOOL_change)) - Config.InstallNamesToUpdate.insert({Arg->getValue(0), Arg->getValue(1)}); + MachOConfig.InstallNamesToUpdate.insert( + {Arg->getValue(0), Arg->getValue(1)}); - Config.RemoveAllRpaths = + MachOConfig.RemoveAllRpaths = InputArgs.hasArg(INSTALL_NAME_TOOL_delete_all_rpaths); SmallVector Positional; @@ -1281,6 +1276,8 @@ ConfigManager ConfigMgr; CommonConfig &Config = ConfigMgr.Common; + ELFConfig &ELFConfig = ConfigMgr.ELF; + MachOConfig &MachOConfig = ConfigMgr.MachO; if (InputArgs.hasArg(STRIP_regex) && InputArgs.hasArg(STRIP_wildcard)) return createStringError(errc::invalid_argument, @@ -1292,7 +1289,7 @@ : InputArgs.hasArg(STRIP_wildcard) ? MatchStyle::Wildcard : MatchStyle::Literal; - Config.AllowBrokenLinks = InputArgs.hasArg(STRIP_allow_broken_links); + ELFConfig.AllowBrokenLinks = InputArgs.hasArg(STRIP_allow_broken_links); Config.StripDebug = InputArgs.hasArg(STRIP_strip_debug); if (InputArgs.hasArg(STRIP_discard_all, STRIP_discard_locals)) @@ -1305,10 +1302,10 @@ if (auto Arg = InputArgs.getLastArg(STRIP_strip_all, STRIP_no_strip_all)) Config.StripAll = Arg->getOption().getID() == STRIP_strip_all; Config.StripAllGNU = InputArgs.hasArg(STRIP_strip_all_gnu); - Config.StripSwiftSymbols = InputArgs.hasArg(STRIP_strip_swift_symbols); + MachOConfig.StripSwiftSymbols = InputArgs.hasArg(STRIP_strip_swift_symbols); Config.OnlyKeepDebug = InputArgs.hasArg(STRIP_only_keep_debug); - Config.KeepFileSymbols = InputArgs.hasArg(STRIP_keep_file_symbols); - Config.KeepUndefined = InputArgs.hasArg(STRIP_keep_undefined); + ELFConfig.KeepFileSymbols = InputArgs.hasArg(STRIP_keep_file_symbols); + MachOConfig.KeepUndefined = InputArgs.hasArg(STRIP_keep_undefined); for (auto Arg : InputArgs.filtered(STRIP_keep_section)) if (Error E = Config.KeepSection.addMatcher(NameOrPattern::create( @@ -1337,7 +1334,7 @@ if (Config.DiscardMode == DiscardType::All) { Config.StripDebug = true; - Config.KeepFileSymbols = true; + ELFConfig.KeepFileSymbols = true; } Config.DeterministicArchives = diff --git a/llvm/tools/llvm-objcopy/ELF/ELFConfig.h b/llvm/tools/llvm-objcopy/ELF/ELFConfig.h --- a/llvm/tools/llvm-objcopy/ELF/ELFConfig.h +++ b/llvm/tools/llvm-objcopy/ELF/ELFConfig.h @@ -20,6 +20,16 @@ // ELF specific configuration for copying/stripping a single file. struct ELFConfig { uint8_t NewSymbolVisibility = (uint8_t)ELF::STV_DEFAULT; + + // ELF entry point address expression. The input parameter is an entry point + // address in the input ELF file. The entry address in the output file is + // calculated with EntryExpr(input_address), when either --set-start or + // --change-start is used. + std::function EntryExpr; + + bool AllowBrokenLinks = false; + bool KeepFileSymbols = false; + bool LocalizeHidden = false; }; } // namespace objcopy diff --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp --- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp +++ b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp @@ -233,7 +233,8 @@ Sym.Type != STT_SECTION; } -static Error updateAndRemoveSymbols(const CommonConfig &Config, Object &Obj) { +static Error updateAndRemoveSymbols(const CommonConfig &Config, + const ELFConfig &ELFConfig, Object &Obj) { // TODO: update or remove symbols only if there is an option that affects // them. if (!Obj.SymbolTable) @@ -243,7 +244,7 @@ // Common and undefined symbols don't make sense as local symbols, and can // even cause crashes if we localize those, so skip them. if (!Sym.isCommon() && Sym.getShndx() != SHN_UNDEF && - ((Config.LocalizeHidden && + ((ELFConfig.LocalizeHidden && (Sym.Visibility == STV_HIDDEN || Sym.Visibility == STV_INTERNAL)) || Config.SymbolsToLocalize.matches(Sym.Name))) Sym.Binding = STB_LOCAL; @@ -293,7 +294,7 @@ auto RemoveSymbolsPred = [&](const Symbol &Sym) { if (Config.SymbolsToKeep.matches(Sym.Name) || - (Config.KeepFileSymbols && Sym.Type == STT_FILE)) + (ELFConfig.KeepFileSymbols && Sym.Type == STT_FILE)) return false; if ((Config.DiscardMode == DiscardType::All || @@ -328,7 +329,8 @@ return Obj.removeSymbols(RemoveSymbolsPred); } -static Error replaceAndRemoveSections(const CommonConfig &Config, Object &Obj) { +static Error replaceAndRemoveSections(const CommonConfig &Config, + const ELFConfig &ELFConfig, Object &Obj) { SectionPred RemovePred = [](const SectionBase &) { return false; }; // Removes: @@ -454,7 +456,7 @@ // and at least one of those symbols is present // (equivalently, the updated symbol table is not empty) // the symbol table and the string table should not be removed. - if ((!Config.SymbolsToKeep.empty() || Config.KeepFileSymbols) && + if ((!Config.SymbolsToKeep.empty() || ELFConfig.KeepFileSymbols) && Obj.SymbolTable && !Obj.SymbolTable->empty()) { RemovePred = [&Obj, RemovePred](const SectionBase &Sec) { if (&Sec == Obj.SymbolTable || &Sec == Obj.SymbolTable->getStrTab()) @@ -463,7 +465,7 @@ }; } - if (Error E = Obj.removeSections(Config.AllowBrokenLinks, RemovePred)) + if (Error E = Obj.removeSections(ELFConfig.AllowBrokenLinks, RemovePred)) return E; if (Config.CompressionType != DebugCompressionType::None) { @@ -562,7 +564,7 @@ if (!Config.SplitDWO.empty() && Config.ExtractDWO) { return Obj.removeSections( - Config.AllowBrokenLinks, + ELFConfig.AllowBrokenLinks, [&Obj](const SectionBase &Sec) { return onlyKeepDWOPred(Obj, Sec); }); } @@ -579,10 +581,10 @@ // remove the relocation sections before removing the symbols. That allows // us to avoid reporting the inappropriate errors about removing symbols // named in relocations. - if (Error E = replaceAndRemoveSections(Config, Obj)) + if (Error E = replaceAndRemoveSections(Config, ELFConfig, Obj)) return E; - if (Error E = updateAndRemoveSymbols(Config, Obj)) + if (Error E = updateAndRemoveSymbols(Config, ELFConfig, Obj)) return E; if (!Config.SectionsToRename.empty()) { @@ -697,8 +699,8 @@ } } - if (Config.EntryExpr) - Obj.Entry = Config.EntryExpr(Obj.Entry); + if (ELFConfig.EntryExpr) + Obj.Entry = ELFConfig.EntryExpr(Obj.Entry); return Error::success(); } diff --git a/llvm/tools/llvm-objcopy/MachO/MachOConfig.h b/llvm/tools/llvm-objcopy/MachO/MachOConfig.h --- a/llvm/tools/llvm-objcopy/MachO/MachOConfig.h +++ b/llvm/tools/llvm-objcopy/MachO/MachOConfig.h @@ -9,11 +9,33 @@ #ifndef LLVM_TOOLS_LLVM_OBJCOPY_MACHO_MACHOCONFIG_H #define LLVM_TOOLS_LLVM_OBJCOPY_MACHO_MACHOCONFIG_H +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/StringRef.h" +#include + namespace llvm { namespace objcopy { // Mach-O specific configuration for copying/stripping a single file. -struct MachOConfig {}; +struct MachOConfig { + // Repeated options + std::vector RPathToAdd; + std::vector RPathToPrepend; + DenseMap RPathsToUpdate; + DenseMap InstallNamesToUpdate; + DenseSet RPathsToRemove; + + // install-name-tool's id option + Optional SharedLibId; + + // Boolean options + bool StripSwiftSymbols = false; + bool KeepUndefined = false; + + // install-name-tool's --delete_all_rpaths + bool RemoveAllRpaths = false; +}; } // namespace objcopy } // namespace llvm diff --git a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.h b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.h --- a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.h +++ b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.h @@ -24,7 +24,8 @@ class MultiFormatConfig; namespace macho { -Error executeObjcopyOnBinary(const CommonConfig &Config, const MachOConfig &, +Error executeObjcopyOnBinary(const CommonConfig &Config, + const MachOConfig &MachOConfig, object::MachOObjectFile &In, raw_ostream &Out); Error executeObjcopyOnMachOUniversalBinary( diff --git a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp --- a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp +++ b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp @@ -9,6 +9,7 @@ #include "MachOObjcopy.h" #include "../llvm-objcopy.h" #include "CommonConfig.h" +#include "MachO/MachOConfig.h" #include "MachOReader.h" #include "MachOWriter.h" #include "MultiFormatConfig.h" @@ -87,17 +88,20 @@ (*ISE.Symbol)->Referenced = true; } -static void updateAndRemoveSymbols(const CommonConfig &Config, Object &Obj) { +static void updateAndRemoveSymbols(const CommonConfig &Config, + const MachOConfig &MachOConfig, + Object &Obj) { for (SymbolEntry &Sym : Obj.SymTable) { auto I = Config.SymbolsToRename.find(Sym.Name); if (I != Config.SymbolsToRename.end()) Sym.Name = std::string(I->getValue()); } - auto RemovePred = [Config, &Obj](const std::unique_ptr &N) { + auto RemovePred = [Config, MachOConfig, + &Obj](const std::unique_ptr &N) { if (N->Referenced) return false; - if (Config.KeepUndefined && N->isUndefinedSymbol()) + if (MachOConfig.KeepUndefined && N->isUndefinedSymbol()) return false; if (N->n_desc & MachO::REFERENCED_DYNAMICALLY) return false; @@ -106,8 +110,9 @@ if (Config.DiscardMode == DiscardType::All && !(N->n_type & MachO::N_EXT)) return true; // This behavior is consistent with cctools' strip. - if (Config.StripSwiftSymbols && (Obj.Header.Flags & MachO::MH_DYLDLINK) && - Obj.SwiftVersion && *Obj.SwiftVersion && N->isSwiftSymbol()) + if (MachOConfig.StripSwiftSymbols && + (Obj.Header.Flags & MachO::MH_DYLDLINK) && Obj.SwiftVersion && + *Obj.SwiftVersion && N->isSwiftSymbol()) return true; return false; }; @@ -139,17 +144,17 @@ return LC; } -static Error processLoadCommands(const CommonConfig &Config, Object &Obj) { +static Error processLoadCommands(const MachOConfig &MachOConfig, Object &Obj) { // Remove RPaths. - DenseSet RPathsToRemove(Config.RPathsToRemove.begin(), - Config.RPathsToRemove.end()); + DenseSet RPathsToRemove(MachOConfig.RPathsToRemove.begin(), + MachOConfig.RPathsToRemove.end()); LoadCommandPred RemovePred = [&RPathsToRemove, - &Config](const LoadCommand &LC) { + &MachOConfig](const LoadCommand &LC) { if (LC.MachOLoadCommand.load_command_data.cmd == MachO::LC_RPATH) { // When removing all RPaths we don't need to care // about what it contains - if (Config.RemoveAllRpaths) + if (MachOConfig.RemoveAllRpaths) return true; StringRef RPath = getPayloadString(LC); @@ -166,7 +171,7 @@ // Emit an error if the Mach-O binary does not contain an rpath path name // specified in -delete_rpath. - for (StringRef RPath : Config.RPathsToRemove) { + for (StringRef RPath : MachOConfig.RPathsToRemove) { if (RPathsToRemove.count(RPath)) return createStringError(errc::invalid_argument, "no LC_RPATH load command with path: %s", @@ -182,7 +187,7 @@ } // Throw errors for invalid RPaths. - for (const auto &OldNew : Config.RPathsToUpdate) { + for (const auto &OldNew : MachOConfig.RPathsToUpdate) { StringRef Old = OldNew.getFirst(); StringRef New = OldNew.getSecond(); if (!RPaths.contains(Old)) @@ -198,14 +203,14 @@ for (LoadCommand &LC : Obj.LoadCommands) { switch (LC.MachOLoadCommand.load_command_data.cmd) { case MachO::LC_ID_DYLIB: - if (Config.SharedLibId) + if (MachOConfig.SharedLibId) updateLoadCommandPayloadString( - LC, *Config.SharedLibId); + LC, *MachOConfig.SharedLibId); break; case MachO::LC_RPATH: { StringRef RPath = getPayloadString(LC); - StringRef NewRPath = Config.RPathsToUpdate.lookup(RPath); + StringRef NewRPath = MachOConfig.RPathsToUpdate.lookup(RPath); if (!NewRPath.empty()) updateLoadCommandPayloadString(LC, NewRPath); break; @@ -217,7 +222,7 @@ case MachO::LC_LOAD_WEAK_DYLIB: StringRef InstallName = getPayloadString(LC); StringRef NewInstallName = - Config.InstallNamesToUpdate.lookup(InstallName); + MachOConfig.InstallNamesToUpdate.lookup(InstallName); if (!NewInstallName.empty()) updateLoadCommandPayloadString(LC, NewInstallName); @@ -226,7 +231,7 @@ } // Add new RPaths. - for (StringRef RPath : Config.RPathToAdd) { + for (StringRef RPath : MachOConfig.RPathToAdd) { if (RPaths.contains(RPath)) return createStringError(errc::invalid_argument, "rpath '" + RPath + @@ -235,7 +240,7 @@ Obj.LoadCommands.push_back(buildRPathLoadCommand(RPath)); } - for (StringRef RPath : Config.RPathToPrepend) { + for (StringRef RPath : MachOConfig.RPathToPrepend) { if (RPaths.contains(RPath)) return createStringError(errc::invalid_argument, "rpath '" + RPath + @@ -248,7 +253,7 @@ // Unlike appending rpaths, the indexes of subsequent load commands must // be recalculated after prepending one. - if (!Config.RPathToPrepend.empty()) + if (!MachOConfig.RPathToPrepend.empty()) Obj.updateLoadCommandIndexes(); return Error::success(); @@ -333,7 +338,8 @@ return Error::success(); } -static Error handleArgs(const CommonConfig &Config, Object &Obj) { +static Error handleArgs(const CommonConfig &Config, + const MachOConfig &MachOConfig, Object &Obj) { // Dump sections before add/remove for compatibility with GNU objcopy. for (StringRef Flag : Config.DumpSection) { StringRef SectionName; @@ -350,7 +356,7 @@ if (Config.StripAll) markSymbols(Config, Obj); - updateAndRemoveSymbols(Config, Obj); + updateAndRemoveSymbols(Config, MachOConfig, Obj); if (Config.StripAll) for (LoadCommand &LC : Obj.LoadCommands) @@ -367,14 +373,14 @@ return E; } - if (Error E = processLoadCommands(Config, Obj)) + if (Error E = processLoadCommands(MachOConfig, Obj)) return E; return Error::success(); } Error objcopy::macho::executeObjcopyOnBinary(const CommonConfig &Config, - const MachOConfig &, + const MachOConfig &MachOConfig, object::MachOObjectFile &In, raw_ostream &Out) { MachOReader Reader(In); @@ -382,7 +388,7 @@ if (!O) return createFileError(Config.InputFilename, O.takeError()); - if (Error E = handleArgs(Config, **O)) + if (Error E = handleArgs(Config, MachOConfig, **O)) return createFileError(Config.InputFilename, std::move(E)); // Page size used for alignment of segment sizes in Mach-O executables and