This allows us to just use a std::unique_ptr to store the pointer to the buffer.
The flip side is that they have to support releasing the buffer back to the
caller.
Overall this looks like a more efficient and less brittle api.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211542
91177308-0d34-0410-b5e6-
96231b3b80d8
23 files changed:
/// deserialization of function bodies. If successful, this takes ownership
/// of 'buffer. On error, this *does not* take ownership of Buffer.
ErrorOr<Module *> getLazyBitcodeModule(MemoryBuffer *Buffer,
/// deserialization of function bodies. If successful, this takes ownership
/// of 'buffer. On error, this *does not* take ownership of Buffer.
ErrorOr<Module *> getLazyBitcodeModule(MemoryBuffer *Buffer,
- LLVMContext &Context,
- bool BufferOwned = true);
/// getStreamedBitcodeModule - Read the header of the specified stream
/// and prepare for lazy deserialization and streaming of function bodies.
/// getStreamedBitcodeModule - Read the header of the specified stream
/// and prepare for lazy deserialization and streaming of function bodies.
/// Make sure the entire Module has been completely read.
///
virtual std::error_code MaterializeModule(Module *M) = 0;
/// Make sure the entire Module has been completely read.
///
virtual std::error_code MaterializeModule(Module *M) = 0;
+
+ virtual void releaseBuffer() = 0;
};
} // End llvm namespace
};
} // End llvm namespace
/// Make sure all GlobalValues in this Module are fully read and clear the
/// Materializer. If the module is corrupt, this DOES NOT clear the old
/// Materializer.
/// Make sure all GlobalValues in this Module are fully read and clear the
/// Materializer. If the module is corrupt, this DOES NOT clear the old
/// Materializer.
- std::error_code materializeAllPermanently();
+ std::error_code materializeAllPermanently(bool ReleaseBuffer = false);
/// @}
/// @name Direct access to the globals list, functions list, and symbol table
/// @}
/// @name Direct access to the globals list, functions list, and symbol table
Binary(const Binary &other) LLVM_DELETED_FUNCTION;
unsigned int TypeID;
Binary(const Binary &other) LLVM_DELETED_FUNCTION;
unsigned int TypeID;
+ std::unique_ptr<MemoryBuffer> Data;
- Binary(unsigned int Type, MemoryBuffer *Source, bool BufferOwned = true);
+ Binary(unsigned int Type, MemoryBuffer *Source);
virtual ~Binary();
StringRef getData() const;
virtual ~Binary();
StringRef getData() const;
+ MemoryBuffer *releaseBuffer() { return Data.release(); }
StringRef getFileName() const;
// Cast methods.
StringRef getFileName() const;
// Cast methods.
StringRef &Result) const override;
public:
StringRef &Result) const override;
public:
- COFFObjectFile(MemoryBuffer *Object, std::error_code &EC,
- bool BufferOwned = true);
+ COFFObjectFile(MemoryBuffer *Object, std::error_code &EC);
basic_symbol_iterator symbol_begin_impl() const override;
basic_symbol_iterator symbol_end_impl() const override;
library_iterator needed_library_begin() const override;
basic_symbol_iterator symbol_begin_impl() const override;
basic_symbol_iterator symbol_end_impl() const override;
library_iterator needed_library_begin() const override;
bool isDyldELFObject;
public:
bool isDyldELFObject;
public:
- ELFObjectFile(MemoryBuffer *Object, std::error_code &EC,
- bool BufferOwned = true);
+ ELFObjectFile(MemoryBuffer *Object, std::error_code &EC);
const Elf_Sym *getSymbol(DataRefImpl Symb) const;
const Elf_Sym *getSymbol(DataRefImpl Symb) const;
-ELFObjectFile<ELFT>::ELFObjectFile(MemoryBuffer *Object, std::error_code &ec,
- bool BufferOwned)
+ELFObjectFile<ELFT>::ELFObjectFile(MemoryBuffer *Object, std::error_code &ec)
: ObjectFile(getELFType(static_cast<endianness>(ELFT::TargetEndianness) ==
support::little,
ELFT::Is64Bits),
: ObjectFile(getELFType(static_cast<endianness>(ELFT::TargetEndianness) ==
support::little,
ELFT::Is64Bits),
EF(Object, ec) {}
template <class ELFT>
EF(Object, ec) {}
template <class ELFT>
std::unique_ptr<Mangler> Mang;
public:
std::unique_ptr<Mangler> Mang;
public:
- IRObjectFile(MemoryBuffer *Object, std::error_code &EC, LLVMContext &Context,
- bool BufferOwned);
+ IRObjectFile(MemoryBuffer *Object, std::error_code &EC, LLVMContext &Context);
+ ~IRObjectFile();
void moveSymbolNext(DataRefImpl &Symb) const override;
std::error_code printSymbolName(raw_ostream &OS,
DataRefImpl Symb) const override;
void moveSymbolNext(DataRefImpl &Symb) const override;
std::error_code printSymbolName(raw_ostream &OS,
DataRefImpl Symb) const override;
};
MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian, bool Is64Bits,
};
MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian, bool Is64Bits,
- std::error_code &EC, bool BufferOwned = true);
void moveSymbolNext(DataRefImpl &Symb) const override;
std::error_code getSymbolName(DataRefImpl Symb,
void moveSymbolNext(DataRefImpl &Symb) const override;
std::error_code getSymbolName(DataRefImpl Symb,
ObjectFile(const ObjectFile &other) LLVM_DELETED_FUNCTION;
protected:
ObjectFile(const ObjectFile &other) LLVM_DELETED_FUNCTION;
protected:
- ObjectFile(unsigned int Type, MemoryBuffer *Source, bool BufferOwned = true);
+ ObjectFile(unsigned int Type, MemoryBuffer *Source);
const uint8_t *base() const {
return reinterpret_cast<const uint8_t *>(Data->getBufferStart());
const uint8_t *base() const {
return reinterpret_cast<const uint8_t *>(Data->getBufferStart());
/// @brief Create ObjectFile from path.
static ErrorOr<ObjectFile *> createObjectFile(StringRef ObjectPath);
static ErrorOr<ObjectFile *> createObjectFile(MemoryBuffer *Object,
/// @brief Create ObjectFile from path.
static ErrorOr<ObjectFile *> createObjectFile(StringRef ObjectPath);
static ErrorOr<ObjectFile *> createObjectFile(MemoryBuffer *Object,
sys::fs::file_magic Type);
static ErrorOr<ObjectFile *> createObjectFile(MemoryBuffer *Object) {
sys::fs::file_magic Type);
static ErrorOr<ObjectFile *> createObjectFile(MemoryBuffer *Object) {
- return createObjectFile(Object, true, sys::fs::file_magic::unknown);
+ return createObjectFile(Object, sys::fs::file_magic::unknown);
- static ErrorOr<ObjectFile *> createCOFFObjectFile(MemoryBuffer *Object,
- bool BufferOwned = true);
- static ErrorOr<ObjectFile *> createELFObjectFile(MemoryBuffer *Object,
- bool BufferOwned = true);
- static ErrorOr<ObjectFile *> createMachOObjectFile(MemoryBuffer *Object,
- bool BufferOwned = true);
+ static ErrorOr<ObjectFile *> createCOFFObjectFile(MemoryBuffer *Object);
+ static ErrorOr<ObjectFile *> createELFObjectFile(MemoryBuffer *Object);
+ static ErrorOr<ObjectFile *> createMachOObjectFile(MemoryBuffer *Object);
};
// Inline function definitions.
};
// Inline function definitions.
class SymbolicFile : public Binary {
public:
virtual ~SymbolicFile();
class SymbolicFile : public Binary {
public:
virtual ~SymbolicFile();
- SymbolicFile(unsigned int Type, MemoryBuffer *Source, bool BufferOwned);
+ SymbolicFile(unsigned int Type, MemoryBuffer *Source);
// virtual interface.
virtual void moveSymbolNext(DataRefImpl &Symb) const = 0;
// virtual interface.
virtual void moveSymbolNext(DataRefImpl &Symb) const = 0;
// construction aux.
static ErrorOr<SymbolicFile *> createIRObjectFile(MemoryBuffer *Object,
// construction aux.
static ErrorOr<SymbolicFile *> createIRObjectFile(MemoryBuffer *Object,
- LLVMContext &Context,
- bool BufferOwned = true);
static ErrorOr<SymbolicFile *> createSymbolicFile(MemoryBuffer *Object,
static ErrorOr<SymbolicFile *> createSymbolicFile(MemoryBuffer *Object,
sys::fs::file_magic Type,
LLVMContext *Context);
static ErrorOr<SymbolicFile *> createSymbolicFile(MemoryBuffer *Object) {
sys::fs::file_magic Type,
LLVMContext *Context);
static ErrorOr<SymbolicFile *> createSymbolicFile(MemoryBuffer *Object) {
- return createSymbolicFile(Object, true, sys::fs::file_magic::unknown,
- nullptr);
+ return createSymbolicFile(Object, sys::fs::file_magic::unknown, nullptr);
}
static ErrorOr<SymbolicFile *> createSymbolicFile(StringRef ObjectPath);
}
static ErrorOr<SymbolicFile *> createSymbolicFile(StringRef ObjectPath);
}
void BitcodeReader::FreeState() {
}
void BitcodeReader::FreeState() {
- if (BufferOwned)
- delete Buffer;
Buffer = nullptr;
std::vector<Type*>().swap(TypeList);
ValueList.clear();
Buffer = nullptr;
std::vector<Type*>().swap(TypeList);
ValueList.clear();
// GVMaterializer implementation
//===----------------------------------------------------------------------===//
// GVMaterializer implementation
//===----------------------------------------------------------------------===//
+void BitcodeReader::releaseBuffer() { Buffer.release(); }
bool BitcodeReader::isMaterializable(const GlobalValue *GV) const {
if (const Function *F = dyn_cast<Function>(GV)) {
bool BitcodeReader::isMaterializable(const GlobalValue *GV) const {
if (const Function *F = dyn_cast<Function>(GV)) {
/// getLazyBitcodeModule - lazy function-at-a-time loading from a file.
///
ErrorOr<Module *> llvm::getLazyBitcodeModule(MemoryBuffer *Buffer,
/// getLazyBitcodeModule - lazy function-at-a-time loading from a file.
///
ErrorOr<Module *> llvm::getLazyBitcodeModule(MemoryBuffer *Buffer,
- LLVMContext &Context,
- bool BufferOwned) {
+ LLVMContext &Context) {
Module *M = new Module(Buffer->getBufferIdentifier(), Context);
Module *M = new Module(Buffer->getBufferIdentifier(), Context);
- BitcodeReader *R = new BitcodeReader(Buffer, Context, BufferOwned);
+ BitcodeReader *R = new BitcodeReader(Buffer, Context);
M->setMaterializer(R);
if (std::error_code EC = R->ParseBitcodeInto(M)) {
R->releaseBuffer(); // Never take ownership on error.
M->setMaterializer(R);
if (std::error_code EC = R->ParseBitcodeInto(M)) {
R->releaseBuffer(); // Never take ownership on error.
ErrorOr<Module *> llvm::parseBitcodeFile(MemoryBuffer *Buffer,
LLVMContext &Context) {
ErrorOr<Module *> llvm::parseBitcodeFile(MemoryBuffer *Buffer,
LLVMContext &Context) {
- ErrorOr<Module *> ModuleOrErr = getLazyBitcodeModule(Buffer, Context, false);
+ ErrorOr<Module *> ModuleOrErr = getLazyBitcodeModule(Buffer, Context);
if (!ModuleOrErr)
return ModuleOrErr;
Module *M = ModuleOrErr.get();
if (!ModuleOrErr)
return ModuleOrErr;
Module *M = ModuleOrErr.get();
// Read in the entire module, and destroy the BitcodeReader.
// Read in the entire module, and destroy the BitcodeReader.
- if (std::error_code EC = M->materializeAllPermanently()) {
+ if (std::error_code EC = M->materializeAllPermanently(true)) {
std::string llvm::getBitcodeTargetTriple(MemoryBuffer *Buffer,
LLVMContext& Context,
std::string *ErrMsg) {
std::string llvm::getBitcodeTargetTriple(MemoryBuffer *Buffer,
LLVMContext& Context,
std::string *ErrMsg) {
- BitcodeReader *R = new BitcodeReader(Buffer, Context, /*BufferOwned*/ false);
+ BitcodeReader *R = new BitcodeReader(Buffer, Context);
std::string Triple("");
if (std::error_code EC = R->ParseTriple(Triple))
if (ErrMsg)
*ErrMsg = EC.message();
std::string Triple("");
if (std::error_code EC = R->ParseTriple(Triple))
if (ErrMsg)
*ErrMsg = EC.message();
delete R;
return Triple;
}
delete R;
return Triple;
}
class BitcodeReader : public GVMaterializer {
LLVMContext &Context;
Module *TheModule;
class BitcodeReader : public GVMaterializer {
LLVMContext &Context;
Module *TheModule;
- MemoryBuffer *Buffer;
- bool BufferOwned;
+ std::unique_ptr<MemoryBuffer> Buffer;
std::unique_ptr<BitstreamReader> StreamFile;
BitstreamCursor Stream;
DataStreamer *LazyStreamer;
std::unique_ptr<BitstreamReader> StreamFile;
BitstreamCursor Stream;
DataStreamer *LazyStreamer;
return std::error_code(E, BitcodeErrorCategory());
}
return std::error_code(E, BitcodeErrorCategory());
}
- explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext &C, bool BufferOwned)
- : Context(C), TheModule(nullptr), Buffer(buffer),
- BufferOwned(BufferOwned), LazyStreamer(nullptr), NextUnreadBit(0),
- SeenValueSymbolTable(false), ValueList(C), MDValueList(C),
- SeenFirstFunctionBody(false), UseRelativeIDs(false) {}
+ explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext &C)
+ : Context(C), TheModule(nullptr), Buffer(buffer), LazyStreamer(nullptr),
+ NextUnreadBit(0), SeenValueSymbolTable(false), ValueList(C),
+ MDValueList(C), SeenFirstFunctionBody(false), UseRelativeIDs(false) {}
explicit BitcodeReader(DataStreamer *streamer, LLVMContext &C)
explicit BitcodeReader(DataStreamer *streamer, LLVMContext &C)
- : Context(C), TheModule(nullptr), Buffer(nullptr), BufferOwned(false),
- LazyStreamer(streamer), NextUnreadBit(0), SeenValueSymbolTable(false),
- ValueList(C), MDValueList(C), SeenFirstFunctionBody(false),
- UseRelativeIDs(false) {}
+ : Context(C), TheModule(nullptr), Buffer(nullptr), LazyStreamer(streamer),
+ NextUnreadBit(0), SeenValueSymbolTable(false), ValueList(C),
+ MDValueList(C), SeenFirstFunctionBody(false), UseRelativeIDs(false) {}
~BitcodeReader() { FreeState(); }
void materializeForwardReferencedFunctions();
void FreeState();
~BitcodeReader() { FreeState(); }
void materializeForwardReferencedFunctions();
void FreeState();
- void releaseBuffer() {
- Buffer = nullptr;
- }
+ void releaseBuffer() override;
bool isMaterializable(const GlobalValue *GV) const override;
bool isDematerializable(const GlobalValue *GV) const override;
bool isMaterializable(const GlobalValue *GV) const override;
bool isDematerializable(const GlobalValue *GV) const override;
return Materializer->MaterializeModule(this);
}
return Materializer->MaterializeModule(this);
}
-std::error_code Module::materializeAllPermanently() {
+std::error_code Module::materializeAllPermanently(bool ReleaseBuffer) {
if (std::error_code EC = materializeAll())
return EC;
if (std::error_code EC = materializeAll())
return EC;
+ if (ReleaseBuffer)
+ Materializer->releaseBuffer();
+
Materializer.reset();
return std::error_code();
}
Materializer.reset();
return std::error_code();
}
ErrorOr<std::unique_ptr<MemoryBuffer>> BuffOrErr = getMemoryBuffer();
if (std::error_code EC = BuffOrErr.getError())
return EC;
ErrorOr<std::unique_ptr<MemoryBuffer>> BuffOrErr = getMemoryBuffer();
if (std::error_code EC = BuffOrErr.getError())
return EC;
- return createBinary(BuffOrErr.get().release(), Context);
+
+ std::unique_ptr<MemoryBuffer> Buff(BuffOrErr.get().release());
+ ErrorOr<std::unique_ptr<Binary>> Ret = createBinary(Buff.get(), Context);
+ if (!Ret.getError())
+ Buff.release();
+ return Ret;
}
ErrorOr<Archive*> Archive::create(MemoryBuffer *Source) {
}
ErrorOr<Archive*> Archive::create(MemoryBuffer *Source) {
using namespace llvm;
using namespace object;
using namespace llvm;
using namespace object;
-Binary::~Binary() {
- if (BufferOwned)
- delete Data;
-}
-Binary::Binary(unsigned int Type, MemoryBuffer *Source, bool BufferOwned)
- : TypeID(Type), BufferOwned(BufferOwned), Data(Source) {}
+Binary::Binary(unsigned int Type, MemoryBuffer *Source)
+ : TypeID(Type), Data(Source) {}
StringRef Binary::getData() const {
return Data->getBuffer();
StringRef Binary::getData() const {
return Data->getBuffer();
return Data->getBufferIdentifier();
}
return Data->getBufferIdentifier();
}
-ErrorOr<Binary *> object::createBinary(MemoryBuffer *Source,
+ErrorOr<Binary *> object::createBinary(MemoryBuffer *Buffer,
- std::unique_ptr<MemoryBuffer> scopedSource(Source);
- sys::fs::file_magic Type = sys::fs::identify_magic(Source->getBuffer());
+ sys::fs::file_magic Type = sys::fs::identify_magic(Buffer->getBuffer());
switch (Type) {
case sys::fs::file_magic::archive:
switch (Type) {
case sys::fs::file_magic::archive:
- return Archive::create(scopedSource.release());
+ return Archive::create(Buffer);
case sys::fs::file_magic::elf_relocatable:
case sys::fs::file_magic::elf_executable:
case sys::fs::file_magic::elf_shared_object:
case sys::fs::file_magic::elf_relocatable:
case sys::fs::file_magic::elf_executable:
case sys::fs::file_magic::elf_shared_object:
case sys::fs::file_magic::coff_import_library:
case sys::fs::file_magic::pecoff_executable:
case sys::fs::file_magic::bitcode:
case sys::fs::file_magic::coff_import_library:
case sys::fs::file_magic::pecoff_executable:
case sys::fs::file_magic::bitcode:
- return ObjectFile::createSymbolicFile(scopedSource.release(), true, 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(scopedSource.release());
+ return MachOUniversalBinary::create(Buffer);
case sys::fs::file_magic::unknown:
case sys::fs::file_magic::windows_resource:
// Unrecognized object file format.
case sys::fs::file_magic::unknown:
case sys::fs::file_magic::windows_resource:
// Unrecognized object file format.
using support::little16_t;
// Returns false if size is greater than the buffer size. And sets ec.
using support::little16_t;
// 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(const MemoryBuffer &M, std::error_code &EC,
- if (M->getBufferSize() < Size) {
+ if (M.getBufferSize() < Size) {
EC = object_error::unexpected_eof;
return false;
}
EC = object_error::unexpected_eof;
return false;
}
// Sets Obj unless any bytes in [addr, addr + size) fall outsize of m.
// Returns unexpected_eof if error.
template <typename T>
// Sets Obj unless any bytes in [addr, addr + size) fall outsize of m.
// Returns unexpected_eof if error.
template <typename T>
-static std::error_code getObject(const T *&Obj, const MemoryBuffer *M,
+static std::error_code getObject(const T *&Obj, const MemoryBuffer &M,
const uint8_t *Ptr,
const size_t Size = sizeof(T)) {
uintptr_t Addr = uintptr_t(Ptr);
const uint8_t *Ptr,
const size_t Size = sizeof(T)) {
uintptr_t Addr = uintptr_t(Ptr);
- if (Addr + Size < Addr ||
- Addr + Size < Size ||
- Addr + Size > uintptr_t(M->getBufferEnd())) {
+ if (Addr + Size < Addr || Addr + Size < Size ||
+ Addr + Size > uintptr_t(M.getBufferEnd())) {
return object_error::unexpected_eof;
}
Obj = reinterpret_cast<const T *>(Addr);
return object_error::unexpected_eof;
}
Obj = reinterpret_cast<const T *>(Addr);
// Initialize the pointer to the symbol table.
std::error_code COFFObjectFile::initSymbolTablePtr() {
if (std::error_code EC = getObject(
// Initialize the pointer to the symbol table.
std::error_code COFFObjectFile::initSymbolTablePtr() {
if (std::error_code EC = getObject(
- SymbolTable, Data, base() + COFFHeader->PointerToSymbolTable,
+ SymbolTable, *Data, base() + COFFHeader->PointerToSymbolTable,
COFFHeader->NumberOfSymbols * sizeof(coff_symbol)))
return EC;
COFFHeader->NumberOfSymbols * sizeof(coff_symbol)))
return EC;
base() + COFFHeader->PointerToSymbolTable +
COFFHeader->NumberOfSymbols * sizeof(coff_symbol);
const ulittle32_t *StringTableSizePtr;
base() + COFFHeader->PointerToSymbolTable +
COFFHeader->NumberOfSymbols * sizeof(coff_symbol);
const ulittle32_t *StringTableSizePtr;
- if (std::error_code EC = getObject(StringTableSizePtr, Data, StringTableAddr))
+ if (std::error_code EC =
+ getObject(StringTableSizePtr, *Data, StringTableAddr))
return EC;
StringTableSize = *StringTableSizePtr;
if (std::error_code EC =
return EC;
StringTableSize = *StringTableSizePtr;
if (std::error_code EC =
- getObject(StringTable, Data, StringTableAddr, StringTableSize))
+ getObject(StringTable, *Data, StringTableAddr, StringTableSize))
return EC;
// Treat table sizes < 4 as empty because contrary to the PECOFF spec, some
return EC;
// Treat table sizes < 4 as empty because contrary to the PECOFF spec, some
return object_error::success;
}
return object_error::success;
}
-COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, std::error_code &EC,
- bool BufferOwned)
- : ObjectFile(Binary::ID_COFF, Object, BufferOwned), COFFHeader(nullptr),
+COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, std::error_code &EC)
+ : ObjectFile(Binary::ID_COFF, Object), COFFHeader(nullptr),
PE32Header(nullptr), PE32PlusHeader(nullptr), DataDirectory(nullptr),
SectionTable(nullptr), SymbolTable(nullptr), StringTable(nullptr),
StringTableSize(0), ImportDirectory(nullptr), NumberOfImportDirectory(0),
ExportDirectory(nullptr) {
// Check that we at least have enough room for a header.
PE32Header(nullptr), PE32PlusHeader(nullptr), DataDirectory(nullptr),
SectionTable(nullptr), SymbolTable(nullptr), StringTable(nullptr),
StringTableSize(0), ImportDirectory(nullptr), NumberOfImportDirectory(0),
ExportDirectory(nullptr) {
// Check that we at least have enough room for a header.
- if (!checkSize(Data, EC, sizeof(coff_file_header))) return;
+ if (!checkSize(*Data, EC, sizeof(coff_file_header)))
+ return;
// The current location in the file where we are looking at.
uint64_t CurPtr = 0;
// The current location in the file where we are looking at.
uint64_t CurPtr = 0;
if (base()[0] == 0x4d && base()[1] == 0x5a) {
// PE/COFF, seek through MS-DOS compatibility stub and 4-byte
// PE signature to find 'normal' COFF header.
if (base()[0] == 0x4d && base()[1] == 0x5a) {
// PE/COFF, seek through MS-DOS compatibility stub and 4-byte
// PE signature to find 'normal' COFF header.
- if (!checkSize(Data, EC, 0x3c + 8)) return;
+ if (!checkSize(*Data, EC, 0x3c + 8))
+ return;
CurPtr = *reinterpret_cast<const ulittle16_t *>(base() + 0x3c);
// Check the PE magic bytes. ("PE\0\0")
if (std::memcmp(base() + CurPtr, "PE\0\0", 4) != 0) {
CurPtr = *reinterpret_cast<const ulittle16_t *>(base() + 0x3c);
// Check the PE magic bytes. ("PE\0\0")
if (std::memcmp(base() + CurPtr, "PE\0\0", 4) != 0) {
- if ((EC = getObject(COFFHeader, Data, base() + CurPtr)))
+ if ((EC = getObject(COFFHeader, *Data, base() + CurPtr)))
return;
CurPtr += sizeof(coff_file_header);
if (HasPEHeader) {
const pe32_header *Header;
return;
CurPtr += sizeof(coff_file_header);
if (HasPEHeader) {
const pe32_header *Header;
- if ((EC = getObject(Header, Data, base() + CurPtr)))
+ if ((EC = getObject(Header, *Data, base() + CurPtr)))
return;
const uint8_t *DataDirAddr;
return;
const uint8_t *DataDirAddr;
EC = object_error::parse_failed;
return;
}
EC = object_error::parse_failed;
return;
}
- if ((EC = getObject(DataDirectory, Data, DataDirAddr, DataDirSize)))
+ if ((EC = getObject(DataDirectory, *Data, DataDirAddr, DataDirSize)))
return;
CurPtr += COFFHeader->SizeOfOptionalHeader;
}
return;
CurPtr += COFFHeader->SizeOfOptionalHeader;
}
if (COFFHeader->isImportLibrary())
return;
if (COFFHeader->isImportLibrary())
return;
- if ((EC = getObject(SectionTable, Data, base() + CurPtr,
+ if ((EC = getObject(SectionTable, *Data, base() + CurPtr,
COFFHeader->NumberOfSections * sizeof(coff_section))))
return;
COFFHeader->NumberOfSections * sizeof(coff_section))))
return;
return object_error::success;
}
return object_error::success;
}
-ErrorOr<ObjectFile *> ObjectFile::createCOFFObjectFile(MemoryBuffer *Object,
- bool BufferOwned) {
+ErrorOr<ObjectFile *> ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) {
- std::unique_ptr<COFFObjectFile> Ret(
- new COFFObjectFile(Object, EC, BufferOwned));
+ std::unique_ptr<COFFObjectFile> Ret(new COFFObjectFile(Object, EC));
if (EC)
return EC;
return Ret.release();
if (EC)
return EC;
return Ret.release();
namespace llvm {
using namespace object;
namespace llvm {
using namespace object;
-static ErrorOr<ObjectFile *> createELFObjectFileAux(MemoryBuffer *Obj,
- bool BufferOwned) {
+ErrorOr<ObjectFile *> ObjectFile::createELFObjectFile(MemoryBuffer *Obj) {
std::pair<unsigned char, unsigned char> Ident = getElfArchType(Obj);
std::size_t MaxAlignment =
1ULL << countTrailingZeros(uintptr_t(Obj->getBufferStart()));
std::pair<unsigned char, unsigned char> Ident = getElfArchType(Obj);
std::size_t MaxAlignment =
1ULL << countTrailingZeros(uintptr_t(Obj->getBufferStart()));
if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 4)
if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 4)
- R.reset(new ELFObjectFile<ELFType<support::little, 4, false> >(
- Obj, EC, BufferOwned));
+ R.reset(new ELFObjectFile<ELFType<support::little, 4, false>>(Obj, EC));
else
#endif
if (MaxAlignment >= 2)
else
#endif
if (MaxAlignment >= 2)
- R.reset(new ELFObjectFile<ELFType<support::little, 2, false> >(
- Obj, EC, BufferOwned));
+ R.reset(new ELFObjectFile<ELFType<support::little, 2, false>>(Obj, EC));
else
return object_error::parse_failed;
else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 4)
else
return object_error::parse_failed;
else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 4)
- R.reset(new ELFObjectFile<ELFType<support::big, 4, false> >(Obj, EC,
- BufferOwned));
+ R.reset(new ELFObjectFile<ELFType<support::big, 4, false>>(Obj, EC));
else
#endif
if (MaxAlignment >= 2)
else
#endif
if (MaxAlignment >= 2)
- R.reset(new ELFObjectFile<ELFType<support::big, 2, false> >(Obj, EC,
- BufferOwned));
+ R.reset(new ELFObjectFile<ELFType<support::big, 2, false>>(Obj, EC));
else
return object_error::parse_failed;
else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 8)
else
return object_error::parse_failed;
else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 8)
- R.reset(new ELFObjectFile<ELFType<support::big, 8, true> >(Obj, EC,
- BufferOwned));
+ R.reset(new ELFObjectFile<ELFType<support::big, 8, true>>(Obj, EC));
else
#endif
if (MaxAlignment >= 2)
else
#endif
if (MaxAlignment >= 2)
- R.reset(new ELFObjectFile<ELFType<support::big, 2, true> >(Obj, EC,
- BufferOwned));
+ R.reset(new ELFObjectFile<ELFType<support::big, 2, true>>(Obj, EC));
else
return object_error::parse_failed;
else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 8)
else
return object_error::parse_failed;
else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 8)
- R.reset(new ELFObjectFile<ELFType<support::little, 8, true> >(
- Obj, EC, BufferOwned));
+ R.reset(new ELFObjectFile<ELFType<support::little, 8, true>>(Obj, EC));
else
#endif
if (MaxAlignment >= 2)
else
#endif
if (MaxAlignment >= 2)
- R.reset(new ELFObjectFile<ELFType<support::little, 2, true> >(
- Obj, EC, BufferOwned));
+ R.reset(new ELFObjectFile<ELFType<support::little, 2, true>>(Obj, EC));
else
return object_error::parse_failed;
}
else
return object_error::parse_failed;
}
-ErrorOr<ObjectFile *> ObjectFile::createELFObjectFile(MemoryBuffer *Obj,
- bool BufferOwned) {
- ErrorOr<ObjectFile *> Ret = createELFObjectFileAux(Obj, BufferOwned);
- if (BufferOwned && Ret.getError())
- delete Obj;
- return Ret;
-}
-
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/GVMaterializer.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
#include "llvm/Object/IRObjectFile.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
#include "llvm/Object/IRObjectFile.h"
using namespace object;
IRObjectFile::IRObjectFile(MemoryBuffer *Object, std::error_code &EC,
using namespace object;
IRObjectFile::IRObjectFile(MemoryBuffer *Object, std::error_code &EC,
- LLVMContext &Context, bool BufferOwned)
- : SymbolicFile(Binary::ID_IR, Object, BufferOwned) {
- ErrorOr<Module *> MOrErr =
- getLazyBitcodeModule(Object, Context, /*BufferOwned*/ false);
+ LLVMContext &Context)
+ : SymbolicFile(Binary::ID_IR, Object) {
+ ErrorOr<Module *> MOrErr = getLazyBitcodeModule(Object, Context);
if ((EC = MOrErr.getError()))
return;
if ((EC = MOrErr.getError()))
return;
Mang.reset(new Mangler(DL));
}
Mang.reset(new Mangler(DL));
}
+IRObjectFile::~IRObjectFile() { M->getMaterializer()->releaseBuffer(); }
+
static const GlobalValue &getGV(DataRefImpl &Symb) {
return *reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3));
}
static const GlobalValue &getGV(DataRefImpl &Symb) {
return *reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3));
}
return basic_symbol_iterator(BasicSymbolRef(Ret, this));
}
return basic_symbol_iterator(BasicSymbolRef(Ret, this));
}
-ErrorOr<SymbolicFile *> llvm::object::SymbolicFile::createIRObjectFile(
- MemoryBuffer *Object, LLVMContext &Context, bool BufferOwned) {
+ErrorOr<SymbolicFile *>
+llvm::object::SymbolicFile::createIRObjectFile(MemoryBuffer *Object,
+ LLVMContext &Context) {
- std::unique_ptr<IRObjectFile> Ret(
- new IRObjectFile(Object, EC, Context, BufferOwned));
+ std::unique_ptr<IRObjectFile> Ret(new IRObjectFile(Object, EC, Context));
if (EC)
return EC;
return Ret.release();
if (EC)
return EC;
return Ret.release();
}
MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian,
}
MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian,
- bool Is64bits, std::error_code &EC,
- bool BufferOwned)
- : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object, BufferOwned),
+ bool Is64bits, std::error_code &EC)
+ : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
DataInCodeLoadCmd(nullptr) {
uint32_t LoadCommandCount = this->getHeader().ncmds;
SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
DataInCodeLoadCmd(nullptr) {
uint32_t LoadCommandCount = this->getHeader().ncmds;
-ErrorOr<ObjectFile *> ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer,
- bool BufferOwned) {
+ErrorOr<ObjectFile *> ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
StringRef Magic = Buffer->getBuffer().slice(0, 4);
std::error_code EC;
std::unique_ptr<MachOObjectFile> Ret;
if (Magic == "\xFE\xED\xFA\xCE")
StringRef Magic = Buffer->getBuffer().slice(0, 4);
std::error_code EC;
std::unique_ptr<MachOObjectFile> Ret;
if (Magic == "\xFE\xED\xFA\xCE")
- Ret.reset(new MachOObjectFile(Buffer, false, false, EC, BufferOwned));
+ 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(Buffer, true, false, EC, BufferOwned));
+ 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(Buffer, false, true, EC, BufferOwned));
+ 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(Buffer, true, true, EC, BufferOwned));
+ Ret.reset(new MachOObjectFile(Buffer, true, true, EC));
else {
delete Buffer;
return object_error::parse_failed;
else {
delete Buffer;
return object_error::parse_failed;
void ObjectFile::anchor() { }
void ObjectFile::anchor() { }
-ObjectFile::ObjectFile(unsigned int Type, MemoryBuffer *Source,
- bool BufferOwned)
- : SymbolicFile(Type, Source, BufferOwned) {}
+ObjectFile::ObjectFile(unsigned int Type, MemoryBuffer *Source)
+ : SymbolicFile(Type, Source) {}
std::error_code ObjectFile::printSymbolName(raw_ostream &OS,
DataRefImpl Symb) const {
std::error_code ObjectFile::printSymbolName(raw_ostream &OS,
DataRefImpl Symb) const {
}
ErrorOr<ObjectFile *> ObjectFile::createObjectFile(MemoryBuffer *Object,
}
ErrorOr<ObjectFile *> ObjectFile::createObjectFile(MemoryBuffer *Object,
sys::fs::file_magic Type) {
if (Type == sys::fs::file_magic::unknown)
Type = sys::fs::identify_magic(Object->getBuffer());
sys::fs::file_magic Type) {
if (Type == sys::fs::file_magic::unknown)
Type = sys::fs::identify_magic(Object->getBuffer());
case sys::fs::file_magic::archive:
case sys::fs::file_magic::macho_universal_binary:
case sys::fs::file_magic::windows_resource:
case sys::fs::file_magic::archive:
case sys::fs::file_magic::macho_universal_binary:
case sys::fs::file_magic::windows_resource:
- if (BufferOwned)
- delete Object;
return object_error::invalid_file_type;
case sys::fs::file_magic::elf_relocatable:
case sys::fs::file_magic::elf_executable:
case sys::fs::file_magic::elf_shared_object:
case sys::fs::file_magic::elf_core:
return object_error::invalid_file_type;
case sys::fs::file_magic::elf_relocatable:
case sys::fs::file_magic::elf_executable:
case sys::fs::file_magic::elf_shared_object:
case sys::fs::file_magic::elf_core:
- return createELFObjectFile(Object, BufferOwned);
+ return createELFObjectFile(Object);
case sys::fs::file_magic::macho_object:
case sys::fs::file_magic::macho_executable:
case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib:
case sys::fs::file_magic::macho_object:
case sys::fs::file_magic::macho_executable:
case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib:
case sys::fs::file_magic::macho_bundle:
case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub:
case sys::fs::file_magic::macho_dsym_companion:
case sys::fs::file_magic::macho_bundle:
case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub:
case sys::fs::file_magic::macho_dsym_companion:
- return createMachOObjectFile(Object, BufferOwned);
+ return createMachOObjectFile(Object);
case sys::fs::file_magic::coff_object:
case sys::fs::file_magic::coff_import_library:
case sys::fs::file_magic::pecoff_executable:
case sys::fs::file_magic::coff_object:
case sys::fs::file_magic::coff_import_library:
case sys::fs::file_magic::pecoff_executable:
- return createCOFFObjectFile(Object, BufferOwned);
+ return createCOFFObjectFile(Object);
}
llvm_unreachable("Unexpected Object File Type");
}
}
llvm_unreachable("Unexpected Object File Type");
}
using namespace llvm;
using namespace object;
using namespace llvm;
using namespace object;
-SymbolicFile::SymbolicFile(unsigned int Type, MemoryBuffer *Source,
- bool BufferOwned)
- : Binary(Type, Source, BufferOwned) {}
+SymbolicFile::SymbolicFile(unsigned int Type, MemoryBuffer *Source)
+ : Binary(Type, Source) {}
SymbolicFile::~SymbolicFile() {}
ErrorOr<SymbolicFile *>
SymbolicFile::~SymbolicFile() {}
ErrorOr<SymbolicFile *>
-SymbolicFile::createSymbolicFile(MemoryBuffer *Object, bool BufferOwned,
- sys::fs::file_magic Type,
+SymbolicFile::createSymbolicFile(MemoryBuffer *Object, sys::fs::file_magic Type,
LLVMContext *Context) {
if (Type == sys::fs::file_magic::unknown)
Type = sys::fs::identify_magic(Object->getBuffer());
LLVMContext *Context) {
if (Type == sys::fs::file_magic::unknown)
Type = sys::fs::identify_magic(Object->getBuffer());
switch (Type) {
case sys::fs::file_magic::bitcode:
if (Context)
switch (Type) {
case sys::fs::file_magic::bitcode:
if (Context)
- return IRObjectFile::createIRObjectFile(Object, *Context, BufferOwned);
+ return IRObjectFile::createIRObjectFile(Object, *Context);
// Fallthrough
case sys::fs::file_magic::unknown:
case sys::fs::file_magic::archive:
case sys::fs::file_magic::macho_universal_binary:
case sys::fs::file_magic::windows_resource:
// Fallthrough
case sys::fs::file_magic::unknown:
case sys::fs::file_magic::archive:
case sys::fs::file_magic::macho_universal_binary:
case sys::fs::file_magic::windows_resource:
- if (BufferOwned)
- delete Object;
return object_error::invalid_file_type;
case sys::fs::file_magic::elf_relocatable:
case sys::fs::file_magic::elf_executable:
return object_error::invalid_file_type;
case sys::fs::file_magic::elf_relocatable:
case sys::fs::file_magic::elf_executable:
case sys::fs::file_magic::coff_object:
case sys::fs::file_magic::coff_import_library:
case sys::fs::file_magic::pecoff_executable:
case sys::fs::file_magic::coff_object:
case sys::fs::file_magic::coff_import_library:
case sys::fs::file_magic::pecoff_executable:
- return ObjectFile::createObjectFile(Object, BufferOwned, Type);
+ return ObjectFile::createObjectFile(Object, Type);
}
llvm_unreachable("Unexpected Binary File Type");
}
}
llvm_unreachable("Unexpected Binary File Type");
}
MemoryBuffer *MemberBuffer = Buffers[MemberNum].get();
ErrorOr<object::SymbolicFile *> ObjOrErr =
object::SymbolicFile::createSymbolicFile(
MemoryBuffer *MemberBuffer = Buffers[MemberNum].get();
ErrorOr<object::SymbolicFile *> ObjOrErr =
object::SymbolicFile::createSymbolicFile(
- MemberBuffer, false, sys::fs::file_magic::unknown, &Context);
+ MemberBuffer, sys::fs::file_magic::unknown, &Context);
if (!ObjOrErr)
continue; // FIXME: check only for "not an object file" errors.
std::unique_ptr<object::SymbolicFile> Obj(ObjOrErr.get());
if (!ObjOrErr)
continue; // FIXME: check only for "not an object file" errors.
std::unique_ptr<object::SymbolicFile> Obj(ObjOrErr.get());
MemberOffsetRefs.push_back(std::make_pair(Out.tell(), MemberNum));
print32BE(Out, 0);
}
MemberOffsetRefs.push_back(std::make_pair(Out.tell(), MemberNum));
print32BE(Out, 0);
}
return;
LLVMContext &Context = getGlobalContext();
return;
LLVMContext &Context = getGlobalContext();
- ErrorOr<Binary *> BinaryOrErr = createBinary(Buffer.release(), &Context);
+ ErrorOr<Binary *> BinaryOrErr = createBinary(Buffer.get(), &Context);
if (error(BinaryOrErr.getError(), Filename))
return;
if (error(BinaryOrErr.getError(), Filename))
return;
std::unique_ptr<Binary> Bin(BinaryOrErr.get());
if (Archive *A = dyn_cast<Archive>(Bin.get())) {
std::unique_ptr<Binary> Bin(BinaryOrErr.get());
if (Archive *A = dyn_cast<Archive>(Bin.get())) {