mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
Make ObjectFile and BitcodeReader always own the MemoryBuffer.
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. llvm-svn: 211542
This commit is contained in:
parent
8d9ccc8516
commit
23e5fb2297
@ -30,8 +30,7 @@ namespace llvm {
|
||||
/// 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);
|
||||
LLVMContext &Context);
|
||||
|
||||
/// getStreamedBitcodeModule - Read the header of the specified stream
|
||||
/// and prepare for lazy deserialization and streaming of function bodies.
|
||||
|
@ -54,6 +54,8 @@ public:
|
||||
/// Make sure the entire Module has been completely read.
|
||||
///
|
||||
virtual std::error_code MaterializeModule(Module *M) = 0;
|
||||
|
||||
virtual void releaseBuffer() = 0;
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -458,7 +458,7 @@ public:
|
||||
/// 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
|
||||
|
@ -32,12 +32,11 @@ private:
|
||||
Binary(const Binary &other) LLVM_DELETED_FUNCTION;
|
||||
|
||||
unsigned int TypeID;
|
||||
bool BufferOwned;
|
||||
|
||||
protected:
|
||||
MemoryBuffer *Data;
|
||||
std::unique_ptr<MemoryBuffer> Data;
|
||||
|
||||
Binary(unsigned int Type, MemoryBuffer *Source, bool BufferOwned = true);
|
||||
Binary(unsigned int Type, MemoryBuffer *Source);
|
||||
|
||||
enum {
|
||||
ID_Archive,
|
||||
@ -79,6 +78,7 @@ public:
|
||||
virtual ~Binary();
|
||||
|
||||
StringRef getData() const;
|
||||
MemoryBuffer *releaseBuffer() { return Data.release(); }
|
||||
StringRef getFileName() const;
|
||||
|
||||
// Cast methods.
|
||||
|
@ -420,8 +420,7 @@ protected:
|
||||
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;
|
||||
|
@ -177,8 +177,7 @@ protected:
|
||||
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;
|
||||
|
||||
@ -774,12 +773,11 @@ ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
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),
|
||||
Object, BufferOwned),
|
||||
Object),
|
||||
EF(Object, ec) {}
|
||||
|
||||
template <class ELFT>
|
||||
|
@ -27,8 +27,8 @@ class IRObjectFile : public SymbolicFile {
|
||||
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;
|
||||
|
@ -57,7 +57,7 @@ public:
|
||||
};
|
||||
|
||||
MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian, bool Is64Bits,
|
||||
std::error_code &EC, bool BufferOwned = true);
|
||||
std::error_code &EC);
|
||||
|
||||
void moveSymbolNext(DataRefImpl &Symb) const override;
|
||||
std::error_code getSymbolName(DataRefImpl Symb,
|
||||
|
@ -208,7 +208,7 @@ class ObjectFile : public SymbolicFile {
|
||||
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());
|
||||
@ -334,10 +334,9 @@ public:
|
||||
/// @brief Create ObjectFile from path.
|
||||
static ErrorOr<ObjectFile *> createObjectFile(StringRef ObjectPath);
|
||||
static ErrorOr<ObjectFile *> createObjectFile(MemoryBuffer *Object,
|
||||
bool BufferOwned,
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@ -346,12 +345,9 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
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.
|
||||
|
@ -115,7 +115,7 @@ const uint64_t UnknownAddressOrSize = ~0ULL;
|
||||
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;
|
||||
@ -143,17 +143,14 @@ public:
|
||||
|
||||
// construction aux.
|
||||
static ErrorOr<SymbolicFile *> createIRObjectFile(MemoryBuffer *Object,
|
||||
LLVMContext &Context,
|
||||
bool BufferOwned = true);
|
||||
LLVMContext &Context);
|
||||
|
||||
static ErrorOr<SymbolicFile *> createSymbolicFile(MemoryBuffer *Object,
|
||||
bool BufferOwned,
|
||||
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);
|
||||
|
||||
|
@ -39,8 +39,6 @@ void BitcodeReader::materializeForwardReferencedFunctions() {
|
||||
}
|
||||
|
||||
void BitcodeReader::FreeState() {
|
||||
if (BufferOwned)
|
||||
delete Buffer;
|
||||
Buffer = nullptr;
|
||||
std::vector<Type*>().swap(TypeList);
|
||||
ValueList.clear();
|
||||
@ -3150,6 +3148,7 @@ std::error_code BitcodeReader::FindFunctionInStream(
|
||||
// GVMaterializer implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void BitcodeReader::releaseBuffer() { Buffer.release(); }
|
||||
|
||||
bool BitcodeReader::isMaterializable(const GlobalValue *GV) const {
|
||||
if (const Function *F = dyn_cast<Function>(GV)) {
|
||||
@ -3374,10 +3373,9 @@ const std::error_category &BitcodeReader::BitcodeErrorCategory() {
|
||||
/// 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);
|
||||
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.
|
||||
@ -3409,13 +3407,12 @@ Module *llvm::getStreamedBitcodeModule(const std::string &name,
|
||||
|
||||
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();
|
||||
|
||||
// Read in the entire module, and destroy the BitcodeReader.
|
||||
if (std::error_code EC = M->materializeAllPermanently()) {
|
||||
if (std::error_code EC = M->materializeAllPermanently(true)) {
|
||||
delete M;
|
||||
return EC;
|
||||
}
|
||||
@ -3429,13 +3426,14 @@ ErrorOr<Module *> llvm::parseBitcodeFile(MemoryBuffer *Buffer,
|
||||
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();
|
||||
|
||||
R->releaseBuffer();
|
||||
delete R;
|
||||
return Triple;
|
||||
}
|
||||
|
@ -125,8 +125,7 @@ public:
|
||||
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;
|
||||
@ -223,25 +222,21 @@ public:
|
||||
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)
|
||||
: 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();
|
||||
|
||||
void releaseBuffer() {
|
||||
Buffer = nullptr;
|
||||
}
|
||||
void releaseBuffer() override;
|
||||
|
||||
bool isMaterializable(const GlobalValue *GV) const override;
|
||||
bool isDematerializable(const GlobalValue *GV) const override;
|
||||
|
@ -400,10 +400,13 @@ std::error_code Module::materializeAll() {
|
||||
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 (ReleaseBuffer)
|
||||
Materializer->releaseBuffer();
|
||||
|
||||
Materializer.reset();
|
||||
return std::error_code();
|
||||
}
|
||||
|
@ -181,7 +181,12 @@ Archive::Child::getAsBinary(LLVMContext *Context) const {
|
||||
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) {
|
||||
|
@ -25,13 +25,10 @@
|
||||
using namespace llvm;
|
||||
using namespace object;
|
||||
|
||||
Binary::~Binary() {
|
||||
if (BufferOwned)
|
||||
delete Data;
|
||||
}
|
||||
Binary::~Binary() {}
|
||||
|
||||
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();
|
||||
@ -41,14 +38,13 @@ StringRef Binary::getFileName() const {
|
||||
return Data->getBufferIdentifier();
|
||||
}
|
||||
|
||||
ErrorOr<Binary *> object::createBinary(MemoryBuffer *Source,
|
||||
ErrorOr<Binary *> object::createBinary(MemoryBuffer *Buffer,
|
||||
LLVMContext *Context) {
|
||||
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:
|
||||
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:
|
||||
@ -67,10 +63,9 @@ ErrorOr<Binary *> object::createBinary(MemoryBuffer *Source,
|
||||
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:
|
||||
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.
|
||||
|
@ -31,9 +31,9 @@ using support::ulittle32_t;
|
||||
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,
|
||||
uint64_t Size) {
|
||||
if (M->getBufferSize() < Size) {
|
||||
if (M.getBufferSize() < Size) {
|
||||
EC = object_error::unexpected_eof;
|
||||
return false;
|
||||
}
|
||||
@ -43,13 +43,12 @@ static bool checkSize(const MemoryBuffer *M, std::error_code &EC,
|
||||
// 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);
|
||||
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);
|
||||
@ -398,7 +397,7 @@ relocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const {
|
||||
// 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;
|
||||
|
||||
@ -409,11 +408,12 @@ std::error_code COFFObjectFile::initSymbolTablePtr() {
|
||||
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 =
|
||||
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
|
||||
@ -511,15 +511,15 @@ std::error_code COFFObjectFile::initExportTablePtr() {
|
||||
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.
|
||||
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;
|
||||
@ -532,7 +532,8 @@ COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, std::error_code &EC,
|
||||
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) {
|
||||
@ -543,13 +544,13 @@ COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, std::error_code &EC,
|
||||
HasPEHeader = true;
|
||||
}
|
||||
|
||||
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;
|
||||
if ((EC = getObject(Header, Data, base() + CurPtr)))
|
||||
if ((EC = getObject(Header, *Data, base() + CurPtr)))
|
||||
return;
|
||||
|
||||
const uint8_t *DataDirAddr;
|
||||
@ -567,7 +568,7 @@ COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, std::error_code &EC,
|
||||
EC = object_error::parse_failed;
|
||||
return;
|
||||
}
|
||||
if ((EC = getObject(DataDirectory, Data, DataDirAddr, DataDirSize)))
|
||||
if ((EC = getObject(DataDirectory, *Data, DataDirAddr, DataDirSize)))
|
||||
return;
|
||||
CurPtr += COFFHeader->SizeOfOptionalHeader;
|
||||
}
|
||||
@ -575,7 +576,7 @@ COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, std::error_code &EC,
|
||||
if (COFFHeader->isImportLibrary())
|
||||
return;
|
||||
|
||||
if ((EC = getObject(SectionTable, Data, base() + CurPtr,
|
||||
if ((EC = getObject(SectionTable, *Data, base() + CurPtr,
|
||||
COFFHeader->NumberOfSections * sizeof(coff_section))))
|
||||
return;
|
||||
|
||||
@ -1110,11 +1111,9 @@ ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const {
|
||||
return object_error::success;
|
||||
}
|
||||
|
||||
ErrorOr<ObjectFile *> ObjectFile::createCOFFObjectFile(MemoryBuffer *Object,
|
||||
bool BufferOwned) {
|
||||
ErrorOr<ObjectFile *> ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) {
|
||||
std::error_code EC;
|
||||
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();
|
||||
|
@ -17,8 +17,7 @@
|
||||
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()));
|
||||
@ -28,49 +27,41 @@ static ErrorOr<ObjectFile *> createELFObjectFileAux(MemoryBuffer *Obj,
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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;
|
||||
}
|
||||
@ -82,12 +73,4 @@ static ErrorOr<ObjectFile *> createELFObjectFileAux(MemoryBuffer *Obj,
|
||||
return R.release();
|
||||
}
|
||||
|
||||
ErrorOr<ObjectFile *> ObjectFile::createELFObjectFile(MemoryBuffer *Obj,
|
||||
bool BufferOwned) {
|
||||
ErrorOr<ObjectFile *> Ret = createELFObjectFileAux(Obj, BufferOwned);
|
||||
if (BufferOwned && Ret.getError())
|
||||
delete Obj;
|
||||
return Ret;
|
||||
}
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#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"
|
||||
@ -21,10 +22,9 @@ using namespace llvm;
|
||||
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;
|
||||
|
||||
@ -38,6 +38,8 @@ IRObjectFile::IRObjectFile(MemoryBuffer *Object, std::error_code &EC,
|
||||
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));
|
||||
}
|
||||
@ -151,11 +153,11 @@ basic_symbol_iterator IRObjectFile::symbol_end_impl() const {
|
||||
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::error_code EC;
|
||||
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();
|
||||
|
@ -423,9 +423,8 @@ static uint32_t getSectionFlags(const MachOObjectFile *O,
|
||||
}
|
||||
|
||||
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;
|
||||
@ -1812,19 +1811,18 @@ void MachOObjectFile::ReadULEB128s(uint64_t Index,
|
||||
}
|
||||
}
|
||||
|
||||
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")
|
||||
Ret.reset(new MachOObjectFile(Buffer, false, false, EC, BufferOwned));
|
||||
Ret.reset(new MachOObjectFile(Buffer, false, false, EC));
|
||||
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")
|
||||
Ret.reset(new MachOObjectFile(Buffer, false, true, EC, BufferOwned));
|
||||
Ret.reset(new MachOObjectFile(Buffer, false, true, EC));
|
||||
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;
|
||||
|
@ -23,9 +23,8 @@ using namespace object;
|
||||
|
||||
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 {
|
||||
@ -47,7 +46,6 @@ section_iterator ObjectFile::getRelocatedSection(DataRefImpl Sec) const {
|
||||
}
|
||||
|
||||
ErrorOr<ObjectFile *> ObjectFile::createObjectFile(MemoryBuffer *Object,
|
||||
bool BufferOwned,
|
||||
sys::fs::file_magic Type) {
|
||||
if (Type == sys::fs::file_magic::unknown)
|
||||
Type = sys::fs::identify_magic(Object->getBuffer());
|
||||
@ -58,14 +56,12 @@ ErrorOr<ObjectFile *> ObjectFile::createObjectFile(MemoryBuffer *Object,
|
||||
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 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:
|
||||
@ -76,11 +72,11 @@ ErrorOr<ObjectFile *> ObjectFile::createObjectFile(MemoryBuffer *Object,
|
||||
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:
|
||||
return createCOFFObjectFile(Object, BufferOwned);
|
||||
return createCOFFObjectFile(Object);
|
||||
}
|
||||
llvm_unreachable("Unexpected Object File Type");
|
||||
}
|
||||
|
@ -19,15 +19,13 @@
|
||||
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::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());
|
||||
@ -35,14 +33,12 @@ SymbolicFile::createSymbolicFile(MemoryBuffer *Object, bool BufferOwned,
|
||||
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:
|
||||
if (BufferOwned)
|
||||
delete Object;
|
||||
return object_error::invalid_file_type;
|
||||
case sys::fs::file_magic::elf_relocatable:
|
||||
case sys::fs::file_magic::elf_executable:
|
||||
@ -61,7 +57,7 @@ SymbolicFile::createSymbolicFile(MemoryBuffer *Object, bool BufferOwned,
|
||||
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");
|
||||
}
|
||||
|
@ -699,7 +699,7 @@ writeSymbolTable(raw_fd_ostream &Out, ArrayRef<NewArchiveIterator> Members,
|
||||
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());
|
||||
@ -724,6 +724,7 @@ writeSymbolTable(raw_fd_ostream &Out, ArrayRef<NewArchiveIterator> Members,
|
||||
MemberOffsetRefs.push_back(std::make_pair(Out.tell(), MemberNum));
|
||||
print32BE(Out, 0);
|
||||
}
|
||||
Obj->releaseBuffer();
|
||||
}
|
||||
Out << NameOS.str();
|
||||
|
||||
|
@ -726,9 +726,10 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
|
||||
return;
|
||||
|
||||
LLVMContext &Context = getGlobalContext();
|
||||
ErrorOr<Binary *> BinaryOrErr = createBinary(Buffer.release(), &Context);
|
||||
ErrorOr<Binary *> BinaryOrErr = createBinary(Buffer.get(), &Context);
|
||||
if (error(BinaryOrErr.getError(), Filename))
|
||||
return;
|
||||
Buffer.release();
|
||||
std::unique_ptr<Binary> Bin(BinaryOrErr.get());
|
||||
|
||||
if (Archive *A = dyn_cast<Archive>(Bin.get())) {
|
||||
|
Loading…
Reference in New Issue
Block a user