1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

Don't own the buffer in object::Binary.

Owning the buffer is somewhat inflexible. Some Binaries have sub Binaries
(like Archive) and we had to create dummy buffers just to handle that. It is
also a bad fit for IRObjectFile where the Module wants to own the buffer too.

Keeping this ownership would make supporting IR inside native objects
particularly painful.

This patch focuses in lib/Object. If something elsewhere used to own an Binary,
now it also owns a MemoryBuffer.

This patch introduces a few new types.

* MemoryBufferRef. This is just a pair of StringRefs for the data and name.
  This is to MemoryBuffer as StringRef is to std::string.
* OwningBinary. A combination of Binary and a MemoryBuffer. This is needed
  for convenience functions that take a filename and return both the
  buffer and the Binary using that buffer.

The C api now uses OwningBinary to avoid any change in semantics. I will start
a new thread to see if we want to change it and how.

llvm-svn: 216002
This commit is contained in:
Rafael Espindola 2014-08-19 18:44:46 +00:00
parent 155b633a98
commit 08aa78de63
48 changed files with 375 additions and 314 deletions

View File

@ -22,6 +22,7 @@
#include "llvm/IR/ValueHandle.h" #include "llvm/IR/ValueHandle.h"
#include "llvm/IR/ValueMap.h" #include "llvm/IR/ValueMap.h"
#include "llvm/MC/MCCodeGenInfo.h" #include "llvm/MC/MCCodeGenInfo.h"
#include "llvm/Object/Binary.h"
#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Mutex.h" #include "llvm/Support/Mutex.h"
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
@ -195,7 +196,7 @@ public:
/// resolve external symbols in objects it is loading. If a symbol is found /// resolve external symbols in objects it is loading. If a symbol is found
/// in the Archive the contained object file will be extracted (in memory) /// in the Archive the contained object file will be extracted (in memory)
/// and loaded for possible execution. /// and loaded for possible execution.
virtual void addArchive(std::unique_ptr<object::Archive> A); virtual void addArchive(object::OwningBinary<object::Archive> A);
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//

View File

@ -24,10 +24,7 @@ namespace llvm {
/// This class acts as a container for the memory buffer used during generation /// This class acts as a container for the memory buffer used during generation
/// and loading of executable objects using MCJIT and RuntimeDyld. The /// and loading of executable objects using MCJIT and RuntimeDyld. The
/// underlying memory for the object will be owned by the ObjectBuffer instance /// underlying memory for the object will be owned by the ObjectBuffer instance
/// throughout its lifetime. The getMemBuffer() method provides a way to create /// throughout its lifetime.
/// a MemoryBuffer wrapper object instance to be owned by other classes (such as
/// ObjectFile) as needed, but the MemoryBuffer instance returned does not own
/// the actual memory it points to.
class ObjectBuffer { class ObjectBuffer {
virtual void anchor(); virtual void anchor();
public: public:
@ -35,13 +32,7 @@ public:
ObjectBuffer(MemoryBuffer* Buf) : Buffer(Buf) {} ObjectBuffer(MemoryBuffer* Buf) : Buffer(Buf) {}
virtual ~ObjectBuffer() {} virtual ~ObjectBuffer() {}
/// Like MemoryBuffer::getMemBuffer() this function returns a pointer to an MemoryBufferRef getMemBuffer() const { return Buffer->getMemBufferRef(); }
/// object that is owned by the caller. However, the caller does not take
/// ownership of the underlying memory.
std::unique_ptr<MemoryBuffer> getMemBuffer() const {
return std::unique_ptr<MemoryBuffer>(MemoryBuffer::getMemBuffer(
Buffer->getBuffer(), Buffer->getBufferIdentifier(), false));
}
const char *getBufferStart() const { return Buffer->getBufferStart(); } const char *getBufferStart() const { return Buffer->getBufferStart(); }
size_t getBufferSize() const { return Buffer->getBufferSize(); } size_t getBufferSize() const { return Buffer->getBufferSize(); }

View File

@ -27,7 +27,7 @@ public:
virtual ~ObjectCache() { } virtual ~ObjectCache() { }
/// notifyObjectCompiled - Provides a pointer to compiled code for Module M. /// notifyObjectCompiled - Provides a pointer to compiled code for Module M.
virtual void notifyObjectCompiled(const Module *M, const MemoryBuffer *Obj) = 0; virtual void notifyObjectCompiled(const Module *M, MemoryBufferRef Obj) = 0;
/// Returns a pointer to a newly allocated MemoryBuffer that contains the /// Returns a pointer to a newly allocated MemoryBuffer that contains the
/// object which corresponds with Module M, or 0 if an object is not /// object which corresponds with Module M, or 0 if an object is not

View File

@ -202,10 +202,9 @@ private:
/// Get string that the data pointer points to. /// Get string that the data pointer points to.
bool objcClassNameFromExpression(const Constant *c, std::string &name); bool objcClassNameFromExpression(const Constant *c, std::string &name);
/// Create an LTOModule (private version). N.B. This method takes ownership of /// Create an LTOModule (private version).
/// the buffer. static LTOModule *makeLTOModule(MemoryBufferRef Buffer, TargetOptions options,
static LTOModule *makeLTOModule(std::unique_ptr<MemoryBuffer> Buffer, std::string &errMsg);
TargetOptions options, std::string &errMsg);
}; };
} }
#endif #endif

View File

@ -89,8 +89,7 @@ public:
return StringRef(Data.data() + StartOfFile, getSize()); return StringRef(Data.data() + StartOfFile, getSize());
} }
ErrorOr<std::unique_ptr<MemoryBuffer>> ErrorOr<MemoryBufferRef> getMemoryBufferRef() const;
getMemoryBuffer(bool FullPath = false) const;
ErrorOr<std::unique_ptr<Binary>> ErrorOr<std::unique_ptr<Binary>>
getAsBinary(LLVMContext *Context = nullptr) const; getAsBinary(LLVMContext *Context = nullptr) const;
@ -164,9 +163,8 @@ public:
} }
}; };
Archive(std::unique_ptr<MemoryBuffer> Source, std::error_code &EC); Archive(MemoryBufferRef Source, std::error_code &EC);
static ErrorOr<std::unique_ptr<Archive>> static ErrorOr<std::unique_ptr<Archive>> create(MemoryBufferRef Source);
create(std::unique_ptr<MemoryBuffer> Source);
enum Kind { enum Kind {
K_GNU, K_GNU,

View File

@ -17,11 +17,11 @@
#include "llvm/Object/Error.h" #include "llvm/Object/Error.h"
#include "llvm/Support/ErrorOr.h" #include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileSystem.h" #include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
namespace llvm { namespace llvm {
class LLVMContext; class LLVMContext;
class MemoryBuffer;
class StringRef; class StringRef;
namespace object { namespace object {
@ -34,9 +34,9 @@ private:
unsigned int TypeID; unsigned int TypeID;
protected: protected:
std::unique_ptr<MemoryBuffer> Data; MemoryBufferRef Data;
Binary(unsigned int Type, std::unique_ptr<MemoryBuffer> Source); Binary(unsigned int Type, MemoryBufferRef Source);
enum { enum {
ID_Archive, ID_Archive,
@ -78,8 +78,8 @@ public:
virtual ~Binary(); virtual ~Binary();
StringRef getData() const; StringRef getData() const;
MemoryBuffer *releaseBuffer() { return Data.release(); }
StringRef getFileName() const; StringRef getFileName() const;
MemoryBufferRef getMemoryBufferRef() const;
// Cast methods. // Cast methods.
unsigned int getType() const { return TypeID; } unsigned int getType() const { return TypeID; }
@ -126,11 +126,37 @@ public:
/// @brief Create a Binary from Source, autodetecting the file type. /// @brief Create a Binary from Source, autodetecting the file type.
/// ///
/// @param Source The data to create the Binary from. /// @param Source The data to create the Binary from.
ErrorOr<std::unique_ptr<Binary>> ErrorOr<std::unique_ptr<Binary>> createBinary(MemoryBufferRef Source,
createBinary(std::unique_ptr<MemoryBuffer> Source, LLVMContext *Context = nullptr);
LLVMContext *Context = nullptr);
ErrorOr<std::unique_ptr<Binary>> createBinary(StringRef Path); template <typename T> class OwningBinary {
std::unique_ptr<T> Bin;
std::unique_ptr<MemoryBuffer> Buf;
public:
OwningBinary();
OwningBinary(std::unique_ptr<T> Bin, std::unique_ptr<MemoryBuffer> Buf);
std::unique_ptr<T> &getBinary();
std::unique_ptr<MemoryBuffer> &getBuffer();
};
template <typename T>
OwningBinary<T>::OwningBinary(std::unique_ptr<T> Bin,
std::unique_ptr<MemoryBuffer> Buf)
: Bin(std::move(Bin)), Buf(std::move(Buf)) {}
template <typename T> OwningBinary<T>::OwningBinary() {}
template <typename T> std::unique_ptr<T> &OwningBinary<T>::getBinary() {
return Bin;
}
template <typename T>
std::unique_ptr<MemoryBuffer> &OwningBinary<T>::getBuffer() {
return Buf;
}
ErrorOr<OwningBinary<Binary>> createBinary(StringRef Path);
} }
} }

View File

@ -415,7 +415,7 @@ protected:
SmallVectorImpl<char> &Result) const override; SmallVectorImpl<char> &Result) const override;
public: public:
COFFObjectFile(std::unique_ptr<MemoryBuffer> Object, std::error_code &EC); COFFObjectFile(MemoryBufferRef Object, std::error_code &EC);
basic_symbol_iterator symbol_begin_impl() const override; basic_symbol_iterator symbol_begin_impl() const override;
basic_symbol_iterator symbol_end_impl() const override; basic_symbol_iterator symbol_end_impl() const override;
section_iterator section_begin() const override; section_iterator section_begin() const override;

View File

@ -37,7 +37,7 @@ namespace object {
class ELFObjectFileBase : public ObjectFile { class ELFObjectFileBase : public ObjectFile {
protected: protected:
ELFObjectFileBase(unsigned int Type, std::unique_ptr<MemoryBuffer> Source); ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source);
public: public:
virtual std::error_code getRelocationAddend(DataRefImpl Rel, virtual std::error_code getRelocationAddend(DataRefImpl Rel,
@ -186,7 +186,7 @@ protected:
bool isDyldELFObject; bool isDyldELFObject;
public: public:
ELFObjectFile(std::unique_ptr<MemoryBuffer> Object, std::error_code &EC); ELFObjectFile(MemoryBufferRef Object, std::error_code &EC);
const Elf_Sym *getSymbol(DataRefImpl Symb) const; const Elf_Sym *getSymbol(DataRefImpl Symb) const;
@ -797,14 +797,13 @@ ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
} }
template <class ELFT> template <class ELFT>
ELFObjectFile<ELFT>::ELFObjectFile(std::unique_ptr<MemoryBuffer> Object, ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, std::error_code &EC)
std::error_code &EC)
: ELFObjectFileBase( : ELFObjectFileBase(
getELFType(static_cast<endianness>(ELFT::TargetEndianness) == getELFType(static_cast<endianness>(ELFT::TargetEndianness) ==
support::little, support::little,
ELFT::Is64Bits), ELFT::Is64Bits),
std::move(Object)), Object),
EF(Data->getBuffer(), EC) {} EF(Data.getBuffer(), EC) {}
template <class ELFT> template <class ELFT>
basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin_impl() const { basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin_impl() const {

View File

@ -28,7 +28,7 @@ class IRObjectFile : public SymbolicFile {
std::vector<std::pair<std::string, uint32_t>> AsmSymbols; std::vector<std::pair<std::string, uint32_t>> AsmSymbols;
public: public:
IRObjectFile(std::unique_ptr<MemoryBuffer> Object, std::unique_ptr<Module> M); IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> M);
~IRObjectFile(); ~IRObjectFile();
void moveSymbolNext(DataRefImpl &Symb) const override; void moveSymbolNext(DataRefImpl &Symb) const override;
std::error_code printSymbolName(raw_ostream &OS, std::error_code printSymbolName(raw_ostream &OS,
@ -49,9 +49,8 @@ public:
return v->isIR(); return v->isIR();
} }
static ErrorOr<IRObjectFile *> static ErrorOr<IRObjectFile *> createIRObjectFile(MemoryBufferRef Object,
createIRObjectFile(std::unique_ptr<MemoryBuffer> Object, LLVMContext &Context);
LLVMContext &Context);
}; };
} }
} }

View File

