summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-objcopy/Object.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-objcopy/Object.cpp')
-rw-r--r--llvm/tools/llvm-objcopy/Object.cpp104
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 {
OpenPOWER on IntegriCloud