From 1f659329b63aa1d1af2b2bfc8b174a8ccdaba2c0 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 23 Jun 2014 21:53:12 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211542 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Bitcode/ReaderWriter.h | 3 +- include/llvm/IR/GVMaterializer.h | 2 ++ include/llvm/IR/Module.h | 2 +- include/llvm/Object/Binary.h | 6 ++-- include/llvm/Object/COFF.h | 3 +- include/llvm/Object/ELFObjectFile.h | 8 ++---- include/llvm/Object/IRObjectFile.h | 4 +-- include/llvm/Object/MachO.h | 2 +- include/llvm/Object/ObjectFile.h | 14 ++++----- include/llvm/Object/SymbolicFile.h | 9 ++---- lib/Bitcode/Reader/BitcodeReader.cpp | 16 +++++------ lib/Bitcode/Reader/BitcodeReader.h | 23 ++++++--------- lib/IR/Module.cpp | 5 +++- lib/Object/Archive.cpp | 7 ++++- lib/Object/Binary.cpp | 21 ++++++-------- lib/Object/COFFObjectFile.cpp | 43 ++++++++++++++-------------- lib/Object/ELFObjectFile.cpp | 35 ++++++---------------- lib/Object/IRObjectFile.cpp | 18 ++++++------ lib/Object/MachOObjectFile.cpp | 16 +++++------ lib/Object/ObjectFile.cpp | 14 ++++----- lib/Object/SymbolicFile.cpp | 14 ++++----- tools/llvm-ar/llvm-ar.cpp | 3 +- tools/llvm-nm/llvm-nm.cpp | 3 +- 23 files changed, 117 insertions(+), 154 deletions(-) diff --git a/include/llvm/Bitcode/ReaderWriter.h b/include/llvm/Bitcode/ReaderWriter.h index 0d0d6a71ab1..4c194a638d4 100644 --- a/include/llvm/Bitcode/ReaderWriter.h +++ b/include/llvm/Bitcode/ReaderWriter.h @@ -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 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. diff --git a/include/llvm/IR/GVMaterializer.h b/include/llvm/IR/GVMaterializer.h index 4afdbb05f85..a1216a17428 100644 --- a/include/llvm/IR/GVMaterializer.h +++ b/include/llvm/IR/GVMaterializer.h @@ -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 diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h index e2b86f62fb8..7230df9f795 100644 --- a/include/llvm/IR/Module.h +++ b/include/llvm/IR/Module.h @@ -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 diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h index 8ac84e78d48..a87a0064509 100644 --- a/include/llvm/Object/Binary.h +++ b/include/llvm/Object/Binary.h @@ -32,12 +32,11 @@ private: Binary(const Binary &other) LLVM_DELETED_FUNCTION; unsigned int TypeID; - bool BufferOwned; protected: - MemoryBuffer *Data; + std::unique_ptr 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. diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index f0f2793a928..1f45ab05db0 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -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; diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index 876206b38a1..72f72161104 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -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::getRela(DataRefImpl Rela) const { } template -ELFObjectFile::ELFObjectFile(MemoryBuffer *Object, std::error_code &ec, - bool BufferOwned) +ELFObjectFile::ELFObjectFile(MemoryBuffer *Object, std::error_code &ec) : ObjectFile(getELFType(static_cast(ELFT::TargetEndianness) == support::little, ELFT::Is64Bits), - Object, BufferOwned), + Object), EF(Object, ec) {} template diff --git a/include/llvm/Object/IRObjectFile.h b/include/llvm/Object/IRObjectFile.h index c87fe1519ac..97a75b763d1 100644 --- a/include/llvm/Object/IRObjectFile.h +++ b/include/llvm/Object/IRObjectFile.h @@ -27,8 +27,8 @@ class IRObjectFile : public SymbolicFile { std::unique_ptr 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; diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index 6e1ab253ec9..182815f49a1 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -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, diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index 152bb7e10c1..62c5b9b7719 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -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(Data->getBufferStart()); @@ -334,10 +334,9 @@ public: /// @brief Create ObjectFile from path. static ErrorOr createObjectFile(StringRef ObjectPath); static ErrorOr createObjectFile(MemoryBuffer *Object, - bool BufferOwned, sys::fs::file_magic Type); static ErrorOr 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 createCOFFObjectFile(MemoryBuffer *Object, - bool BufferOwned = true); - static ErrorOr createELFObjectFile(MemoryBuffer *Object, - bool BufferOwned = true); - static ErrorOr createMachOObjectFile(MemoryBuffer *Object, - bool BufferOwned = true); + static ErrorOr createCOFFObjectFile(MemoryBuffer *Object); + static ErrorOr createELFObjectFile(MemoryBuffer *Object); + static ErrorOr createMachOObjectFile(MemoryBuffer *Object); }; // Inline function definitions. diff --git a/include/llvm/Object/SymbolicFile.h b/include/llvm/Object/SymbolicFile.h index 40015ec9f6d..5c2d956d695 100644 --- a/include/llvm/Object/SymbolicFile.h +++ b/include/llvm/Object/SymbolicFile.h @@ -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 createIRObjectFile(MemoryBuffer *Object, - LLVMContext &Context, - bool BufferOwned = true); + LLVMContext &Context); static ErrorOr createSymbolicFile(MemoryBuffer *Object, - bool BufferOwned, sys::fs::file_magic Type, LLVMContext *Context); static ErrorOr createSymbolicFile(MemoryBuffer *Object) { - return createSymbolicFile(Object, true, sys::fs::file_magic::unknown, - nullptr); + return createSymbolicFile(Object, sys::fs::file_magic::unknown, nullptr); } static ErrorOr createSymbolicFile(StringRef ObjectPath); diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 9c398277d42..696e714ff6f 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -39,8 +39,6 @@ void BitcodeReader::materializeForwardReferencedFunctions() { } void BitcodeReader::FreeState() { - if (BufferOwned) - delete Buffer; Buffer = nullptr; std::vector().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(GV)) { @@ -3374,10 +3373,9 @@ const std::error_category &BitcodeReader::BitcodeErrorCategory() { /// getLazyBitcodeModule - lazy function-at-a-time loading from a file. /// ErrorOr 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 llvm::parseBitcodeFile(MemoryBuffer *Buffer, LLVMContext &Context) { - ErrorOr ModuleOrErr = getLazyBitcodeModule(Buffer, Context, false); + ErrorOr 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 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; } diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h index 6aa3e0e5adf..7d797266c3f 100644 --- a/lib/Bitcode/Reader/BitcodeReader.h +++ b/lib/Bitcode/Reader/BitcodeReader.h @@ -125,8 +125,7 @@ public: class BitcodeReader : public GVMaterializer { LLVMContext &Context; Module *TheModule; - MemoryBuffer *Buffer; - bool BufferOwned; + std::unique_ptr Buffer; std::unique_ptr 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; diff --git a/lib/IR/Module.cpp b/lib/IR/Module.cpp index 6a5b386c199..eea14df3f38 100644 --- a/lib/IR/Module.cpp +++ b/lib/IR/Module.cpp @@ -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(); } diff --git a/lib/Object/Archive.cpp b/lib/Object/Archive.cpp index 05e891384f1..cd8924920a8 100644 --- a/lib/Object/Archive.cpp +++ b/lib/Object/Archive.cpp @@ -181,7 +181,12 @@ Archive::Child::getAsBinary(LLVMContext *Context) const { ErrorOr> BuffOrErr = getMemoryBuffer(); if (std::error_code EC = BuffOrErr.getError()) return EC; - return createBinary(BuffOrErr.get().release(), Context); + + std::unique_ptr Buff(BuffOrErr.get().release()); + ErrorOr> Ret = createBinary(Buff.get(), Context); + if (!Ret.getError()) + Buff.release(); + return Ret; } ErrorOr Archive::create(MemoryBuffer *Source) { diff --git a/lib/Object/Binary.cpp b/lib/Object/Binary.cpp index c55ed0c7598..785b3d2318b 100644 --- a/lib/Object/Binary.cpp +++ b/lib/Object/Binary.cpp @@ -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 object::createBinary(MemoryBuffer *Source, +ErrorOr object::createBinary(MemoryBuffer *Buffer, LLVMContext *Context) { - std::unique_ptr 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 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. diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp index 186d64bafd4..1b149742ebf 100644 --- a/lib/Object/COFFObjectFile.cpp +++ b/lib/Object/COFFObjectFile.cpp @@ -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 -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(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(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::createCOFFObjectFile(MemoryBuffer *Object, - bool BufferOwned) { +ErrorOr ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) { std::error_code EC; - std::unique_ptr Ret( - new COFFObjectFile(Object, EC, BufferOwned)); + std::unique_ptr Ret(new COFFObjectFile(Object, EC)); if (EC) return EC; return Ret.release(); diff --git a/lib/Object/ELFObjectFile.cpp b/lib/Object/ELFObjectFile.cpp index 0a3e2cb790d..295cb111c38 100644 --- a/lib/Object/ELFObjectFile.cpp +++ b/lib/Object/ELFObjectFile.cpp @@ -17,8 +17,7 @@ namespace llvm { using namespace object; -static ErrorOr createELFObjectFileAux(MemoryBuffer *Obj, - bool BufferOwned) { +ErrorOr ObjectFile::createELFObjectFile(MemoryBuffer *Obj) { std::pair Ident = getElfArchType(Obj); std::size_t MaxAlignment = 1ULL << countTrailingZeros(uintptr_t(Obj->getBufferStart())); @@ -28,49 +27,41 @@ static ErrorOr 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 >( - Obj, EC, BufferOwned)); + R.reset(new ELFObjectFile>(Obj, EC)); else #endif if (MaxAlignment >= 2) - R.reset(new ELFObjectFile >( - Obj, EC, BufferOwned)); + R.reset(new ELFObjectFile>(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 >(Obj, EC, - BufferOwned)); + R.reset(new ELFObjectFile>(Obj, EC)); else #endif if (MaxAlignment >= 2) - R.reset(new ELFObjectFile >(Obj, EC, - BufferOwned)); + R.reset(new ELFObjectFile>(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 >(Obj, EC, - BufferOwned)); + R.reset(new ELFObjectFile>(Obj, EC)); else #endif if (MaxAlignment >= 2) - R.reset(new ELFObjectFile >(Obj, EC, - BufferOwned)); + R.reset(new ELFObjectFile>(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 >( - Obj, EC, BufferOwned)); + R.reset(new ELFObjectFile>(Obj, EC)); else #endif if (MaxAlignment >= 2) - R.reset(new ELFObjectFile >( - Obj, EC, BufferOwned)); + R.reset(new ELFObjectFile>(Obj, EC)); else return object_error::parse_failed; } @@ -82,12 +73,4 @@ static ErrorOr createELFObjectFileAux(MemoryBuffer *Obj, return R.release(); } -ErrorOr ObjectFile::createELFObjectFile(MemoryBuffer *Obj, - bool BufferOwned) { - ErrorOr Ret = createELFObjectFileAux(Obj, BufferOwned); - if (BufferOwned && Ret.getError()) - delete Obj; - return Ret; -} - } // end namespace llvm diff --git a/lib/Object/IRObjectFile.cpp b/lib/Object/IRObjectFile.cpp index 004d8de065d..ef544aa13b5 100644 --- a/lib/Object/IRObjectFile.cpp +++ b/lib/Object/IRObjectFile.cpp @@ -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 MOrErr = - getLazyBitcodeModule(Object, Context, /*BufferOwned*/ false); + LLVMContext &Context) + : SymbolicFile(Binary::ID_IR, Object) { + ErrorOr 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(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 llvm::object::SymbolicFile::createIRObjectFile( - MemoryBuffer *Object, LLVMContext &Context, bool BufferOwned) { +ErrorOr +llvm::object::SymbolicFile::createIRObjectFile(MemoryBuffer *Object, + LLVMContext &Context) { std::error_code EC; - std::unique_ptr Ret( - new IRObjectFile(Object, EC, Context, BufferOwned)); + std::unique_ptr Ret(new IRObjectFile(Object, EC, Context)); if (EC) return EC; return Ret.release(); diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index a072b0f28ca..7fc02fb893f 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -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::createMachOObjectFile(MemoryBuffer *Buffer, - bool BufferOwned) { +ErrorOr ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { StringRef Magic = Buffer->getBuffer().slice(0, 4); std::error_code EC; std::unique_ptr 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; diff --git a/lib/Object/ObjectFile.cpp b/lib/Object/ObjectFile.cpp index 7666ed53c37..738ea5fbb92 100644 --- a/lib/Object/ObjectFile.cpp +++ b/lib/Object/ObjectFile.cpp @@ -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::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::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::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"); } diff --git a/lib/Object/SymbolicFile.cpp b/lib/Object/SymbolicFile.cpp index 495f0b62bc5..48fea0256ef 100644 --- a/lib/Object/SymbolicFile.cpp +++ b/lib/Object/SymbolicFile.cpp @@ -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::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"); } diff --git a/tools/llvm-ar/llvm-ar.cpp b/tools/llvm-ar/llvm-ar.cpp index 2f0d7689b11..a58ab8bce0e 100644 --- a/tools/llvm-ar/llvm-ar.cpp +++ b/tools/llvm-ar/llvm-ar.cpp @@ -699,7 +699,7 @@ writeSymbolTable(raw_fd_ostream &Out, ArrayRef Members, MemoryBuffer *MemberBuffer = Buffers[MemberNum].get(); ErrorOr 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 Obj(ObjOrErr.get()); @@ -724,6 +724,7 @@ writeSymbolTable(raw_fd_ostream &Out, ArrayRef Members, MemberOffsetRefs.push_back(std::make_pair(Out.tell(), MemberNum)); print32BE(Out, 0); } + Obj->releaseBuffer(); } Out << NameOS.str(); diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index aeb7ba10724..fef3d5cbea1 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -726,9 +726,10 @@ static void dumpSymbolNamesFromFile(std::string &Filename) { return; LLVMContext &Context = getGlobalContext(); - ErrorOr BinaryOrErr = createBinary(Buffer.release(), &Context); + ErrorOr BinaryOrErr = createBinary(Buffer.get(), &Context); if (error(BinaryOrErr.getError(), Filename)) return; + Buffer.release(); std::unique_ptr Bin(BinaryOrErr.get()); if (Archive *A = dyn_cast(Bin.get())) { -- 2.34.1