@ -56,8 +56,8 @@ public:
MachO::load_command C; // The command itself. MachO::load_command C; // The command itself.
}; };
MachOObjectFile(std::unique_ptr<MemoryBuffer> Object, bool IsLittleEndian, MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits,
bool Is64Bits, std::error_code &EC); std::error_code &EC);
void moveSymbolNext(DataRefImpl &Symb) const override; void moveSymbolNext(DataRefImpl &Symb) const override;
std::error_code getSymbolName(DataRefImpl Symb, std::error_code getSymbolName(DataRefImpl Symb,

View File

@ -84,10 +84,8 @@ public:
} }
}; };
MachOUniversalBinary(std::unique_ptr<MemoryBuffer> Source, MachOUniversalBinary(MemoryBufferRef Souce, std::error_code &EC);
std::error_code &ec); static ErrorOr<MachOUniversalBinary *> create(MemoryBufferRef Source);
static ErrorOr<MachOUniversalBinary *>
create(std::unique_ptr<MemoryBuffer> Source);
object_iterator begin_objects() const { object_iterator begin_objects() const {
return ObjectForArch(this, 0); return ObjectForArch(this, 0);

View File

@ -187,10 +187,10 @@ class ObjectFile : public SymbolicFile {
ObjectFile(const ObjectFile &other) LLVM_DELETED_FUNCTION; ObjectFile(const ObjectFile &other) LLVM_DELETED_FUNCTION;
protected: protected:
ObjectFile(unsigned int Type, std::unique_ptr<MemoryBuffer> Source); ObjectFile(unsigned int Type, MemoryBufferRef Source);
const uint8_t *base() const { const uint8_t *base() const {
return reinterpret_cast<const uint8_t *>(Data->getBufferStart()); return reinterpret_cast<const uint8_t *>(Data.getBufferStart());
} }
// These functions are for SymbolRef to call internally. The main goal of // These functions are for SymbolRef to call internally. The main goal of
@ -309,14 +309,13 @@ public:
/// @param ObjectPath The path to the object file. ObjectPath.isObject must /// @param ObjectPath The path to the object file. ObjectPath.isObject must
/// return true. /// return true.
/// @brief Create ObjectFile from path. /// @brief Create ObjectFile from path.
static ErrorOr<std::unique_ptr<ObjectFile>> static ErrorOr<OwningBinary<ObjectFile>>
createObjectFile(StringRef ObjectPath); createObjectFile(StringRef ObjectPath);
static ErrorOr<std::unique_ptr<ObjectFile>> static ErrorOr<std::unique_ptr<ObjectFile>>
createObjectFile(std::unique_ptr<MemoryBuffer> &Object, createObjectFile(MemoryBufferRef Object, sys::fs::file_magic Type);
sys::fs::file_magic Type);
static ErrorOr<std::unique_ptr<ObjectFile>> static ErrorOr<std::unique_ptr<ObjectFile>>
createObjectFile(std::unique_ptr<MemoryBuffer> &Object) { createObjectFile(MemoryBufferRef Object) {
return createObjectFile(Object, sys::fs::file_magic::unknown); return createObjectFile(Object, sys::fs::file_magic::unknown);
} }
@ -326,13 +325,13 @@ public:
} }
static ErrorOr<std::unique_ptr<COFFObjectFile>> static ErrorOr<std::unique_ptr<COFFObjectFile>>
createCOFFObjectFile(std::unique_ptr<MemoryBuffer> Object); createCOFFObjectFile(MemoryBufferRef Object);
static ErrorOr<std::unique_ptr<ObjectFile>> static ErrorOr<std::unique_ptr<ObjectFile>>
createELFObjectFile(std::unique_ptr<MemoryBuffer> &Object); createELFObjectFile(MemoryBufferRef Object);
static ErrorOr<std::unique_ptr<MachOObjectFile>> static ErrorOr<std::unique_ptr<MachOObjectFile>>
createMachOObjectFile(std::unique_ptr<MemoryBuffer> &Object); createMachOObjectFile(MemoryBufferRef Object);
}; };
// Inline function definitions. // Inline function definitions.

View File

