diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2014-06-23 21:53:12 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2014-06-23 21:53:12 +0000 |
commit | 1f659329b63aa1d1af2b2bfc8b174a8ccdaba2c0 (patch) | |
tree | dc64a751796af7cd61a83b0cb8a8d8ca3145a95c | |
parent | 7e7e89f17819d30703543375120dff52d5aaa414 (diff) | |
download | llvm-1f659329b63aa1d1af2b2bfc8b174a8ccdaba2c0.tar.gz llvm-1f659329b63aa1d1af2b2bfc8b174a8ccdaba2c0.tar.bz2 llvm-1f659329b63aa1d1af2b2bfc8b174a8ccdaba2c0.tar.xz |
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
-rw-r--r-- | include/llvm/Bitcode/ReaderWriter.h | 3 | ||||
-rw-r--r-- | include/llvm/IR/GVMaterializer.h | 2 | ||||
-rw-r--r-- | include/llvm/IR/Module.h | 2 | ||||
-rw-r--r-- | include/llvm/Object/Binary.h | 6 | ||||
-rw-r--r-- | include/llvm/Object/COFF.h | 3 | ||||
-rw-r--r-- | include/llvm/Object/ELFObjectFile.h | 8 | ||||
-rw-r--r-- | include/llvm/Object/IRObjectFile.h | 4 | ||||
-rw-r--r-- | include/llvm/Object/MachO.h | 2 | ||||
-rw-r--r-- | include/llvm/Object/ObjectFile.h | 14 | ||||
-rw-r--r-- | include/llvm/Object/SymbolicFile.h | 9 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 16 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.h | 23 | ||||
-rw-r--r-- | lib/IR/Module.cpp | 5 | ||||
-rw-r--r-- | lib/Object/Archive.cpp | 7 | ||||
-rw-r--r-- | lib/Object/Binary.cpp | 21 | ||||
-rw-r--r-- | lib/Object/COFFObjectFile.cpp | 43 | ||||
-rw-r--r-- | lib/Object/ELFObjectFile.cpp | 35 | ||||
-rw-r--r-- | lib/Object/IRObjectFile.cpp | 18 | ||||
-rw-r--r-- | lib/Object/MachOObjectFile.cpp | 16 | ||||
-rw-r--r-- | lib/Object/ObjectFile.cpp | 14 | ||||
-rw-r--r-- | lib/Object/SymbolicFile.cpp | 14 | ||||
-rw-r--r-- | tools/llvm-ar/llvm-ar.cpp | 3 | ||||
-rw-r--r-- | 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 0d0d6a71ab..4c194a638d 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<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. diff --git a/include/llvm/IR/GVMaterializer.h b/include/llvm/IR/GVMaterializer.h index 4afdbb05f8..a1216a1742 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 e2b86f62fb..7230df9f79 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 8ac84e78d4..a87a006450 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<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. diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index f0f2793a92..1f45ab05db 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 876206b38a..72f7216110 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<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> diff --git a/include/llvm/Object/IRObjectFile.h b/include/llvm/Object/IRObjectFile.h index c87fe1519a..97a75b763d 100644 --- a/include/llvm/Object/IRObjectFile.h +++ b/include/llvm/Object/IRObjectFile.h @@ -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; diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index 6e1ab253ec..182815f49a 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 152bb7e10c..62c5b9b771 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<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. diff --git a/include/llvm/Object/SymbolicFile.h b/include/llvm/Object/SymbolicFile.h index 40015ec9f6..5c2d956d69 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<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); diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 9c398277d4..696e714ff6 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<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; } diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h index 6aa3e0e5ad..7d797266c3 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<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; diff --git a/lib/IR/Module.cpp b/lib/IR/Module.cpp index 6a5b386c19..eea14df3f3 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 05e891384f..cd8924920a 100644 --- a/lib/Object/Archive.cpp +++ b/lib/Object/Archive.cpp @@ -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) { diff --git a/lib/Object/Binary.cpp b/lib/Object/Binary.cpp index c55ed0c759..785b3d2318 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<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. diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp index 186d64bafd..1b149742eb 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 <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(); diff --git a/lib/Object/ELFObjectFile.cpp b/lib/Object/ELFObjectFile.cpp index 0a3e2cb790..295cb111c3 100644 --- a/lib/Object/ELFObjectFile.cpp +++ b/lib/Object/ELFObjectFile.cpp @@ -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 diff --git a/lib/Object/IRObjectFile.cpp b/lib/Object/IRObjectFile.cpp index 004d8de065..ef544aa13b 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<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(); diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index a072b0f28c..7fc02fb893 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 *> 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; diff --git a/lib/Object/ObjectFile.cpp b/lib/Object/ObjectFile.cpp index 7666ed53c3..738ea5fbb9 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 *> 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"); } diff --git a/lib/Object/SymbolicFile.cpp b/lib/Object/SymbolicFile.cpp index 495f0b62bc..48fea0256e 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 *> -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 2f0d7689b1..a58ab8bce0 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<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(); diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index aeb7ba1072..fef3d5cbea 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<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())) { |