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:
parent
155b633a98
commit
08aa78de63
@ -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);
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
@ -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(); }
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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 {
|
||||||
|
@ -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);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
|
@ -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.
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
@ -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).
|
||||||
|
@ -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()) {
|
||||||
|
@ -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.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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()) {
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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");
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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:
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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.
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user