@ -116,7 +116,7 @@ const uint64_t UnknownAddressOrSize = ~0ULL;
class SymbolicFile : public Binary { class SymbolicFile : public Binary {
public: public:
virtual ~SymbolicFile(); virtual ~SymbolicFile();
SymbolicFile(unsigned int Type, std::unique_ptr<MemoryBuffer> Source); SymbolicFile(unsigned int Type, MemoryBufferRef Source);
// virtual interface. // virtual interface.
virtual void moveSymbolNext(DataRefImpl &Symb) const = 0; virtual void moveSymbolNext(DataRefImpl &Symb) const = 0;
@ -144,14 +144,14 @@ public:
// construction aux. // construction aux.
static ErrorOr<std::unique_ptr<SymbolicFile>> static ErrorOr<std::unique_ptr<SymbolicFile>>
createSymbolicFile(std::unique_ptr<MemoryBuffer> &Object, createSymbolicFile(MemoryBufferRef Object, sys::fs::file_magic Type,
sys::fs::file_magic Type, LLVMContext *Context); LLVMContext *Context);
static ErrorOr<std::unique_ptr<SymbolicFile>> static ErrorOr<std::unique_ptr<SymbolicFile>>
createSymbolicFile(std::unique_ptr<MemoryBuffer> &Object) { createSymbolicFile(MemoryBufferRef Object) {
return createSymbolicFile(Object, sys::fs::file_magic::unknown, nullptr); return createSymbolicFile(Object, sys::fs::file_magic::unknown, nullptr);
} }
static ErrorOr<std::unique_ptr<SymbolicFile>> static ErrorOr<OwningBinary<SymbolicFile>>
createSymbolicFile(StringRef ObjectPath); createSymbolicFile(StringRef ObjectPath);
static inline bool classof(const Binary *v) { static inline bool classof(const Binary *v) {

View File

@ -157,7 +157,7 @@ public:
private: private:
std::error_code LastError; std::error_code LastError;
std::unique_ptr<llvm::object::ObjectFile> Object; object::OwningBinary<object::ObjectFile> Object;
std::vector<StringRef> Filenames; std::vector<StringRef> Filenames;
std::vector<ProfileMappingRecord> MappingRecords; std::vector<ProfileMappingRecord> MappingRecords;
size_t CurrentRecord; size_t CurrentRecord;

View File

@ -24,9 +24,11 @@
#include <system_error> #include <system_error>
namespace llvm { namespace llvm {
/// This interface provides simple read-only access to a block/ of memory, and class MemoryBufferRef;
/// This interface provides simple read-only access to a block of memory, and
/// provides simple methods for reading files and standard input into a memory /// provides simple methods for reading files and standard input into a memory
/// buffer. In addition to basic access to the characters in the file, this /// buffer. In addition to basic access to the characters in the file, this
/// interface guarantees you can read one character past the end of the file, /// interface guarantees you can read one character past the end of the file,
/// and that this character will read as '\0'. /// and that this character will read as '\0'.
/// ///
@ -136,7 +138,27 @@ public:
/// Return information on the memory mechanism used to support the /// Return information on the memory mechanism used to support the
/// MemoryBuffer. /// MemoryBuffer.
virtual BufferKind getBufferKind() const = 0; virtual BufferKind getBufferKind() const = 0;
MemoryBufferRef getMemBufferRef() const;
};
class MemoryBufferRef {
StringRef Buffer;
StringRef Identifier;
public:
MemoryBufferRef() {}
MemoryBufferRef(StringRef Buffer, StringRef Identifier)
: Buffer(Buffer), Identifier(Identifier) {}
StringRef getBuffer() const { return Buffer; }
StringRef getBufferIdentifier() const { return Identifier; }
const char *getBufferStart() const { return Buffer.begin(); }
const char *getBufferEnd() const { return Buffer.end(); }
size_t getBufferSize() const { return Buffer.size(); }
}; };
// Create wrappers for C Binding types (see CBindingWrapping.h). // Create wrappers for C Binding types (see CBindingWrapping.h).

View File

@ -261,12 +261,12 @@ bool DWARFUnit::parseDWO() {
sys::path::append(AbsolutePath, CompilationDir); sys::path::append(AbsolutePath, CompilationDir);
} }
sys::path::append(AbsolutePath, DWOFileName); sys::path::append(AbsolutePath, DWOFileName);
ErrorOr<std::unique_ptr<object::ObjectFile>> DWOFile = ErrorOr<object::OwningBinary<object::ObjectFile>> DWOFile =
object::ObjectFile::createObjectFile(AbsolutePath); object::ObjectFile::createObjectFile(AbsolutePath);
if (!DWOFile) if (!DWOFile)
return false; return false;
// Reset DWOHolder. // Reset DWOHolder.
DWO = llvm::make_unique<DWOHolder>(std::move(*DWOFile)); DWO = llvm::make_unique<DWOHolder>(std::move(DWOFile->getBinary()));
DWARFUnit *DWOCU = DWO->getUnit(); DWARFUnit *DWOCU = DWO->getUnit();
// Verify that compile unit in .dwo file is valid. // Verify that compile unit in .dwo file is valid.
if (!DWOCU || DWOCU->getDWOId() != getDWOId()) { if (!DWOCU || DWOCU->getDWOId() != getDWOId()) {

View File

@ -124,7 +124,7 @@ void ExecutionEngine::addObjectFile(std::unique_ptr<object::ObjectFile> O) {
llvm_unreachable("ExecutionEngine subclass doesn't implement addObjectFile."); llvm_unreachable("ExecutionEngine subclass doesn't implement addObjectFile.");
} }
void ExecutionEngine::addArchive(std::unique_ptr<object::Archive> A) { void ExecutionEngine::addArchive(object::OwningBinary<object::Archive> A) {
llvm_unreachable("ExecutionEngine subclass doesn't implement addArchive."); llvm_unreachable("ExecutionEngine subclass doesn't implement addArchive.");
} }

View File

@ -119,7 +119,7 @@ void MCJIT::addObjectFile(std::unique_ptr<object::ObjectFile> Obj) {
NotifyObjectEmitted(*LoadedObject); NotifyObjectEmitted(*LoadedObject);
} }
void MCJIT::addArchive(std::unique_ptr<object::Archive> A) { void MCJIT::addArchive(object::OwningBinary<object::Archive> A) {
Archives.push_back(std::move(A)); Archives.push_back(std::move(A));
} }
@ -161,8 +161,8 @@ ObjectBufferStream* MCJIT::emitObject(Module *M) {
if (ObjCache) { if (ObjCache) {
// MemoryBuffer is a thin wrapper around the actual memory, so it's OK // MemoryBuffer is a thin wrapper around the actual memory, so it's OK
// to create a temporary object here and delete it after the call. // to create a temporary object here and delete it after the call.
std::unique_ptr<MemoryBuffer> MB = CompiledObject->getMemBuffer(); MemoryBufferRef MB = CompiledObject->getMemBuffer();
ObjCache->notifyObjectCompiled(M, MB.get()); ObjCache->notifyObjectCompiled(M, MB);
} }
return CompiledObject.release(); return CompiledObject.release();
@ -295,7 +295,8 @@ uint64_t MCJIT::getSymbolAddress(const std::string &Name,
if (Addr) if (Addr)
return Addr; return Addr;
for (std::unique_ptr<object::Archive> &A : Archives) { for (object::OwningBinary<object::Archive> &OB : Archives) {
object::Archive *A = OB.getBinary().get();
// Look for our symbols in each Archive // Look for our symbols in each Archive
object::Archive::child_iterator ChildIt = A->findSym(Name); object::Archive::child_iterator ChildIt = A->findSym(Name);
if (ChildIt != A->child_end()) { if (ChildIt != A->child_end()) {

View File

@ -216,7 +216,7 @@ class MCJIT : public ExecutionEngine {
OwningModuleContainer OwnedModules; OwningModuleContainer OwnedModules;
SmallVector<std::unique_ptr<object::Archive>, 2> Archives; SmallVector<object::OwningBinary<object::Archive>, 2> Archives;
typedef SmallVector<ObjectImage *, 2> LoadedObjectList; typedef SmallVector<ObjectImage *, 2> LoadedObjectList;
LoadedObjectList LoadedObjects; LoadedObjectList LoadedObjects;
@ -240,7 +240,7 @@ public:
/// @{ /// @{
void addModule(std::unique_ptr<Module> M) override; void addModule(std::unique_ptr<Module> M) override;
void addObjectFile(std::unique_ptr<object::ObjectFile> O) override; void addObjectFile(std::unique_ptr<object::ObjectFile> O) override;
void addArchive(std::unique_ptr<object::Archive> O) override; void addArchive(object::OwningBinary<object::Archive> O) override;
bool removeModule(Module *M) override; bool removeModule(Module *M) override;
/// FindFunctionNamed - Search all of the active modules to find the one that /// FindFunctionNamed - Search all of the active modules to find the one that

View File

@ -48,7 +48,7 @@ public:
{ {
// FIXME: error checking? createObjectFile returns an ErrorOr<ObjectFile*> // FIXME: error checking? createObjectFile returns an ErrorOr<ObjectFile*>
// and should probably be checked for failure. // and should probably be checked for failure.
std::unique_ptr<MemoryBuffer> Buf = Buffer->getMemBuffer(); MemoryBufferRef Buf = Buffer->getMemBuffer();
ObjFile = std::move(object::ObjectFile::createObjectFile(Buf).get()); ObjFile = std::move(object::ObjectFile::createObjectFile(Buf).get());
} }
ObjectImageCommon(std::unique_ptr<object::ObjectFile> Input) ObjectImageCommon(std::unique_ptr<object::ObjectFile> Input)

View File

@ -55,9 +55,9 @@ template <class ELFT> class DyldELFObject : public ELFObjectFile<ELFT> {
public: public:
DyldELFObject(std::unique_ptr<ObjectFile> UnderlyingFile, DyldELFObject(std::unique_ptr<ObjectFile> UnderlyingFile,
std::unique_ptr<MemoryBuffer> Wrapper, std::error_code &ec); MemoryBufferRef Wrapper, std::error_code &ec);
DyldELFObject(std::unique_ptr<MemoryBuffer> Wrapper, std::error_code &ec); DyldELFObject(MemoryBufferRef Wrapper, std::error_code &ec);
void updateSectionAddress(const SectionRef &Sec, uint64_t Addr); void updateSectionAddress(const SectionRef &Sec, uint64_t Addr);
void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr); void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr);
@ -109,17 +109,15 @@ public:
// actual memory. Ultimately, the Binary parent class will take ownership of // actual memory. Ultimately, the Binary parent class will take ownership of
// this MemoryBuffer object but not the underlying memory. // this MemoryBuffer object but not the underlying memory.
template <class ELFT> template <class ELFT>
DyldELFObject<ELFT>::DyldELFObject(std::unique_ptr<MemoryBuffer> Wrapper, DyldELFObject<ELFT>::DyldELFObject(MemoryBufferRef Wrapper, std::error_code &EC)
std::error_code &EC) : ELFObjectFile<ELFT>(Wrapper, EC) {
: ELFObjectFile<ELFT>(std::move(Wrapper), EC) {
this->isDyldELFObject = true; this->isDyldELFObject = true;
} }
template <class ELFT> template <class ELFT>
DyldELFObject<ELFT>::DyldELFObject(std::unique_ptr<ObjectFile> UnderlyingFile, DyldELFObject<ELFT>::DyldELFObject(std::unique_ptr<ObjectFile> UnderlyingFile,
std::unique_ptr<MemoryBuffer> Wrapper, MemoryBufferRef Wrapper, std::error_code &EC)
std::error_code &EC) : ELFObjectFile<ELFT>(Wrapper, EC),
: ELFObjectFile<ELFT>(std::move(Wrapper), EC),
UnderlyingFile(std::move(UnderlyingFile)) { UnderlyingFile(std::move(UnderlyingFile)) {
this->isDyldELFObject = true; this->isDyldELFObject = true;
} }
@ -185,29 +183,28 @@ RuntimeDyldELF::createObjectImageFromFile(std::unique_ptr<object::ObjectFile> Ob
return nullptr; return nullptr;
std::error_code ec; std::error_code ec;
std::unique_ptr<MemoryBuffer> Buffer( MemoryBufferRef Buffer = ObjFile->getMemoryBufferRef();
MemoryBuffer::getMemBuffer(ObjFile->getData(), "", false));
if (ObjFile->getBytesInAddress() == 4 && ObjFile->isLittleEndian()) { if (ObjFile->getBytesInAddress() == 4 && ObjFile->isLittleEndian()) {
auto Obj = auto Obj =
llvm::make_unique<DyldELFObject<ELFType<support::little, 2, false>>>( llvm::make_unique<DyldELFObject<ELFType<support::little, 2, false>>>(
std::move(ObjFile), std::move(Buffer), ec); std::move(ObjFile), Buffer, ec);
return new ELFObjectImage<ELFType<support::little, 2, false>>( return new ELFObjectImage<ELFType<support::little, 2, false>>(
nullptr, std::move(Obj)); nullptr, std::move(Obj));
} else if (ObjFile->getBytesInAddress() == 4 && !ObjFile->isLittleEndian()) { } else if (ObjFile->getBytesInAddress() == 4 && !ObjFile->isLittleEndian()) {
auto Obj = auto Obj =
llvm::make_unique<DyldELFObject<ELFType<support::big, 2, false>>>( llvm::make_unique<DyldELFObject<ELFType<support::big, 2, false>>>(
std::move(ObjFile), std::move(Buffer), ec); std::move(ObjFile), Buffer, ec);
return new ELFObjectImage<ELFType<support::big, 2, false>>(nullptr, std::move(Obj)); return new ELFObjectImage<ELFType<support::big, 2, false>>(nullptr, std::move(Obj));
} else if (ObjFile->getBytesInAddress() == 8 && !ObjFile->isLittleEndian()) { } else if (ObjFile->getBytesInAddress() == 8 && !ObjFile->isLittleEndian()) {
auto Obj = llvm::make_unique<DyldELFObject<ELFType<support::big, 2, true>>>( auto Obj = llvm::make_unique<DyldELFObject<ELFType<support::big, 2, true>>>(
std::move(ObjFile), std::move(Buffer), ec); std::move(ObjFile), Buffer, ec);
return new ELFObjectImage<ELFType<support::big, 2, true>>(nullptr, return new ELFObjectImage<ELFType<support::big, 2, true>>(nullptr,
std::move(Obj)); std::move(Obj));
} else if (ObjFile->getBytesInAddress() == 8 && ObjFile->isLittleEndian()) { } else if (ObjFile->getBytesInAddress() == 8 && ObjFile->isLittleEndian()) {
auto Obj = auto Obj =
llvm::make_unique<DyldELFObject<ELFType<support::little, 2, true>>>( llvm::make_unique<DyldELFObject<ELFType<support::little, 2, true>>>(
std::move(ObjFile), std::move(Buffer), ec); std::move(ObjFile), Buffer, ec);
return new ELFObjectImage<ELFType<support::little, 2, true>>( return new ELFObjectImage<ELFType<support::little, 2, true>>(
nullptr, std::move(Obj)); nullptr, std::move(Obj));
} else } else
@ -222,31 +219,31 @@ ObjectImage *RuntimeDyldELF::createObjectImage(ObjectBuffer *Buffer) {
(uint8_t)Buffer->getBufferStart()[ELF::EI_DATA]); (uint8_t)Buffer->getBufferStart()[ELF::EI_DATA]);
std::error_code ec; std::error_code ec;
std::unique_ptr<MemoryBuffer> Buf = Buffer->getMemBuffer(); MemoryBufferRef Buf = Buffer->getMemBuffer();
if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) { if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) {
auto Obj = auto Obj =
llvm::make_unique<DyldELFObject<ELFType<support::little, 4, false>>>( llvm::make_unique<DyldELFObject<ELFType<support::little, 4, false>>>(
std::move(Buf), ec); Buf, ec);
return new ELFObjectImage<ELFType<support::little, 4, false>>( return new ELFObjectImage<ELFType<support::little, 4, false>>(
Buffer, std::move(Obj)); Buffer, std::move(Obj));
} else if (Ident.first == ELF::ELFCLASS32 && } else if (Ident.first == ELF::ELFCLASS32 &&
Ident.second == ELF::ELFDATA2MSB) { Ident.second == ELF::ELFDATA2MSB) {
auto Obj = auto Obj =
llvm::make_unique<DyldELFObject<ELFType<support::big, 4, false>>>( llvm::make_unique<DyldELFObject<ELFType<support::big, 4, false>>>(Buf,
std::move(Buf), ec); ec);
return new ELFObjectImage<ELFType<support::big, 4, false>>(Buffer, return new ELFObjectImage<ELFType<support::big, 4, false>>(Buffer,
std::move(Obj)); std::move(Obj));
} else if (Ident.first == ELF::ELFCLASS64 && } else if (Ident.first == ELF::ELFCLASS64 &&
Ident.second == ELF::ELFDATA2MSB) { Ident.second == ELF::ELFDATA2MSB) {
auto Obj = llvm::make_unique<DyldELFObject<ELFType<support::big, 8, true>>>( auto Obj = llvm::make_unique<DyldELFObject<ELFType<support::big, 8, true>>>(
std::move(Buf), ec); Buf, ec);
return new ELFObjectImage<ELFType<support::big, 8, true>>(Buffer, std::move(Obj)); return new ELFObjectImage<ELFType<support::big, 8, true>>(Buffer, std::move(Obj));
} else if (Ident.first == ELF::ELFCLASS64 && } else if (Ident.first == ELF::ELFCLASS64 &&
Ident.second == ELF::ELFDATA2LSB) { Ident.second == ELF::ELFDATA2LSB) {
auto Obj = auto Obj =
llvm::make_unique<DyldELFObject<ELFType<support::little, 8, true>>>( llvm::make_unique<DyldELFObject<ELFType<support::little, 8, true>>>(Buf,
std::move(Buf), ec); ec);
return new ELFObjectImage<ELFType<support::little, 8, true>>(Buffer, std::move(Obj)); return new ELFObjectImage<ELFType<support::little, 8, true>>(Buffer, std::move(Obj));
} else } else
llvm_unreachable("Unexpected ELF format"); llvm_unreachable("Unexpected ELF format");

View File

@ -77,7 +77,8 @@ LTOModule *LTOModule::createFromFile(const char *path, TargetOptions options,
errMsg = EC.message(); errMsg = EC.message();
return nullptr; return nullptr;
} }
return makeLTOModule(std::move(BufferOrErr.get()), options, errMsg); std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get());
return makeLTOModule(Buffer->getMemBufferRef(), options, errMsg);
} }
LTOModule *LTOModule::createFromOpenFile(int fd, const char *path, size_t size, LTOModule *LTOModule::createFromOpenFile(int fd, const char *path, size_t size,
@ -96,23 +97,30 @@ LTOModule *LTOModule::createFromOpenFileSlice(int fd, const char *path,
errMsg = EC.message(); errMsg = EC.message();
return nullptr; return nullptr;
} }
return makeLTOModule(std::move(BufferOrErr.get()), options, errMsg); std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get());
return makeLTOModule(Buffer->getMemBufferRef(), options, errMsg);
} }
LTOModule *LTOModule::createFromBuffer(const void *mem, size_t length, LTOModule *LTOModule::createFromBuffer(const void *mem, size_t length,
TargetOptions options, TargetOptions options,
std::string &errMsg, StringRef path) { std::string &errMsg, StringRef path) {
std::unique_ptr<MemoryBuffer> buffer(makeBuffer(mem, length, path)); StringRef Data((char *)mem, length);
if (!buffer) MemoryBufferRef Buffer(Data, path);
return nullptr; return makeLTOModule(Buffer, options, errMsg);
return makeLTOModule(std::move(buffer), options, errMsg);
} }
LTOModule *LTOModule::makeLTOModule(std::unique_ptr<MemoryBuffer> Buffer, LTOModule *LTOModule::makeLTOModule(MemoryBufferRef Buffer,
TargetOptions options, TargetOptions options,
std::string &errMsg) { std::string &errMsg) {
StringRef Data = Buffer.getBuffer();
StringRef FileName = Buffer.getBufferIdentifier();
std::unique_ptr<MemoryBuffer> MemBuf(
makeBuffer(Data.begin(), Data.size(), FileName));
if (!MemBuf)
return nullptr;
ErrorOr<Module *> MOrErr = ErrorOr<Module *> MOrErr =
getLazyBitcodeModule(Buffer.get(), getGlobalContext()); getLazyBitcodeModule(MemBuf.get(), getGlobalContext());
if (std::error_code EC = MOrErr.getError()) { if (std::error_code EC = MOrErr.getError()) {
errMsg = EC.message(); errMsg = EC.message();
return nullptr; return nullptr;
@ -150,7 +158,7 @@ LTOModule *LTOModule::makeLTOModule(std::unique_ptr<MemoryBuffer> Buffer,
M->setDataLayout(target->getSubtargetImpl()->getDataLayout()); M->setDataLayout(target->getSubtargetImpl()->getDataLayout());
std::unique_ptr<object::IRObjectFile> IRObj( std::unique_ptr<object::IRObjectFile> IRObj(
new object::IRObjectFile(std::move(Buffer), std::move(M))); new object::IRObjectFile(Buffer, std::move(M)));
LTOModule *Ret = new LTOModule(std::move(IRObj), target); LTOModule *Ret = new LTOModule(std::move(IRObj), target);

View File

@ -109,7 +109,7 @@ Archive::Child Archive::Child::getNext() const {
const char *NextLoc = Data.data() + SpaceToSkip; const char *NextLoc = Data.data() + SpaceToSkip;
// Check to see if this is past the end of the archive. // Check to see if this is past the end of the archive.
if (NextLoc >= Parent->Data->getBufferEnd()) if (NextLoc >= Parent->Data.getBufferEnd())
return Child(Parent, nullptr); return Child(Parent, nullptr);
return Child(Parent, NextLoc); return Child(Parent, NextLoc);
@ -159,45 +159,36 @@ ErrorOr<StringRef> Archive::Child::getName() const {
return name; return name;
} }
ErrorOr<std::unique_ptr<MemoryBuffer>> ErrorOr<MemoryBufferRef> Archive::Child::getMemoryBufferRef() const {
Archive::Child::getMemoryBuffer(bool FullPath) const {
ErrorOr<StringRef> NameOrErr = getName(); ErrorOr<StringRef> NameOrErr = getName();
if (std::error_code EC = NameOrErr.getError()) if (std::error_code EC = NameOrErr.getError())
return EC; return EC;
StringRef Name = NameOrErr.get(); StringRef Name = NameOrErr.get();
SmallString<128> Path; return MemoryBufferRef(getBuffer(), Name);
std::unique_ptr<MemoryBuffer> Ret(MemoryBuffer::getMemBuffer(
getBuffer(),
FullPath
? (Twine(Parent->getFileName()) + "(" + Name + ")").toStringRef(Path)
: Name,
false));
return std::move(Ret);
} }
ErrorOr<std::unique_ptr<Binary>> ErrorOr<std::unique_ptr<Binary>>
Archive::Child::getAsBinary(LLVMContext *Context) const { Archive::Child::getAsBinary(LLVMContext *Context) const {
ErrorOr<std::unique_ptr<MemoryBuffer>> BuffOrErr = getMemoryBuffer(); ErrorOr<MemoryBufferRef> BuffOrErr = getMemoryBufferRef();
if (std::error_code EC = BuffOrErr.getError()) if (std::error_code EC = BuffOrErr.getError())
return EC; return EC;
return createBinary(std::move(*BuffOrErr), Context); return createBinary(BuffOrErr.get(), Context);
} }
ErrorOr<std::unique_ptr<Archive>> ErrorOr<std::unique_ptr<Archive>> Archive::create(MemoryBufferRef Source) {
Archive::create(std::unique_ptr<MemoryBuffer> Source) {
std::error_code EC; std::error_code EC;
std::unique_ptr<Archive> Ret(new Archive(std::move(Source), EC)); std::unique_ptr<Archive> Ret(new Archive(Source, EC));
if (EC) if (EC)
return EC; return EC;
return std::move(Ret); return std::move(Ret);
} }
Archive::Archive(std::unique_ptr<MemoryBuffer> Source, std::error_code &ec) Archive::Archive(MemoryBufferRef Source, std::error_code &ec)
: Binary(Binary::ID_Archive, std::move(Source)), SymbolTable(child_end()) { : Binary(Binary::ID_Archive, Source), SymbolTable(child_end()) {
// Check for sufficient magic. // Check for sufficient magic.
if (Data->getBufferSize() < 8 || if (Data.getBufferSize() < 8 ||
StringRef(Data->getBufferStart(), 8) != Magic) { StringRef(Data.getBufferStart(), 8) != Magic) {
ec = object_error::invalid_file_type; ec = object_error::invalid_file_type;
return; return;
} }
@ -311,13 +302,13 @@ Archive::Archive(std::unique_ptr<MemoryBuffer> Source, std::error_code &ec)
} }
Archive::child_iterator Archive::child_begin(bool SkipInternal) const { Archive::child_iterator Archive::child_begin(bool SkipInternal) const {
if (Data->getBufferSize() == 8) // empty archive. if (Data.getBufferSize() == 8) // empty archive.
return child_end(); return child_end();
if (SkipInternal) if (SkipInternal)
return FirstRegular; return FirstRegular;
const char *Loc = Data->getBufferStart() + strlen(Magic); const char *Loc = Data.getBufferStart() + strlen(Magic);
Child c(this, Loc); Child c(this, Loc);
return c; return c;
} }

View File

@ -27,25 +27,22 @@ using namespace object;
Binary::~Binary() {} Binary::~Binary() {}
Binary::Binary(unsigned int Type, std::unique_ptr<MemoryBuffer> Source) Binary::Binary(unsigned int Type, MemoryBufferRef Source)
: TypeID(Type), Data(std::move(Source)) {} : TypeID(Type), Data(Source) {}
StringRef Binary::getData() const { StringRef Binary::getData() const { return Data.getBuffer(); }
return Data->getBuffer();
}
StringRef Binary::getFileName() const { StringRef Binary::getFileName() const { return Data.getBufferIdentifier(); }
return Data->getBufferIdentifier();
}
ErrorOr<std::unique_ptr<Binary>> MemoryBufferRef Binary::getMemoryBufferRef() const { return Data; }
object::createBinary(std::unique_ptr<MemoryBuffer> Buffer,
LLVMContext *Context) { ErrorOr<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
sys::fs::file_magic Type = sys::fs::identify_magic(Buffer->getBuffer()); LLVMContext *Context) {
sys::fs::file_magic Type = sys::fs::identify_magic(Buffer.getBuffer());
switch (Type) { switch (Type) {
case sys::fs::file_magic::archive: case sys::fs::file_magic::archive:
return Archive::create(std::move(Buffer)); return Archive::create(Buffer);
case sys::fs::file_magic::elf_relocatable: case sys::fs::file_magic::elf_relocatable:
case sys::fs::file_magic::elf_executable: case sys::fs::file_magic::elf_executable:
case sys::fs::file_magic::elf_shared_object: case sys::fs::file_magic::elf_shared_object:
@ -66,7 +63,7 @@ object::createBinary(std::unique_ptr<MemoryBuffer> Buffer,
case sys::fs::file_magic::bitcode: case sys::fs::file_magic::bitcode:
return ObjectFile::createSymbolicFile(Buffer, Type, Context); return ObjectFile::createSymbolicFile(Buffer, Type, Context);
case sys::fs::file_magic::macho_universal_binary: case sys::fs::file_magic::macho_universal_binary:
return MachOUniversalBinary::create(std::move(Buffer)); return MachOUniversalBinary::create(Buffer);
case sys::fs::file_magic::unknown: case sys::fs::file_magic::unknown:
case sys::fs::file_magic::windows_resource: case sys::fs::file_magic::windows_resource:
// Unrecognized object file format. // Unrecognized object file format.
@ -75,10 +72,18 @@ object::createBinary(std::unique_ptr<MemoryBuffer> Buffer,
llvm_unreachable("Unexpected Binary File Type"); llvm_unreachable("Unexpected Binary File Type");
} }
ErrorOr<std::unique_ptr<Binary>> object::createBinary(StringRef Path) { ErrorOr<OwningBinary<Binary>> object::createBinary(StringRef Path) {
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
MemoryBuffer::getFileOrSTDIN(Path); MemoryBuffer::getFileOrSTDIN(Path);
if (std::error_code EC = FileOrErr.getError()) if (std::error_code EC = FileOrErr.getError())
return EC; return EC;
return createBinary(std::move(*FileOrErr)); std::unique_ptr<MemoryBuffer> &Buffer = FileOrErr.get();
ErrorOr<std::unique_ptr<Binary>> BinOrErr =
createBinary(Buffer->getMemBufferRef());
if (std::error_code EC = BinOrErr.getError())
return EC;
std::unique_ptr<Binary> &Bin = BinOrErr.get();
return OwningBinary<Binary>(std::move(Bin), std::move(Buffer));
} }

View File

@ -31,8 +31,7 @@ using support::ulittle32_t;
using support::little16_t; using support::little16_t;
// Returns false if size is greater than the buffer size. And sets ec. // Returns false if size is greater than the buffer size. And sets ec.
static bool checkSize(const MemoryBuffer &M, std::error_code &EC, static bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Size) {
uint64_t Size) {
if (M.getBufferSize() < Size) { if (M.getBufferSize() < Size) {
EC = object_error::unexpected_eof; EC = object_error::unexpected_eof;
return false; return false;
@ -43,7 +42,7 @@ static bool checkSize(const MemoryBuffer &M, std::error_code &EC,
// Sets Obj unless any bytes in [addr, addr + size) fall outsize of m. // Sets Obj unless any bytes in [addr, addr + size) fall outsize of m.
// Returns unexpected_eof if error. // Returns unexpected_eof if error.
template <typename T> template <typename T>
static std::error_code getObject(const T *&Obj, const MemoryBuffer &M, static std::error_code getObject(const T *&Obj, MemoryBufferRef M,
const uint8_t *Ptr, const uint8_t *Ptr,
const size_t Size = sizeof(T)) { const size_t Size = sizeof(T)) {
uintptr_t Addr = uintptr_t(Ptr); uintptr_t Addr = uintptr_t(Ptr);
@ -397,7 +396,7 @@ relocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const {
// Initialize the pointer to the symbol table. // Initialize the pointer to the symbol table.
std::error_code COFFObjectFile::initSymbolTablePtr() { std::error_code COFFObjectFile::initSymbolTablePtr() {
if (std::error_code EC = getObject( if (std::error_code EC = getObject(
SymbolTable, *Data, base() + COFFHeader->PointerToSymbolTable, SymbolTable, Data, base() + COFFHeader->PointerToSymbolTable,
COFFHeader->NumberOfSymbols * sizeof(coff_symbol))) COFFHeader->NumberOfSymbols * sizeof(coff_symbol)))
return EC; return EC;
@ -408,12 +407,11 @@ std::error_code COFFObjectFile::initSymbolTablePtr() {
base() + COFFHeader->PointerToSymbolTable + base() + COFFHeader->PointerToSymbolTable +
COFFHeader->NumberOfSymbols * sizeof(coff_symbol); COFFHeader->NumberOfSymbols * sizeof(coff_symbol);
const ulittle32_t *StringTableSizePtr; const ulittle32_t *StringTableSizePtr;
if (std::error_code EC = if (std::error_code EC = getObject(StringTableSizePtr, Data, StringTableAddr))
getObject(StringTableSizePtr, *Data, StringTableAddr))
return EC; return EC;
StringTableSize = *StringTableSizePtr; StringTableSize = *StringTableSizePtr;
if (std::error_code EC = if (std::error_code EC =
getObject(StringTable, *Data, StringTableAddr, StringTableSize)) getObject(StringTable, Data, StringTableAddr, StringTableSize))
return EC; return EC;
// Treat table sizes < 4 as empty because contrary to the PECOFF spec, some // Treat table sizes < 4 as empty because contrary to the PECOFF spec, some
@ -511,15 +509,14 @@ std::error_code COFFObjectFile::initExportTablePtr() {
return object_error::success; return object_error::success;
} }
COFFObjectFile::COFFObjectFile(std::unique_ptr<MemoryBuffer> Object, COFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
std::error_code &EC) : ObjectFile(Binary::ID_COFF, Object), COFFHeader(nullptr),
: ObjectFile(Binary::ID_COFF, std::move(Object)), COFFHeader(nullptr),
PE32Header(nullptr), PE32PlusHeader(nullptr), DataDirectory(nullptr), PE32Header(nullptr), PE32PlusHeader(nullptr), DataDirectory(nullptr),
SectionTable(nullptr), SymbolTable(nullptr), StringTable(nullptr), SectionTable(nullptr), SymbolTable(nullptr), StringTable(nullptr),
StringTableSize(0), ImportDirectory(nullptr), NumberOfImportDirectory(0), StringTableSize(0), ImportDirectory(nullptr), NumberOfImportDirectory(0),
ExportDirectory(nullptr) { ExportDirectory(nullptr) {
// Check that we at least have enough room for a header. // Check that we at least have enough room for a header.
if (!checkSize(*Data, EC, sizeof(coff_file_header))) if (!checkSize(Data, EC, sizeof(coff_file_header)))
return; return;
// The current location in the file where we are looking at. // The current location in the file where we are looking at.
@ -533,7 +530,7 @@ COFFObjectFile::COFFObjectFile(std::unique_ptr<MemoryBuffer> Object,
if (base()[0] == 0x4d && base()[1] == 0x5a) { if (base()[0] == 0x4d && base()[1] == 0x5a) {
// PE/COFF, seek through MS-DOS compatibility stub and 4-byte // PE/COFF, seek through MS-DOS compatibility stub and 4-byte
// PE signature to find 'normal' COFF header. // PE signature to find 'normal' COFF header.
if (!checkSize(*Data, EC, 0x3c + 8)) if (!checkSize(Data, EC, 0x3c + 8))
return; return;
CurPtr = *reinterpret_cast<const ulittle16_t *>(base() + 0x3c); CurPtr = *reinterpret_cast<const ulittle16_t *>(base() + 0x3c);
// Check the PE magic bytes. ("PE\0\0") // Check the PE magic bytes. ("PE\0\0")
@ -545,13 +542,13 @@ COFFObjectFile::COFFObjectFile(std::unique_ptr<MemoryBuffer> Object,
HasPEHeader = true; HasPEHeader = true;
} }
if ((EC = getObject(COFFHeader, *Data, base() + CurPtr))) if ((EC = getObject(COFFHeader, Data, base() + CurPtr)))
return; return;
CurPtr += sizeof(coff_file_header); CurPtr += sizeof(coff_file_header);
if (HasPEHeader) { if (HasPEHeader) {
const pe32_header *Header; const pe32_header *Header;
if ((EC = getObject(Header, *Data, base() + CurPtr))) if ((EC = getObject(Header, Data, base() + CurPtr)))
return; return;
const uint8_t *DataDirAddr; const uint8_t *DataDirAddr;
@ -569,7 +566,7 @@ COFFObjectFile::COFFObjectFile(std::unique_ptr<MemoryBuffer> Object,
EC = object_error::parse_failed; EC = object_error::parse_failed;
return; return;
} }
if ((EC = getObject(DataDirectory, *Data, DataDirAddr, DataDirSize))) if ((EC = getObject(DataDirectory, Data, DataDirAddr, DataDirSize)))
return; return;
CurPtr += COFFHeader->SizeOfOptionalHeader; CurPtr += COFFHeader->SizeOfOptionalHeader;
} }
@ -577,7 +574,7 @@ COFFObjectFile::COFFObjectFile(std::unique_ptr<MemoryBuffer> Object,
if (COFFHeader->isImportLibrary()) if (COFFHeader->isImportLibrary())
return; return;
if ((EC = getObject(SectionTable, *Data, base() + CurPtr, if ((EC = getObject(SectionTable, Data, base() + CurPtr,
COFFHeader->NumberOfSections * sizeof(coff_section)))) COFFHeader->NumberOfSections * sizeof(coff_section))))
return; return;
@ -826,7 +823,7 @@ COFFObjectFile::getSectionContents(const coff_section *Sec,
// data, as there's nothing that says that is not allowed. // data, as there's nothing that says that is not allowed.
uintptr_t ConStart = uintptr_t(base()) + Sec->PointerToRawData; uintptr_t ConStart = uintptr_t(base()) + Sec->PointerToRawData;
uintptr_t ConEnd = ConStart + Sec->SizeOfRawData; uintptr_t ConEnd = ConStart + Sec->SizeOfRawData;
if (ConEnd > uintptr_t(Data->getBufferEnd())) if (ConEnd > uintptr_t(Data.getBufferEnd()))
return object_error::parse_failed; return object_error::parse_failed;
Res = ArrayRef<uint8_t>(reinterpret_cast<const unsigned char*>(ConStart), Res = ArrayRef<uint8_t>(reinterpret_cast<const unsigned char*>(ConStart),
Sec->SizeOfRawData); Sec->SizeOfRawData);
@ -1092,10 +1089,9 @@ ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const {
} }
ErrorOr<std::unique_ptr<COFFObjectFile>> ErrorOr<std::unique_ptr<COFFObjectFile>>
ObjectFile::createCOFFObjectFile(std::unique_ptr<MemoryBuffer> Object) { ObjectFile::createCOFFObjectFile(MemoryBufferRef Object) {
std::error_code EC; std::error_code EC;
std::unique_ptr<COFFObjectFile> Ret( std::unique_ptr<COFFObjectFile> Ret(new COFFObjectFile(Object, EC));
new COFFObjectFile(std::move(Object), EC));
if (EC) if (EC)
return EC; return EC;
return std::move(Ret); return std::move(Ret);

View File

@ -17,65 +17,56 @@
namespace llvm { namespace llvm {
using namespace object; using namespace object;
ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source)
std::unique_ptr<MemoryBuffer> Source) : ObjectFile(Type, Source) {}
: ObjectFile(Type, std::move(Source)) {}
ErrorOr<std::unique_ptr<ObjectFile>> ErrorOr<std::unique_ptr<ObjectFile>>
ObjectFile::createELFObjectFile(std::unique_ptr<MemoryBuffer> &Obj) { ObjectFile::createELFObjectFile(MemoryBufferRef Obj) {
std::pair<unsigned char, unsigned char> Ident = std::pair<unsigned char, unsigned char> Ident =
getElfArchType(Obj->getBuffer()); getElfArchType(Obj.getBuffer());
std::size_t MaxAlignment = std::size_t MaxAlignment =
1ULL << countTrailingZeros(uintptr_t(Obj->getBufferStart())); 1ULL << countTrailingZeros(uintptr_t(Obj.getBufferStart()));
std::error_code EC; std::error_code EC;
std::unique_ptr<ObjectFile> R; std::unique_ptr<ObjectFile> R;
if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
#if !LLVM_IS_UNALIGNED_ACCESS_FAST #if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 4) if (MaxAlignment >= 4)
R.reset(new ELFObjectFile<ELFType<support::little, 4, false>>( R.reset(new ELFObjectFile<ELFType<support::little, 4, false>>(Obj, EC));
std::move(Obj), EC));
else else
#endif #endif
if (MaxAlignment >= 2) if (MaxAlignment >= 2)
R.reset(new ELFObjectFile<ELFType<support::little, 2, false>>( R.reset(new ELFObjectFile<ELFType<support::little, 2, false>>(Obj, EC));
std::move(Obj), EC));
else else
return object_error::parse_failed; return object_error::parse_failed;
else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB) else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
#if !LLVM_IS_UNALIGNED_ACCESS_FAST #if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 4) if (MaxAlignment >= 4)
R.reset(new ELFObjectFile<ELFType<support::big, 4, false>>(std::move(Obj), R.reset(new ELFObjectFile<ELFType<support::big, 4, false>>(Obj, EC));
EC));
else else
#endif #endif
if (MaxAlignment >= 2) if (MaxAlignment >= 2)
R.reset(new ELFObjectFile<ELFType<support::big, 2, false>>(std::move(Obj), R.reset(new ELFObjectFile<ELFType<support::big, 2, false>>(Obj, EC));
EC));
else else
return object_error::parse_failed; return object_error::parse_failed;
else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB) else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
#if !LLVM_IS_UNALIGNED_ACCESS_FAST #if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 8) if (MaxAlignment >= 8)
R.reset(new ELFObjectFile<ELFType<support::big, 8, true>>(std::move(Obj), R.reset(new ELFObjectFile<ELFType<support::big, 8, true>>(Obj, EC));
EC));
else else
#endif #endif
if (MaxAlignment >= 2) if (MaxAlignment >= 2)
R.reset(new ELFObjectFile<ELFType<support::big, 2, true>>(std::move(Obj), R.reset(new ELFObjectFile<ELFType<support::big, 2, true>>(Obj, EC));
EC));
else else
return object_error::parse_failed; return object_error::parse_failed;
else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) { else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
#if !LLVM_IS_UNALIGNED_ACCESS_FAST #if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 8) if (MaxAlignment >= 8)
R.reset(new ELFObjectFile<ELFType<support::little, 8, true>>( R.reset(new ELFObjectFile<ELFType<support::little, 8, true>>(Obj, EC));
std::move(Obj), EC));
else else
#endif #endif
if (MaxAlignment >= 2) if (MaxAlignment >= 2)
R.reset(new ELFObjectFile<ELFType<support::little, 2, true>>( R.reset(new ELFObjectFile<ELFType<support::little, 2, true>>(Obj, EC));
std::move(Obj), EC));
else else
return object_error::parse_failed; return object_error::parse_failed;
} }

View File

@ -32,9 +32,8 @@
using namespace llvm; using namespace llvm;
using namespace object; using namespace object;
IRObjectFile::IRObjectFile(std::unique_ptr<MemoryBuffer> Object, IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> Mod)
std::unique_ptr<Module> Mod) : SymbolicFile(Binary::ID_IR, Object), M(std::move(Mod)) {
: SymbolicFile(Binary::ID_IR, std::move(Object)), M(std::move(Mod)) {
// If we have a DataLayout, setup a mangler. // If we have a DataLayout, setup a mangler.
const DataLayout *DL = M->getDataLayout(); const DataLayout *DL = M->getDataLayout();
if (!DL) if (!DL)
@ -114,9 +113,6 @@ IRObjectFile::IRObjectFile(std::unique_ptr<MemoryBuffer> Object,
} }
IRObjectFile::~IRObjectFile() { IRObjectFile::~IRObjectFile() {
GVMaterializer *GVM = M->getMaterializer();
if (GVM)
GVM->releaseBuffer();
} }
static const GlobalValue *getGV(DataRefImpl &Symb) { static const GlobalValue *getGV(DataRefImpl &Symb) {
@ -268,12 +264,20 @@ basic_symbol_iterator IRObjectFile::symbol_end_impl() const {
return basic_symbol_iterator(BasicSymbolRef(Ret, this)); return basic_symbol_iterator(BasicSymbolRef(Ret, this));
} }
ErrorOr<IRObjectFile *> llvm::object::IRObjectFile::createIRObjectFile( ErrorOr<IRObjectFile *>
std::unique_ptr<MemoryBuffer> Object, LLVMContext &Context) { llvm::object::IRObjectFile::createIRObjectFile(MemoryBufferRef Object,
ErrorOr<Module *> MOrErr = getLazyBitcodeModule(Object.get(), Context); LLVMContext &Context) {
StringRef Data = Object.getBuffer();
StringRef FileName = Object.getBufferIdentifier();
std::unique_ptr<MemoryBuffer> Buff(
MemoryBuffer::getMemBuffer(Data, FileName, false));
ErrorOr<Module *> MOrErr = getLazyBitcodeModule(Buff.get(), Context);
if (std::error_code EC = MOrErr.getError()) if (std::error_code EC = MOrErr.getError())
return EC; return EC;
Buff.release();
std::unique_ptr<Module> M(MOrErr.get()); std::unique_ptr<Module> M(MOrErr.get());
return new IRObjectFile(std::move(Object), std::move(M)); return new IRObjectFile(Object, std::move(M));
} }

View File

@ -222,10 +222,9 @@ static uint32_t getSectionFlags(const MachOObjectFile *O,
return Sect.flags; return Sect.flags;
} }
MachOObjectFile::MachOObjectFile(std::unique_ptr<MemoryBuffer> Object, MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
bool IsLittleEndian, bool Is64bits, bool Is64bits, std::error_code &EC)
std::error_code &EC) : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
: ObjectFile(getMachOType(IsLittleEndian, Is64bits), std::move(Object)),
SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr), SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
DataInCodeLoadCmd(nullptr) { DataInCodeLoadCmd(nullptr) {
uint32_t LoadCommandCount = this->getHeader().ncmds; uint32_t LoadCommandCount = this->getHeader().ncmds;
@ -1776,18 +1775,18 @@ bool MachOObjectFile::isRelocatableObject() const {
} }
ErrorOr<std::unique_ptr<MachOObjectFile>> ErrorOr<std::unique_ptr<MachOObjectFile>>
ObjectFile::createMachOObjectFile(std::unique_ptr<MemoryBuffer> &Buffer) { ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer) {
StringRef Magic = Buffer->getBuffer().slice(0, 4); StringRef Magic = Buffer.getBuffer().slice(0, 4);
std::error_code EC; std::error_code EC;
std::unique_ptr<MachOObjectFile> Ret; std::unique_ptr<MachOObjectFile> Ret;
if (Magic == "\xFE\xED\xFA\xCE") if (Magic == "\xFE\xED\xFA\xCE")
Ret.reset(new MachOObjectFile(std::move(Buffer), false, false, EC)); Ret.reset(new MachOObjectFile(Buffer, false, false, EC));
else if (Magic == "\xCE\xFA\xED\xFE") else if (Magic == "\xCE\xFA\xED\xFE")
Ret.reset(new MachOObjectFile(std::move(Buffer), true, false, EC)); Ret.reset(new MachOObjectFile(Buffer, true, false, EC));
else if (Magic == "\xFE\xED\xFA\xCF") else if (Magic == "\xFE\xED\xFA\xCF")
Ret.reset(new MachOObjectFile(std::move(Buffer), false, true, EC)); Ret.reset(new MachOObjectFile(Buffer, false, true, EC));
else if (Magic == "\xCF\xFA\xED\xFE") else if (Magic == "\xCF\xFA\xED\xFE")
Ret.reset(new MachOObjectFile(std::move(Buffer), true, true, EC)); Ret.reset(new MachOObjectFile(Buffer, true, true, EC));
else else
return object_error::parse_failed; return object_error::parse_failed;

View File

@ -72,9 +72,8 @@ MachOUniversalBinary::ObjectForArch::getAsObjectFile() const {
if (Parent) { if (Parent) {
StringRef ParentData = Parent->getData(); StringRef ParentData = Parent->getData();
StringRef ObjectData = ParentData.substr(Header.offset, Header.size); StringRef ObjectData = ParentData.substr(Header.offset, Header.size);
std::string ObjectName = Parent->getFileName().str(); StringRef ObjectName = Parent->getFileName().str();
std::unique_ptr<MemoryBuffer> ObjBuffer( MemoryBufferRef ObjBuffer(ObjectData, ObjectName);
MemoryBuffer::getMemBuffer(ObjectData, ObjectName, false));
return ObjectFile::createMachOObjectFile(ObjBuffer); return ObjectFile::createMachOObjectFile(ObjBuffer);
} }
return object_error::parse_failed; return object_error::parse_failed;
@ -86,10 +85,8 @@ std::error_code MachOUniversalBinary::ObjectForArch::getAsArchive(
StringRef ParentData = Parent->getData(); StringRef ParentData = Parent->getData();
StringRef ObjectData = ParentData.substr(Header.offset, Header.size); StringRef ObjectData = ParentData.substr(Header.offset, Header.size);
std::string ObjectName = Parent->getFileName().str(); std::string ObjectName = Parent->getFileName().str();
std::unique_ptr<MemoryBuffer> ObjBuffer( MemoryBufferRef ObjBuffer(ObjectData, ObjectName);
MemoryBuffer::getMemBuffer(ObjectData, ObjectName, false)); ErrorOr<std::unique_ptr<Archive>> Obj = Archive::create(ObjBuffer);
ErrorOr<std::unique_ptr<Archive>> Obj =
Archive::create(std::move(ObjBuffer));
if (std::error_code EC = Obj.getError()) if (std::error_code EC = Obj.getError())
return EC; return EC;
Result = std::move(Obj.get()); Result = std::move(Obj.get());
@ -101,20 +98,19 @@ std::error_code MachOUniversalBinary::ObjectForArch::getAsArchive(
void MachOUniversalBinary::anchor() { } void MachOUniversalBinary::anchor() { }
ErrorOr<MachOUniversalBinary *> ErrorOr<MachOUniversalBinary *>
MachOUniversalBinary::create(std::unique_ptr<MemoryBuffer> Source) { MachOUniversalBinary::create(MemoryBufferRef Source) {
std::error_code EC; std::error_code EC;
std::unique_ptr<MachOUniversalBinary> Ret( std::unique_ptr<MachOUniversalBinary> Ret(
new MachOUniversalBinary(std::move(Source), EC)); new MachOUniversalBinary(Source, EC));
if (EC) if (EC)
return EC; return EC;
return Ret.release(); return Ret.release();
} }
MachOUniversalBinary::MachOUniversalBinary(std::unique_ptr<MemoryBuffer> Source, MachOUniversalBinary::MachOUniversalBinary(MemoryBufferRef Source,
std::error_code &ec) std::error_code &ec)
: Binary(Binary::ID_MachOUniversalBinary, std::move(Source)), : Binary(Binary::ID_MachOUniversalBinary, Source), NumberOfObjects(0) {
NumberOfObjects(0) { if (Data.getBufferSize() < sizeof(MachO::fat_header)) {
if (Data->getBufferSize() < sizeof(MachO::fat_header)) {
ec = object_error::invalid_file_type; ec = object_error::invalid_file_type;
return; return;
} }

View File

@ -19,12 +19,13 @@
using namespace llvm; using namespace llvm;
using namespace object; using namespace object;
inline ObjectFile *unwrap(LLVMObjectFileRef OF) { inline OwningBinary<ObjectFile> *unwrap(LLVMObjectFileRef OF) {
return reinterpret_cast<ObjectFile*>(OF); return reinterpret_cast<OwningBinary<ObjectFile> *>(OF);
} }
inline LLVMObjectFileRef wrap(const ObjectFile *OF) { inline LLVMObjectFileRef wrap(const OwningBinary<ObjectFile> *OF) {
return reinterpret_cast<LLVMObjectFileRef>(const_cast<ObjectFile*>(OF)); return reinterpret_cast<LLVMObjectFileRef>(
const_cast<OwningBinary<ObjectFile> *>(OF));
} }
inline section_iterator *unwrap(LLVMSectionIteratorRef SI) { inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
@ -61,10 +62,12 @@ wrap(const relocation_iterator *SI) {
LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) { LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) {
std::unique_ptr<MemoryBuffer> Buf(unwrap(MemBuf)); std::unique_ptr<MemoryBuffer> Buf(unwrap(MemBuf));
ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr( ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr(
ObjectFile::createObjectFile(Buf)); ObjectFile::createObjectFile(Buf->getMemBufferRef()));
Buf.release(); std::unique_ptr<ObjectFile> Obj;
ObjectFile *Obj = ObjOrErr ? ObjOrErr.get().release() : nullptr; if (ObjOrErr)
return wrap(Obj); Obj = std::move(ObjOrErr.get());
auto *Ret = new OwningBinary<ObjectFile>(std::move(Obj), std::move(Buf));
return wrap(Ret);
} }
void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) { void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) {
@ -72,8 +75,9 @@ void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) {
} }
// ObjectFile Section iterators // ObjectFile Section iterators
LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef ObjectFile) { LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef OF) {
section_iterator SI = unwrap(ObjectFile)->section_begin(); OwningBinary<ObjectFile> *OB = unwrap(OF);
section_iterator SI = OB->getBinary()->section_begin();
return wrap(new section_iterator(SI)); return wrap(new section_iterator(SI));
} }
@ -81,9 +85,10 @@ void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) {
delete unwrap(SI); delete unwrap(SI);
} }
LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef ObjectFile, LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef OF,
LLVMSectionIteratorRef SI) { LLVMSectionIteratorRef SI) {
return (*unwrap(SI) == unwrap(ObjectFile)->section_end()) ? 1 : 0; OwningBinary<ObjectFile> *OB = unwrap(OF);
return (*unwrap(SI) == OB->getBinary()->section_end()) ? 1 : 0;
} }
void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) { void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) {
@ -97,8 +102,9 @@ void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect,
} }
// ObjectFile Symbol iterators // ObjectFile Symbol iterators
LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef ObjectFile) { LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef OF) {
symbol_iterator SI = unwrap(ObjectFile)->symbol_begin(); OwningBinary<ObjectFile> *OB = unwrap(OF);
symbol_iterator SI = OB->getBinary()->symbol_begin();
return wrap(new symbol_iterator(SI)); return wrap(new symbol_iterator(SI));
} }
@ -106,9 +112,10 @@ void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI) {
delete unwrap(SI); delete unwrap(SI);
} }
LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef ObjectFile, LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef OF,
LLVMSymbolIteratorRef SI) { LLVMSymbolIteratorRef SI) {
return (*unwrap(SI) == unwrap(ObjectFile)->symbol_end()) ? 1 : 0; OwningBinary<ObjectFile> *OB = unwrap(OF);
return (*unwrap(SI) == OB->getBinary()->symbol_end()) ? 1 : 0;
} }
void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) { void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) {

View File

@ -25,8 +25,8 @@ using namespace object;
void ObjectFile::anchor() { } void ObjectFile::anchor() { }
ObjectFile::ObjectFile(unsigned int Type, std::unique_ptr<MemoryBuffer> Source) ObjectFile::ObjectFile(unsigned int Type, MemoryBufferRef Source)
: SymbolicFile(Type, std::move(Source)) {} : SymbolicFile(Type, Source) {}
std::error_code ObjectFile::printSymbolName(raw_ostream &OS, std::error_code ObjectFile::printSymbolName(raw_ostream &OS,
DataRefImpl Symb) const { DataRefImpl Symb) const {
@ -48,10 +48,10 @@ section_iterator ObjectFile::getRelocatedSection(DataRefImpl Sec) const {
} }
ErrorOr<std::unique_ptr<ObjectFile>> ErrorOr<std::unique_ptr<ObjectFile>>
ObjectFile::createObjectFile(std::unique_ptr<MemoryBuffer> &Object, ObjectFile::createObjectFile(MemoryBufferRef Object, sys::fs::file_magic Type) {
sys::fs::file_magic Type) { StringRef Data = Object.getBuffer();
if (Type == sys::fs::file_magic::unknown) if (Type == sys::fs::file_magic::unknown)
Type = sys::fs::identify_magic(Object->getBuffer()); Type = sys::fs::identify_magic(Data);
switch (Type) { switch (Type) {
case sys::fs::file_magic::unknown: case sys::fs::file_magic::unknown:
@ -79,16 +79,24 @@ ObjectFile::createObjectFile(std::unique_ptr<MemoryBuffer> &Object,
case sys::fs::file_magic::coff_object: case sys::fs::file_magic::coff_object:
case sys::fs::file_magic::coff_import_library: case sys::fs::file_magic::coff_import_library:
case sys::fs::file_magic::pecoff_executable: case sys::fs::file_magic::pecoff_executable:
return createCOFFObjectFile(std::move(Object)); return createCOFFObjectFile(Object);
} }
llvm_unreachable("Unexpected Object File Type"); llvm_unreachable("Unexpected Object File Type");
} }
ErrorOr<std::unique_ptr<ObjectFile>> ErrorOr<OwningBinary<ObjectFile>>
ObjectFile::createObjectFile(StringRef ObjectPath) { ObjectFile::createObjectFile(StringRef ObjectPath) {
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
MemoryBuffer::getFile(ObjectPath); MemoryBuffer::getFile(ObjectPath);
if (std::error_code EC = FileOrErr.getError()) if (std::error_code EC = FileOrErr.getError())
return EC; return EC;
return createObjectFile(FileOrErr.get()); std::unique_ptr<MemoryBuffer> Buffer = std::move(FileOrErr.get());
ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr =
createObjectFile(Buffer->getMemBufferRef());
if (std::error_code EC = ObjOrErr.getError())
return EC;
std::unique_ptr<ObjectFile> Obj = std::move(ObjOrErr.get());
return OwningBinary<ObjectFile>(std::move(Obj), std::move(Buffer));
} }

View File

@ -19,23 +19,21 @@
using namespace llvm; using namespace llvm;
using namespace object; using namespace object;
SymbolicFile::SymbolicFile(unsigned int Type, SymbolicFile::SymbolicFile(unsigned int Type, MemoryBufferRef Source)
std::unique_ptr<MemoryBuffer> Source) : Binary(Type, Source) {}
: Binary(Type, std::move(Source)) {}
SymbolicFile::~SymbolicFile() {} SymbolicFile::~SymbolicFile() {}
ErrorOr<std::unique_ptr<SymbolicFile>> ErrorOr<std::unique_ptr<SymbolicFile>> SymbolicFile::createSymbolicFile(
SymbolicFile::createSymbolicFile(std::unique_ptr<MemoryBuffer> &Object, MemoryBufferRef Object, sys::fs::file_magic Type, LLVMContext *Context) {
sys::fs::file_magic Type, StringRef Data = Object.getBuffer();
LLVMContext *Context) {
if (Type == sys::fs::file_magic::unknown) if (Type == sys::fs::file_magic::unknown)
Type = sys::fs::identify_magic(Object->getBuffer()); Type = sys::fs::identify_magic(Data);
switch (Type) { switch (Type) {
case sys::fs::file_magic::bitcode: case sys::fs::file_magic::bitcode:
if (Context) if (Context)
return IRObjectFile::createIRObjectFile(std::move(Object), *Context); return IRObjectFile::createIRObjectFile(Object, *Context);
// Fallthrough // Fallthrough
case sys::fs::file_magic::unknown: case sys::fs::file_magic::unknown:
case sys::fs::file_magic::archive: case sys::fs::file_magic::archive:

View File

@ -292,11 +292,13 @@ ObjectFileCoverageMappingReader::ObjectFileCoverageMappingReader(
ObjectFileCoverageMappingReader::ObjectFileCoverageMappingReader( ObjectFileCoverageMappingReader::ObjectFileCoverageMappingReader(
std::unique_ptr<MemoryBuffer> &ObjectBuffer, sys::fs::file_magic Type) std::unique_ptr<MemoryBuffer> &ObjectBuffer, sys::fs::file_magic Type)
: CurrentRecord(0) { : CurrentRecord(0) {
auto File = llvm::object::ObjectFile::createObjectFile(ObjectBuffer, Type); auto File = object::ObjectFile::createObjectFile(
ObjectBuffer->getMemBufferRef(), Type);
if (!File) if (!File)
error(File.getError()); error(File.getError());
else else
Object = std::move(File.get()); Object = OwningBinary<ObjectFile>(std::move(File.get()),
std::move(ObjectBuffer));
} }
namespace { namespace {
@ -429,16 +431,17 @@ std::error_code readCoverageMappingData(
} }
std::error_code ObjectFileCoverageMappingReader::readHeader() { std::error_code ObjectFileCoverageMappingReader::readHeader() {
if (!Object) ObjectFile *OF = Object.getBinary().get();
if (!OF)
return getError(); return getError();
auto BytesInAddress = Object->getBytesInAddress(); auto BytesInAddress = OF->getBytesInAddress();
if (BytesInAddress != 4 && BytesInAddress != 8) if (BytesInAddress != 4 && BytesInAddress != 8)
return error(instrprof_error::malformed); return error(instrprof_error::malformed);
// Look for the sections that we are interested in. // Look for the sections that we are interested in.
int FoundSectionCount = 0; int FoundSectionCount = 0;
SectionRef ProfileNames, CoverageMapping; SectionRef ProfileNames, CoverageMapping;
for (const auto &Section : Object->sections()) { for (const auto &Section : OF->sections()) {
StringRef Name; StringRef Name;
if (auto Err = Section.getName(Name)) if (auto Err = Section.getName(Name))
return Err; return Err;

View File

@ -416,3 +416,9 @@ ErrorOr<std::unique_ptr<MemoryBuffer>> MemoryBuffer::getSTDIN() {
return getMemoryBufferForStream(0, "<stdin>"); return getMemoryBufferForStream(0, "<stdin>");
} }
MemoryBufferRef MemoryBuffer::getMemBufferRef() const {
StringRef Data = getBuffer();
StringRef Identifier = getBufferIdentifier();
return MemoryBufferRef(Data, Identifier);
}

View File

@ -263,7 +263,7 @@ public:
} }
virtual ~LLIObjectCache() {} virtual ~LLIObjectCache() {}
void notifyObjectCompiled(const Module *M, const MemoryBuffer *Obj) override { void notifyObjectCompiled(const Module *M, MemoryBufferRef Obj) override {
const std::string ModuleID = M->getModuleIdentifier(); const std::string ModuleID = M->getModuleIdentifier();
std::string CacheName; std::string CacheName;
if (!getCacheFilename(ModuleID, CacheName)) if (!getCacheFilename(ModuleID, CacheName))
@ -275,7 +275,7 @@ public:
sys::fs::create_directories(Twine(dir)); sys::fs::create_directories(Twine(dir));
} }
raw_fd_ostream outfile(CacheName.c_str(), errStr, sys::fs::F_None); raw_fd_ostream outfile(CacheName.c_str(), errStr, sys::fs::F_None);
outfile.write(Obj->getBufferStart(), Obj->getBufferSize()); outfile.write(Obj.getBufferStart(), Obj.getBufferSize());
outfile.close(); outfile.close();
} }
@ -530,30 +530,35 @@ int main(int argc, char **argv, char * const *envp) {
} }
for (unsigned i = 0, e = ExtraObjects.size(); i != e; ++i) { for (unsigned i = 0, e = ExtraObjects.size(); i != e; ++i) {
ErrorOr<std::unique_ptr<object::ObjectFile>> Obj = ErrorOr<object::OwningBinary<object::ObjectFile>> Obj =
object::ObjectFile::createObjectFile(ExtraObjects[i]); object::ObjectFile::createObjectFile(ExtraObjects[i]);
if (!Obj) { if (!Obj) {
Err.print(argv[0], errs()); Err.print(argv[0], errs());
return 1; return 1;
} }
EE->addObjectFile(std::move(Obj.get())); EE->addObjectFile(std::move(Obj.get().getBinary()));
} }
for (unsigned i = 0, e = ExtraArchives.size(); i != e; ++i) { for (unsigned i = 0, e = ExtraArchives.size(); i != e; ++i) {
ErrorOr<std::unique_ptr<MemoryBuffer>> ArBuf = ErrorOr<std::unique_ptr<MemoryBuffer>> ArBufOrErr =
MemoryBuffer::getFileOrSTDIN(ExtraArchives[i]); MemoryBuffer::getFileOrSTDIN(ExtraArchives[i]);
if (!ArBuf) { if (!ArBufOrErr) {
Err.print(argv[0], errs()); Err.print(argv[0], errs());
return 1; return 1;
} }
std::unique_ptr<MemoryBuffer> &ArBuf = ArBufOrErr.get();
ErrorOr<std::unique_ptr<object::Archive>> ArOrErr = ErrorOr<std::unique_ptr<object::Archive>> ArOrErr =
object::Archive::create(std::move(ArBuf.get())); object::Archive::create(ArBuf->getMemBufferRef());
if (std::error_code EC = ArOrErr.getError()) { if (std::error_code EC = ArOrErr.getError()) {
errs() << EC.message(); errs() << EC.message();
return 1; return 1;
} }
EE->addArchive(std::move(ArOrErr.get())); std::unique_ptr<object::Archive> &Ar = ArOrErr.get();
object::OwningBinary<object::Archive> OB(std::move(Ar), std::move(ArBuf));
EE->addArchive(std::move(OB));
} }
// If the target is Cygwin/MingW and we are generating remote code, we // If the target is Cygwin/MingW and we are generating remote code, we

View File

@ -686,7 +686,7 @@ static void writeStringTable(raw_fd_ostream &Out,
static void static void
writeSymbolTable(raw_fd_ostream &Out, ArrayRef<NewArchiveIterator> Members, writeSymbolTable(raw_fd_ostream &Out, ArrayRef<NewArchiveIterator> Members,
MutableArrayRef<std::unique_ptr<MemoryBuffer>> Buffers, ArrayRef<MemoryBufferRef> Buffers,
std::vector<std::pair<unsigned, unsigned>> &MemberOffsetRefs) { std::vector<std::pair<unsigned, unsigned>> &MemberOffsetRefs) {
unsigned StartOffset = 0; unsigned StartOffset = 0;
unsigned MemberNum = 0; unsigned MemberNum = 0;
@ -697,7 +697,7 @@ writeSymbolTable(raw_fd_ostream &Out, ArrayRef<NewArchiveIterator> Members,
for (ArrayRef<NewArchiveIterator>::iterator I = Members.begin(), for (ArrayRef<NewArchiveIterator>::iterator I = Members.begin(),
E = Members.end(); E = Members.end();
I != E; ++I, ++MemberNum) { I != E; ++I, ++MemberNum) {
std::unique_ptr<MemoryBuffer> &MemberBuffer = Buffers[MemberNum]; MemoryBufferRef MemberBuffer = Buffers[MemberNum];
ErrorOr<std::unique_ptr<object::SymbolicFile>> ObjOrErr = ErrorOr<std::unique_ptr<object::SymbolicFile>> ObjOrErr =
object::SymbolicFile::createSymbolicFile( object::SymbolicFile::createSymbolicFile(
MemberBuffer, sys::fs::file_magic::unknown, &Context); MemberBuffer, sys::fs::file_magic::unknown, &Context);
@ -725,7 +725,6 @@ writeSymbolTable(raw_fd_ostream &Out, ArrayRef<NewArchiveIterator> Members,
MemberOffsetRefs.push_back(std::make_pair(Out.tell(), MemberNum)); MemberOffsetRefs.push_back(std::make_pair(Out.tell(), MemberNum));
print32BE(Out, 0); print32BE(Out, 0);
} }
MemberBuffer.reset(Obj.releaseBuffer());
} }
Out << NameOS.str(); Out << NameOS.str();
@ -759,12 +758,12 @@ static void performWriteOperation(ArchiveOperation Operation,
std::vector<std::pair<unsigned, unsigned> > MemberOffsetRefs; std::vector<std::pair<unsigned, unsigned> > MemberOffsetRefs;
std::vector<std::unique_ptr<MemoryBuffer>> MemberBuffers; std::vector<std::unique_ptr<MemoryBuffer>> Buffers;
MemberBuffers.resize(NewMembers.size()); std::vector<MemoryBufferRef> Members;
for (unsigned I = 0, N = NewMembers.size(); I < N; ++I) { for (unsigned I = 0, N = NewMembers.size(); I < N; ++I) {
std::unique_ptr<MemoryBuffer> &MemberBuffer = MemberBuffers[I];
NewArchiveIterator &Member = NewMembers[I]; NewArchiveIterator &Member = NewMembers[I];
MemoryBufferRef MemberRef;
if (Member.isNewMember()) { if (Member.isNewMember()) {
const char *Filename = Member.getNew(); const char *Filename = Member.getNew();
@ -773,18 +772,20 @@ static void performWriteOperation(ArchiveOperation Operation,
ErrorOr<std::unique_ptr<MemoryBuffer>> MemberBufferOrErr = ErrorOr<std::unique_ptr<MemoryBuffer>> MemberBufferOrErr =
MemoryBuffer::getOpenFile(FD, Filename, Status.getSize(), false); MemoryBuffer::getOpenFile(FD, Filename, Status.getSize(), false);
failIfError(MemberBufferOrErr.getError(), Filename); failIfError(MemberBufferOrErr.getError(), Filename);
MemberBuffer = std::move(MemberBufferOrErr.get()); Buffers.push_back(std::move(MemberBufferOrErr.get()));
MemberRef = Buffers.back()->getMemBufferRef();
} else { } else {
object::Archive::child_iterator OldMember = Member.getOld(); object::Archive::child_iterator OldMember = Member.getOld();
ErrorOr<std::unique_ptr<MemoryBuffer>> MemberBufferOrErr = ErrorOr<MemoryBufferRef> MemberBufferOrErr =
OldMember->getMemoryBuffer(); OldMember->getMemoryBufferRef();
failIfError(MemberBufferOrErr.getError()); failIfError(MemberBufferOrErr.getError());
MemberBuffer = std::move(MemberBufferOrErr.get()); MemberRef = MemberBufferOrErr.get();
} }
Members.push_back(MemberRef);
} }
if (Symtab) { if (Symtab) {
writeSymbolTable(Out, NewMembers, MemberBuffers, MemberOffsetRefs); writeSymbolTable(Out, NewMembers, Members, MemberOffsetRefs);
} }
std::vector<unsigned> StringMapIndexes; std::vector<unsigned> StringMapIndexes;
@ -808,7 +809,7 @@ static void performWriteOperation(ArchiveOperation Operation,
} }
Out.seek(Pos); Out.seek(Pos);
const MemoryBuffer *File = MemberBuffers[MemberNum].get(); MemoryBufferRef File = Members[MemberNum];
if (I->isNewMember()) { if (I->isNewMember()) {
const char *FileName = I->getNew(); const char *FileName = I->getNew();
const sys::fs::file_status &Status = I->getStatus(); const sys::fs::file_status &Status = I->getStatus();
@ -838,7 +839,7 @@ static void performWriteOperation(ArchiveOperation Operation,
OldMember->getSize()); OldMember->getSize());
} }
Out << File->getBuffer(); Out << File.getBuffer();
if (Out.tell() % 2) if (Out.tell() % 2)
Out << '\n'; Out << '\n';
@ -943,7 +944,7 @@ static int performOperation(ArchiveOperation Operation) {
} }
if (!EC) { if (!EC) {
object::Archive Archive(std::move(Buf.get()), EC); object::Archive Archive(Buf.get()->getMemBufferRef(), EC);
if (EC) { if (EC) {
errs() << ToolName << ": error loading '" << ArchiveName errs() << ToolName << ": error loading '" << ArchiveName

View File

@ -66,16 +66,17 @@ DumpType("debug-dump", cl::init(DIDT_All),
clEnumValEnd)); clEnumValEnd));
static void DumpInput(const StringRef &Filename) { static void DumpInput(const StringRef &Filename) {
ErrorOr<std::unique_ptr<MemoryBuffer>> Buff = ErrorOr<std::unique_ptr<MemoryBuffer>> BuffOrErr =
MemoryBuffer::getFileOrSTDIN(Filename); MemoryBuffer::getFileOrSTDIN(Filename);
if (std::error_code EC = Buff.getError()) { if (std::error_code EC = BuffOrErr.getError()) {
errs() << Filename << ": " << EC.message() << "\n"; errs() << Filename << ": " << EC.message() << "\n";
return; return;
} }
std::unique_ptr<MemoryBuffer> Buff = std::move(BuffOrErr.get());
ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr =
ObjectFile::createObjectFile(Buff.get()); ObjectFile::createObjectFile(Buff->getMemBufferRef());
if (std::error_code EC = ObjOrErr.getError()) { if (std::error_code EC = ObjOrErr.getError()) {
errs() << Filename << ": " << EC.message() << '\n'; errs() << Filename << ": " << EC.message() << '\n';
return; return;

View File

@ -1010,7 +1010,7 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
LLVMContext &Context = getGlobalContext(); LLVMContext &Context = getGlobalContext();
ErrorOr<std::unique_ptr<Binary>> BinaryOrErr = ErrorOr<std::unique_ptr<Binary>> BinaryOrErr =
createBinary(std::move(*BufferOrErr), &Context); createBinary(BufferOrErr.get()->getMemBufferRef(), &Context);
if (error(BinaryOrErr.getError(), Filename)) if (error(BinaryOrErr.getError(), Filename))
return; return;
Binary &Bin = *BinaryOrErr.get(); Binary &Bin = *BinaryOrErr.get();

View File

@ -210,15 +210,16 @@ static void DisassembleInputMachO2(StringRef Filename,
MachOObjectFile *MachOOF); MachOObjectFile *MachOOF);
void llvm::DisassembleInputMachO(StringRef Filename) { void llvm::DisassembleInputMachO(StringRef Filename) {
ErrorOr<std::unique_ptr<MemoryBuffer>> Buff = ErrorOr<std::unique_ptr<MemoryBuffer>> BuffOrErr =
MemoryBuffer::getFileOrSTDIN(Filename); MemoryBuffer::getFileOrSTDIN(Filename);
if (std::error_code EC = Buff.getError()) { if (std::error_code EC = BuffOrErr.getError()) {
errs() << "llvm-objdump: " << Filename << ": " << EC.message() << "\n"; errs() << "llvm-objdump: " << Filename << ": " << EC.message() << "\n";
return; return;
} }
std::unique_ptr<MemoryBuffer> Buff = std::move(BuffOrErr.get());
std::unique_ptr<MachOObjectFile> MachOOF = std::unique_ptr<MachOObjectFile> MachOOF = std::move(
std::move(ObjectFile::createMachOObjectFile(Buff.get()).get()); ObjectFile::createMachOObjectFile(Buff.get()->getMemBufferRef()).get());
DisassembleInputMachO2(Filename, MachOOF.get()); DisassembleInputMachO2(Filename, MachOOF.get());
} }
@ -352,13 +353,16 @@ static void DisassembleInputMachO2(StringRef Filename,
// A separate DSym file path was specified, parse it as a macho file, // A separate DSym file path was specified, parse it as a macho file,
// get the sections and supply it to the section name parsing machinery. // get the sections and supply it to the section name parsing machinery.
if (!DSYMFile.empty()) { if (!DSYMFile.empty()) {
ErrorOr<std::unique_ptr<MemoryBuffer>> Buf = ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
MemoryBuffer::getFileOrSTDIN(DSYMFile); MemoryBuffer::getFileOrSTDIN(DSYMFile);
if (std::error_code EC = Buf.getError()) { if (std::error_code EC = BufOrErr.getError()) {
errs() << "llvm-objdump: " << Filename << ": " << EC.message() << '\n'; errs() << "llvm-objdump: " << Filename << ": " << EC.message() << '\n';
return; return;
} }
DbgObj = ObjectFile::createMachOObjectFile(Buf.get()).get().release(); DbgObj =
ObjectFile::createMachOObjectFile(BufOrErr.get()->getMemBufferRef())
.get()
.release();
} }
// Setup the DIContext // Setup the DIContext

View File

@ -892,12 +892,12 @@ static void DumpInput(StringRef file) {
} }
// Attempt to open the binary. // Attempt to open the binary.
ErrorOr<std::unique_ptr<Binary>> BinaryOrErr = createBinary(file); ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(file);
if (std::error_code EC = BinaryOrErr.getError()) { if (std::error_code EC = BinaryOrErr.getError()) {
errs() << ToolName << ": '" << file << "': " << EC.message() << ".\n"; errs() << ToolName << ": '" << file << "': " << EC.message() << ".\n";
return; return;
} }
Binary &Binary = *BinaryOrErr.get(); Binary &Binary = *BinaryOrErr.get().getBinary();
if (Archive *a = dyn_cast<Archive>(&Binary)) if (Archive *a = dyn_cast<Archive>(&Binary))
DumpArchive(a); DumpArchive(a);

View File

@ -299,12 +299,12 @@ static void dumpInput(StringRef File) {
} }
// Attempt to open the binary. // Attempt to open the binary.
ErrorOr<std::unique_ptr<Binary>> BinaryOrErr = createBinary(File); ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(File);
if (std::error_code EC = BinaryOrErr.getError()) { if (std::error_code EC = BinaryOrErr.getError()) {
reportError(File, EC); reportError(File, EC);
return; return;
} }
Binary &Binary = *BinaryOrErr.get(); Binary &Binary = *BinaryOrErr.get().getBinary();
if (Archive *Arc = dyn_cast<Archive>(&Binary)) if (Archive *Arc = dyn_cast<Archive>(&Binary))
dumpArchive(Arc); dumpArchive(Arc);

View File

@ -453,12 +453,12 @@ static void PrintFileSectionSizes(StringRef file) {
} }
// Attempt to open the binary. // Attempt to open the binary.
ErrorOr<std::unique_ptr<Binary>> BinaryOrErr = createBinary(file); ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(file);
if (std::error_code EC = BinaryOrErr.getError()) { if (std::error_code EC = BinaryOrErr.getError()) {
errs() << ToolName << ": " << file << ": " << EC.message() << ".\n"; errs() << ToolName << ": " << file << ": " << EC.message() << ".\n";
return; return;
} }
Binary &Bin = *BinaryOrErr.get(); Binary &Bin = *BinaryOrErr.get().getBinary();
if (Archive *a = dyn_cast<Archive>(&Bin)) { if (Archive *a = dyn_cast<Archive>(&Bin)) {
// This is an archive. Iterate over each member and display its sizes. // This is an archive. Iterate over each member and display its sizes.

View File

@ -300,12 +300,12 @@ LLVMSymbolizer::getOrCreateBinary(const std::string &Path) {
return I->second; return I->second;
Binary *Bin = nullptr; Binary *Bin = nullptr;
Binary *DbgBin = nullptr; Binary *DbgBin = nullptr;
ErrorOr<std::unique_ptr<Binary>> BinaryOrErr = createBinary(Path); ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(Path);
if (!error(BinaryOrErr.getError())) { if (!error(BinaryOrErr.getError())) {
std::unique_ptr<Binary> &ParsedBinary = BinaryOrErr.get(); OwningBinary<Binary> &ParsedBinary = BinaryOrErr.get();
// Check if it's a universal binary. // Check if it's a universal binary.
Bin = ParsedBinary.get(); Bin = ParsedBinary.getBinary().get();
ParsedBinariesAndObjects.push_back(std::move(ParsedBinary)); addOwningBinary(std::move(ParsedBinary));
if (Bin->isMachO() || Bin->isMachOUniversalBinary()) { if (Bin->isMachO() || Bin->isMachOUniversalBinary()) {
// On Darwin we may find DWARF in separate object file in // On Darwin we may find DWARF in separate object file in
// resource directory. // resource directory.
@ -314,8 +314,9 @@ LLVMSymbolizer::getOrCreateBinary(const std::string &Path) {
BinaryOrErr = createBinary(ResourcePath); BinaryOrErr = createBinary(ResourcePath);
std::error_code EC = BinaryOrErr.getError(); std::error_code EC = BinaryOrErr.getError();
if (EC != errc::no_such_file_or_directory && !error(EC)) { if (EC != errc::no_such_file_or_directory && !error(EC)) {
DbgBin = BinaryOrErr.get().get(); OwningBinary<Binary> B = std::move(BinaryOrErr.get());
ParsedBinariesAndObjects.push_back(std::move(BinaryOrErr.get())); DbgBin = B.getBinary().get();
addOwningBinary(std::move(B));
} }
} }
// Try to locate the debug binary using .gnu_debuglink section. // Try to locate the debug binary using .gnu_debuglink section.
@ -327,8 +328,9 @@ LLVMSymbolizer::getOrCreateBinary(const std::string &Path) {
findDebugBinary(Path, DebuglinkName, CRCHash, DebugBinaryPath)) { findDebugBinary(Path, DebuglinkName, CRCHash, DebugBinaryPath)) {
BinaryOrErr = createBinary(DebugBinaryPath); BinaryOrErr = createBinary(DebugBinaryPath);
if (!error(BinaryOrErr.getError())) { if (!error(BinaryOrErr.getError())) {
DbgBin = BinaryOrErr.get().get(); OwningBinary<Binary> B = std::move(BinaryOrErr.get());
ParsedBinariesAndObjects.push_back(std::move(BinaryOrErr.get())); DbgBin = B.getBinary().get();
addOwningBinary(std::move(B));
} }
} }
} }

View File

@ -75,6 +75,12 @@ private:
// Owns all the parsed binaries and object files. // Owns all the parsed binaries and object files.
SmallVector<std::unique_ptr<Binary>, 4> ParsedBinariesAndObjects; SmallVector<std::unique_ptr<Binary>, 4> ParsedBinariesAndObjects;
SmallVector<std::unique_ptr<MemoryBuffer>, 4> MemoryBuffers;
void addOwningBinary(OwningBinary<Binary> Bin) {
ParsedBinariesAndObjects.push_back(std::move(Bin.getBinary()));
MemoryBuffers.push_back(std::move(Bin.getBuffer()));
}
// Owns module info objects. // Owns module info objects.
typedef std::map<std::string, ModuleInfo *> ModuleMapTy; typedef std::map<std::string, ModuleInfo *> ModuleMapTy;
ModuleMapTy Modules; ModuleMapTy Modules;

View File

@ -164,12 +164,12 @@ static void dumpInput(StringRef File) {
} }
// Attempt to open the binary. // Attempt to open the binary.
ErrorOr<std::unique_ptr<Binary>> BinaryOrErr = createBinary(File); ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(File);
if (std::error_code EC = BinaryOrErr.getError()) { if (std::error_code EC = BinaryOrErr.getError()) {
reportError(File, EC); reportError(File, EC);
return; return;
} }
Binary &Binary = *BinaryOrErr.get(); Binary &Binary = *BinaryOrErr.get().getBinary();
if (Archive *Arc = dyn_cast<Archive>(&Binary)) if (Archive *Arc = dyn_cast<Archive>(&Binary))
dumpArchive(Arc); dumpArchive(Arc);

View File

@ -403,10 +403,10 @@ int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, "llvm Mach-O dumping tool\n"); cl::ParseCommandLineOptions(argc, argv, "llvm Mach-O dumping tool\n");
ErrorOr<std::unique_ptr<Binary>> BinaryOrErr = createBinary(InputFile); ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(InputFile);
if (std::error_code EC = BinaryOrErr.getError()) if (std::error_code EC = BinaryOrErr.getError())
return Error("unable to read input: '" + EC.message() + "'"); return Error("unable to read input: '" + EC.message() + "'");
Binary &Binary = *BinaryOrErr.get(); Binary &Binary = *BinaryOrErr.get().getBinary();
const MachOObjectFile *InputObject = dyn_cast<MachOObjectFile>(&Binary); const MachOObjectFile *InputObject = dyn_cast<MachOObjectFile>(&Binary);
if (!InputObject) if (!InputObject)

View File

@ -32,11 +32,11 @@ static std::error_code dumpInput(StringRef File) {
if (File != "-" && !sys::fs::exists(File)) if (File != "-" && !sys::fs::exists(File))
return obj2yaml_error::file_not_found; return obj2yaml_error::file_not_found;
ErrorOr<std::unique_ptr<Binary>> BinaryOrErr = createBinary(File); ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(File);
if (std::error_code EC = BinaryOrErr.getError()) if (std::error_code EC = BinaryOrErr.getError())
return EC; return EC;
Binary &Binary = *BinaryOrErr.get(); Binary &Binary = *BinaryOrErr.get().getBinary();
// TODO: If this is an archive, then burst it and dump each entry // TODO: If this is an archive, then burst it and dump each entry
if (ObjectFile *Obj = dyn_cast<ObjectFile>(&Binary)) if (ObjectFile *Obj = dyn_cast<ObjectFile>(&Binary))
return dumpObject(*Obj); return dumpObject(*Obj);

View File

@ -25,7 +25,7 @@ class TestObjectCache : public ObjectCache {
public: public:
TestObjectCache() : DuplicateInserted(false) { } TestObjectCache() : DuplicateInserted(false) { }
virtual void notifyObjectCompiled(const Module *M, const MemoryBuffer *Obj) { void notifyObjectCompiled(const Module *M, MemoryBufferRef Obj) override {
// If we've seen this module before, note that. // If we've seen this module before, note that.
const std::string ModuleID = M->getModuleIdentifier(); const std::string ModuleID = M->getModuleIdentifier();
if (ObjMap.find(ModuleID) != ObjMap.end()) if (ObjMap.find(ModuleID) != ObjMap.end())
@ -63,10 +63,10 @@ public:
} }
private: private:
MemoryBuffer *copyBuffer(const MemoryBuffer *Buf) { MemoryBuffer *copyBuffer(MemoryBufferRef Buf) {
// Create a local copy of the buffer. // Create a local copy of the buffer.
std::unique_ptr<MemoryBuffer> NewBuffer( std::unique_ptr<MemoryBuffer> NewBuffer(
MemoryBuffer::getMemBufferCopy(Buf->getBuffer())); MemoryBuffer::getMemBufferCopy(Buf.getBuffer()));
MemoryBuffer *Ret = NewBuffer.get(); MemoryBuffer *Ret = NewBuffer.get();
AllocatedBuffers.push_back(std::move(NewBuffer)); AllocatedBuffers.push_back(std::move(NewBuffer));
return Ret; return Ret;