[llvm] 50467c0 - [llvm-objcopy][NFC] Refactor CopyConfig structure - categorize options.
Alexey Lapshin via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 8 09:17:49 PDT 2021
Author: Alexey Lapshin
Date: 2021-09-08T19:16:38+03:00
New Revision: 50467c0852d0f1b46829c45b597c1f5b2dd29893
URL: https://github.com/llvm/llvm-project/commit/50467c0852d0f1b46829c45b597c1f5b2dd29893
DIFF: https://github.com/llvm/llvm-project/commit/50467c0852d0f1b46829c45b597c1f5b2dd29893.diff
LOG: [llvm-objcopy][NFC] Refactor CopyConfig structure - categorize options.
This patch continues refactoring done by D99055. It puts format specific
options into the correponding CopyConfig structures.
Differential Revision: https://reviews.llvm.org/D102277
Added:
Modified:
llvm/tools/llvm-objcopy/CommonConfig.h
llvm/tools/llvm-objcopy/ConfigManager.cpp
llvm/tools/llvm-objcopy/ELF/ELFConfig.h
llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
llvm/tools/llvm-objcopy/MachO/MachOConfig.h
llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
llvm/tools/llvm-objcopy/MachO/MachOObjcopy.h
Removed:
################################################################################
diff --git a/llvm/tools/llvm-objcopy/CommonConfig.h b/llvm/tools/llvm-objcopy/CommonConfig.h
index 131ce5c591146..2a0e1930bd022 100644
--- a/llvm/tools/llvm-objcopy/CommonConfig.h
+++ b/llvm/tools/llvm-objcopy/CommonConfig.h
@@ -210,14 +210,6 @@ struct CommonConfig {
// Repeated options
std::vector<StringRef> AddSection;
std::vector<StringRef> DumpSection;
- std::vector<StringRef> RPathToAdd;
- std::vector<StringRef> RPathToPrepend;
- DenseMap<StringRef, StringRef> RPathsToUpdate;
- DenseMap<StringRef, StringRef> InstallNamesToUpdate;
- DenseSet<StringRef> RPathsToRemove;
-
- // install-name-tool's id option
- Optional<StringRef> SharedLibId;
// Section matchers
NameMatcher KeepSection;
@@ -239,23 +231,13 @@ struct CommonConfig {
StringMap<SectionFlagsUpdate> SetSectionFlags;
StringMap<StringRef> 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<uint64_t(uint64_t)> EntryExpr;
-
// Symbol info specified by --add-symbol option.
std::vector<NewSymbolInfo> 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 @@ struct CommonConfig {
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
index 9f7d06b99418d..2cd82ffec55e2 100644
--- a/llvm/tools/llvm-objcopy/ConfigManager.cpp
+++ b/llvm/tools/llvm-objcopy/ConfigManager.cpp
@@ -559,27 +559,21 @@ static Expected<NewSymbolInfo> parseNewSymbolInfo(StringRef FlagValue) {
}
Expected<const ELFConfig &> 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<const COFFConfig &> 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<const COFFConfig &> ConfigManager::getCOFFConfig() const {
}
Expected<const MachOConfig &> 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 @@ Expected<const WasmConfig &> ConfigManager::getWasmConfig() const {
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 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
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 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
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 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
? 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 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
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 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
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<int64_t>(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 @@ objcopy::parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr) {
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 @@ objcopy::parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr) {
}
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 @@ objcopy::parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr) {
// Cannot specify duplicate -rpath entries
auto It1 = find_if(
- Config.RPathsToUpdate,
+ MachOConfig.RPathsToUpdate,
[&Match](const DenseMap<StringRef, StringRef>::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<StringRef, 2> Positional;
@@ -1281,6 +1276,8 @@ objcopy::parseStripOptions(ArrayRef<const char *> RawArgsArr,
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 @@ objcopy::parseStripOptions(ArrayRef<const char *> RawArgsArr,
: 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 @@ objcopy::parseStripOptions(ArrayRef<const char *> RawArgsArr,
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 @@ objcopy::parseStripOptions(ArrayRef<const char *> RawArgsArr,
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
index 42d407da17fff..229a8d61fb83c 100644
--- a/llvm/tools/llvm-objcopy/ELF/ELFConfig.h
+++ b/llvm/tools/llvm-objcopy/ELF/ELFConfig.h
@@ -20,6 +20,16 @@ namespace objcopy {
// 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<uint64_t(uint64_t)> 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
index 946191f8764d9..2ff8dcc88731e 100644
--- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
+++ b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
@@ -233,7 +233,8 @@ static bool isUnneededSymbol(const Symbol &Sym) {
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 @@ static Error updateAndRemoveSymbols(const CommonConfig &Config, Object &Obj) {
// 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 @@ static Error updateAndRemoveSymbols(const CommonConfig &Config, Object &Obj) {
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 @@ static Error updateAndRemoveSymbols(const CommonConfig &Config, Object &Obj) {
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 @@ static Error replaceAndRemoveSections(const CommonConfig &Config, Object &Obj) {
// 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 @@ static Error replaceAndRemoveSections(const CommonConfig &Config, Object &Obj) {
};
}
- 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 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
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 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
// 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 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
}
}
- 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
index 7c5dbfde19a0b..93f9facfcf0bb 100644
--- 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 <vector>
+
namespace llvm {
namespace objcopy {
// Mach-O specific configuration for copying/stripping a single file.
-struct MachOConfig {};
+struct MachOConfig {
+ // Repeated options
+ std::vector<StringRef> RPathToAdd;
+ std::vector<StringRef> RPathToPrepend;
+ DenseMap<StringRef, StringRef> RPathsToUpdate;
+ DenseMap<StringRef, StringRef> InstallNamesToUpdate;
+ DenseSet<StringRef> RPathsToRemove;
+
+ // install-name-tool's id option
+ Optional<StringRef> 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.cpp b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
index 823306916bbe5..1b05779e03d03 100644
--- 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 @@ static void markSymbols(const CommonConfig &, Object &Obj) {
(*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<SymbolEntry> &N) {
+ auto RemovePred = [Config, MachOConfig,
+ &Obj](const std::unique_ptr<SymbolEntry> &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 @@ static void updateAndRemoveSymbols(const CommonConfig &Config, Object &Obj) {
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 @@ static LoadCommand buildRPathLoadCommand(StringRef Path) {
return LC;
}
-static Error processLoadCommands(const CommonConfig &Config, Object &Obj) {
+static Error processLoadCommands(const MachOConfig &MachOConfig, Object &Obj) {
// Remove RPaths.
- DenseSet<StringRef> RPathsToRemove(Config.RPathsToRemove.begin(),
- Config.RPathsToRemove.end());
+ DenseSet<StringRef> 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 @@ static Error processLoadCommands(const CommonConfig &Config, Object &Obj) {
// 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 @@ static Error processLoadCommands(const CommonConfig &Config, Object &Obj) {
}
// 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 @@ static Error processLoadCommands(const CommonConfig &Config, Object &Obj) {
for (LoadCommand &LC : Obj.LoadCommands) {
switch (LC.MachOLoadCommand.load_command_data.cmd) {
case MachO::LC_ID_DYLIB:
- if (Config.SharedLibId)
+ if (MachOConfig.SharedLibId)
updateLoadCommandPayloadString<MachO::dylib_command>(
- 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<MachO::rpath_command>(LC, NewRPath);
break;
@@ -217,7 +222,7 @@ static Error processLoadCommands(const CommonConfig &Config, Object &Obj) {
case MachO::LC_LOAD_WEAK_DYLIB:
StringRef InstallName = getPayloadString(LC);
StringRef NewInstallName =
- Config.InstallNamesToUpdate.lookup(InstallName);
+ MachOConfig.InstallNamesToUpdate.lookup(InstallName);
if (!NewInstallName.empty())
updateLoadCommandPayloadString<MachO::dylib_command>(LC,
NewInstallName);
@@ -226,7 +231,7 @@ static Error processLoadCommands(const CommonConfig &Config, Object &Obj) {
}
// 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 @@ static Error processLoadCommands(const CommonConfig &Config, Object &Obj) {
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 @@ static Error processLoadCommands(const CommonConfig &Config, Object &Obj) {
// 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 @@ static Error isValidMachOCannonicalName(StringRef Name) {
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 @@ static Error handleArgs(const CommonConfig &Config, Object &Obj) {
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 @@ static Error handleArgs(const CommonConfig &Config, Object &Obj) {
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 @@ Error objcopy::macho::executeObjcopyOnBinary(const CommonConfig &Config,
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
diff --git a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.h b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.h
index e30940a8d6eba..d03eee9d5fdbb 100644
--- a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.h
+++ b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.h
@@ -24,7 +24,8 @@ struct MachOConfig;
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(
More information about the llvm-commits
mailing list