[llvm] 081c625 - [llvm-objcopy] Refactor CopyConfig structure.
Alexey Lapshin via llvm-commits
llvm-commits at lists.llvm.org
Thu May 20 03:17:33 PDT 2021
Author: Alexey Lapshin
Date: 2021-05-20T13:14:51+03:00
New Revision: 081c62501e4f0aad4ab31de52f871f98403073ad
URL: https://github.com/llvm/llvm-project/commit/081c62501e4f0aad4ab31de52f871f98403073ad
DIFF: https://github.com/llvm/llvm-project/commit/081c62501e4f0aad4ab31de52f871f98403073ad.diff
LOG: [llvm-objcopy] Refactor CopyConfig structure.
This patch prepares llvm-objcopy to move its implementation
into a separate library. To make it possible it is necessary
to minimize internal dependencies.
Differential Revision: https://reviews.llvm.org/D99055
Added:
llvm/tools/llvm-objcopy/COFF/COFFConfig.h
llvm/tools/llvm-objcopy/CommonConfig.h
llvm/tools/llvm-objcopy/ConfigManager.cpp
llvm/tools/llvm-objcopy/ConfigManager.h
llvm/tools/llvm-objcopy/MachO/MachOConfig.h
llvm/tools/llvm-objcopy/MultiFormatConfig.h
llvm/tools/llvm-objcopy/wasm/WasmConfig.h
Modified:
llvm/tools/llvm-objcopy/CMakeLists.txt
llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
llvm/tools/llvm-objcopy/COFF/COFFObjcopy.h
llvm/tools/llvm-objcopy/ELF/ELFConfig.h
llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
llvm/tools/llvm-objcopy/ELF/ELFObjcopy.h
llvm/tools/llvm-objcopy/ELF/Object.h
llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
llvm/tools/llvm-objcopy/MachO/MachOObjcopy.h
llvm/tools/llvm-objcopy/llvm-objcopy.cpp
llvm/tools/llvm-objcopy/llvm-objcopy.h
llvm/tools/llvm-objcopy/wasm/WasmObjcopy.cpp
llvm/tools/llvm-objcopy/wasm/WasmObjcopy.h
Removed:
llvm/tools/llvm-objcopy/CopyConfig.cpp
llvm/tools/llvm-objcopy/CopyConfig.h
llvm/tools/llvm-objcopy/ELF/ELFConfig.cpp
################################################################################
diff --git a/llvm/tools/llvm-objcopy/CMakeLists.txt b/llvm/tools/llvm-objcopy/CMakeLists.txt
index 20e1e40dcff2c..d14d2135f5db7 100644
--- a/llvm/tools/llvm-objcopy/CMakeLists.txt
+++ b/llvm/tools/llvm-objcopy/CMakeLists.txt
@@ -22,13 +22,12 @@ tablegen(LLVM StripOpts.inc -gen-opt-parser-defs)
add_public_tablegen_target(StripOptsTableGen)
add_llvm_tool(llvm-objcopy
- CopyConfig.cpp
+ ConfigManager.cpp
llvm-objcopy.cpp
COFF/COFFObjcopy.cpp
COFF/Object.cpp
COFF/Reader.cpp
COFF/Writer.cpp
- ELF/ELFConfig.cpp
ELF/ELFObjcopy.cpp
ELF/Object.cpp
MachO/MachOObjcopy.cpp
diff --git a/llvm/tools/llvm-objcopy/COFF/COFFConfig.h b/llvm/tools/llvm-objcopy/COFF/COFFConfig.h
new file mode 100644
index 0000000000000..3897ff47724bb
--- /dev/null
+++ b/llvm/tools/llvm-objcopy/COFF/COFFConfig.h
@@ -0,0 +1,21 @@
+//===- COFFConfig.h ---------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_OBJCOPY_COFF_COFFCONFIG_H
+#define LLVM_TOOLS_LLVM_OBJCOPY_COFF_COFFCONFIG_H
+
+namespace llvm {
+namespace objcopy {
+
+// Coff specific configuration for copying/stripping a single file.
+struct COFFConfig {};
+
+} // namespace objcopy
+} // namespace llvm
+
+#endif // LLVM_TOOLS_LLVM_OBJCOPY_COFF_COFFCONFIG_H
diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
index de76fee526675..e50ac2e12e2f5 100644
--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
@@ -7,7 +7,8 @@
//===----------------------------------------------------------------------===//
#include "COFFObjcopy.h"
-#include "CopyConfig.h"
+#include "COFFConfig.h"
+#include "CommonConfig.h"
#include "Object.h"
#include "Reader.h"
#include "Writer.h"
@@ -130,7 +131,7 @@ static void setSectionFlags(Section &Sec, SectionFlag AllFlags) {
Sec.Header.Characteristics = NewCharacteristics;
}
-static Error handleArgs(const CopyConfig &Config, Object &Obj) {
+static Error handleArgs(const CommonConfig &Config, Object &Obj) {
// Perform the actual section removals.
Obj.removeSections([&Config](const Section &Sec) {
// Contrary to --only-keep-debug, --only-section fully removes sections that
@@ -248,28 +249,11 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
if (Error E = addGnuDebugLink(Obj, Config.AddGnuDebugLink))
return E;
- if (Config.AllowBrokenLinks || !Config.SplitDWO.empty() ||
- !Config.SymbolsPrefix.empty() || !Config.AllocSectionsPrefix.empty() ||
- !Config.DumpSection.empty() || !Config.KeepSection.empty() ||
- Config.NewSymbolVisibility || !Config.SymbolsToGlobalize.empty() ||
- !Config.SymbolsToKeep.empty() || !Config.SymbolsToLocalize.empty() ||
- !Config.SymbolsToWeaken.empty() || !Config.SymbolsToKeepGlobal.empty() ||
- !Config.SectionsToRename.empty() || !Config.SetSectionAlignment.empty() ||
- Config.ExtractDWO || Config.LocalizeHidden || Config.PreserveDates ||
- Config.StripDWO || Config.StripNonAlloc || Config.StripSections ||
- Config.StripSwiftSymbols || Config.KeepUndefined || Config.Weaken ||
- Config.DecompressDebugSections ||
- Config.DiscardMode == DiscardType::Locals ||
- !Config.SymbolsToAdd.empty() || Config.EntryExpr) {
- return createStringError(llvm::errc::invalid_argument,
- "option not supported by llvm-objcopy for COFF");
- }
-
return Error::success();
}
-Error executeObjcopyOnBinary(const CopyConfig &Config, COFFObjectFile &In,
- raw_ostream &Out) {
+Error executeObjcopyOnBinary(const CommonConfig &Config, const COFFConfig &,
+ COFFObjectFile &In, raw_ostream &Out) {
COFFReader Reader(In);
Expected<std::unique_ptr<Object>> ObjOrErr = Reader.create();
if (!ObjOrErr)
diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.h b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.h
index 64f65dbb7b093..2c7ccd34653d7 100644
--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.h
+++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.h
@@ -18,10 +18,12 @@ class COFFObjectFile;
} // end namespace object
namespace objcopy {
-struct CopyConfig;
+struct CommonConfig;
+struct COFFConfig;
namespace coff {
-Error executeObjcopyOnBinary(const CopyConfig &Config,
+
+Error executeObjcopyOnBinary(const CommonConfig &Config, const COFFConfig &,
object::COFFObjectFile &In, raw_ostream &Out);
} // end namespace coff
diff --git a/llvm/tools/llvm-objcopy/CopyConfig.h b/llvm/tools/llvm-objcopy/CommonConfig.h
similarity index 72%
rename from llvm/tools/llvm-objcopy/CopyConfig.h
rename to llvm/tools/llvm-objcopy/CommonConfig.h
index 1b99e24137dd6..d08765cbc5458 100644
--- a/llvm/tools/llvm-objcopy/CopyConfig.h
+++ b/llvm/tools/llvm-objcopy/CommonConfig.h
@@ -1,4 +1,4 @@
-//===- CopyConfig.h -------------------------------------------------------===//
+//===- CommonConfig.h -------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,20 +6,16 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TOOLS_LLVM_OBJCOPY_COPY_CONFIG_H
-#define LLVM_TOOLS_LLVM_OBJCOPY_COPY_CONFIG_H
+#ifndef LLVM_TOOLS_LLVM_OBJCOPY_COMMONCONFIG_H
+#define LLVM_TOOLS_LLVM_OBJCOPY_COMMONCONFIG_H
-#include "ELF/ELFConfig.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/ELFTypes.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Error.h"
#include "llvm/Support/GlobPattern.h"
#include "llvm/Support/Regex.h"
// Necessary for llvm::DebugCompressionType::None
@@ -99,7 +95,7 @@ enum class MatchStyle {
class NameOrPattern {
StringRef Name;
- // Regex is shared between multiple CopyConfig instances.
+ // Regex is shared between multiple CommonConfig instances.
std::shared_ptr<Regex> R;
std::shared_ptr<GlobPattern> G;
bool IsPositiveMatch = true;
@@ -146,10 +142,7 @@ class NameMatcher {
};
// Configuration for copying/stripping a single file.
-struct CopyConfig {
- // Format-specific options to be initialized lazily when needed.
- Optional<elf::ELFCopyConfig> ELF;
-
+struct CommonConfig {
// Main input/output options
StringRef InputFilename;
FileFormat InputFormat = FileFormat::Unspecified;
@@ -168,12 +161,10 @@ struct CopyConfig {
StringRef SymbolsPrefix;
StringRef AllocSectionsPrefix;
DiscardType DiscardMode = DiscardType::None;
- Optional<StringRef> NewSymbolVisibility;
// Repeated options
std::vector<StringRef> AddSection;
std::vector<StringRef> DumpSection;
- std::vector<StringRef> SymbolsToAdd;
std::vector<StringRef> RPathToAdd;
std::vector<StringRef> RPathToPrepend;
DenseMap<StringRef, StringRef> RPathsToUpdate;
@@ -233,55 +224,9 @@ struct CopyConfig {
bool RemoveAllRpaths = false;
DebugCompressionType CompressionType = DebugCompressionType::None;
-
- // parseELFConfig performs ELF-specific command-line parsing. Fills `ELF` on
- // success or returns an Error otherwise.
- Error parseELFConfig() {
- if (!ELF) {
- Expected<elf::ELFCopyConfig> ELFConfig = elf::parseConfig(*this);
- if (!ELFConfig)
- return ELFConfig.takeError();
- ELF = *ELFConfig;
- }
- return Error::success();
- }
};
-// Configuration for the overall invocation of this tool. When invoked as
-// objcopy, will always contain exactly one CopyConfig. When invoked as strip,
-// will contain one or more CopyConfigs.
-struct DriverConfig {
- SmallVector<CopyConfig, 1> CopyConfigs;
- BumpPtrAllocator Alloc;
-};
-
-// ParseObjcopyOptions returns the config and sets the input arguments. If a
-// help flag is set then ParseObjcopyOptions will print the help messege and
-// exit. ErrorCallback is used to handle recoverable errors. An Error returned
-// by the callback aborts the parsing and is then returned by this function.
-Expected<DriverConfig>
-parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
- llvm::function_ref<Error(Error)> ErrorCallback);
-
-// ParseInstallNameToolOptions returns the config and sets the input arguments.
-// If a help flag is set then ParseInstallNameToolOptions will print the help
-// messege and exit.
-Expected<DriverConfig>
-parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr);
-
-// ParseBitcodeStripOptions returns the config and sets the input arguments.
-// If a help flag is set then ParseBitcodeStripOptions will print the help
-// messege and exit.
-Expected<DriverConfig> parseBitcodeStripOptions(ArrayRef<const char *> ArgsArr);
-
-// ParseStripOptions returns the config and sets the input arguments. If a
-// help flag is set then ParseStripOptions will print the help messege and
-// exit. ErrorCallback is used to handle recoverable errors. An Error returned
-// by the callback aborts the parsing and is then returned by this function.
-Expected<DriverConfig>
-parseStripOptions(ArrayRef<const char *> ArgsArr,
- llvm::function_ref<Error(Error)> ErrorCallback);
} // namespace objcopy
} // namespace llvm
-#endif
+#endif // LLVM_TOOLS_LLVM_OBJCOPY_COMMONCONFIG_H
diff --git a/llvm/tools/llvm-objcopy/CopyConfig.cpp b/llvm/tools/llvm-objcopy/ConfigManager.cpp
similarity index 84%
rename from llvm/tools/llvm-objcopy/CopyConfig.cpp
rename to llvm/tools/llvm-objcopy/ConfigManager.cpp
index ce68101f0c859..b4bc6b1b0b57e 100644
--- a/llvm/tools/llvm-objcopy/CopyConfig.cpp
+++ b/llvm/tools/llvm-objcopy/ConfigManager.cpp
@@ -1,4 +1,4 @@
-//===- CopyConfig.cpp -----------------------------------------------------===//
+//===- ConfigManager.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,8 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "CopyConfig.h"
-
+#include "ConfigManager.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
@@ -18,6 +17,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/StringSaver.h"
#include <memory>
@@ -466,6 +466,190 @@ static void printHelp(const opt::OptTable &OptTable, raw_ostream &OS,
OS << "\nPass @FILE as argument to read options from FILE.\n";
}
+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;
+}
+
+Expected<const ELFConfig &> ConfigManager::getELFConfig() const {
+ if (!ELF) {
+ if (Common.StripSwiftSymbols || Common.KeepUndefined)
+ return createStringError(llvm::errc::invalid_argument,
+ "option not supported by llvm-objcopy for ELF");
+
+ // Parse lazy options.
+ ELFConfig ResConfig;
+
+ if (NewSymbolVisibility) {
+ const uint8_t Invalid = 0xff;
+ ResConfig.NewSymbolVisibility =
+ StringSwitch<uint8_t>(*NewSymbolVisibility)
+ .Case("default", ELF::STV_DEFAULT)
+ .Case("hidden", ELF::STV_HIDDEN)
+ .Case("internal", ELF::STV_INTERNAL)
+ .Case("protected", ELF::STV_PROTECTED)
+ .Default(Invalid);
+
+ if (ResConfig.NewSymbolVisibility == Invalid)
+ return createStringError(errc::invalid_argument,
+ "'%s' is not a valid symbol visibility",
+ NewSymbolVisibility->str().c_str());
+ }
+
+ for (StringRef Arg : SymbolsToAdd) {
+ Expected<NewSymbolInfo> NSI = parseNewSymbolInfo(
+ Arg,
+ ResConfig.NewSymbolVisibility.getValueOr((uint8_t)ELF::STV_DEFAULT));
+ if (!NSI)
+ return NSI.takeError();
+ ResConfig.SymbolsToAdd.push_back(*NSI);
+ }
+
+ ELF = std::move(ResConfig);
+ }
+
+ 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() ||
+ NewSymbolVisibility || !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.DecompressDebugSections ||
+ Common.DiscardMode == DiscardType::Locals || !SymbolsToAdd.empty() ||
+ Common.EntryExpr) {
+ return createStringError(llvm::errc::invalid_argument,
+ "option not supported by llvm-objcopy for COFF");
+ }
+
+ return COFF;
+}
+
+Expected<const MachOConfig &> ConfigManager::getMachOConfig() const {
+ if (Common.AllowBrokenLinks || !Common.SplitDWO.empty() ||
+ !Common.SymbolsPrefix.empty() || !Common.AllocSectionsPrefix.empty() ||
+ !Common.KeepSection.empty() || NewSymbolVisibility ||
+ !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 ||
+ !SymbolsToAdd.empty() || Common.EntryExpr) {
+ return createStringError(llvm::errc::invalid_argument,
+ "option not supported by llvm-objcopy for MachO");
+ }
+
+ return MachO;
+}
+
+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 || NewSymbolVisibility ||
+ !SymbolsToAdd.empty() || !Common.RPathToAdd.empty() ||
+ !Common.OnlySection.empty() || !Common.SymbolsToGlobalize.empty() ||
+ !Common.SymbolsToKeep.empty() || !Common.SymbolsToLocalize.empty() ||
+ !Common.SymbolsToRemove.empty() ||
+ !Common.UnneededSymbolsToRemove.empty() ||
+ !Common.SymbolsToWeaken.empty() || !Common.SymbolsToKeepGlobal.empty() ||
+ !Common.SectionsToRename.empty() || !Common.SetSectionAlignment.empty() ||
+ !Common.SetSectionFlags.empty() || !Common.SymbolsToRename.empty()) {
+ return createStringError(
+ llvm::errc::invalid_argument,
+ "only add-section, dump-section, and remove-section are supported");
+ }
+
+ return Wasm;
+}
+
// ParseObjcopyOptions returns the config and sets the input arguments. If a
// help flag is set then ParseObjcopyOptions will print the help messege and
// exit.
@@ -519,7 +703,8 @@ parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
return createStringError(errc::invalid_argument,
"too many positional arguments");
- CopyConfig Config;
+ ConfigManager ConfigMgr;
+ CommonConfig &Config = ConfigMgr.Common;
Config.InputFilename = Positional[0];
Config.OutputFilename = Positional[Positional.size() == 1 ? 0 : 1];
if (InputArgs.hasArg(OBJCOPY_target) &&
@@ -559,7 +744,7 @@ parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
.Default(FileFormat::Unspecified);
if (InputArgs.hasArg(OBJCOPY_new_symbol_visibility))
- Config.NewSymbolVisibility =
+ ConfigMgr.NewSymbolVisibility =
InputArgs.getLastArgValue(OBJCOPY_new_symbol_visibility);
Config.OutputFormat = StringSwitch<FileFormat>(OutputFormat)
@@ -808,7 +993,7 @@ parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
SymbolMatchStyle, ErrorCallback))
return std::move(E);
for (auto Arg : InputArgs.filtered(OBJCOPY_add_symbol))
- Config.SymbolsToAdd.push_back(Arg->getValue());
+ ConfigMgr.SymbolsToAdd.push_back(Arg->getValue());
Config.AllowBrokenLinks = InputArgs.hasArg(OBJCOPY_allow_broken_links);
@@ -862,7 +1047,7 @@ parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
"cannot specify --extract-partition together with "
"--extract-main-partition");
- DC.CopyConfigs.push_back(std::move(Config));
+ DC.CopyConfigs.push_back(std::move(ConfigMgr));
return std::move(DC);
}
@@ -872,7 +1057,8 @@ parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
Expected<DriverConfig>
parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr) {
DriverConfig DC;
- CopyConfig Config;
+ ConfigManager ConfigMgr;
+ CommonConfig &Config = ConfigMgr.Common;
InstallNameToolOptTable T;
unsigned MissingArgumentIndex, MissingArgumentCount;
llvm::opt::InputArgList InputArgs =
@@ -996,14 +1182,15 @@ parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr) {
Config.InputFilename = Positional[0];
Config.OutputFilename = Positional[0];
- DC.CopyConfigs.push_back(std::move(Config));
+ DC.CopyConfigs.push_back(std::move(ConfigMgr));
return std::move(DC);
}
Expected<DriverConfig>
parseBitcodeStripOptions(ArrayRef<const char *> ArgsArr) {
DriverConfig DC;
- CopyConfig Config;
+ ConfigManager ConfigMgr;
+ CommonConfig &Config = ConfigMgr.Common;
BitcodeStripOptTable T;
unsigned MissingArgumentIndex, MissingArgumentCount;
opt::InputArgList InputArgs =
@@ -1040,7 +1227,7 @@ parseBitcodeStripOptions(ArrayRef<const char *> ArgsArr) {
Config.InputFilename = Positional[0];
Config.OutputFilename = Positional[0];
- DC.CopyConfigs.push_back(std::move(Config));
+ DC.CopyConfigs.push_back(std::move(ConfigMgr));
return std::move(DC);
}
@@ -1086,7 +1273,8 @@ parseStripOptions(ArrayRef<const char *> ArgsArr,
errc::invalid_argument,
"multiple input files cannot be used in combination with -o");
- CopyConfig Config;
+ ConfigManager ConfigMgr;
+ CommonConfig &Config = ConfigMgr.Common;
if (InputArgs.hasArg(STRIP_regex) && InputArgs.hasArg(STRIP_wildcard))
return createStringError(errc::invalid_argument,
@@ -1159,7 +1347,7 @@ parseStripOptions(ArrayRef<const char *> ArgsArr,
Config.InputFilename = Positional[0];
Config.OutputFilename =
InputArgs.getLastArgValue(STRIP_output, Positional[0]);
- DC.CopyConfigs.push_back(std::move(Config));
+ DC.CopyConfigs.push_back(std::move(ConfigMgr));
} else {
StringMap<unsigned> InputFiles;
for (StringRef Filename : Positional) {
@@ -1175,7 +1363,7 @@ parseStripOptions(ArrayRef<const char *> ArgsArr,
}
Config.InputFilename = Filename;
Config.OutputFilename = Filename;
- DC.CopyConfigs.push_back(Config);
+ DC.CopyConfigs.push_back(ConfigMgr);
}
}
diff --git a/llvm/tools/llvm-objcopy/ConfigManager.h b/llvm/tools/llvm-objcopy/ConfigManager.h
new file mode 100644
index 0000000000000..ec1d2f33f6a0e
--- /dev/null
+++ b/llvm/tools/llvm-objcopy/ConfigManager.h
@@ -0,0 +1,84 @@
+//===- ConfigManager.h ----------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_OBJCOPY_CONFIGMANAGER_H
+#define LLVM_TOOLS_LLVM_OBJCOPY_CONFIGMANAGER_H
+
+#include "COFF/COFFConfig.h"
+#include "CommonConfig.h"
+#include "ELF/ELFConfig.h"
+#include "MachO/MachOConfig.h"
+#include "MultiFormatConfig.h"
+#include "wasm/WasmConfig.h"
+#include "llvm/Support/Allocator.h"
+#include <vector>
+
+namespace llvm {
+namespace objcopy {
+
+// ConfigManager keeps all configurations and prepare
+// format-specific options.
+struct ConfigManager : public MultiFormatConfig {
+ virtual ~ConfigManager() {}
+
+ const CommonConfig &getCommonConfig() const override { return Common; }
+ Expected<const ELFConfig &> getELFConfig() const override;
+ Expected<const COFFConfig &> getCOFFConfig() const override;
+ Expected<const MachOConfig &> getMachOConfig() const override;
+ Expected<const WasmConfig &> getWasmConfig() const override;
+
+ // String representation for lazy ELF options.
+ std::vector<StringRef> SymbolsToAdd;
+ Optional<StringRef> NewSymbolVisibility;
+
+ // All configs.
+ CommonConfig Common;
+ mutable Optional<ELFConfig> ELF;
+ COFFConfig COFF;
+ MachOConfig MachO;
+ WasmConfig Wasm;
+};
+
+// Configuration for the overall invocation of this tool. When invoked as
+// objcopy, will always contain exactly one CopyConfig. When invoked as strip,
+// will contain one or more CopyConfigs.
+struct DriverConfig {
+ SmallVector<ConfigManager, 1> CopyConfigs;
+ BumpPtrAllocator Alloc;
+};
+
+// ParseObjcopyOptions returns the config and sets the input arguments. If a
+// help flag is set then ParseObjcopyOptions will print the help messege and
+// exit. ErrorCallback is used to handle recoverable errors. An Error returned
+// by the callback aborts the parsing and is then returned by this function.
+Expected<DriverConfig>
+parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
+ llvm::function_ref<Error(Error)> ErrorCallback);
+
+// ParseInstallNameToolOptions returns the config and sets the input arguments.
+// If a help flag is set then ParseInstallNameToolOptions will print the help
+// messege and exit.
+Expected<DriverConfig>
+parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr);
+
+// ParseBitcodeStripOptions returns the config and sets the input arguments.
+// If a help flag is set then ParseBitcodeStripOptions will print the help
+// messege and exit.
+Expected<DriverConfig> parseBitcodeStripOptions(ArrayRef<const char *> ArgsArr);
+
+// ParseStripOptions returns the config and sets the input arguments. If a
+// help flag is set then ParseStripOptions will print the help messege and
+// exit. ErrorCallback is used to handle recoverable errors. An Error returned
+// by the callback aborts the parsing and is then returned by this function.
+Expected<DriverConfig>
+parseStripOptions(ArrayRef<const char *> ArgsArr,
+ llvm::function_ref<Error(Error)> ErrorCallback);
+} // namespace objcopy
+} // namespace llvm
+
+#endif // LLVM_TOOLS_LLVM_OBJCOPY_CONFIGMANAGER_H
diff --git a/llvm/tools/llvm-objcopy/ELF/ELFConfig.cpp b/llvm/tools/llvm-objcopy/ELF/ELFConfig.cpp
deleted file mode 100644
index 40993760add79..0000000000000
--- a/llvm/tools/llvm-objcopy/ELF/ELFConfig.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-//===- ELFConfig.cpp ------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "CopyConfig.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Support/Errc.h"
-#include "llvm/Support/Error.h"
-
-namespace llvm {
-namespace objcopy {
-namespace elf {
-
-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;
-}
-
-Expected<ELFCopyConfig> parseConfig(const CopyConfig &Config) {
- ELFCopyConfig ELFConfig;
- if (Config.NewSymbolVisibility) {
- const uint8_t Invalid = 0xff;
- ELFConfig.NewSymbolVisibility =
- StringSwitch<uint8_t>(*Config.NewSymbolVisibility)
- .Case("default", ELF::STV_DEFAULT)
- .Case("hidden", ELF::STV_HIDDEN)
- .Case("internal", ELF::STV_INTERNAL)
- .Case("protected", ELF::STV_PROTECTED)
- .Default(Invalid);
-
- if (ELFConfig.NewSymbolVisibility == Invalid)
- return createStringError(errc::invalid_argument,
- "'%s' is not a valid symbol visibility",
- Config.NewSymbolVisibility->str().c_str());
- }
-
- for (StringRef Arg : Config.SymbolsToAdd) {
- Expected<elf::NewSymbolInfo> NSI = parseNewSymbolInfo(
- Arg,
- ELFConfig.NewSymbolVisibility.getValueOr((uint8_t)ELF::STV_DEFAULT));
- if (!NSI)
- return NSI.takeError();
- ELFConfig.SymbolsToAdd.push_back(*NSI);
- }
-
- return ELFConfig;
-}
-
-} // end namespace elf
-} // end namespace objcopy
-} // end namespace llvm
diff --git a/llvm/tools/llvm-objcopy/ELF/ELFConfig.h b/llvm/tools/llvm-objcopy/ELF/ELFConfig.h
index 977efbc4166fa..cb170bd93a5c5 100644
--- a/llvm/tools/llvm-objcopy/ELF/ELFConfig.h
+++ b/llvm/tools/llvm-objcopy/ELF/ELFConfig.h
@@ -6,20 +6,16 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TOOLS_OBJCOPY_ELFCONFIG_H
-#define LLVM_TOOLS_OBJCOPY_ELFCONFIG_H
+#ifndef LLVM_TOOLS_LLVM_OBJCOPY_ELF_ELFCONFIG_H
+#define LLVM_TOOLS_LLVM_OBJCOPY_ELF_ELFCONFIG_H
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/ELFTypes.h"
-#include "llvm/Support/Error.h"
#include <vector>
namespace llvm {
namespace objcopy {
-struct CopyConfig;
-
-namespace elf {
struct NewSymbolInfo {
StringRef SymbolName;
@@ -30,15 +26,13 @@ struct NewSymbolInfo {
uint8_t Visibility = ELF::STV_DEFAULT;
};
-struct ELFCopyConfig {
+// ELF specific configuration for copying/stripping a single file.
+struct ELFConfig {
Optional<uint8_t> NewSymbolVisibility;
std::vector<NewSymbolInfo> SymbolsToAdd;
};
-Expected<ELFCopyConfig> parseConfig(const CopyConfig &Config);
-
-} // namespace elf
} // namespace objcopy
} // namespace llvm
-#endif
+#endif // LLVM_TOOLS_LLVM_OBJCOPY_ELF_ELFCONFIG_H
diff --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
index d139814617b14..806cd73dae0d0 100644
--- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
+++ b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
@@ -7,7 +7,8 @@
//===----------------------------------------------------------------------===//
#include "ELFObjcopy.h"
-#include "CopyConfig.h"
+#include "CommonConfig.h"
+#include "ELFConfig.h"
#include "Object.h"
#include "llvm-objcopy.h"
#include "llvm/ADT/BitmaskEnum.h"
@@ -132,7 +133,7 @@ static ElfType getOutputElfType(const MachineInfo &MI) {
return MI.IsLittleEndian ? ELFT_ELF32LE : ELFT_ELF32BE;
}
-static std::unique_ptr<Writer> createELFWriter(const CopyConfig &Config,
+static std::unique_ptr<Writer> createELFWriter(const CommonConfig &Config,
Object &Obj, raw_ostream &Out,
ElfType OutputElfType) {
// Depending on the initial ELFT and OutputFormat we need a
diff erent Writer.
@@ -153,7 +154,7 @@ static std::unique_ptr<Writer> createELFWriter(const CopyConfig &Config,
llvm_unreachable("Invalid output format");
}
-static std::unique_ptr<Writer> createWriter(const CopyConfig &Config,
+static std::unique_ptr<Writer> createWriter(const CommonConfig &Config,
Object &Obj, raw_ostream &Out,
ElfType OutputElfType) {
switch (Config.OutputFormat) {
@@ -243,7 +244,7 @@ static bool isUnneededSymbol(const Symbol &Sym) {
Sym.Type != STT_SECTION;
}
-static Error updateAndRemoveSymbols(const CopyConfig &Config, Object &Obj) {
+static Error updateAndRemoveSymbols(const CommonConfig &Config, Object &Obj) {
// TODO: update or remove symbols only if there is an option that affects
// them.
if (!Obj.SymbolTable)
@@ -338,7 +339,7 @@ static Error updateAndRemoveSymbols(const CopyConfig &Config, Object &Obj) {
return Obj.removeSymbols(RemoveSymbolsPred);
}
-static Error replaceAndRemoveSections(const CopyConfig &Config, Object &Obj) {
+static Error replaceAndRemoveSections(const CommonConfig &Config, Object &Obj) {
SectionPred RemovePred = [](const SectionBase &) { return false; };
// Removes:
@@ -506,11 +507,8 @@ static Error replaceAndRemoveSections(const CopyConfig &Config, Object &Obj) {
// any previous removals. Lastly whether or not something is removed shouldn't
// depend a) on the order the options occur in or b) on some opaque priority
// system. The only priority is that keeps/copies overrule removes.
-static Error handleArgs(const CopyConfig &Config, Object &Obj) {
- if (Config.StripSwiftSymbols || Config.KeepUndefined)
- return createStringError(llvm::errc::invalid_argument,
- "option not supported by llvm-objcopy for ELF");
-
+static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
+ Object &Obj) {
if (Config.OutputArch) {
Obj.Machine = Config.OutputArch.getValue().EMachine;
Obj.OSABI = Config.OutputArch.getValue().OSABI;
@@ -635,11 +633,11 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
// If the symbol table was previously removed, we need to create a new one
// before adding new symbols.
- if (!Obj.SymbolTable && !Config.ELF->SymbolsToAdd.empty())
+ if (!Obj.SymbolTable && !ELFConfig.SymbolsToAdd.empty())
if (Error E = Obj.addNewSymbolTable())
return E;
- for (const NewSymbolInfo &SI : Config.ELF->SymbolsToAdd) {
+ for (const NewSymbolInfo &SI : ELFConfig.SymbolsToAdd) {
SectionBase *Sec = Obj.findSection(SI.SectionName);
uint64_t Value = Sec ? Sec->Addr + SI.Value : SI.Value;
Obj.SymbolTable->addSymbol(
@@ -663,7 +661,7 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
return Error::success();
}
-static Error writeOutput(const CopyConfig &Config, Object &Obj,
+static Error writeOutput(const CommonConfig &Config, Object &Obj,
raw_ostream &Out, ElfType OutputElfType) {
std::unique_ptr<Writer> Writer =
createWriter(Config, Obj, Out, OutputElfType);
@@ -672,7 +670,8 @@ static Error writeOutput(const CopyConfig &Config, Object &Obj,
return Writer->write();
}
-Error executeObjcopyOnIHex(const CopyConfig &Config, MemoryBuffer &In,
+Error executeObjcopyOnIHex(const CommonConfig &Config,
+ const ELFConfig &ELFConfig, MemoryBuffer &In,
raw_ostream &Out) {
IHexReader Reader(&In);
Expected<std::unique_ptr<Object>> Obj = Reader.create(true);
@@ -681,15 +680,16 @@ Error executeObjcopyOnIHex(const CopyConfig &Config, MemoryBuffer &In,
const ElfType OutputElfType =
getOutputElfType(Config.OutputArch.getValueOr(MachineInfo()));
- if (Error E = handleArgs(Config, **Obj))
+ if (Error E = handleArgs(Config, ELFConfig, **Obj))
return E;
return writeOutput(Config, **Obj, Out, OutputElfType);
}
-Error executeObjcopyOnRawBinary(const CopyConfig &Config, MemoryBuffer &In,
+Error executeObjcopyOnRawBinary(const CommonConfig &Config,
+ const ELFConfig &ELFConfig, MemoryBuffer &In,
raw_ostream &Out) {
uint8_t NewSymbolVisibility =
- Config.ELF->NewSymbolVisibility.getValueOr((uint8_t)ELF::STV_DEFAULT);
+ ELFConfig.NewSymbolVisibility.getValueOr((uint8_t)ELF::STV_DEFAULT);
BinaryReader Reader(&In, NewSymbolVisibility);
Expected<std::unique_ptr<Object>> Obj = Reader.create(true);
if (!Obj)
@@ -699,16 +699,17 @@ Error executeObjcopyOnRawBinary(const CopyConfig &Config, MemoryBuffer &In,
// (-B<arch>).
const ElfType OutputElfType =
getOutputElfType(Config.OutputArch.getValueOr(MachineInfo()));
- if (Error E = handleArgs(Config, **Obj))
+ if (Error E = handleArgs(Config, ELFConfig, **Obj))
return E;
return writeOutput(Config, **Obj, Out, OutputElfType);
}
-Error executeObjcopyOnBinary(const CopyConfig &Config,
+Error executeObjcopyOnBinary(const CommonConfig &Config,
+ const ELFConfig &ELFConfig,
object::ELFObjectFileBase &In, raw_ostream &Out) {
ELFReader Reader(&In, Config.ExtractPartition);
Expected<std::unique_ptr<Object>> Obj =
- Reader.create(!Config.SymbolsToAdd.empty());
+ Reader.create(!ELFConfig.SymbolsToAdd.empty());
if (!Obj)
return Obj.takeError();
// Prefer OutputArch (-O<format>) if set, otherwise infer it from the input.
@@ -716,7 +717,7 @@ Error executeObjcopyOnBinary(const CopyConfig &Config,
Config.OutputArch ? getOutputElfType(Config.OutputArch.getValue())
: getOutputElfType(In);
- if (Error E = handleArgs(Config, **Obj))
+ if (Error E = handleArgs(Config, ELFConfig, **Obj))
return createFileError(Config.InputFilename, std::move(E));
if (Error E = writeOutput(Config, **Obj, Out, OutputElfType))
diff --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.h b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.h
index 13aa905e0caac..852661e68f37b 100644
--- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.h
+++ b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.h
@@ -19,14 +19,18 @@ class ELFObjectFileBase;
} // end namespace object
namespace objcopy {
-struct CopyConfig;
+struct CommonConfig;
+struct ELFConfig;
namespace elf {
-Error executeObjcopyOnIHex(const CopyConfig &Config, MemoryBuffer &In,
+Error executeObjcopyOnIHex(const CommonConfig &Config,
+ const ELFConfig &ELFConfig, MemoryBuffer &In,
raw_ostream &Out);
-Error executeObjcopyOnRawBinary(const CopyConfig &Config, MemoryBuffer &In,
+Error executeObjcopyOnRawBinary(const CommonConfig &Config,
+ const ELFConfig &ELFConfig, MemoryBuffer &In,
raw_ostream &Out);
-Error executeObjcopyOnBinary(const CopyConfig &Config,
+Error executeObjcopyOnBinary(const CommonConfig &Config,
+ const ELFConfig &ELFConfig,
object::ELFObjectFileBase &In, raw_ostream &Out);
} // end namespace elf
diff --git a/llvm/tools/llvm-objcopy/ELF/Object.h b/llvm/tools/llvm-objcopy/ELF/Object.h
index 6848100d3e84f..6fd26afa3ca1e 100644
--- a/llvm/tools/llvm-objcopy/ELF/Object.h
+++ b/llvm/tools/llvm-objcopy/ELF/Object.h
@@ -9,7 +9,7 @@
#ifndef LLVM_TOOLS_OBJCOPY_OBJECT_H
#define LLVM_TOOLS_OBJCOPY_OBJECT_H
-#include "CopyConfig.h"
+#include "CommonConfig.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
diff --git a/llvm/tools/llvm-objcopy/MachO/MachOConfig.h b/llvm/tools/llvm-objcopy/MachO/MachOConfig.h
new file mode 100644
index 0000000000000..7c5dbfde19a0b
--- /dev/null
+++ b/llvm/tools/llvm-objcopy/MachO/MachOConfig.h
@@ -0,0 +1,21 @@
+//===- MachOConfig.h --------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_OBJCOPY_MACHO_MACHOCONFIG_H
+#define LLVM_TOOLS_LLVM_OBJCOPY_MACHO_MACHOCONFIG_H
+
+namespace llvm {
+namespace objcopy {
+
+// Mach-O specific configuration for copying/stripping a single file.
+struct MachOConfig {};
+
+} // namespace objcopy
+} // namespace llvm
+
+#endif // LLVM_TOOLS_LLVM_OBJCOPY_MACHO_MACHOCONFIG_H
diff --git a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
index 90babd7ad3fcc..30c2a166b7be9 100644
--- a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
+++ b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
@@ -7,10 +7,11 @@
//===----------------------------------------------------------------------===//
#include "MachOObjcopy.h"
-#include "../CopyConfig.h"
#include "../llvm-objcopy.h"
+#include "CommonConfig.h"
#include "MachOReader.h"
#include "MachOWriter.h"
+#include "MultiFormatConfig.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/Object/ArchiveWriter.h"
#include "llvm/Object/MachOUniversal.h"
@@ -48,7 +49,7 @@ static StringRef getPayloadString(const LoadCommand &LC) {
.rtrim('\0');
}
-static Error removeSections(const CopyConfig &Config, Object &Obj) {
+static Error removeSections(const CommonConfig &Config, Object &Obj) {
SectionPred RemovePred = [](const std::unique_ptr<Section> &) {
return false;
};
@@ -79,14 +80,14 @@ static Error removeSections(const CopyConfig &Config, Object &Obj) {
return Obj.removeSections(RemovePred);
}
-static void markSymbols(const CopyConfig &Config, Object &Obj) {
+static void markSymbols(const CommonConfig &, 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 updateAndRemoveSymbols(const CopyConfig &Config, Object &Obj) {
+static void updateAndRemoveSymbols(const CommonConfig &Config, Object &Obj) {
for (SymbolEntry &Sym : Obj.SymTable) {
auto I = Config.SymbolsToRename.find(Sym.Name);
if (I != Config.SymbolsToRename.end())
@@ -136,7 +137,7 @@ static LoadCommand buildRPathLoadCommand(StringRef Path) {
return LC;
}
-static Error processLoadCommands(const CopyConfig &Config, Object &Obj) {
+static Error processLoadCommands(const CommonConfig &Config, Object &Obj) {
// Remove RPaths.
DenseSet<StringRef> RPathsToRemove(Config.RPathsToRemove.begin(),
Config.RPathsToRemove.end());
@@ -330,24 +331,7 @@ static Error isValidMachOCannonicalName(StringRef Name) {
return Error::success();
}
-static Error handleArgs(const CopyConfig &Config, Object &Obj) {
- if (Config.AllowBrokenLinks || !Config.SplitDWO.empty() ||
- !Config.SymbolsPrefix.empty() || !Config.AllocSectionsPrefix.empty() ||
- !Config.KeepSection.empty() || Config.NewSymbolVisibility ||
- !Config.SymbolsToGlobalize.empty() || !Config.SymbolsToKeep.empty() ||
- !Config.SymbolsToLocalize.empty() || !Config.SymbolsToWeaken.empty() ||
- !Config.SymbolsToKeepGlobal.empty() || !Config.SectionsToRename.empty() ||
- !Config.UnneededSymbolsToRemove.empty() ||
- !Config.SetSectionAlignment.empty() || !Config.SetSectionFlags.empty() ||
- Config.ExtractDWO || Config.LocalizeHidden || Config.PreserveDates ||
- Config.StripAllGNU || Config.StripDWO || Config.StripNonAlloc ||
- Config.StripSections || Config.Weaken || Config.DecompressDebugSections ||
- Config.StripUnneeded || Config.DiscardMode == DiscardType::Locals ||
- !Config.SymbolsToAdd.empty() || Config.EntryExpr) {
- return createStringError(llvm::errc::invalid_argument,
- "option not supported by llvm-objcopy for MachO");
- }
-
+static Error handleArgs(const CommonConfig &Config, Object &Obj) {
// Dump sections before add/remove for compatibility with GNU objcopy.
for (StringRef Flag : Config.DumpSection) {
StringRef SectionName;
@@ -387,7 +371,7 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
return Error::success();
}
-Error executeObjcopyOnBinary(const CopyConfig &Config,
+Error executeObjcopyOnBinary(const CommonConfig &Config, const MachOConfig &,
object::MachOObjectFile &In, raw_ostream &Out) {
MachOReader Reader(In);
Expected<std::unique_ptr<Object>> O = Reader.create();
@@ -416,7 +400,7 @@ Error executeObjcopyOnBinary(const CopyConfig &Config,
return Writer.write();
}
-Error executeObjcopyOnMachOUniversalBinary(CopyConfig &Config,
+Error executeObjcopyOnMachOUniversalBinary(const MultiFormatConfig &Config,
const MachOUniversalBinary &In,
raw_ostream &Out) {
SmallVector<OwningBinary<Binary>, 2> Binaries;
@@ -431,7 +415,7 @@ Error executeObjcopyOnMachOUniversalBinary(CopyConfig &Config,
Expected<std::unique_ptr<MemoryBuffer>> OutputBufferOrErr =
writeArchiveToBuffer(*NewArchiveMembersOrErr,
(*ArOrErr)->hasSymbolTable(), (*ArOrErr)->kind(),
- Config.DeterministicArchives,
+ Config.getCommonConfig().DeterministicArchives,
(*ArOrErr)->isThin());
if (!OutputBufferOrErr)
return OutputBufferOrErr.takeError();
@@ -455,18 +439,24 @@ Error executeObjcopyOnMachOUniversalBinary(CopyConfig &Config,
Expected<std::unique_ptr<MachOObjectFile>> ObjOrErr = O.getAsObjectFile();
if (!ObjOrErr) {
consumeError(ObjOrErr.takeError());
- return createStringError(std::errc::invalid_argument,
- "slice for '%s' of the universal Mach-O binary "
- "'%s' is not a Mach-O object or an archive",
- O.getArchFlagName().c_str(),
- Config.InputFilename.str().c_str());
+ return createStringError(
+ std::errc::invalid_argument,
+ "slice for '%s' of the universal Mach-O binary "
+ "'%s' is not a Mach-O object or an archive",
+ O.getArchFlagName().c_str(),
+ Config.getCommonConfig().InputFilename.str().c_str());
}
std::string ArchFlagName = O.getArchFlagName();
SmallVector<char, 0> Buffer;
raw_svector_ostream MemStream(Buffer);
- if (Error E = executeObjcopyOnBinary(Config, **ObjOrErr, MemStream))
+ Expected<const MachOConfig &> MachO = Config.getMachOConfig();
+ if (!MachO)
+ return MachO.takeError();
+
+ if (Error E = executeObjcopyOnBinary(Config.getCommonConfig(), *MachO,
+ **ObjOrErr, MemStream))
return E;
std::unique_ptr<MemoryBuffer> MB =
diff --git a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.h b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.h
index 424c68771b777..e30940a8d6eba 100644
--- a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.h
+++ b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.h
@@ -19,15 +19,16 @@ class MachOUniversalBinary;
} // end namespace object
namespace objcopy {
-struct CopyConfig;
-class Buffer;
+struct CommonConfig;
+struct MachOConfig;
+class MultiFormatConfig;
namespace macho {
-Error executeObjcopyOnBinary(const CopyConfig &Config,
+Error executeObjcopyOnBinary(const CommonConfig &Config, const MachOConfig &,
object::MachOObjectFile &In, raw_ostream &Out);
Error executeObjcopyOnMachOUniversalBinary(
- CopyConfig &Config, const object::MachOUniversalBinary &In,
+ const MultiFormatConfig &Config, const object::MachOUniversalBinary &In,
raw_ostream &Out);
} // end namespace macho
diff --git a/llvm/tools/llvm-objcopy/MultiFormatConfig.h b/llvm/tools/llvm-objcopy/MultiFormatConfig.h
new file mode 100644
index 0000000000000..31d9883d6d3a3
--- /dev/null
+++ b/llvm/tools/llvm-objcopy/MultiFormatConfig.h
@@ -0,0 +1,37 @@
+//===- MultiFormatConfig.h --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_OBJCOPY_MULTIFORMATCONFIG_H
+#define LLVM_TOOLS_LLVM_OBJCOPY_MULTIFORMATCONFIG_H
+
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace objcopy {
+
+struct CommonConfig;
+struct ELFConfig;
+struct COFFConfig;
+struct MachOConfig;
+struct WasmConfig;
+
+class MultiFormatConfig {
+public:
+ virtual ~MultiFormatConfig() {}
+
+ virtual const CommonConfig &getCommonConfig() const = 0;
+ virtual Expected<const ELFConfig &> getELFConfig() const = 0;
+ virtual Expected<const COFFConfig &> getCOFFConfig() const = 0;
+ virtual Expected<const MachOConfig &> getMachOConfig() const = 0;
+ virtual Expected<const WasmConfig &> getWasmConfig() const = 0;
+};
+
+} // namespace objcopy
+} // namespace llvm
+
+#endif // LLVM_TOOLS_LLVM_OBJCOPY_MULTIFORMATCONFIG_H
diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
index d3cc94782bedd..af1e903c207fe 100644
--- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
+++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
@@ -7,10 +7,15 @@
//===----------------------------------------------------------------------===//
#include "llvm-objcopy.h"
+#include "COFF/COFFConfig.h"
#include "COFF/COFFObjcopy.h"
-#include "CopyConfig.h"
+#include "CommonConfig.h"
+#include "ConfigManager.h"
+#include "ELF/ELFConfig.h"
#include "ELF/ELFObjcopy.h"
+#include "MachO/MachOConfig.h"
#include "MachO/MachOObjcopy.h"
+#include "wasm/WasmConfig.h"
#include "wasm/WasmObjcopy.h"
#include "llvm/ADT/STLExtras.h"
@@ -133,18 +138,22 @@ static Error deepWriteArchive(StringRef ArcName,
/// The function executeObjcopyOnIHex does the dispatch based on the format
/// of the output specified by the command line options.
-static Error executeObjcopyOnIHex(CopyConfig &Config, MemoryBuffer &In,
+static Error executeObjcopyOnIHex(ConfigManager &ConfigMgr, MemoryBuffer &In,
raw_ostream &Out) {
// TODO: support output formats other than ELF.
- if (Error E = Config.parseELFConfig())
- return E;
- return elf::executeObjcopyOnIHex(Config, In, Out);
+ Expected<const ELFConfig &> ELFConfig = ConfigMgr.getELFConfig();
+ if (!ELFConfig)
+ return ELFConfig.takeError();
+
+ return elf::executeObjcopyOnIHex(ConfigMgr.getCommonConfig(), *ELFConfig, In,
+ Out);
}
/// The function executeObjcopyOnRawBinary does the dispatch based on the format
/// of the output specified by the command line options.
-static Error executeObjcopyOnRawBinary(CopyConfig &Config, MemoryBuffer &In,
- raw_ostream &Out) {
+static Error executeObjcopyOnRawBinary(ConfigManager &ConfigMgr,
+ MemoryBuffer &In, raw_ostream &Out) {
+ const CommonConfig &Config = ConfigMgr.getCommonConfig();
switch (Config.OutputFormat) {
case FileFormat::ELF:
// FIXME: Currently, we call elf::executeObjcopyOnRawBinary even if the
@@ -153,9 +162,11 @@ static Error executeObjcopyOnRawBinary(CopyConfig &Config, MemoryBuffer &In,
case FileFormat::Binary:
case FileFormat::IHex:
case FileFormat::Unspecified:
- if (Error E = Config.parseELFConfig())
- return E;
- return elf::executeObjcopyOnRawBinary(Config, In, Out);
+ Expected<const ELFConfig &> ELFConfig = ConfigMgr.getELFConfig();
+ if (!ELFConfig)
+ return ELFConfig.takeError();
+
+ return elf::executeObjcopyOnRawBinary(Config, *ELFConfig, In, Out);
}
llvm_unreachable("unsupported output format");
@@ -163,23 +174,41 @@ static Error executeObjcopyOnRawBinary(CopyConfig &Config, MemoryBuffer &In,
/// The function executeObjcopyOnBinary does the dispatch based on the format
/// of the input binary (ELF, MachO or COFF).
-static Error executeObjcopyOnBinary(CopyConfig &Config, object::Binary &In,
- raw_ostream &Out) {
+static Error executeObjcopyOnBinary(const MultiFormatConfig &Config,
+ object::Binary &In, raw_ostream &Out) {
if (auto *ELFBinary = dyn_cast<object::ELFObjectFileBase>(&In)) {
- if (Error E = Config.parseELFConfig())
- return E;
- return elf::executeObjcopyOnBinary(Config, *ELFBinary, Out);
- } else if (auto *COFFBinary = dyn_cast<object::COFFObjectFile>(&In))
- return coff::executeObjcopyOnBinary(Config, *COFFBinary, Out);
- else if (auto *MachOBinary = dyn_cast<object::MachOObjectFile>(&In))
- return macho::executeObjcopyOnBinary(Config, *MachOBinary, Out);
- else if (auto *MachOUniversalBinary =
- dyn_cast<object::MachOUniversalBinary>(&In))
+ Expected<const ELFConfig &> ELFConfig = Config.getELFConfig();
+ if (!ELFConfig)
+ return ELFConfig.takeError();
+
+ return elf::executeObjcopyOnBinary(Config.getCommonConfig(), *ELFConfig,
+ *ELFBinary, Out);
+ } else if (auto *COFFBinary = dyn_cast<object::COFFObjectFile>(&In)) {
+ Expected<const COFFConfig &> COFFConfig = Config.getCOFFConfig();
+ if (!COFFConfig)
+ return COFFConfig.takeError();
+
+ return coff::executeObjcopyOnBinary(Config.getCommonConfig(), *COFFConfig,
+ *COFFBinary, Out);
+ } else if (auto *MachOBinary = dyn_cast<object::MachOObjectFile>(&In)) {
+ Expected<const MachOConfig &> MachOConfig = Config.getMachOConfig();
+ if (!MachOConfig)
+ return MachOConfig.takeError();
+
+ return macho::executeObjcopyOnBinary(Config.getCommonConfig(), *MachOConfig,
+ *MachOBinary, Out);
+ } else if (auto *MachOUniversalBinary =
+ dyn_cast<object::MachOUniversalBinary>(&In)) {
return macho::executeObjcopyOnMachOUniversalBinary(
Config, *MachOUniversalBinary, Out);
- else if (auto *WasmBinary = dyn_cast<object::WasmObjectFile>(&In))
- return objcopy::wasm::executeObjcopyOnBinary(Config, *WasmBinary, Out);
- else
+ } else if (auto *WasmBinary = dyn_cast<object::WasmObjectFile>(&In)) {
+ Expected<const WasmConfig &> WasmConfig = Config.getWasmConfig();
+ if (!WasmConfig)
+ return WasmConfig.takeError();
+
+ return objcopy::wasm::executeObjcopyOnBinary(Config.getCommonConfig(),
+ *WasmConfig, *WasmBinary, Out);
+ } else
return createStringError(object_error::invalid_file_type,
"unsupported object file format");
}
@@ -188,7 +217,7 @@ namespace llvm {
namespace objcopy {
Expected<std::vector<NewArchiveMember>>
-createNewArchiveMembers(CopyConfig &Config, const Archive &Ar) {
+createNewArchiveMembers(const MultiFormatConfig &Config, const Archive &Ar) {
std::vector<NewArchiveMember> NewArchiveMembers;
Error Err = Error::success();
for (const Archive::Child &Child : Ar.children(Err)) {
@@ -207,8 +236,8 @@ createNewArchiveMembers(CopyConfig &Config, const Archive &Ar) {
if (Error E = executeObjcopyOnBinary(Config, *ChildOrErr->get(), MemStream))
return std::move(E);
- Expected<NewArchiveMember> Member =
- NewArchiveMember::getOldMember(Child, Config.DeterministicArchives);
+ Expected<NewArchiveMember> Member = NewArchiveMember::getOldMember(
+ Child, Config.getCommonConfig().DeterministicArchives);
if (!Member)
return createFileError(Ar.getFileName(), Member.takeError());
@@ -218,19 +247,21 @@ createNewArchiveMembers(CopyConfig &Config, const Archive &Ar) {
NewArchiveMembers.push_back(std::move(*Member));
}
if (Err)
- return createFileError(Config.InputFilename, std::move(Err));
+ return createFileError(Config.getCommonConfig().InputFilename,
+ std::move(Err));
return std::move(NewArchiveMembers);
}
} // end namespace objcopy
} // end namespace llvm
-static Error executeObjcopyOnArchive(CopyConfig &Config,
+static Error executeObjcopyOnArchive(const ConfigManager &ConfigMgr,
const object::Archive &Ar) {
Expected<std::vector<NewArchiveMember>> NewArchiveMembersOrErr =
- createNewArchiveMembers(Config, Ar);
+ createNewArchiveMembers(ConfigMgr, Ar);
if (!NewArchiveMembersOrErr)
return NewArchiveMembersOrErr.takeError();
+ const CommonConfig &Config = ConfigMgr.getCommonConfig();
return deepWriteArchive(Config.OutputFilename, *NewArchiveMembersOrErr,
Ar.hasSymbolTable(), Ar.kind(),
Config.DeterministicArchives, Ar.isThin());
@@ -238,8 +269,9 @@ static Error executeObjcopyOnArchive(CopyConfig &Config,
static Error restoreStatOnFile(StringRef Filename,
const sys::fs::file_status &Stat,
- const CopyConfig &Config) {
+ const ConfigManager &ConfigMgr) {
int FD;
+ const CommonConfig &Config = ConfigMgr.getCommonConfig();
// Writing to stdout should not be treated as an error here, just
// do not set access/modification times or permissions.
@@ -285,7 +317,9 @@ static Error restoreStatOnFile(StringRef Filename,
/// The function executeObjcopy does the higher level dispatch based on the type
/// of input (raw binary, archive or single object file) and takes care of the
/// format-agnostic modifications, i.e. preserving dates.
-static Error executeObjcopy(CopyConfig &Config) {
+static Error executeObjcopy(ConfigManager &ConfigMgr) {
+ CommonConfig &Config = ConfigMgr.Common;
+
sys::fs::file_status Stat;
if (Config.InputFilename != "-") {
if (auto EC = sys::fs::status(Config.InputFilename, Stat))
@@ -310,12 +344,13 @@ static Error executeObjcopy(CopyConfig &Config) {
if (Config.InputFormat == FileFormat::Binary)
ObjcopyFunc = [&](raw_ostream &OutFile) -> Error {
// Handle FileFormat::Binary.
- return executeObjcopyOnRawBinary(Config, *MemoryBufferHolder, OutFile);
+ return executeObjcopyOnRawBinary(ConfigMgr, *MemoryBufferHolder,
+ OutFile);
};
else
ObjcopyFunc = [&](raw_ostream &OutFile) -> Error {
// Handle FileFormat::IHex.
- return executeObjcopyOnIHex(Config, *MemoryBufferHolder, OutFile);
+ return executeObjcopyOnIHex(ConfigMgr, *MemoryBufferHolder, OutFile);
};
} else {
Expected<OwningBinary<llvm::object::Binary>> BinaryOrErr =
@@ -326,12 +361,12 @@ static Error executeObjcopy(CopyConfig &Config) {
if (Archive *Ar = dyn_cast<Archive>(BinaryHolder.getBinary())) {
// Handle Archive.
- if (Error E = executeObjcopyOnArchive(Config, *Ar))
+ if (Error E = executeObjcopyOnArchive(ConfigMgr, *Ar))
return E;
} else {
// Handle llvm::object::Binary.
ObjcopyFunc = [&](raw_ostream &OutFile) -> Error {
- return executeObjcopyOnBinary(Config, *BinaryHolder.getBinary(),
+ return executeObjcopyOnBinary(ConfigMgr, *BinaryHolder.getBinary(),
OutFile);
};
}
@@ -360,12 +395,12 @@ static Error executeObjcopy(CopyConfig &Config) {
}
}
- if (Error E = restoreStatOnFile(Config.OutputFilename, Stat, Config))
+ if (Error E = restoreStatOnFile(Config.OutputFilename, Stat, ConfigMgr))
return E;
if (!Config.SplitDWO.empty()) {
Stat.permissions(static_cast<sys::fs::perms>(0666));
- if (Error E = restoreStatOnFile(Config.SplitDWO, Stat, Config))
+ if (Error E = restoreStatOnFile(Config.SplitDWO, Stat, ConfigMgr))
return E;
}
@@ -401,8 +436,8 @@ int main(int argc, char **argv) {
WithColor::error(errs(), ToolName));
return 1;
}
- for (CopyConfig &CopyConfig : DriverConfig->CopyConfigs) {
- if (Error E = executeObjcopy(CopyConfig)) {
+ for (ConfigManager &ConfigMgr : DriverConfig->CopyConfigs) {
+ if (Error E = executeObjcopy(ConfigMgr)) {
logAllUnhandledErrors(std::move(E), WithColor::error(errs(), ToolName));
return 1;
}
diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.h b/llvm/tools/llvm-objcopy/llvm-objcopy.h
index 64b554f5c5aa3..182c95dc64c8c 100644
--- a/llvm/tools/llvm-objcopy/llvm-objcopy.h
+++ b/llvm/tools/llvm-objcopy/llvm-objcopy.h
@@ -23,9 +23,10 @@ class Archive;
} // end namespace object
namespace objcopy {
-struct CopyConfig;
+class MultiFormatConfig;
Expected<std::vector<NewArchiveMember>>
-createNewArchiveMembers(CopyConfig &Config, const object::Archive &Ar);
+createNewArchiveMembers(const MultiFormatConfig &Config,
+ const object::Archive &Ar);
} // end namespace objcopy
} // end namespace llvm
diff --git a/llvm/tools/llvm-objcopy/wasm/WasmConfig.h b/llvm/tools/llvm-objcopy/wasm/WasmConfig.h
new file mode 100644
index 0000000000000..4e40926ae4530
--- /dev/null
+++ b/llvm/tools/llvm-objcopy/wasm/WasmConfig.h
@@ -0,0 +1,21 @@
+//===- WasmConfig.h ---------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_OBJCOPY_WASM_WASMCONFIG_H
+#define LLVM_TOOLS_LLVM_OBJCOPY_WASM_WASMCONFIG_H
+
+namespace llvm {
+namespace objcopy {
+
+// Wasm specific configuration for copying/stripping a single file.
+struct WasmConfig {};
+
+} // namespace objcopy
+} // namespace llvm
+
+#endif // LLVM_TOOLS_LLVM_OBJCOPY_WASM_WASMCONFIG_H
diff --git a/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.cpp b/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.cpp
index fa88bee424b8b..75c4749167891 100644
--- a/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.cpp
+++ b/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "WasmObjcopy.h"
-#include "CopyConfig.h"
+#include "CommonConfig.h"
#include "Object.h"
#include "Reader.h"
#include "Writer.h"
@@ -39,7 +39,7 @@ static Error dumpSectionToFile(StringRef SecName, StringRef Filename,
return createStringError(errc::invalid_argument, "section '%s' not found",
SecName.str().c_str());
}
-static Error handleArgs(const CopyConfig &Config, Object &Obj) {
+static Error handleArgs(const CommonConfig &Config, Object &Obj) {
// Only support AddSection, DumpSection, RemoveSection for now.
for (StringRef Flag : Config.DumpSection) {
StringRef SecName;
@@ -72,26 +72,10 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
Obj.addSectionWithOwnedContents(Sec, std::move(Buf));
}
- if (!Config.AddGnuDebugLink.empty() || Config.ExtractPartition ||
- !Config.SplitDWO.empty() || !Config.SymbolsPrefix.empty() ||
- !Config.AllocSectionsPrefix.empty() ||
- Config.DiscardMode != DiscardType::None || Config.NewSymbolVisibility ||
- !Config.SymbolsToAdd.empty() || !Config.RPathToAdd.empty() ||
- !Config.OnlySection.empty() || !Config.SymbolsToGlobalize.empty() ||
- !Config.SymbolsToKeep.empty() || !Config.SymbolsToLocalize.empty() ||
- !Config.SymbolsToRemove.empty() ||
- !Config.UnneededSymbolsToRemove.empty() ||
- !Config.SymbolsToWeaken.empty() || !Config.SymbolsToKeepGlobal.empty() ||
- !Config.SectionsToRename.empty() || !Config.SetSectionAlignment.empty() ||
- !Config.SetSectionFlags.empty() || !Config.SymbolsToRename.empty()) {
- return createStringError(
- llvm::errc::invalid_argument,
- "only add-section, dump-section, and remove-section are supported");
- }
return Error::success();
}
-Error executeObjcopyOnBinary(const CopyConfig &Config,
+Error executeObjcopyOnBinary(const CommonConfig &Config, const WasmConfig &,
object::WasmObjectFile &In, raw_ostream &Out) {
Reader TheReader(In);
Expected<std::unique_ptr<Object>> ObjOrErr = TheReader.create();
diff --git a/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.h b/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.h
index 05a84d7ceb392..28268e38c5849 100644
--- a/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.h
+++ b/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.h
@@ -18,10 +18,11 @@ class WasmObjectFile;
} // end namespace object
namespace objcopy {
-struct CopyConfig;
+struct CommonConfig;
+struct WasmConfig;
namespace wasm {
-Error executeObjcopyOnBinary(const CopyConfig &Config,
+Error executeObjcopyOnBinary(const CommonConfig &Config, const WasmConfig &,
object::WasmObjectFile &In, raw_ostream &Out);
} // end namespace wasm
More information about the llvm-commits
mailing list