[llvm-objcopy] Refactor ELF-specific config out to ELFCopyConfig. NFC.
Summary:
This patch splits the command-line parsing into two phases:
First, parse cross-platform options and leave ELF-specific options unparsed.
Second, in the ELF implementation, parse ELF-specific options and construct ELFCopyConfig.
Reviewers: espindola, alexshap, rupprecht, jhenderson, jakehehrlich, MaskRay
Reviewed By: alexshap, jhenderson, jakehehrlich, MaskRay
Subscribers: mgorny, emaste, arichardson, jakehehrlich, MaskRay, abrachet, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D67139
llvm-svn: 372712
diff --git a/llvm/tools/llvm-objcopy/CopyConfig.cpp b/llvm/tools/llvm-objcopy/CopyConfig.cpp
index a84114e..1425321 100644
--- a/llvm/tools/llvm-objcopy/CopyConfig.cpp
+++ b/llvm/tools/llvm-objcopy/CopyConfig.cpp
@@ -177,87 +177,6 @@
return SFU;
}
-static Expected<NewSymbolInfo> parseNewSymbolInfo(StringRef FlagValue,
- uint8_t DefaultVisibility) {
- // Parse value given with --add-symbol option and create the
- // new symbol if possible. The value format for --add-symbol is:
- //
- // <name>=[<section>:]<value>[,<flags>]
- //
- // where:
- // <name> - symbol name, can be empty string
- // <section> - optional section name. If not given ABS symbol is created
- // <value> - symbol value, can be decimal or hexadecimal number prefixed
- // with 0x.
- // <flags> - optional flags affecting symbol type, binding or visibility:
- // The following are currently supported:
- //
- // global, local, weak, default, hidden, file, section, object,
- // indirect-function.
- //
- // The following flags are ignored and provided for GNU
- // compatibility only:
- //
- // warning, debug, constructor, indirect, synthetic,
- // unique-object, before=<symbol>.
- NewSymbolInfo SI;
- StringRef Value;
- std::tie(SI.SymbolName, Value) = FlagValue.split('=');
- if (Value.empty())
- return createStringError(
- errc::invalid_argument,
- "bad format for --add-symbol, missing '=' after '%s'",
- SI.SymbolName.str().c_str());
-
- if (Value.contains(':')) {
- std::tie(SI.SectionName, Value) = Value.split(':');
- if (SI.SectionName.empty() || Value.empty())
- return createStringError(
- errc::invalid_argument,
- "bad format for --add-symbol, missing section name or symbol value");
- }
-
- SmallVector<StringRef, 6> Flags;
- Value.split(Flags, ',');
- if (Flags[0].getAsInteger(0, SI.Value))
- return createStringError(errc::invalid_argument, "bad symbol value: '%s'",
- Flags[0].str().c_str());
-
- SI.Visibility = DefaultVisibility;
-
- using Functor = std::function<void(void)>;
- SmallVector<StringRef, 6> UnsupportedFlags;
- for (size_t I = 1, NumFlags = Flags.size(); I < NumFlags; ++I)
- static_cast<Functor>(
- StringSwitch<Functor>(Flags[I])
- .CaseLower("global", [&SI] { SI.Bind = ELF::STB_GLOBAL; })
- .CaseLower("local", [&SI] { SI.Bind = ELF::STB_LOCAL; })
- .CaseLower("weak", [&SI] { SI.Bind = ELF::STB_WEAK; })
- .CaseLower("default", [&SI] { SI.Visibility = ELF::STV_DEFAULT; })
- .CaseLower("hidden", [&SI] { SI.Visibility = ELF::STV_HIDDEN; })
- .CaseLower("protected", [&SI] { SI.Visibility = ELF::STV_PROTECTED; })
- .CaseLower("file", [&SI] { SI.Type = ELF::STT_FILE; })
- .CaseLower("section", [&SI] { SI.Type = ELF::STT_SECTION; })
- .CaseLower("object", [&SI] { SI.Type = ELF::STT_OBJECT; })
- .CaseLower("function", [&SI] { SI.Type = ELF::STT_FUNC; })
- .CaseLower("indirect-function",
- [&SI] { SI.Type = ELF::STT_GNU_IFUNC; })
- .CaseLower("debug", [] {})
- .CaseLower("constructor", [] {})
- .CaseLower("warning", [] {})
- .CaseLower("indirect", [] {})
- .CaseLower("synthetic", [] {})
- .CaseLower("unique-object", [] {})
- .StartsWithLower("before", [] {})
- .Default([&] { UnsupportedFlags.push_back(Flags[I]); }))();
- if (!UnsupportedFlags.empty())
- return createStringError(errc::invalid_argument,
- "unsupported flag%s for --add-symbol: '%s'",
- UnsupportedFlags.size() > 1 ? "s" : "",
- join(UnsupportedFlags, "', '").c_str());
- return SI;
-}
-
struct TargetInfo {
FileFormat Format;
MachineInfo Machine;
@@ -467,20 +386,9 @@
.Case("ihex", FileFormat::IHex)
.Default(FileFormat::Unspecified);
- if (opt::Arg *A = InputArgs.getLastArg(OBJCOPY_new_symbol_visibility)) {
- const uint8_t Invalid = 0xff;
- Config.NewSymbolVisibility = StringSwitch<uint8_t>(A->getValue())
- .Case("default", ELF::STV_DEFAULT)
- .Case("hidden", ELF::STV_HIDDEN)
- .Case("internal", ELF::STV_INTERNAL)
- .Case("protected", ELF::STV_PROTECTED)
- .Default(Invalid);
-
- if (Config.NewSymbolVisibility == Invalid)
- return createStringError(
- errc::invalid_argument, "'%s' is not a valid symbol visibility",
- InputArgs.getLastArgValue(OBJCOPY_new_symbol_visibility).str().c_str());
- }
+ if (opt::Arg *A = InputArgs.getLastArg(OBJCOPY_new_symbol_visibility))
+ Config.NewSymbolVisibility =
+ InputArgs.getLastArgValue(OBJCOPY_new_symbol_visibility);
Config.OutputFormat = StringSwitch<FileFormat>(OutputFormat)
.Case("binary", FileFormat::Binary)
@@ -694,14 +602,8 @@
if (Error E = addSymbolsFromFile(Config.SymbolsToKeep, DC.Alloc,
Arg->getValue(), UseRegex))
return std::move(E);
- for (auto Arg : InputArgs.filtered(OBJCOPY_add_symbol)) {
- Expected<NewSymbolInfo> NSI = parseNewSymbolInfo(
- Arg->getValue(),
- Config.NewSymbolVisibility.getValueOr((uint8_t)ELF::STV_DEFAULT));
- if (!NSI)
- return NSI.takeError();
- Config.SymbolsToAdd.push_back(*NSI);
- }
+ for (auto Arg : InputArgs.filtered(OBJCOPY_add_symbol))
+ Config.SymbolsToAdd.push_back(Arg->getValue());
Config.AllowBrokenLinks = InputArgs.hasArg(OBJCOPY_allow_broken_links);