diff options
author | Alexander Shaposhnikov <shal1t712@gmail.com> | 2018-07-06 17:51:03 +0000 |
---|---|---|
committer | Alexander Shaposhnikov <shal1t712@gmail.com> | 2018-07-06 17:51:03 +0000 |
commit | 42b5ef026908953c823b4849ea1b9d3955c5c172 (patch) | |
tree | 92707c71aa6f0cdab6520566d54f9436a07eee9f /llvm/tools/llvm-objcopy/Object.cpp | |
parent | 573958773514f18bbd0ffc13b38ee853d0e32c5a (diff) | |
download | bcm5719-llvm-42b5ef026908953c823b4849ea1b9d3955c5c172.tar.gz bcm5719-llvm-42b5ef026908953c823b4849ea1b9d3955c5c172.zip |
[llvm-objcopy] Add support for static libraries
This diff adds support for handling static libraries
to llvm-objcopy and llvm-strip.
Test plan: make check-all
Differential revision: https://reviews.llvm.org/D48413
llvm-svn: 336455
Diffstat (limited to 'llvm/tools/llvm-objcopy/Object.cpp')
-rw-r--r-- | llvm/tools/llvm-objcopy/Object.cpp | 104 |
1 files changed, 58 insertions, 46 deletions
diff --git a/llvm/tools/llvm-objcopy/Object.cpp b/llvm/tools/llvm-objcopy/Object.cpp index 68420670d52..f803ffe1d81 100644 --- a/llvm/tools/llvm-objcopy/Object.cpp +++ b/llvm/tools/llvm-objcopy/Object.cpp @@ -30,12 +30,43 @@ using namespace llvm; using namespace object; using namespace ELF; +Buffer::~Buffer() {} + +void FileBuffer::allocate(size_t Size) { + Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr = + FileOutputBuffer::create(getName(), Size, FileOutputBuffer::F_executable); + handleAllErrors(BufferOrErr.takeError(), [this](const ErrorInfoBase &E) { + error("failed to open " + getName() + ": " + E.message()); + }); + Buf = std::move(*BufferOrErr); +} + +Error FileBuffer::commit() { return Buf->commit(); } + +uint8_t *FileBuffer::getBufferStart() { + return reinterpret_cast<uint8_t *>(Buf->getBufferStart()); +} + +void MemBuffer::allocate(size_t Size) { + Buf = WritableMemoryBuffer::getNewMemBuffer(Size, getName()); +} + +Error MemBuffer::commit() { return Error::success(); } + +uint8_t *MemBuffer::getBufferStart() { + return reinterpret_cast<uint8_t *>(Buf->getBufferStart()); +} + +std::unique_ptr<WritableMemoryBuffer> MemBuffer::releaseMemoryBuffer() { + return std::move(Buf); +} + template <class ELFT> void ELFWriter<ELFT>::writePhdr(const Segment &Seg) { using Elf_Phdr = typename ELFT::Phdr; - uint8_t *Buf = BufPtr->getBufferStart(); - Buf += Obj.ProgramHdrSegment.Offset + Seg.Index * sizeof(Elf_Phdr); - Elf_Phdr &Phdr = *reinterpret_cast<Elf_Phdr *>(Buf); + uint8_t *B = Buf.getBufferStart(); + B += Obj.ProgramHdrSegment.Offset + Seg.Index * sizeof(Elf_Phdr); + Elf_Phdr &Phdr = *reinterpret_cast<Elf_Phdr *>(B); Phdr.p_type = Seg.Type; Phdr.p_flags = Seg.Flags; Phdr.p_offset = Seg.Offset; @@ -53,9 +84,9 @@ void SectionBase::finalize() {} void SectionBase::markSymbols() {} template <class ELFT> void ELFWriter<ELFT>::writeShdr(const SectionBase &Sec) { - uint8_t *Buf = BufPtr->getBufferStart(); - Buf += Sec.HeaderOffset; - typename ELFT::Shdr &Shdr = *reinterpret_cast<typename ELFT::Shdr *>(Buf); + uint8_t *B = Buf.getBufferStart(); + B += Sec.HeaderOffset; + typename ELFT::Shdr &Shdr = *reinterpret_cast<typename ELFT::Shdr *>(B); Shdr.sh_name = Sec.NameIndex; Shdr.sh_type = Sec.Type; Shdr.sh_flags = Sec.Flags; @@ -410,9 +441,7 @@ void Section::initialize(SectionTableRef SecTable) { } } -void Section::finalize() { - this->Link = LinkSection ? LinkSection->Index : 0; -} +void Section::finalize() { this->Link = LinkSection ? LinkSection->Index : 0; } void GnuDebugLinkSection::init(StringRef File, StringRef Data) { FileName = sys::path::filename(File); @@ -814,41 +843,33 @@ Writer::~Writer() {} Reader::~Reader() {} -ELFReader::ELFReader(StringRef File) { - auto BinaryOrErr = createBinary(File); - if (!BinaryOrErr) - reportError(File, BinaryOrErr.takeError()); - auto OwnedBin = std::move(BinaryOrErr.get()); - std::tie(Bin, Data) = OwnedBin.takeBinary(); -} - ElfType ELFReader::getElfType() const { - if (isa<ELFObjectFile<ELF32LE>>(Bin.get())) + if (isa<ELFObjectFile<ELF32LE>>(Bin)) return ELFT_ELF32LE; - if (isa<ELFObjectFile<ELF64LE>>(Bin.get())) + if (isa<ELFObjectFile<ELF64LE>>(Bin)) return ELFT_ELF64LE; - if (isa<ELFObjectFile<ELF32BE>>(Bin.get())) + if (isa<ELFObjectFile<ELF32BE>>(Bin)) return ELFT_ELF32BE; - if (isa<ELFObjectFile<ELF64BE>>(Bin.get())) + if (isa<ELFObjectFile<ELF64BE>>(Bin)) return ELFT_ELF64BE; llvm_unreachable("Invalid ELFType"); } std::unique_ptr<Object> ELFReader::create() const { auto Obj = llvm::make_unique<Object>(); - if (auto *o = dyn_cast<ELFObjectFile<ELF32LE>>(Bin.get())) { + if (auto *o = dyn_cast<ELFObjectFile<ELF32LE>>(Bin)) { ELFBuilder<ELF32LE> Builder(*o, *Obj); Builder.build(); return Obj; - } else if (auto *o = dyn_cast<ELFObjectFile<ELF64LE>>(Bin.get())) { + } else if (auto *o = dyn_cast<ELFObjectFile<ELF64LE>>(Bin)) { ELFBuilder<ELF64LE> Builder(*o, *Obj); Builder.build(); return Obj; - } else if (auto *o = dyn_cast<ELFObjectFile<ELF32BE>>(Bin.get())) { + } else if (auto *o = dyn_cast<ELFObjectFile<ELF32BE>>(Bin)) { ELFBuilder<ELF32BE> Builder(*o, *Obj); Builder.build(); return Obj; - } else if (auto *o = dyn_cast<ELFObjectFile<ELF64BE>>(Bin.get())) { + } else if (auto *o = dyn_cast<ELFObjectFile<ELF64BE>>(Bin)) { ELFBuilder<ELF64BE> Builder(*o, *Obj); Builder.build(); return Obj; @@ -857,8 +878,8 @@ std::unique_ptr<Object> ELFReader::create() const { } template <class ELFT> void ELFWriter<ELFT>::writeEhdr() { - uint8_t *Buf = BufPtr->getBufferStart(); - Elf_Ehdr &Ehdr = *reinterpret_cast<Elf_Ehdr *>(Buf); + uint8_t *B = Buf.getBufferStart(); + Elf_Ehdr &Ehdr = *reinterpret_cast<Elf_Ehdr *>(B); std::copy(Obj.Ident, Obj.Ident + 16, Ehdr.e_ident); Ehdr.e_type = Obj.Type; Ehdr.e_machine = Obj.Machine; @@ -887,10 +908,10 @@ template <class ELFT> void ELFWriter<ELFT>::writePhdrs() { } template <class ELFT> void ELFWriter<ELFT>::writeShdrs() { - uint8_t *Buf = BufPtr->getBufferStart() + Obj.SHOffset; + uint8_t *B = Buf.getBufferStart() + Obj.SHOffset; // This reference serves to write the dummy section header at the begining // of the file. It is not used for anything else - Elf_Shdr &Shdr = *reinterpret_cast<Elf_Shdr *>(Buf); + Elf_Shdr &Shdr = *reinterpret_cast<Elf_Shdr *>(B); Shdr.sh_name = 0; Shdr.sh_type = SHT_NULL; Shdr.sh_flags = 0; @@ -1076,17 +1097,8 @@ template <class ELFT> void ELFWriter<ELFT>::write() { writeSectionData(); if (WriteSectionHeaders) writeShdrs(); - if (auto E = BufPtr->commit()) - reportError(File, errorToErrorCode(std::move(E))); -} - -void Writer::createBuffer(uint64_t Size) { - auto BufferOrErr = - FileOutputBuffer::create(File, Size, FileOutputBuffer::F_executable); - handleAllErrors(BufferOrErr.takeError(), [this](const ErrorInfoBase &) { - error("failed to open " + File); - }); - BufPtr = std::move(*BufferOrErr); + if (auto E = Buf.commit()) + reportError(Buf.getName(), errorToErrorCode(std::move(E))); } template <class ELFT> void ELFWriter<ELFT>::finalize() { @@ -1123,8 +1135,8 @@ template <class ELFT> void ELFWriter<ELFT>::finalize() { Section.finalize(); } - createBuffer(totalSize()); - SecWriter = llvm::make_unique<ELFSectionWriter<ELFT>>(*BufPtr); + Buf.allocate(totalSize()); + SecWriter = llvm::make_unique<ELFSectionWriter<ELFT>>(Buf); } void BinaryWriter::write() { @@ -1133,8 +1145,8 @@ void BinaryWriter::write() { continue; Section.accept(*SecWriter); } - if (auto E = BufPtr->commit()) - reportError(File, errorToErrorCode(std::move(E))); + if (auto E = Buf.commit()) + reportError(Buf.getName(), errorToErrorCode(std::move(E))); } void BinaryWriter::finalize() { @@ -1216,8 +1228,8 @@ void BinaryWriter::finalize() { TotalSize = std::max(TotalSize, Section->Offset + Section->Size); } - createBuffer(TotalSize); - SecWriter = llvm::make_unique<BinarySectionWriter>(*BufPtr); + Buf.allocate(TotalSize); + SecWriter = llvm::make_unique<BinarySectionWriter>(Buf); } namespace llvm { |