[llvm-objcopy] Factor out Buffer

In this diff we move out the hierarchy of buffers from Object.h/Object.cpp 
into separate files since it is not ELF-specific and will be reused later. 
After this change Object.h/Object.cpp are almost exclusively ELF-specific.

Test plan: make check-all

Differential revision: https://reviews.llvm.org/D53298

llvm-svn: 344585
This commit is contained in:
Alexander Shaposhnikov 2018-10-16 05:40:18 +00:00
parent fdfd98ceec
commit 3d4c4aca06
6 changed files with 120 additions and 74 deletions

View File

@ -0,0 +1,51 @@
//===- Buffer.cpp ---------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "Buffer.h"
#include "llvm-objcopy.h"
#include "llvm/Support/FileOutputBuffer.h"
#include "llvm/Support/MemoryBuffer.h"
#include <memory>
namespace llvm {
namespace objcopy {
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);
}
} // end namespace objcopy
} // end namespace llvm

View File

@ -0,0 +1,66 @@
//===- Buffer.h -------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TOOLS_OBJCOPY_BUFFER_H
#define LLVM_TOOLS_OBJCOPY_BUFFER_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/FileOutputBuffer.h"
#include "llvm/Support/MemoryBuffer.h"
#include <memory>
namespace llvm {
namespace objcopy {
// The class Buffer abstracts out the common interface of FileOutputBuffer and
// WritableMemoryBuffer so that the hierarchy of Writers depends on this
// abstract interface and doesn't depend on a particular implementation.
// TODO: refactor the buffer classes in LLVM to enable us to use them here
// directly.
class Buffer {
StringRef Name;
public:
virtual ~Buffer();
virtual void allocate(size_t Size) = 0;
virtual uint8_t *getBufferStart() = 0;
virtual Error commit() = 0;
explicit Buffer(StringRef Name) : Name(Name) {}
StringRef getName() const { return Name; }
};
class FileBuffer : public Buffer {
std::unique_ptr<FileOutputBuffer> Buf;
public:
void allocate(size_t Size) override;
uint8_t *getBufferStart() override;
Error commit() override;
explicit FileBuffer(StringRef FileName) : Buffer(FileName) {}
};
class MemBuffer : public Buffer {
std::unique_ptr<WritableMemoryBuffer> Buf;
public:
void allocate(size_t Size) override;
uint8_t *getBufferStart() override;
Error commit() override;
explicit MemBuffer(StringRef Name) : Buffer(Name) {}
std::unique_ptr<WritableMemoryBuffer> releaseMemoryBuffer();
};
} // end namespace objcopy
} // end namespace llvm
#endif // LLVM_TOOLS_OBJCOPY_BUFFER_H

View File

@ -14,6 +14,7 @@ tablegen(LLVM StripOpts.inc -gen-opt-parser-defs)
add_public_tablegen_target(StripOptsTableGen)
add_llvm_tool(llvm-objcopy
Buffer.cpp
CopyConfig.cpp
llvm-objcopy.cpp
Object.cpp

View File

@ -33,37 +33,6 @@ using namespace llvm::objcopy;
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) {
uint8_t *B = Buf.getBufferStart();
B += Obj.ProgramHdrSegment.Offset + Seg.Index * sizeof(Elf_Phdr);

View File

@ -10,6 +10,7 @@
#ifndef LLVM_TOOLS_OBJCOPY_OBJECT_H
#define LLVM_TOOLS_OBJCOPY_OBJECT_H
#include "Buffer.h"
#include "CopyConfig.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
@ -30,7 +31,6 @@ namespace llvm {
enum class DebugCompressionType;
namespace objcopy {
class Buffer;
class SectionBase;
class Section;
class OwnedDataSection;
@ -146,48 +146,6 @@ public:
explicit BinarySectionWriter(Buffer &Buf) : SectionWriter(Buf) {}
};
// The class Buffer abstracts out the common interface of FileOutputBuffer and
// WritableMemoryBuffer so that the hierarchy of Writers depends on this
// abstract interface and doesn't depend on a particular implementation.
// TODO: refactor the buffer classes in LLVM to enable us to use them here
// directly.
class Buffer {
StringRef Name;
public:
virtual ~Buffer();
virtual void allocate(size_t Size) = 0;
virtual uint8_t *getBufferStart() = 0;
virtual Error commit() = 0;
explicit Buffer(StringRef Name) : Name(Name) {}
StringRef getName() const { return Name; }
};
class FileBuffer : public Buffer {
std::unique_ptr<FileOutputBuffer> Buf;
public:
void allocate(size_t Size) override;
uint8_t *getBufferStart() override;
Error commit() override;
explicit FileBuffer(StringRef FileName) : Buffer(FileName) {}
};
class MemBuffer : public Buffer {
std::unique_ptr<WritableMemoryBuffer> Buf;
public:
void allocate(size_t Size) override;
uint8_t *getBufferStart() override;
Error commit() override;
explicit MemBuffer(StringRef Name) : Buffer(Name) {}
std::unique_ptr<WritableMemoryBuffer> releaseMemoryBuffer();
};
class Writer {
protected:
Object &Obj;

View File

@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llvm-objcopy.h"
#include "Buffer.h"
#include "CopyConfig.h"
#include "Object.h"