forked from OSchip/llvm-project
[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
This commit is contained in:
parent
168b3fb38b
commit
c83eefcfda
|
@ -21,6 +21,7 @@ add_llvm_tool(llvm-objcopy
|
|||
COFF/Object.cpp
|
||||
COFF/Reader.cpp
|
||||
COFF/Writer.cpp
|
||||
ELF/ELFConfig.cpp
|
||||
ELF/ELFObjcopy.cpp
|
||||
ELF/Object.cpp
|
||||
MachO/MachOObjcopy.cpp
|
||||
|
|
|
@ -177,87 +177,6 @@ parseSetSectionFlagValue(StringRef FlagValue) {
|
|||
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 @@ Expected<DriverConfig> parseObjcopyOptions(ArrayRef<const char *> ArgsArr) {
|
|||
.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 @@ Expected<DriverConfig> parseObjcopyOptions(ArrayRef<const char *> ArgsArr) {
|
|||
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);
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#ifndef LLVM_TOOLS_LLVM_OBJCOPY_COPY_CONFIG_H
|
||||
#define LLVM_TOOLS_LLVM_OBJCOPY_COPY_CONFIG_H
|
||||
|
||||
#include "ELF/ELFConfig.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/BitmaskEnum.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
|
@ -111,17 +112,11 @@ public:
|
|||
bool empty() const { return Matchers.empty(); }
|
||||
};
|
||||
|
||||
struct NewSymbolInfo {
|
||||
StringRef SymbolName;
|
||||
StringRef SectionName;
|
||||
uint64_t Value = 0;
|
||||
uint8_t Type = ELF::STT_NOTYPE;
|
||||
uint8_t Bind = ELF::STB_GLOBAL;
|
||||
uint8_t Visibility = ELF::STV_DEFAULT;
|
||||
};
|
||||
|
||||
// Configuration for copying/stripping a single file.
|
||||
struct CopyConfig {
|
||||
// Format-specific options to be initialized lazily when needed.
|
||||
Optional<elf::ELFCopyConfig> ELF;
|
||||
|
||||
// Main input/output options
|
||||
StringRef InputFilename;
|
||||
FileFormat InputFormat;
|
||||
|
@ -143,12 +138,12 @@ struct CopyConfig {
|
|||
StringRef SymbolsPrefix;
|
||||
StringRef AllocSectionsPrefix;
|
||||
DiscardType DiscardMode = DiscardType::None;
|
||||
Optional<uint8_t> NewSymbolVisibility;
|
||||
Optional<StringRef> NewSymbolVisibility;
|
||||
|
||||
// Repeated options
|
||||
std::vector<StringRef> AddSection;
|
||||
std::vector<StringRef> DumpSection;
|
||||
std::vector<NewSymbolInfo> SymbolsToAdd;
|
||||
std::vector<StringRef> SymbolsToAdd;
|
||||
|
||||
// Section matchers
|
||||
NameMatcher KeepSection;
|
||||
|
@ -194,6 +189,18 @@ struct CopyConfig {
|
|||
bool Weaken = false;
|
||||
bool DecompressDebugSections = 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
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
//===- 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
|
|
@ -0,0 +1,44 @@
|
|||
//===- ELFConfig.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_OBJCOPY_ELFCONFIG_H
|
||||
#define LLVM_TOOLS_OBJCOPY_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;
|
||||
StringRef SectionName;
|
||||
uint64_t Value = 0;
|
||||
uint8_t Type = ELF::STT_NOTYPE;
|
||||
uint8_t Bind = ELF::STB_GLOBAL;
|
||||
uint8_t Visibility = ELF::STV_DEFAULT;
|
||||
};
|
||||
|
||||
struct ELFCopyConfig {
|
||||
Optional<uint8_t> NewSymbolVisibility;
|
||||
std::vector<NewSymbolInfo> SymbolsToAdd;
|
||||
};
|
||||
|
||||
Expected<ELFCopyConfig> parseConfig(const CopyConfig &Config);
|
||||
|
||||
} // namespace elf
|
||||
} // namespace objcopy
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
|
@ -710,7 +710,7 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj,
|
|||
Obj.addSection<GnuDebugLinkSection>(Config.AddGnuDebugLink,
|
||||
Config.GnuDebugLinkCRC32);
|
||||
|
||||
for (const NewSymbolInfo &SI : Config.SymbolsToAdd) {
|
||||
for (const NewSymbolInfo &SI : Config.ELF->SymbolsToAdd) {
|
||||
SectionBase *Sec = Obj.findSection(SI.SectionName);
|
||||
uint64_t Value = Sec ? Sec->Addr + SI.Value : SI.Value;
|
||||
Obj.SymbolTable->addSymbol(
|
||||
|
@ -746,7 +746,7 @@ Error executeObjcopyOnIHex(const CopyConfig &Config, MemoryBuffer &In,
|
|||
Error executeObjcopyOnRawBinary(const CopyConfig &Config, MemoryBuffer &In,
|
||||
Buffer &Out) {
|
||||
uint8_t NewSymbolVisibility =
|
||||
Config.NewSymbolVisibility.getValueOr((uint8_t)ELF::STV_DEFAULT);
|
||||
Config.ELF->NewSymbolVisibility.getValueOr((uint8_t)ELF::STV_DEFAULT);
|
||||
BinaryReader Reader(&In, NewSymbolVisibility);
|
||||
std::unique_ptr<Object> Obj = Reader.create();
|
||||
|
||||
|
|
|
@ -132,16 +132,18 @@ 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(const CopyConfig &Config, MemoryBuffer &In,
|
||||
static Error executeObjcopyOnIHex(CopyConfig &Config, MemoryBuffer &In,
|
||||
Buffer &Out) {
|
||||
// TODO: support output formats other than ELF.
|
||||
if (Error E = Config.parseELFConfig())
|
||||
return E;
|
||||
return elf::executeObjcopyOnIHex(Config, In, Out);
|
||||
}
|
||||
|
||||
/// The function executeObjcopyOnRawBinary does the dispatch based on the format
|
||||
/// of the output specified by the command line options.
|
||||
static Error executeObjcopyOnRawBinary(const CopyConfig &Config,
|
||||
MemoryBuffer &In, Buffer &Out) {
|
||||
static Error executeObjcopyOnRawBinary(CopyConfig &Config, MemoryBuffer &In,
|
||||
Buffer &Out) {
|
||||
switch (Config.OutputFormat) {
|
||||
case FileFormat::ELF:
|
||||
// FIXME: Currently, we call elf::executeObjcopyOnRawBinary even if the
|
||||
|
@ -150,6 +152,8 @@ static Error executeObjcopyOnRawBinary(const CopyConfig &Config,
|
|||
case FileFormat::Binary:
|
||||
case FileFormat::IHex:
|
||||
case FileFormat::Unspecified:
|
||||
if (Error E = Config.parseELFConfig())
|
||||
return E;
|
||||
return elf::executeObjcopyOnRawBinary(Config, In, Out);
|
||||
}
|
||||
|
||||
|
@ -158,11 +162,13 @@ static Error executeObjcopyOnRawBinary(const CopyConfig &Config,
|
|||
|
||||
/// The function executeObjcopyOnBinary does the dispatch based on the format
|
||||
/// of the input binary (ELF, MachO or COFF).
|
||||
static Error executeObjcopyOnBinary(const CopyConfig &Config,
|
||||
object::Binary &In, Buffer &Out) {
|
||||
if (auto *ELFBinary = dyn_cast<object::ELFObjectFileBase>(&In))
|
||||
static Error executeObjcopyOnBinary(CopyConfig &Config, object::Binary &In,
|
||||
Buffer &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))
|
||||
} 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);
|
||||
|
@ -171,8 +177,7 @@ static Error executeObjcopyOnBinary(const CopyConfig &Config,
|
|||
"unsupported object file format");
|
||||
}
|
||||
|
||||
static Error executeObjcopyOnArchive(const CopyConfig &Config,
|
||||
const Archive &Ar) {
|
||||
static Error executeObjcopyOnArchive(CopyConfig &Config, const Archive &Ar) {
|
||||
std::vector<NewArchiveMember> NewArchiveMembers;
|
||||
Error Err = Error::success();
|
||||
for (const Archive::Child &Child : Ar.children(Err)) {
|
||||
|
@ -248,7 +253,7 @@ 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(const CopyConfig &Config) {
|
||||
static Error executeObjcopy(CopyConfig &Config) {
|
||||
sys::fs::file_status Stat;
|
||||
if (Config.InputFilename != "-") {
|
||||
if (auto EC = sys::fs::status(Config.InputFilename, Stat))
|
||||
|
@ -257,7 +262,7 @@ static Error executeObjcopy(const CopyConfig &Config) {
|
|||
Stat.permissions(static_cast<sys::fs::perms>(0777));
|
||||
}
|
||||
|
||||
typedef Error (*ProcessRawFn)(const CopyConfig &, MemoryBuffer &, Buffer &);
|
||||
using ProcessRawFn = Error (*)(CopyConfig &, MemoryBuffer &, Buffer &);
|
||||
ProcessRawFn ProcessRaw;
|
||||
switch (Config.InputFormat) {
|
||||
case FileFormat::Binary:
|
||||
|
@ -336,7 +341,7 @@ int main(int argc, char **argv) {
|
|||
WithColor::error(errs(), ToolName));
|
||||
return 1;
|
||||
}
|
||||
for (const CopyConfig &CopyConfig : DriverConfig->CopyConfigs) {
|
||||
for (CopyConfig &CopyConfig : DriverConfig->CopyConfigs) {
|
||||
if (Error E = executeObjcopy(CopyConfig)) {
|
||||
logAllUnhandledErrors(std::move(E), WithColor::error(errs(), ToolName));
|
||||
return 1;
|
||||
|
|
Loading…
Reference in New Issue