summaryrefslogtreecommitdiffstats
path: root/llvm/tools
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools')
-rw-r--r--llvm/tools/llvm-objcopy/Object.cpp147
-rw-r--r--llvm/tools/llvm-objcopy/Object.h54
-rw-r--r--llvm/tools/llvm-objcopy/llvm-objcopy.cpp136
3 files changed, 273 insertions, 64 deletions
diff --git a/llvm/tools/llvm-objcopy/Object.cpp b/llvm/tools/llvm-objcopy/Object.cpp
index 1fb0de81c8b..12fd80228bf 100644
--- a/llvm/tools/llvm-objcopy/Object.cpp
+++ b/llvm/tools/llvm-objcopy/Object.cpp
@@ -230,12 +230,12 @@ void SymbolTableSection::assignIndices() {
Sym->Index = Index++;
}
-void SymbolTableSection::addSymbol(StringRef Name, uint8_t Bind, uint8_t Type,
+void SymbolTableSection::addSymbol(Twine Name, uint8_t Bind, uint8_t Type,
SectionBase *DefinedIn, uint64_t Value,
uint8_t Visibility, uint16_t Shndx,
- uint64_t Sz) {
+ uint64_t Size) {
Symbol Sym;
- Sym.Name = Name;
+ Sym.Name = Name.str();
Sym.Binding = Bind;
Sym.Type = Type;
Sym.DefinedIn = DefinedIn;
@@ -249,7 +249,7 @@ void SymbolTableSection::addSymbol(StringRef Name, uint8_t Bind, uint8_t Type,
}
Sym.Value = Value;
Sym.Visibility = Visibility;
- Sym.Size = Sz;
+ Sym.Size = Size;
Sym.Index = Symbols.size();
Symbols.emplace_back(llvm::make_unique<Symbol>(Sym));
Size += this->EntrySize;
@@ -587,6 +587,84 @@ static bool compareSegmentsByPAddr(const Segment *A, const Segment *B) {
return A->Index < B->Index;
}
+template <class ELFT> void BinaryELFBuilder<ELFT>::initFileHeader() {
+ Obj->Flags = 0x0;
+ Obj->Type = ET_REL;
+ Obj->Entry = 0x0;
+ Obj->Machine = EMachine;
+ Obj->Version = 1;
+}
+
+template <class ELFT> void BinaryELFBuilder<ELFT>::initHeaderSegment() {
+ Obj->ElfHdrSegment.Index = 0;
+}
+
+template <class ELFT> StringTableSection *BinaryELFBuilder<ELFT>::addStrTab() {
+ auto &StrTab = Obj->addSection<StringTableSection>();
+ StrTab.Name = ".strtab";
+
+ Obj->SectionNames = &StrTab;
+ return &StrTab;
+}
+
+template <class ELFT>
+SymbolTableSection *
+BinaryELFBuilder<ELFT>::addSymTab(StringTableSection *StrTab) {
+ auto &SymTab = Obj->addSection<SymbolTableSection>();
+
+ SymTab.Name = ".symtab";
+ SymTab.Link = StrTab->Index;
+ // TODO: Factor out dependence on ElfType here.
+ SymTab.EntrySize = sizeof(Elf_Sym);
+
+ // The symbol table always needs a null symbol
+ SymTab.addSymbol("", 0, 0, nullptr, 0, 0, 0, 0);
+
+ Obj->SymbolTable = &SymTab;
+ return &SymTab;
+}
+
+template <class ELFT>
+void BinaryELFBuilder<ELFT>::addData(SymbolTableSection *SymTab) {
+ auto Data = ArrayRef<uint8_t>(
+ reinterpret_cast<const uint8_t *>(MemBuf->getBufferStart()),
+ MemBuf->getBufferSize());
+ auto &DataSection = Obj->addSection<Section>(Data);
+ DataSection.Name = ".data";
+ DataSection.Type = ELF::SHT_PROGBITS;
+ DataSection.Size = Data.size();
+ DataSection.Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE;
+
+ std::string SanitizedFilename = MemBuf->getBufferIdentifier().str();
+ std::replace_if(std::begin(SanitizedFilename), std::end(SanitizedFilename),
+ [](char c) { return !isalnum(c); }, '_');
+ Twine Prefix = Twine("_binary_") + SanitizedFilename;
+
+ SymTab->addSymbol(Prefix + "_start", STB_GLOBAL, STT_NOTYPE, &DataSection,
+ /*Value=*/0, STV_DEFAULT, 0, 0);
+ SymTab->addSymbol(Prefix + "_end", STB_GLOBAL, STT_NOTYPE, &DataSection,
+ /*Value=*/DataSection.Size, STV_DEFAULT, 0, 0);
+ SymTab->addSymbol(Prefix + "_size", STB_GLOBAL, STT_NOTYPE, nullptr,
+ /*Value=*/DataSection.Size, STV_DEFAULT, SHN_ABS, 0);
+}
+
+template <class ELFT> void BinaryELFBuilder<ELFT>::initSections() {
+ for (auto &Section : Obj->sections()) {
+ Section.initialize(Obj->sections());
+ }
+}
+
+template <class ELFT> std::unique_ptr<Object> BinaryELFBuilder<ELFT>::build() {
+ initFileHeader();
+ initHeaderSegment();
+ StringTableSection *StrTab = addStrTab();
+ SymbolTableSection *SymTab = addSymTab(StrTab);
+ initSections();
+ addData(SymTab);
+
+ return std::move(Obj);
+}
+
template <class ELFT> void ELFBuilder<ELFT>::setParentSegment(Segment &Child) {
for (auto &Parent : Obj.segments()) {
// Every segment will overlap with itself but we don't want a segment to
@@ -631,15 +709,6 @@ template <class ELFT> void ELFBuilder<ELFT>::readProgramHeaders() {
}
auto &ElfHdr = Obj.ElfHdrSegment;
- // Creating multiple PT_PHDR segments technically is not valid, but PT_LOAD
- // segments must not overlap, and other types fit even less.
- ElfHdr.Type = PT_PHDR;
- ElfHdr.Flags = 0;
- ElfHdr.OriginalOffset = ElfHdr.Offset = 0;
- ElfHdr.VAddr = 0;
- ElfHdr.PAddr = 0;
- ElfHdr.FileSize = ElfHdr.MemSize = sizeof(Elf_Ehdr);
- ElfHdr.Align = 0;
ElfHdr.Index = Index++;
const auto &Ehdr = *ElfFile.getHeader();
@@ -894,7 +963,6 @@ template <class ELFT> void ELFBuilder<ELFT>::readSectionHeaders() {
template <class ELFT> void ELFBuilder<ELFT>::build() {
const auto &Ehdr = *ElfFile.getHeader();
- std::copy(Ehdr.e_ident, Ehdr.e_ident + 16, Obj.Ident);
Obj.Type = Ehdr.e_type;
Obj.Machine = Ehdr.e_machine;
Obj.Version = Ehdr.e_version;
@@ -926,16 +994,15 @@ Writer::~Writer() {}
Reader::~Reader() {}
-ElfType ELFReader::getElfType() const {
- if (isa<ELFObjectFile<ELF32LE>>(Bin))
- return ELFT_ELF32LE;
- if (isa<ELFObjectFile<ELF64LE>>(Bin))
- return ELFT_ELF64LE;
- if (isa<ELFObjectFile<ELF32BE>>(Bin))
- return ELFT_ELF32BE;
- if (isa<ELFObjectFile<ELF64BE>>(Bin))
- return ELFT_ELF64BE;
- llvm_unreachable("Invalid ELFType");
+std::unique_ptr<Object> BinaryReader::create() const {
+ if (MInfo.Is64Bit)
+ return MInfo.IsLittleEndian
+ ? BinaryELFBuilder<ELF64LE>(MInfo.EMachine, MemBuf).build()
+ : BinaryELFBuilder<ELF64BE>(MInfo.EMachine, MemBuf).build();
+ else
+ return MInfo.IsLittleEndian
+ ? BinaryELFBuilder<ELF32LE>(MInfo.EMachine, MemBuf).build()
+ : BinaryELFBuilder<ELF32BE>(MInfo.EMachine, MemBuf).build();
}
std::unique_ptr<Object> ELFReader::create() const {
@@ -963,11 +1030,24 @@ std::unique_ptr<Object> ELFReader::create() const {
template <class ELFT> void ELFWriter<ELFT>::writeEhdr() {
uint8_t *B = Buf.getBufferStart();
Elf_Ehdr &Ehdr = *reinterpret_cast<Elf_Ehdr *>(B);
- std::copy(Obj.Ident, Obj.Ident + 16, Ehdr.e_ident);
+ std::fill(Ehdr.e_ident, Ehdr.e_ident + 16, 0);
+ Ehdr.e_ident[EI_MAG0] = 0x7f;
+ Ehdr.e_ident[EI_MAG1] = 'E';
+ Ehdr.e_ident[EI_MAG2] = 'L';
+ Ehdr.e_ident[EI_MAG3] = 'F';
+ Ehdr.e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32;
+ Ehdr.e_ident[EI_DATA] =
+ ELFT::TargetEndianness == support::big ? ELFDATA2MSB : ELFDATA2LSB;
+ Ehdr.e_ident[EI_VERSION] = EV_CURRENT;
+ Ehdr.e_ident[EI_OSABI] = ELFOSABI_NONE;
+ Ehdr.e_ident[EI_ABIVERSION] = 0;
+
Ehdr.e_type = Obj.Type;
Ehdr.e_machine = Obj.Machine;
Ehdr.e_version = Obj.Version;
Ehdr.e_entry = Obj.Entry;
+ // TODO: Only set phoff when a program header exists, to avoid tools
+ // thinking this is corrupt data.
Ehdr.e_phoff = Obj.ProgramHdrSegment.Offset;
Ehdr.e_flags = Obj.Flags;
Ehdr.e_ehsize = sizeof(Elf_Ehdr);
@@ -1172,6 +1252,17 @@ static uint64_t LayoutSections(Range Sections, uint64_t Offset) {
return Offset;
}
+template <class ELFT> void ELFWriter<ELFT>::initEhdrSegment() {
+ auto &ElfHdr = Obj.ElfHdrSegment;
+ ElfHdr.Type = PT_PHDR;
+ ElfHdr.Flags = 0;
+ ElfHdr.OriginalOffset = ElfHdr.Offset = 0;
+ ElfHdr.VAddr = 0;
+ ElfHdr.PAddr = 0;
+ ElfHdr.FileSize = ElfHdr.MemSize = sizeof(Elf_Ehdr);
+ ElfHdr.Align = 0;
+}
+
template <class ELFT> void ELFWriter<ELFT>::assignOffsets() {
// We need a temporary list of segments that has a special order to it
// so that we know that anytime ->ParentSegment is set that segment has
@@ -1263,6 +1354,7 @@ template <class ELFT> void ELFWriter<ELFT>::finalize() {
Obj.SectionNames->addString(Section.Name);
}
+ initEhdrSegment();
// Before we can prepare for layout the indexes need to be finalized.
uint64_t Index = 0;
for (auto &Sec : Obj.sections())
@@ -1390,6 +1482,11 @@ void BinaryWriter::finalize() {
namespace llvm {
namespace objcopy {
+template class BinaryELFBuilder<ELF64LE>;
+template class BinaryELFBuilder<ELF64BE>;
+template class BinaryELFBuilder<ELF32LE>;
+template class BinaryELFBuilder<ELF32BE>;
+
template class ELFBuilder<ELF64LE>;
template class ELFBuilder<ELF64BE>;
template class ELFBuilder<ELF32LE>;
diff --git a/llvm/tools/llvm-objcopy/Object.h b/llvm/tools/llvm-objcopy/Object.h
index cabab03abd2..e9a4c35d398 100644
--- a/llvm/tools/llvm-objcopy/Object.h
+++ b/llvm/tools/llvm-objcopy/Object.h
@@ -64,6 +64,15 @@ public:
enum ElfType { ELFT_ELF32LE, ELFT_ELF64LE, ELFT_ELF32BE, ELFT_ELF64BE };
+// This type keeps track of the machine info for various architectures. This
+// lets us map architecture names to ELF types and the e_machine value of the
+// ELF file.
+struct MachineInfo {
+ uint16_t EMachine;
+ bool Is64Bit;
+ bool IsLittleEndian;
+};
+
class SectionVisitor {
public:
virtual ~SectionVisitor();
@@ -196,6 +205,8 @@ private:
using Elf_Phdr = typename ELFT::Phdr;
using Elf_Ehdr = typename ELFT::Ehdr;
+ void initEhdrSegment();
+
void writeEhdr();
void writePhdr(const Segment &Seg);
void writeShdr(const SectionBase &Sec);
@@ -440,9 +451,11 @@ protected:
using SymPtr = std::unique_ptr<Symbol>;
public:
- void addSymbol(StringRef Name, uint8_t Bind, uint8_t Type,
- SectionBase *DefinedIn, uint64_t Value, uint8_t Visibility,
- uint16_t Shndx, uint64_t Sz);
+ SymbolTableSection() { Type = ELF::SHT_SYMTAB; }
+
+ void addSymbol(Twine Name, uint8_t Bind, uint8_t Type, SectionBase *DefinedIn,
+ uint64_t Value, uint8_t Visibility, uint16_t Shndx,
+ uint64_t Size);
void prepareForLayout();
// An 'empty' symbol table still contains a null symbol.
bool empty() const { return Symbols.size() == 1; }
@@ -626,11 +639,31 @@ using object::ELFFile;
using object::ELFObjectFile;
using object::OwningBinary;
+template <class ELFT> class BinaryELFBuilder {
+ using Elf_Sym = typename ELFT::Sym;
+
+ uint16_t EMachine;
+ MemoryBuffer *MemBuf;
+ std::unique_ptr<Object> Obj;
+
+ void initFileHeader();
+ void initHeaderSegment();
+ StringTableSection *addStrTab();
+ SymbolTableSection *addSymTab(StringTableSection *StrTab);
+ void addData(SymbolTableSection *SymTab);
+ void initSections();
+
+public:
+ BinaryELFBuilder(uint16_t EM, MemoryBuffer *MB)
+ : EMachine(EM), MemBuf(MB), Obj(llvm::make_unique<Object>()) {}
+
+ std::unique_ptr<Object> build();
+};
+
template <class ELFT> class ELFBuilder {
private:
using Elf_Addr = typename ELFT::Addr;
using Elf_Shdr = typename ELFT::Shdr;
- using Elf_Ehdr = typename ELFT::Ehdr;
using Elf_Word = typename ELFT::Word;
const ELFFile<ELFT> &ElfFile;
@@ -650,11 +683,20 @@ public:
void build();
};
+class BinaryReader : public Reader {
+ const MachineInfo &MInfo;
+ MemoryBuffer *MemBuf;
+
+public:
+ BinaryReader(const MachineInfo &MI, MemoryBuffer *MB)
+ : MInfo(MI), MemBuf(MB) {}
+ std::unique_ptr<Object> create() const override;
+};
+
class ELFReader : public Reader {
Binary *Bin;
public:
- ElfType getElfType() const;
std::unique_ptr<Object> create() const override;
explicit ELFReader(Binary *B) : Bin(B) {}
};
@@ -685,7 +727,6 @@ public:
Segment ElfHdrSegment;
Segment ProgramHdrSegment;
- uint8_t Ident[16];
uint64_t Entry;
uint64_t SHOffset;
uint32_t Type;
@@ -711,6 +752,7 @@ public:
auto Sec = llvm::make_unique<T>(std::forward<Ts>(Args)...);
auto Ptr = Sec.get();
Sections.emplace_back(std::move(Sec));
+ Ptr->Index = Sections.size();
return *Ptr;
}
Segment &addSegment(ArrayRef<uint8_t> Data) {
diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
index ca6609f9a99..7713aa6f42b 100644
--- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
+++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
@@ -34,6 +34,7 @@
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileOutputBuffer.h"
#include "llvm/Support/InitLLVM.h"
+#include "llvm/Support/Memory.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/WithColor.h"
@@ -128,41 +129,51 @@ struct SectionRename {
};
struct CopyConfig {
- StringRef OutputFilename;
+ // Main input/output options
StringRef InputFilename;
- StringRef OutputFormat;
StringRef InputFormat;
- StringRef BinaryArch;
+ StringRef OutputFilename;
+ StringRef OutputFormat;
- StringRef SplitDWO;
+ // Only applicable for --input-format=Binary
+ MachineInfo BinaryArch;
+
+ // Advanced options
StringRef AddGnuDebugLink;
+ StringRef SplitDWO;
StringRef SymbolsPrefix;
- std::vector<StringRef> ToRemove;
- std::vector<StringRef> Keep;
- std::vector<StringRef> OnlyKeep;
+
+ // Repeated options
std::vector<StringRef> AddSection;
std::vector<StringRef> DumpSection;
- std::vector<StringRef> SymbolsToLocalize;
+ std::vector<StringRef> Keep;
+ std::vector<StringRef> OnlyKeep;
std::vector<StringRef> SymbolsToGlobalize;
- std::vector<StringRef> SymbolsToWeaken;
- std::vector<StringRef> SymbolsToRemove;
std::vector<StringRef> SymbolsToKeep;
+ std::vector<StringRef> SymbolsToLocalize;
+ std::vector<StringRef> SymbolsToRemove;
+ std::vector<StringRef> SymbolsToWeaken;
+ std::vector<StringRef> ToRemove;
+
+ // Map options
StringMap<SectionRename> SectionsToRename;
StringMap<StringRef> SymbolsToRename;
+
+ // Boolean options
+ bool DiscardAll = false;
+ bool ExtractDWO = false;
+ bool KeepFileSymbols = false;
+ bool LocalizeHidden = false;
+ bool OnlyKeepDebug = false;
+ bool PreserveDates = false;
bool StripAll = false;
bool StripAllGNU = false;
+ bool StripDWO = false;
bool StripDebug = false;
- bool StripSections = false;
bool StripNonAlloc = false;
- bool StripDWO = false;
+ bool StripSections = false;
bool StripUnneeded = false;
- bool ExtractDWO = false;
- bool LocalizeHidden = false;
bool Weaken = false;
- bool DiscardAll = false;
- bool OnlyKeepDebug = false;
- bool KeepFileSymbols = false;
- bool PreserveDates = false;
};
using SectionPred = std::function<bool(const SectionBase &Sec)>;
@@ -295,6 +306,45 @@ static bool onlyKeepDWOPred(const Object &Obj, const SectionBase &Sec) {
return !isDWOSection(Sec);
}
+static const StringMap<MachineInfo> ArchMap{
+ // Name, {EMachine, 64bit, LittleEndian}
+ {"aarch64", {EM_AARCH64, true, true}},
+ {"arm", {EM_ARM, false, true}},
+ {"i386", {EM_386, false, true}},
+ {"i386:x86-64", {EM_X86_64, true, true}},
+ {"powerpc:common64", {EM_PPC64, true, true}},
+ {"sparc", {EM_SPARC, false, true}},
+ {"x86-64", {EM_X86_64, true, true}},
+};
+
+static const MachineInfo &getMachineInfo(StringRef Arch) {
+ auto Iter = ArchMap.find(Arch);
+ if (Iter == std::end(ArchMap))
+ error("Invalid architecture: '" + Arch + "'");
+ return Iter->getValue();
+}
+
+static ElfType getOutputElfType(const Binary &Bin) {
+ // Infer output ELF type from the input ELF object
+ if (isa<ELFObjectFile<ELF32LE>>(Bin))
+ return ELFT_ELF32LE;
+ if (isa<ELFObjectFile<ELF64LE>>(Bin))
+ return ELFT_ELF64LE;
+ if (isa<ELFObjectFile<ELF32BE>>(Bin))
+ return ELFT_ELF32BE;
+ if (isa<ELFObjectFile<ELF64BE>>(Bin))
+ return ELFT_ELF64BE;
+ llvm_unreachable("Invalid ELFType");
+}
+
+static ElfType getOutputElfType(const MachineInfo &MI) {
+ // Infer output ELF type from the binary arch specified
+ if (MI.Is64Bit)
+ return MI.IsLittleEndian ? ELFT_ELF64LE : ELFT_ELF64BE;
+ else
+ return MI.IsLittleEndian ? ELFT_ELF32LE : ELFT_ELF32BE;
+}
+
static std::unique_ptr<Writer> createWriter(const CopyConfig &Config,
Object &Obj, Buffer &Buf,
ElfType OutputElfType) {
@@ -603,15 +653,14 @@ static void handleArgs(const CopyConfig &Config, Object &Obj,
Obj.addSection<GnuDebugLinkSection>(Config.AddGnuDebugLink);
}
-static void executeElfObjcopyOnBinary(const CopyConfig &Config, Binary &Binary,
- Buffer &Out) {
- ELFReader Reader(&Binary);
+static void executeElfObjcopyOnBinary(const CopyConfig &Config, Reader &Reader,
+ Buffer &Out, ElfType OutputElfType) {
std::unique_ptr<Object> Obj = Reader.create();
- handleArgs(Config, *Obj, Reader, Reader.getElfType());
+ handleArgs(Config, *Obj, Reader, OutputElfType);
std::unique_ptr<Writer> Writer =
- createWriter(Config, *Obj, Out, Reader.getElfType());
+ createWriter(Config, *Obj, Out, OutputElfType);
Writer->finalize();
Writer->write();
}
@@ -653,12 +702,15 @@ static void executeElfObjcopyOnArchive(const CopyConfig &Config,
Expected<std::unique_ptr<Binary>> ChildOrErr = Child.getAsBinary();
if (!ChildOrErr)
reportError(Ar.getFileName(), ChildOrErr.takeError());
+ Binary *Bin = ChildOrErr->get();
+
Expected<StringRef> ChildNameOrErr = Child.getName();
if (!ChildNameOrErr)
reportError(Ar.getFileName(), ChildNameOrErr.takeError());
MemBuffer MB(ChildNameOrErr.get());
- executeElfObjcopyOnBinary(Config, **ChildOrErr, MB);
+ ELFReader Reader(Bin);
+ executeElfObjcopyOnBinary(Config, Reader, MB, getOutputElfType(*Bin));
Expected<NewArchiveMember> Member =
NewArchiveMember::getOldMember(Child, true);
@@ -698,16 +750,29 @@ static void executeElfObjcopy(const CopyConfig &Config) {
if (auto EC = sys::fs::status(Config.InputFilename, Stat))
reportError(Config.InputFilename, EC);
- Expected<OwningBinary<llvm::object::Binary>> BinaryOrErr =
- createBinary(Config.InputFilename);
- if (!BinaryOrErr)
- reportError(Config.InputFilename, BinaryOrErr.takeError());
+ if (Config.InputFormat == "binary") {
+ auto BufOrErr = MemoryBuffer::getFile(Config.InputFilename);
+ if (!BufOrErr)
+ reportError(Config.InputFilename, BufOrErr.getError());
- if (Archive *Ar = dyn_cast<Archive>(BinaryOrErr.get().getBinary())) {
- executeElfObjcopyOnArchive(Config, *Ar);
- } else {
FileBuffer FB(Config.OutputFilename);
- executeElfObjcopyOnBinary(Config, *BinaryOrErr.get().getBinary(), FB);
+ BinaryReader Reader(Config.BinaryArch, BufOrErr->get());
+ executeElfObjcopyOnBinary(Config, Reader, FB,
+ getOutputElfType(Config.BinaryArch));
+ } else {
+ Expected<OwningBinary<llvm::object::Binary>> BinaryOrErr =
+ createBinary(Config.InputFilename);
+ if (!BinaryOrErr)
+ reportError(Config.InputFilename, BinaryOrErr.takeError());
+
+ if (Archive *Ar = dyn_cast<Archive>(BinaryOrErr.get().getBinary())) {
+ executeElfObjcopyOnArchive(Config, *Ar);
+ } else {
+ FileBuffer FB(Config.OutputFilename);
+ Binary *Bin = BinaryOrErr.get().getBinary();
+ ELFReader Reader(Bin);
+ executeElfObjcopyOnBinary(Config, Reader, FB, getOutputElfType(*Bin));
+ }
}
if (Config.PreserveDates) {
@@ -755,7 +820,12 @@ static CopyConfig parseObjcopyOptions(ArrayRef<const char *> ArgsArr) {
Config.OutputFilename = Positional[Positional.size() == 1 ? 0 : 1];
Config.InputFormat = InputArgs.getLastArgValue(OBJCOPY_input_target);
Config.OutputFormat = InputArgs.getLastArgValue(OBJCOPY_output_target);
- Config.BinaryArch = InputArgs.getLastArgValue(OBJCOPY_binary_architecture);
+ if (Config.InputFormat == "binary") {
+ auto BinaryArch = InputArgs.getLastArgValue(OBJCOPY_binary_architecture);
+ if (BinaryArch.empty())
+ error("Specified binary input without specifiying an architecture");
+ Config.BinaryArch = getMachineInfo(BinaryArch);
+ }
Config.SplitDWO = InputArgs.getLastArgValue(OBJCOPY_split_dwo);
Config.AddGnuDebugLink = InputArgs.getLastArgValue(OBJCOPY_add_gnu_debuglink);
OpenPOWER on IntegriCloud