diff options
author | Jordan Rupprecht <rupprecht@google.com> | 2018-08-17 18:51:11 +0000 |
---|---|---|
committer | Jordan Rupprecht <rupprecht@google.com> | 2018-08-17 18:51:11 +0000 |
commit | cf67633e66de0853ed061dd38960623209aa9dba (patch) | |
tree | 94c5ddb942206dd032741ffe052c4e957f85050c /llvm/tools/llvm-objcopy/Object.h | |
parent | da5864c73c454441fe1ffdb309d5022eeda3f284 (diff) | |
download | bcm5719-llvm-cf67633e66de0853ed061dd38960623209aa9dba.tar.gz bcm5719-llvm-cf67633e66de0853ed061dd38960623209aa9dba.zip |
[llvm-objcopy] Add support for -I binary -B <arch>.
Summary:
The -I (--input-target) and -B (--binary-architecture) flags exist but are currently silently ignored. This adds support for -I binary for architectures i386, x86-64 (and alias i386:x86-64), arm, aarch64, sparc, and ppc (powerpc:common64). This is largely based on D41687.
This is done by implementing an additional subclass of Reader, BinaryReader, which works by interpreting the input file as contents for .data field, sets up a synthetic header, and adds additional sections/symbols (e.g. _binary__tmp_data_txt_start).
Reviewers: jakehehrlich, alexshap, jhenderson, javed.absar
Reviewed By: jhenderson
Subscribers: jyknight, nemanjai, kbarton, fedor.sergeev, jrtc27, kristof.beyls, paulsemel, llvm-commits
Differential Revision: https://reviews.llvm.org/D50343
llvm-svn: 340070
Diffstat (limited to 'llvm/tools/llvm-objcopy/Object.h')
-rw-r--r-- | llvm/tools/llvm-objcopy/Object.h | 54 |
1 files changed, 48 insertions, 6 deletions
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) { |