From 548f2b6e8fc5499fa8c9394fe7d110f50c487802 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 19 Aug 2014 18:44:46 +0000 Subject: [PATCH] Don't own the buffer in object::Binary. Owning the buffer is somewhat inflexible. Some Binaries have sub Binaries (like Archive) and we had to create dummy buffers just to handle that. It is also a bad fit for IRObjectFile where the Module wants to own the buffer too. Keeping this ownership would make supporting IR inside native objects particularly painful. This patch focuses in lib/Object. If something elsewhere used to own an Binary, now it also owns a MemoryBuffer. This patch introduces a few new types. * MemoryBufferRef. This is just a pair of StringRefs for the data and name. This is to MemoryBuffer as StringRef is to std::string. * OwningBinary. A combination of Binary and a MemoryBuffer. This is needed for convenience functions that take a filename and return both the buffer and the Binary using that buffer. The C api now uses OwningBinary to avoid any change in semantics. I will start a new thread to see if we want to change it and how. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216002 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../llvm/ExecutionEngine/ExecutionEngine.h | 3 +- include/llvm/ExecutionEngine/ObjectBuffer.h | 13 +----- include/llvm/ExecutionEngine/ObjectCache.h | 2 +- include/llvm/LTO/LTOModule.h | 7 ++- include/llvm/Object/Archive.h | 8 ++-- include/llvm/Object/Binary.h | 42 ++++++++++++++---- include/llvm/Object/COFF.h | 2 +- include/llvm/Object/ELFObjectFile.h | 11 +++-- include/llvm/Object/IRObjectFile.h | 7 ++- include/llvm/Object/MachO.h | 4 +- include/llvm/Object/MachOUniversal.h | 6 +-- include/llvm/Object/ObjectFile.h | 17 ++++---- include/llvm/Object/SymbolicFile.h | 10 ++--- .../llvm/ProfileData/CoverageMappingReader.h | 2 +- include/llvm/Support/MemoryBuffer.h | 28 ++++++++++-- lib/DebugInfo/DWARFUnit.cpp | 4 +- lib/ExecutionEngine/ExecutionEngine.cpp | 2 +- lib/ExecutionEngine/MCJIT/MCJIT.cpp | 9 ++-- lib/ExecutionEngine/MCJIT/MCJIT.h | 4 +- .../RuntimeDyld/ObjectImageCommon.h | 2 +- .../RuntimeDyld/RuntimeDyldELF.cpp | 39 ++++++++--------- lib/LTO/LTOModule.cpp | 26 +++++++---- lib/Object/Archive.cpp | 35 ++++++--------- lib/Object/Binary.cpp | 37 +++++++++------- lib/Object/COFFObjectFile.cpp | 36 +++++++--------- lib/Object/ELFObjectFile.cpp | 35 ++++++--------- lib/Object/IRObjectFile.cpp | 24 ++++++----- lib/Object/MachOObjectFile.cpp | 19 ++++---- lib/Object/MachOUniversal.cpp | 22 ++++------ lib/Object/Object.cpp | 43 +++++++++++-------- lib/Object/ObjectFile.cpp | 24 +++++++---- lib/Object/SymbolicFile.cpp | 16 +++---- lib/ProfileData/CoverageMappingReader.cpp | 13 +++--- lib/Support/MemoryBuffer.cpp | 6 +++ tools/lli/lli.cpp | 21 +++++---- tools/llvm-ar/llvm-ar.cpp | 29 +++++++------ tools/llvm-dwarfdump/llvm-dwarfdump.cpp | 7 +-- tools/llvm-nm/llvm-nm.cpp | 2 +- tools/llvm-objdump/MachODump.cpp | 18 +++++--- tools/llvm-objdump/llvm-objdump.cpp | 4 +- tools/llvm-readobj/llvm-readobj.cpp | 4 +- tools/llvm-size/llvm-size.cpp | 4 +- tools/llvm-symbolizer/LLVMSymbolize.cpp | 18 ++++---- tools/llvm-symbolizer/LLVMSymbolize.h | 6 +++ tools/llvm-vtabledump/llvm-vtabledump.cpp | 4 +- tools/macho-dump/macho-dump.cpp | 4 +- tools/obj2yaml/obj2yaml.cpp | 4 +- .../MCJIT/MCJITObjectCacheTest.cpp | 6 +-- 48 files changed, 375 insertions(+), 314 deletions(-) diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index 8fbf61d2e86..aff4c7180cc 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -22,6 +22,7 @@ #include "llvm/IR/ValueHandle.h" #include "llvm/IR/ValueMap.h" #include "llvm/MC/MCCodeGenInfo.h" +#include "llvm/Object/Binary.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Mutex.h" #include "llvm/Target/TargetMachine.h" @@ -195,7 +196,7 @@ public: /// resolve external symbols in objects it is loading. If a symbol is found /// in the Archive the contained object file will be extracted (in memory) /// and loaded for possible execution. - virtual void addArchive(std::unique_ptr A); + virtual void addArchive(object::OwningBinary A); //===--------------------------------------------------------------------===// diff --git a/include/llvm/ExecutionEngine/ObjectBuffer.h b/include/llvm/ExecutionEngine/ObjectBuffer.h index ff282eacba9..9b234684fac 100644 --- a/include/llvm/ExecutionEngine/ObjectBuffer.h +++ b/include/llvm/ExecutionEngine/ObjectBuffer.h @@ -24,10 +24,7 @@ namespace llvm { /// This class acts as a container for the memory buffer used during generation /// and loading of executable objects using MCJIT and RuntimeDyld. The /// underlying memory for the object will be owned by the ObjectBuffer instance -/// throughout its lifetime. The getMemBuffer() method provides a way to create -/// a MemoryBuffer wrapper object instance to be owned by other classes (such as -/// ObjectFile) as needed, but the MemoryBuffer instance returned does not own -/// the actual memory it points to. +/// throughout its lifetime. class ObjectBuffer { virtual void anchor(); public: @@ -35,13 +32,7 @@ public: ObjectBuffer(MemoryBuffer* Buf) : Buffer(Buf) {} virtual ~ObjectBuffer() {} - /// Like MemoryBuffer::getMemBuffer() this function returns a pointer to an - /// object that is owned by the caller. However, the caller does not take - /// ownership of the underlying memory. - std::unique_ptr getMemBuffer() const { - return std::unique_ptr(MemoryBuffer::getMemBuffer( - Buffer->getBuffer(), Buffer->getBufferIdentifier(), false)); - } + MemoryBufferRef getMemBuffer() const { return Buffer->getMemBufferRef(); } const char *getBufferStart() const { return Buffer->getBufferStart(); } size_t getBufferSize() const { return Buffer->getBufferSize(); } diff --git a/include/llvm/ExecutionEngine/ObjectCache.h b/include/llvm/ExecutionEngine/ObjectCache.h index 78049a2a7d4..cc01a4e5899 100644 --- a/include/llvm/ExecutionEngine/ObjectCache.h +++ b/include/llvm/ExecutionEngine/ObjectCache.h @@ -27,7 +27,7 @@ public: virtual ~ObjectCache() { } /// notifyObjectCompiled - Provides a pointer to compiled code for Module M. - virtual void notifyObjectCompiled(const Module *M, const MemoryBuffer *Obj) = 0; + virtual void notifyObjectCompiled(const Module *M, MemoryBufferRef Obj) = 0; /// Returns a pointer to a newly allocated MemoryBuffer that contains the /// object which corresponds with Module M, or 0 if an object is not diff --git a/include/llvm/LTO/LTOModule.h b/include/llvm/LTO/LTOModule.h index 80cbac86ed3..fc583a20f68 100644 --- a/include/llvm/LTO/LTOModule.h +++ b/include/llvm/LTO/LTOModule.h @@ -202,10 +202,9 @@ private: /// Get string that the data pointer points to. bool objcClassNameFromExpression(const Constant *c, std::string &name); - /// Create an LTOModule (private version). N.B. This method takes ownership of - /// the buffer. - static LTOModule *makeLTOModule(std::unique_ptr Buffer, - TargetOptions options, std::string &errMsg); + /// Create an LTOModule (private version). + static LTOModule *makeLTOModule(MemoryBufferRef Buffer, TargetOptions options, + std::string &errMsg); }; } #endif diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h index d6f9ab06549..5526dd13ba6 100644 --- a/include/llvm/Object/Archive.h +++ b/include/llvm/Object/Archive.h @@ -89,8 +89,7 @@ public: return StringRef(Data.data() + StartOfFile, getSize()); } - ErrorOr> - getMemoryBuffer(bool FullPath = false) const; + ErrorOr getMemoryBufferRef() const; ErrorOr> getAsBinary(LLVMContext *Context = nullptr) const; @@ -164,9 +163,8 @@ public: } }; - Archive(std::unique_ptr Source, std::error_code &EC); - static ErrorOr> - create(std::unique_ptr Source); + Archive(MemoryBufferRef Source, std::error_code &EC); + static ErrorOr> create(MemoryBufferRef Source); enum Kind { K_GNU, diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h index 1fd997c082c..bebbaf62f6f 100644 --- a/include/llvm/Object/Binary.h +++ b/include/llvm/Object/Binary.h @@ -17,11 +17,11 @@ #include "llvm/Object/Error.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/MemoryBuffer.h" namespace llvm { class LLVMContext; -class MemoryBuffer; class StringRef; namespace object { @@ -34,9 +34,9 @@ private: unsigned int TypeID; protected: - std::unique_ptr Data; + MemoryBufferRef Data; - Binary(unsigned int Type, std::unique_ptr Source); + Binary(unsigned int Type, MemoryBufferRef Source); enum { ID_Archive, @@ -78,8 +78,8 @@ public: virtual ~Binary(); StringRef getData() const; - MemoryBuffer *releaseBuffer() { return Data.release(); } StringRef getFileName() const; + MemoryBufferRef getMemoryBufferRef() const; // Cast methods. unsigned int getType() const { return TypeID; } @@ -126,11 +126,37 @@ public: /// @brief Create a Binary from Source, autodetecting the file type. /// /// @param Source The data to create the Binary from. -ErrorOr> -createBinary(std::unique_ptr Source, - LLVMContext *Context = nullptr); +ErrorOr> createBinary(MemoryBufferRef Source, + LLVMContext *Context = nullptr); -ErrorOr> createBinary(StringRef Path); +template class OwningBinary { + std::unique_ptr Bin; + std::unique_ptr Buf; + +public: + OwningBinary(); + OwningBinary(std::unique_ptr Bin, std::unique_ptr Buf); + std::unique_ptr &getBinary(); + std::unique_ptr &getBuffer(); +}; + +template +OwningBinary::OwningBinary(std::unique_ptr Bin, + std::unique_ptr Buf) + : Bin(std::move(Bin)), Buf(std::move(Buf)) {} + +template OwningBinary::OwningBinary() {} + +template std::unique_ptr &OwningBinary::getBinary() { + return Bin; +} + +template +std::unique_ptr &OwningBinary::getBuffer() { + return Buf; +} + +ErrorOr> createBinary(StringRef Path); } } diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index fdeab2c92f3..a483e4e1d01 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -415,7 +415,7 @@ protected: SmallVectorImpl &Result) const override; public: - COFFObjectFile(std::unique_ptr Object, std::error_code &EC); + COFFObjectFile(MemoryBufferRef Object, std::error_code &EC); basic_symbol_iterator symbol_begin_impl() const override; basic_symbol_iterator symbol_end_impl() const override; section_iterator section_begin() const override; diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index 8a9e1257655..b2c22336b7b 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -37,7 +37,7 @@ namespace object { class ELFObjectFileBase : public ObjectFile { protected: - ELFObjectFileBase(unsigned int Type, std::unique_ptr Source); + ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source); public: virtual std::error_code getRelocationAddend(DataRefImpl Rel, @@ -186,7 +186,7 @@ protected: bool isDyldELFObject; public: - ELFObjectFile(std::unique_ptr Object, std::error_code &EC); + ELFObjectFile(MemoryBufferRef Object, std::error_code &EC); const Elf_Sym *getSymbol(DataRefImpl Symb) const; @@ -797,14 +797,13 @@ ELFObjectFile::getRela(DataRefImpl Rela) const { } template -ELFObjectFile::ELFObjectFile(std::unique_ptr Object, - std::error_code &EC) +ELFObjectFile::ELFObjectFile(MemoryBufferRef Object, std::error_code &EC) : ELFObjectFileBase( getELFType(static_cast(ELFT::TargetEndianness) == support::little, ELFT::Is64Bits), - std::move(Object)), - EF(Data->getBuffer(), EC) {} + Object), + EF(Data.getBuffer(), EC) {} template basic_symbol_iterator ELFObjectFile::symbol_begin_impl() const { diff --git a/include/llvm/Object/IRObjectFile.h b/include/llvm/Object/IRObjectFile.h index 9f27ffefce1..60a85981b7f 100644 --- a/include/llvm/Object/IRObjectFile.h +++ b/include/llvm/Object/IRObjectFile.h @@ -28,7 +28,7 @@ class IRObjectFile : public SymbolicFile { std::vector> AsmSymbols; public: - IRObjectFile(std::unique_ptr Object, std::unique_ptr M); + IRObjectFile(MemoryBufferRef Object, std::unique_ptr M); ~IRObjectFile(); void moveSymbolNext(DataRefImpl &Symb) const override; std::error_code printSymbolName(raw_ostream &OS, @@ -49,9 +49,8 @@ public: return v->isIR(); } - static ErrorOr - createIRObjectFile(std::unique_ptr Object, - LLVMContext &Context); + static ErrorOr createIRObjectFile(MemoryBufferRef Object, + LLVMContext &Context); }; } } diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index 3319b789942..e0b152b128c 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -56,8 +56,8 @@ public: MachO::load_command C; // The command itself. }; - MachOObjectFile(std::unique_ptr Object, bool IsLittleEndian, - bool Is64Bits, std::error_code &EC); + MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits, + std::error_code &EC); void moveSymbolNext(DataRefImpl &Symb) const override; std::error_code getSymbolName(DataRefImpl Symb, diff --git a/include/llvm/Object/MachOUniversal.h b/include/llvm/Object/MachOUniversal.h index e6677f5bf28..491565ba8e5 100644 --- a/include/llvm/Object/MachOUniversal.h +++ b/include/llvm/Object/MachOUniversal.h @@ -84,10 +84,8 @@ public: } }; - MachOUniversalBinary(std::unique_ptr Source, - std::error_code &ec); - static ErrorOr - create(std::unique_ptr Source); + MachOUniversalBinary(MemoryBufferRef Souce, std::error_code &EC); + static ErrorOr create(MemoryBufferRef Source); object_iterator begin_objects() const { return ObjectForArch(this, 0); diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index 100f65b47a0..a0b5380a291 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -187,10 +187,10 @@ class ObjectFile : public SymbolicFile { ObjectFile(const ObjectFile &other) LLVM_DELETED_FUNCTION; protected: - ObjectFile(unsigned int Type, std::unique_ptr Source); + ObjectFile(unsigned int Type, MemoryBufferRef Source); const uint8_t *base() const { - return reinterpret_cast(Data->getBufferStart()); + return reinterpret_cast(Data.getBufferStart()); } // These functions are for SymbolRef to call internally. The main goal of @@ -309,14 +309,13 @@ public: /// @param ObjectPath The path to the object file. ObjectPath.isObject must /// return true. /// @brief Create ObjectFile from path. - static ErrorOr> + static ErrorOr> createObjectFile(StringRef ObjectPath); static ErrorOr> - createObjectFile(std::unique_ptr &Object, - sys::fs::file_magic Type); + createObjectFile(MemoryBufferRef Object, sys::fs::file_magic Type); static ErrorOr> - createObjectFile(std::unique_ptr &Object) { + createObjectFile(MemoryBufferRef Object) { return createObjectFile(Object, sys::fs::file_magic::unknown); } @@ -326,13 +325,13 @@ public: } static ErrorOr> - createCOFFObjectFile(std::unique_ptr Object); + createCOFFObjectFile(MemoryBufferRef Object); static ErrorOr> - createELFObjectFile(std::unique_ptr &Object); + createELFObjectFile(MemoryBufferRef Object); static ErrorOr> - createMachOObjectFile(std::unique_ptr &Object); + createMachOObjectFile(MemoryBufferRef Object); }; // Inline function definitions. diff --git a/include/llvm/Object/SymbolicFile.h b/include/llvm/Object/SymbolicFile.h index 0057ed23abc..435799a34eb 100644 --- a/include/llvm/Object/SymbolicFile.h +++ b/include/llvm/Object/SymbolicFile.h @@ -116,7 +116,7 @@ const uint64_t UnknownAddressOrSize = ~0ULL; class SymbolicFile : public Binary { public: virtual ~SymbolicFile(); - SymbolicFile(unsigned int Type, std::unique_ptr Source); + SymbolicFile(unsigned int Type, MemoryBufferRef Source); // virtual interface. virtual void moveSymbolNext(DataRefImpl &Symb) const = 0; @@ -144,14 +144,14 @@ public: // construction aux. static ErrorOr> - createSymbolicFile(std::unique_ptr &Object, - sys::fs::file_magic Type, LLVMContext *Context); + createSymbolicFile(MemoryBufferRef Object, sys::fs::file_magic Type, + LLVMContext *Context); static ErrorOr> - createSymbolicFile(std::unique_ptr &Object) { + createSymbolicFile(MemoryBufferRef Object) { return createSymbolicFile(Object, sys::fs::file_magic::unknown, nullptr); } - static ErrorOr> + static ErrorOr> createSymbolicFile(StringRef ObjectPath); static inline bool classof(const Binary *v) { diff --git a/include/llvm/ProfileData/CoverageMappingReader.h b/include/llvm/ProfileData/CoverageMappingReader.h index 0ad38824df8..1d8b16e2532 100644 --- a/include/llvm/ProfileData/CoverageMappingReader.h +++ b/include/llvm/ProfileData/CoverageMappingReader.h @@ -157,7 +157,7 @@ public: private: std::error_code LastError; - std::unique_ptr Object; + object::OwningBinary Object; std::vector Filenames; std::vector MappingRecords; size_t CurrentRecord; diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h index 5bfd28b091f..acea48a8bf8 100644 --- a/include/llvm/Support/MemoryBuffer.h +++ b/include/llvm/Support/MemoryBuffer.h @@ -24,9 +24,11 @@ #include namespace llvm { -/// This interface provides simple read-only access to a block/ of memory, and +class MemoryBufferRef; + +/// This interface provides simple read-only access to a block of memory, and /// provides simple methods for reading files and standard input into a memory -/// buffer. In addition to basic access to the characters in the file, this +/// buffer. In addition to basic access to the characters in the file, this /// interface guarantees you can read one character past the end of the file, /// and that this character will read as '\0'. /// @@ -136,7 +138,27 @@ public: /// Return information on the memory mechanism used to support the /// MemoryBuffer. - virtual BufferKind getBufferKind() const = 0; + virtual BufferKind getBufferKind() const = 0; + + MemoryBufferRef getMemBufferRef() const; +}; + +class MemoryBufferRef { + StringRef Buffer; + StringRef Identifier; + +public: + MemoryBufferRef() {} + MemoryBufferRef(StringRef Buffer, StringRef Identifier) + : Buffer(Buffer), Identifier(Identifier) {} + + StringRef getBuffer() const { return Buffer; } + + StringRef getBufferIdentifier() const { return Identifier; } + + const char *getBufferStart() const { return Buffer.begin(); } + const char *getBufferEnd() const { return Buffer.end(); } + size_t getBufferSize() const { return Buffer.size(); } }; // Create wrappers for C Binding types (see CBindingWrapping.h). diff --git a/lib/DebugInfo/DWARFUnit.cpp b/lib/DebugInfo/DWARFUnit.cpp index d52821602d2..6ed3e04b7bf 100644 --- a/lib/DebugInfo/DWARFUnit.cpp +++ b/lib/DebugInfo/DWARFUnit.cpp @@ -261,12 +261,12 @@ bool DWARFUnit::parseDWO() { sys::path::append(AbsolutePath, CompilationDir); } sys::path::append(AbsolutePath, DWOFileName); - ErrorOr> DWOFile = + ErrorOr> DWOFile = object::ObjectFile::createObjectFile(AbsolutePath); if (!DWOFile) return false; // Reset DWOHolder. - DWO = llvm::make_unique(std::move(*DWOFile)); + DWO = llvm::make_unique(std::move(DWOFile->getBinary())); DWARFUnit *DWOCU = DWO->getUnit(); // Verify that compile unit in .dwo file is valid. if (!DWOCU || DWOCU->getDWOId() != getDWOId()) { diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index 4ef6e73c131..f112e08b42b 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -124,7 +124,7 @@ void ExecutionEngine::addObjectFile(std::unique_ptr O) { llvm_unreachable("ExecutionEngine subclass doesn't implement addObjectFile."); } -void ExecutionEngine::addArchive(std::unique_ptr A) { +void ExecutionEngine::addArchive(object::OwningBinary A) { llvm_unreachable("ExecutionEngine subclass doesn't implement addArchive."); } diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/lib/ExecutionEngine/MCJIT/MCJIT.cpp index 65e2aba29ee..9583fb2add6 100644 --- a/lib/ExecutionEngine/MCJIT/MCJIT.cpp +++ b/lib/ExecutionEngine/MCJIT/MCJIT.cpp @@ -119,7 +119,7 @@ void MCJIT::addObjectFile(std::unique_ptr Obj) { NotifyObjectEmitted(*LoadedObject); } -void MCJIT::addArchive(std::unique_ptr A) { +void MCJIT::addArchive(object::OwningBinary A) { Archives.push_back(std::move(A)); } @@ -161,8 +161,8 @@ ObjectBufferStream* MCJIT::emitObject(Module *M) { if (ObjCache) { // MemoryBuffer is a thin wrapper around the actual memory, so it's OK // to create a temporary object here and delete it after the call. - std::unique_ptr MB = CompiledObject->getMemBuffer(); - ObjCache->notifyObjectCompiled(M, MB.get()); + MemoryBufferRef MB = CompiledObject->getMemBuffer(); + ObjCache->notifyObjectCompiled(M, MB); } return CompiledObject.release(); @@ -295,7 +295,8 @@ uint64_t MCJIT::getSymbolAddress(const std::string &Name, if (Addr) return Addr; - for (std::unique_ptr &A : Archives) { + for (object::OwningBinary &OB : Archives) { + object::Archive *A = OB.getBinary().get(); // Look for our symbols in each Archive object::Archive::child_iterator ChildIt = A->findSym(Name); if (ChildIt != A->child_end()) { diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.h b/lib/ExecutionEngine/MCJIT/MCJIT.h index 6a814db5ef2..4bf6d2939e7 100644 --- a/lib/ExecutionEngine/MCJIT/MCJIT.h +++ b/lib/ExecutionEngine/MCJIT/MCJIT.h @@ -216,7 +216,7 @@ class MCJIT : public ExecutionEngine { OwningModuleContainer OwnedModules; - SmallVector, 2> Archives; + SmallVector, 2> Archives; typedef SmallVector LoadedObjectList; LoadedObjectList LoadedObjects; @@ -240,7 +240,7 @@ public: /// @{ void addModule(std::unique_ptr M) override; void addObjectFile(std::unique_ptr O) override; - void addArchive(std::unique_ptr O) override; + void addArchive(object::OwningBinary O) override; bool removeModule(Module *M) override; /// FindFunctionNamed - Search all of the active modules to find the one that diff --git a/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h b/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h index 3d65eaaacd7..ddf0e89b408 100644 --- a/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h +++ b/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h @@ -48,7 +48,7 @@ public: { // FIXME: error checking? createObjectFile returns an ErrorOr // and should probably be checked for failure. - std::unique_ptr Buf = Buffer->getMemBuffer(); + MemoryBufferRef Buf = Buffer->getMemBuffer(); ObjFile = std::move(object::ObjectFile::createObjectFile(Buf).get()); } ObjectImageCommon(std::unique_ptr Input) diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index abf29a7a960..b3c94b38628 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -55,9 +55,9 @@ template class DyldELFObject : public ELFObjectFile { public: DyldELFObject(std::unique_ptr UnderlyingFile, - std::unique_ptr Wrapper, std::error_code &ec); + MemoryBufferRef Wrapper, std::error_code &ec); - DyldELFObject(std::unique_ptr Wrapper, std::error_code &ec); + DyldELFObject(MemoryBufferRef Wrapper, std::error_code &ec); void updateSectionAddress(const SectionRef &Sec, uint64_t Addr); void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr); @@ -109,17 +109,15 @@ public: // actual memory. Ultimately, the Binary parent class will take ownership of // this MemoryBuffer object but not the underlying memory. template -DyldELFObject::DyldELFObject(std::unique_ptr Wrapper, - std::error_code &EC) - : ELFObjectFile(std::move(Wrapper), EC) { +DyldELFObject::DyldELFObject(MemoryBufferRef Wrapper, std::error_code &EC) + : ELFObjectFile(Wrapper, EC) { this->isDyldELFObject = true; } template DyldELFObject::DyldELFObject(std::unique_ptr UnderlyingFile, - std::unique_ptr Wrapper, - std::error_code &EC) - : ELFObjectFile(std::move(Wrapper), EC), + MemoryBufferRef Wrapper, std::error_code &EC) + : ELFObjectFile(Wrapper, EC), UnderlyingFile(std::move(UnderlyingFile)) { this->isDyldELFObject = true; } @@ -185,29 +183,28 @@ RuntimeDyldELF::createObjectImageFromFile(std::unique_ptr Ob return nullptr; std::error_code ec; - std::unique_ptr Buffer( - MemoryBuffer::getMemBuffer(ObjFile->getData(), "", false)); + MemoryBufferRef Buffer = ObjFile->getMemoryBufferRef(); if (ObjFile->getBytesInAddress() == 4 && ObjFile->isLittleEndian()) { auto Obj = llvm::make_unique>>( - std::move(ObjFile), std::move(Buffer), ec); + std::move(ObjFile), Buffer, ec); return new ELFObjectImage>( nullptr, std::move(Obj)); } else if (ObjFile->getBytesInAddress() == 4 && !ObjFile->isLittleEndian()) { auto Obj = llvm::make_unique>>( - std::move(ObjFile), std::move(Buffer), ec); + std::move(ObjFile), Buffer, ec); return new ELFObjectImage>(nullptr, std::move(Obj)); } else if (ObjFile->getBytesInAddress() == 8 && !ObjFile->isLittleEndian()) { auto Obj = llvm::make_unique>>( - std::move(ObjFile), std::move(Buffer), ec); + std::move(ObjFile), Buffer, ec); return new ELFObjectImage>(nullptr, std::move(Obj)); } else if (ObjFile->getBytesInAddress() == 8 && ObjFile->isLittleEndian()) { auto Obj = llvm::make_unique>>( - std::move(ObjFile), std::move(Buffer), ec); + std::move(ObjFile), Buffer, ec); return new ELFObjectImage>( nullptr, std::move(Obj)); } else @@ -222,31 +219,31 @@ ObjectImage *RuntimeDyldELF::createObjectImage(ObjectBuffer *Buffer) { (uint8_t)Buffer->getBufferStart()[ELF::EI_DATA]); std::error_code ec; - std::unique_ptr Buf = Buffer->getMemBuffer(); + MemoryBufferRef Buf = Buffer->getMemBuffer(); if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) { auto Obj = llvm::make_unique>>( - std::move(Buf), ec); + Buf, ec); return new ELFObjectImage>( Buffer, std::move(Obj)); } else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB) { auto Obj = - llvm::make_unique>>( - std::move(Buf), ec); + llvm::make_unique>>(Buf, + ec); return new ELFObjectImage>(Buffer, std::move(Obj)); } else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB) { auto Obj = llvm::make_unique>>( - std::move(Buf), ec); + Buf, ec); return new ELFObjectImage>(Buffer, std::move(Obj)); } else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) { auto Obj = - llvm::make_unique>>( - std::move(Buf), ec); + llvm::make_unique>>(Buf, + ec); return new ELFObjectImage>(Buffer, std::move(Obj)); } else llvm_unreachable("Unexpected ELF format"); diff --git a/lib/LTO/LTOModule.cpp b/lib/LTO/LTOModule.cpp index 5083a59900a..083af9e552e 100644 --- a/lib/LTO/LTOModule.cpp +++ b/lib/LTO/LTOModule.cpp @@ -77,7 +77,8 @@ LTOModule *LTOModule::createFromFile(const char *path, TargetOptions options, errMsg = EC.message(); return nullptr; } - return makeLTOModule(std::move(BufferOrErr.get()), options, errMsg); + std::unique_ptr Buffer = std::move(BufferOrErr.get()); + return makeLTOModule(Buffer->getMemBufferRef(), options, errMsg); } LTOModule *LTOModule::createFromOpenFile(int fd, const char *path, size_t size, @@ -96,23 +97,30 @@ LTOModule *LTOModule::createFromOpenFileSlice(int fd, const char *path, errMsg = EC.message(); return nullptr; } - return makeLTOModule(std::move(BufferOrErr.get()), options, errMsg); + std::unique_ptr Buffer = std::move(BufferOrErr.get()); + return makeLTOModule(Buffer->getMemBufferRef(), options, errMsg); } LTOModule *LTOModule::createFromBuffer(const void *mem, size_t length, TargetOptions options, std::string &errMsg, StringRef path) { - std::unique_ptr buffer(makeBuffer(mem, length, path)); - if (!buffer) - return nullptr; - return makeLTOModule(std::move(buffer), options, errMsg); + StringRef Data((char *)mem, length); + MemoryBufferRef Buffer(Data, path); + return makeLTOModule(Buffer, options, errMsg); } -LTOModule *LTOModule::makeLTOModule(std::unique_ptr Buffer, +LTOModule *LTOModule::makeLTOModule(MemoryBufferRef Buffer, TargetOptions options, std::string &errMsg) { + StringRef Data = Buffer.getBuffer(); + StringRef FileName = Buffer.getBufferIdentifier(); + std::unique_ptr MemBuf( + makeBuffer(Data.begin(), Data.size(), FileName)); + if (!MemBuf) + return nullptr; + ErrorOr MOrErr = - getLazyBitcodeModule(Buffer.get(), getGlobalContext()); + getLazyBitcodeModule(MemBuf.get(), getGlobalContext()); if (std::error_code EC = MOrErr.getError()) { errMsg = EC.message(); return nullptr; @@ -150,7 +158,7 @@ LTOModule *LTOModule::makeLTOModule(std::unique_ptr Buffer, M->setDataLayout(target->getSubtargetImpl()->getDataLayout()); std::unique_ptr IRObj( - new object::IRObjectFile(std::move(Buffer), std::move(M))); + new object::IRObjectFile(Buffer, std::move(M))); LTOModule *Ret = new LTOModule(std::move(IRObj), target); diff --git a/lib/Object/Archive.cpp b/lib/Object/Archive.cpp index 45156f1311e..070fe812eec 100644 --- a/lib/Object/Archive.cpp +++ b/lib/Object/Archive.cpp @@ -109,7 +109,7 @@ Archive::Child Archive::Child::getNext() const { const char *NextLoc = Data.data() + SpaceToSkip; // Check to see if this is past the end of the archive. - if (NextLoc >= Parent->Data->getBufferEnd()) + if (NextLoc >= Parent->Data.getBufferEnd()) return Child(Parent, nullptr); return Child(Parent, NextLoc); @@ -159,45 +159,36 @@ ErrorOr Archive::Child::getName() const { return name; } -ErrorOr> -Archive::Child::getMemoryBuffer(bool FullPath) const { +ErrorOr Archive::Child::getMemoryBufferRef() const { ErrorOr NameOrErr = getName(); if (std::error_code EC = NameOrErr.getError()) return EC; StringRef Name = NameOrErr.get(); - SmallString<128> Path; - std::unique_ptr Ret(MemoryBuffer::getMemBuffer( - getBuffer(), - FullPath - ? (Twine(Parent->getFileName()) + "(" + Name + ")").toStringRef(Path) - : Name, - false)); - return std::move(Ret); + return MemoryBufferRef(getBuffer(), Name); } ErrorOr> Archive::Child::getAsBinary(LLVMContext *Context) const { - ErrorOr> BuffOrErr = getMemoryBuffer(); + ErrorOr BuffOrErr = getMemoryBufferRef(); if (std::error_code EC = BuffOrErr.getError()) return EC; - return createBinary(std::move(*BuffOrErr), Context); + return createBinary(BuffOrErr.get(), Context); } -ErrorOr> -Archive::create(std::unique_ptr Source) { +ErrorOr> Archive::create(MemoryBufferRef Source) { std::error_code EC; - std::unique_ptr Ret(new Archive(std::move(Source), EC)); + std::unique_ptr Ret(new Archive(Source, EC)); if (EC) return EC; return std::move(Ret); } -Archive::Archive(std::unique_ptr Source, std::error_code &ec) - : Binary(Binary::ID_Archive, std::move(Source)), SymbolTable(child_end()) { +Archive::Archive(MemoryBufferRef Source, std::error_code &ec) + : Binary(Binary::ID_Archive, Source), SymbolTable(child_end()) { // Check for sufficient magic. - if (Data->getBufferSize() < 8 || - StringRef(Data->getBufferStart(), 8) != Magic) { + if (Data.getBufferSize() < 8 || + StringRef(Data.getBufferStart(), 8) != Magic) { ec = object_error::invalid_file_type; return; } @@ -311,13 +302,13 @@ Archive::Archive(std::unique_ptr Source, std::error_code &ec) } Archive::child_iterator Archive::child_begin(bool SkipInternal) const { - if (Data->getBufferSize() == 8) // empty archive. + if (Data.getBufferSize() == 8) // empty archive. return child_end(); if (SkipInternal) return FirstRegular; - const char *Loc = Data->getBufferStart() + strlen(Magic); + const char *Loc = Data.getBufferStart() + strlen(Magic); Child c(this, Loc); return c; } diff --git a/lib/Object/Binary.cpp b/lib/Object/Binary.cpp index 89e9d732ce9..d23ee590569 100644 --- a/lib/Object/Binary.cpp +++ b/lib/Object/Binary.cpp @@ -27,25 +27,22 @@ using namespace object; Binary::~Binary() {} -Binary::Binary(unsigned int Type, std::unique_ptr Source) - : TypeID(Type), Data(std::move(Source)) {} +Binary::Binary(unsigned int Type, MemoryBufferRef Source) + : TypeID(Type), Data(Source) {} -StringRef Binary::getData() const { - return Data->getBuffer(); -} +StringRef Binary::getData() const { return Data.getBuffer(); } -StringRef Binary::getFileName() const { - return Data->getBufferIdentifier(); -} +StringRef Binary::getFileName() const { return Data.getBufferIdentifier(); } + +MemoryBufferRef Binary::getMemoryBufferRef() const { return Data; } -ErrorOr> -object::createBinary(std::unique_ptr Buffer, - LLVMContext *Context) { - sys::fs::file_magic Type = sys::fs::identify_magic(Buffer->getBuffer()); +ErrorOr> object::createBinary(MemoryBufferRef Buffer, + LLVMContext *Context) { + sys::fs::file_magic Type = sys::fs::identify_magic(Buffer.getBuffer()); switch (Type) { case sys::fs::file_magic::archive: - return Archive::create(std::move(Buffer)); + return Archive::create(Buffer); case sys::fs::file_magic::elf_relocatable: case sys::fs::file_magic::elf_executable: case sys::fs::file_magic::elf_shared_object: @@ -66,7 +63,7 @@ object::createBinary(std::unique_ptr Buffer, case sys::fs::file_magic::bitcode: return ObjectFile::createSymbolicFile(Buffer, Type, Context); case sys::fs::file_magic::macho_universal_binary: - return MachOUniversalBinary::create(std::move(Buffer)); + return MachOUniversalBinary::create(Buffer); case sys::fs::file_magic::unknown: case sys::fs::file_magic::windows_resource: // Unrecognized object file format. @@ -75,10 +72,18 @@ object::createBinary(std::unique_ptr Buffer, llvm_unreachable("Unexpected Binary File Type"); } -ErrorOr> object::createBinary(StringRef Path) { +ErrorOr> object::createBinary(StringRef Path) { ErrorOr> FileOrErr = MemoryBuffer::getFileOrSTDIN(Path); if (std::error_code EC = FileOrErr.getError()) return EC; - return createBinary(std::move(*FileOrErr)); + std::unique_ptr &Buffer = FileOrErr.get(); + + ErrorOr> BinOrErr = + createBinary(Buffer->getMemBufferRef()); + if (std::error_code EC = BinOrErr.getError()) + return EC; + std::unique_ptr &Bin = BinOrErr.get(); + + return OwningBinary(std::move(Bin), std::move(Buffer)); } diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp index 717f019509b..0c2ec116804 100644 --- a/lib/Object/COFFObjectFile.cpp +++ b/lib/Object/COFFObjectFile.cpp @@ -31,8 +31,7 @@ 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, - uint64_t Size) { +static bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Size) { if (M.getBufferSize() < Size) { EC = object_error::unexpected_eof; return false; @@ -43,7 +42,7 @@ static bool checkSize(const MemoryBuffer &M, std::error_code &EC, // Sets Obj unless any bytes in [addr, addr + size) fall outsize of m. // 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, MemoryBufferRef M, const uint8_t *Ptr, const size_t Size = sizeof(T)) { uintptr_t Addr = uintptr_t(Ptr); @@ -397,7 +396,7 @@ relocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const { // Initialize the pointer to the symbol table. 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; @@ -408,12 +407,11 @@ 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 +509,14 @@ std::error_code COFFObjectFile::initExportTablePtr() { return object_error::success; } -COFFObjectFile::COFFObjectFile(std::unique_ptr Object, - std::error_code &EC) - : ObjectFile(Binary::ID_COFF, std::move(Object)), COFFHeader(nullptr), +COFFObjectFile::COFFObjectFile(MemoryBufferRef 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))) + if (!checkSize(Data, EC, sizeof(coff_file_header))) return; // The current location in the file where we are looking at. @@ -533,7 +530,7 @@ COFFObjectFile::COFFObjectFile(std::unique_ptr Object, 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)) + if (!checkSize(Data, EC, 0x3c + 8)) return; CurPtr = *reinterpret_cast(base() + 0x3c); // Check the PE magic bytes. ("PE\0\0") @@ -545,13 +542,13 @@ COFFObjectFile::COFFObjectFile(std::unique_ptr Object, 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; @@ -569,7 +566,7 @@ COFFObjectFile::COFFObjectFile(std::unique_ptr Object, EC = object_error::parse_failed; return; } - if ((EC = getObject(DataDirectory, *Data, DataDirAddr, DataDirSize))) + if ((EC = getObject(DataDirectory, Data, DataDirAddr, DataDirSize))) return; CurPtr += COFFHeader->SizeOfOptionalHeader; } @@ -577,7 +574,7 @@ COFFObjectFile::COFFObjectFile(std::unique_ptr Object, if (COFFHeader->isImportLibrary()) return; - if ((EC = getObject(SectionTable, *Data, base() + CurPtr, + if ((EC = getObject(SectionTable, Data, base() + CurPtr, COFFHeader->NumberOfSections * sizeof(coff_section)))) return; @@ -826,7 +823,7 @@ COFFObjectFile::getSectionContents(const coff_section *Sec, // data, as there's nothing that says that is not allowed. uintptr_t ConStart = uintptr_t(base()) + Sec->PointerToRawData; uintptr_t ConEnd = ConStart + Sec->SizeOfRawData; - if (ConEnd > uintptr_t(Data->getBufferEnd())) + if (ConEnd > uintptr_t(Data.getBufferEnd())) return object_error::parse_failed; Res = ArrayRef(reinterpret_cast(ConStart), Sec->SizeOfRawData); @@ -1092,10 +1089,9 @@ ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const { } ErrorOr> -ObjectFile::createCOFFObjectFile(std::unique_ptr Object) { +ObjectFile::createCOFFObjectFile(MemoryBufferRef Object) { std::error_code EC; - std::unique_ptr Ret( - new COFFObjectFile(std::move(Object), EC)); + std::unique_ptr Ret(new COFFObjectFile(Object, EC)); if (EC) return EC; return std::move(Ret); diff --git a/lib/Object/ELFObjectFile.cpp b/lib/Object/ELFObjectFile.cpp index 2e5e3c8836c..8ccb2538ac7 100644 --- a/lib/Object/ELFObjectFile.cpp +++ b/lib/Object/ELFObjectFile.cpp @@ -17,65 +17,56 @@ namespace llvm { using namespace object; -ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, - std::unique_ptr Source) - : ObjectFile(Type, std::move(Source)) {} +ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source) + : ObjectFile(Type, Source) {} ErrorOr> -ObjectFile::createELFObjectFile(std::unique_ptr &Obj) { +ObjectFile::createELFObjectFile(MemoryBufferRef Obj) { std::pair Ident = - getElfArchType(Obj->getBuffer()); + getElfArchType(Obj.getBuffer()); std::size_t MaxAlignment = - 1ULL << countTrailingZeros(uintptr_t(Obj->getBufferStart())); + 1ULL << countTrailingZeros(uintptr_t(Obj.getBufferStart())); std::error_code EC; std::unique_ptr R; if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) #if !LLVM_IS_UNALIGNED_ACCESS_FAST if (MaxAlignment >= 4) - R.reset(new ELFObjectFile>( - std::move(Obj), EC)); + R.reset(new ELFObjectFile>(Obj, EC)); else #endif if (MaxAlignment >= 2) - R.reset(new ELFObjectFile>( - std::move(Obj), EC)); + 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>(std::move(Obj), - EC)); + R.reset(new ELFObjectFile>(Obj, EC)); else #endif if (MaxAlignment >= 2) - R.reset(new ELFObjectFile>(std::move(Obj), - EC)); + 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>(std::move(Obj), - EC)); + R.reset(new ELFObjectFile>(Obj, EC)); else #endif if (MaxAlignment >= 2) - R.reset(new ELFObjectFile>(std::move(Obj), - EC)); + 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>( - std::move(Obj), EC)); + R.reset(new ELFObjectFile>(Obj, EC)); else #endif if (MaxAlignment >= 2) - R.reset(new ELFObjectFile>( - std::move(Obj), EC)); + R.reset(new ELFObjectFile>(Obj, EC)); else return object_error::parse_failed; } diff --git a/lib/Object/IRObjectFile.cpp b/lib/Object/IRObjectFile.cpp index 5323d9277ee..d6b4b6bd257 100644 --- a/lib/Object/IRObjectFile.cpp +++ b/lib/Object/IRObjectFile.cpp @@ -32,9 +32,8 @@ using namespace llvm; using namespace object; -IRObjectFile::IRObjectFile(std::unique_ptr Object, - std::unique_ptr Mod) - : SymbolicFile(Binary::ID_IR, std::move(Object)), M(std::move(Mod)) { +IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr Mod) + : SymbolicFile(Binary::ID_IR, Object), M(std::move(Mod)) { // If we have a DataLayout, setup a mangler. const DataLayout *DL = M->getDataLayout(); if (!DL) @@ -114,9 +113,6 @@ IRObjectFile::IRObjectFile(std::unique_ptr Object, } IRObjectFile::~IRObjectFile() { - GVMaterializer *GVM = M->getMaterializer(); - if (GVM) - GVM->releaseBuffer(); } static const GlobalValue *getGV(DataRefImpl &Symb) { @@ -268,12 +264,20 @@ basic_symbol_iterator IRObjectFile::symbol_end_impl() const { return basic_symbol_iterator(BasicSymbolRef(Ret, this)); } -ErrorOr llvm::object::IRObjectFile::createIRObjectFile( - std::unique_ptr Object, LLVMContext &Context) { - ErrorOr MOrErr = getLazyBitcodeModule(Object.get(), Context); +ErrorOr +llvm::object::IRObjectFile::createIRObjectFile(MemoryBufferRef Object, + LLVMContext &Context) { + + StringRef Data = Object.getBuffer(); + StringRef FileName = Object.getBufferIdentifier(); + std::unique_ptr Buff( + MemoryBuffer::getMemBuffer(Data, FileName, false)); + + ErrorOr MOrErr = getLazyBitcodeModule(Buff.get(), Context); if (std::error_code EC = MOrErr.getError()) return EC; + Buff.release(); std::unique_ptr M(MOrErr.get()); - return new IRObjectFile(std::move(Object), std::move(M)); + return new IRObjectFile(Object, std::move(M)); } diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 5bcb4bae8ea..746fd7391bc 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -222,10 +222,9 @@ static uint32_t getSectionFlags(const MachOObjectFile *O, return Sect.flags; } -MachOObjectFile::MachOObjectFile(std::unique_ptr Object, - bool IsLittleEndian, bool Is64bits, - std::error_code &EC) - : ObjectFile(getMachOType(IsLittleEndian, Is64bits), std::move(Object)), +MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, + bool Is64bits, std::error_code &EC) + : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object), SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr), DataInCodeLoadCmd(nullptr) { uint32_t LoadCommandCount = this->getHeader().ncmds; @@ -1776,18 +1775,18 @@ bool MachOObjectFile::isRelocatableObject() const { } ErrorOr> -ObjectFile::createMachOObjectFile(std::unique_ptr &Buffer) { - StringRef Magic = Buffer->getBuffer().slice(0, 4); +ObjectFile::createMachOObjectFile(MemoryBufferRef 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(std::move(Buffer), false, false, EC)); + Ret.reset(new MachOObjectFile(Buffer, false, false, EC)); else if (Magic == "\xCE\xFA\xED\xFE") - Ret.reset(new MachOObjectFile(std::move(Buffer), true, false, EC)); + Ret.reset(new MachOObjectFile(Buffer, true, false, EC)); else if (Magic == "\xFE\xED\xFA\xCF") - Ret.reset(new MachOObjectFile(std::move(Buffer), false, true, EC)); + Ret.reset(new MachOObjectFile(Buffer, false, true, EC)); else if (Magic == "\xCF\xFA\xED\xFE") - Ret.reset(new MachOObjectFile(std::move(Buffer), true, true, EC)); + Ret.reset(new MachOObjectFile(Buffer, true, true, EC)); else return object_error::parse_failed; diff --git a/lib/Object/MachOUniversal.cpp b/lib/Object/MachOUniversal.cpp index ece652b4c09..8d24403d033 100644 --- a/lib/Object/MachOUniversal.cpp +++ b/lib/Object/MachOUniversal.cpp @@ -72,9 +72,8 @@ MachOUniversalBinary::ObjectForArch::getAsObjectFile() const { if (Parent) { StringRef ParentData = Parent->getData(); StringRef ObjectData = ParentData.substr(Header.offset, Header.size); - std::string ObjectName = Parent->getFileName().str(); - std::unique_ptr ObjBuffer( - MemoryBuffer::getMemBuffer(ObjectData, ObjectName, false)); + StringRef ObjectName = Parent->getFileName().str(); + MemoryBufferRef ObjBuffer(ObjectData, ObjectName); return ObjectFile::createMachOObjectFile(ObjBuffer); } return object_error::parse_failed; @@ -86,10 +85,8 @@ std::error_code MachOUniversalBinary::ObjectForArch::getAsArchive( StringRef ParentData = Parent->getData(); StringRef ObjectData = ParentData.substr(Header.offset, Header.size); std::string ObjectName = Parent->getFileName().str(); - std::unique_ptr ObjBuffer( - MemoryBuffer::getMemBuffer(ObjectData, ObjectName, false)); - ErrorOr> Obj = - Archive::create(std::move(ObjBuffer)); + MemoryBufferRef ObjBuffer(ObjectData, ObjectName); + ErrorOr> Obj = Archive::create(ObjBuffer); if (std::error_code EC = Obj.getError()) return EC; Result = std::move(Obj.get()); @@ -101,20 +98,19 @@ std::error_code MachOUniversalBinary::ObjectForArch::getAsArchive( void MachOUniversalBinary::anchor() { } ErrorOr -MachOUniversalBinary::create(std::unique_ptr Source) { +MachOUniversalBinary::create(MemoryBufferRef Source) { std::error_code EC; std::unique_ptr Ret( - new MachOUniversalBinary(std::move(Source), EC)); + new MachOUniversalBinary(Source, EC)); if (EC) return EC; return Ret.release(); } -MachOUniversalBinary::MachOUniversalBinary(std::unique_ptr Source, +MachOUniversalBinary::MachOUniversalBinary(MemoryBufferRef Source, std::error_code &ec) - : Binary(Binary::ID_MachOUniversalBinary, std::move(Source)), - NumberOfObjects(0) { - if (Data->getBufferSize() < sizeof(MachO::fat_header)) { + : Binary(Binary::ID_MachOUniversalBinary, Source), NumberOfObjects(0) { + if (Data.getBufferSize() < sizeof(MachO::fat_header)) { ec = object_error::invalid_file_type; return; } diff --git a/lib/Object/Object.cpp b/lib/Object/Object.cpp index 2b3861b4bdc..4d3478bc14f 100644 --- a/lib/Object/Object.cpp +++ b/lib/Object/Object.cpp @@ -19,12 +19,13 @@ using namespace llvm; using namespace object; -inline ObjectFile *unwrap(LLVMObjectFileRef OF) { - return reinterpret_cast(OF); +inline OwningBinary *unwrap(LLVMObjectFileRef OF) { + return reinterpret_cast *>(OF); } -inline LLVMObjectFileRef wrap(const ObjectFile *OF) { - return reinterpret_cast(const_cast(OF)); +inline LLVMObjectFileRef wrap(const OwningBinary *OF) { + return reinterpret_cast( + const_cast *>(OF)); } inline section_iterator *unwrap(LLVMSectionIteratorRef SI) { @@ -61,10 +62,12 @@ wrap(const relocation_iterator *SI) { LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) { std::unique_ptr Buf(unwrap(MemBuf)); ErrorOr> ObjOrErr( - ObjectFile::createObjectFile(Buf)); - Buf.release(); - ObjectFile *Obj = ObjOrErr ? ObjOrErr.get().release() : nullptr; - return wrap(Obj); + ObjectFile::createObjectFile(Buf->getMemBufferRef())); + std::unique_ptr Obj; + if (ObjOrErr) + Obj = std::move(ObjOrErr.get()); + auto *Ret = new OwningBinary(std::move(Obj), std::move(Buf)); + return wrap(Ret); } void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) { @@ -72,8 +75,9 @@ void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) { } // ObjectFile Section iterators -LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef ObjectFile) { - section_iterator SI = unwrap(ObjectFile)->section_begin(); +LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef OF) { + OwningBinary *OB = unwrap(OF); + section_iterator SI = OB->getBinary()->section_begin(); return wrap(new section_iterator(SI)); } @@ -81,9 +85,10 @@ void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) { delete unwrap(SI); } -LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef ObjectFile, - LLVMSectionIteratorRef SI) { - return (*unwrap(SI) == unwrap(ObjectFile)->section_end()) ? 1 : 0; +LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef OF, + LLVMSectionIteratorRef SI) { + OwningBinary *OB = unwrap(OF); + return (*unwrap(SI) == OB->getBinary()->section_end()) ? 1 : 0; } void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) { @@ -97,8 +102,9 @@ void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect, } // ObjectFile Symbol iterators -LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef ObjectFile) { - symbol_iterator SI = unwrap(ObjectFile)->symbol_begin(); +LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef OF) { + OwningBinary *OB = unwrap(OF); + symbol_iterator SI = OB->getBinary()->symbol_begin(); return wrap(new symbol_iterator(SI)); } @@ -106,9 +112,10 @@ void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI) { delete unwrap(SI); } -LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef ObjectFile, - LLVMSymbolIteratorRef SI) { - return (*unwrap(SI) == unwrap(ObjectFile)->symbol_end()) ? 1 : 0; +LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef OF, + LLVMSymbolIteratorRef SI) { + OwningBinary *OB = unwrap(OF); + return (*unwrap(SI) == OB->getBinary()->symbol_end()) ? 1 : 0; } void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) { diff --git a/lib/Object/ObjectFile.cpp b/lib/Object/ObjectFile.cpp index 0e77541dec5..9565d02f35a 100644 --- a/lib/Object/ObjectFile.cpp +++ b/lib/Object/ObjectFile.cpp @@ -25,8 +25,8 @@ using namespace object; void ObjectFile::anchor() { } -ObjectFile::ObjectFile(unsigned int Type, std::unique_ptr Source) - : SymbolicFile(Type, std::move(Source)) {} +ObjectFile::ObjectFile(unsigned int Type, MemoryBufferRef Source) + : SymbolicFile(Type, Source) {} std::error_code ObjectFile::printSymbolName(raw_ostream &OS, DataRefImpl Symb) const { @@ -48,10 +48,10 @@ section_iterator ObjectFile::getRelocatedSection(DataRefImpl Sec) const { } ErrorOr> -ObjectFile::createObjectFile(std::unique_ptr &Object, - sys::fs::file_magic Type) { +ObjectFile::createObjectFile(MemoryBufferRef Object, sys::fs::file_magic Type) { + StringRef Data = Object.getBuffer(); if (Type == sys::fs::file_magic::unknown) - Type = sys::fs::identify_magic(Object->getBuffer()); + Type = sys::fs::identify_magic(Data); switch (Type) { case sys::fs::file_magic::unknown: @@ -79,16 +79,24 @@ ObjectFile::createObjectFile(std::unique_ptr &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(std::move(Object)); + return createCOFFObjectFile(Object); } llvm_unreachable("Unexpected Object File Type"); } -ErrorOr> +ErrorOr> ObjectFile::createObjectFile(StringRef ObjectPath) { ErrorOr> FileOrErr = MemoryBuffer::getFile(ObjectPath); if (std::error_code EC = FileOrErr.getError()) return EC; - return createObjectFile(FileOrErr.get()); + std::unique_ptr Buffer = std::move(FileOrErr.get()); + + ErrorOr> ObjOrErr = + createObjectFile(Buffer->getMemBufferRef()); + if (std::error_code EC = ObjOrErr.getError()) + return EC; + std::unique_ptr Obj = std::move(ObjOrErr.get()); + + return OwningBinary(std::move(Obj), std::move(Buffer)); } diff --git a/lib/Object/SymbolicFile.cpp b/lib/Object/SymbolicFile.cpp index 790d5a75ba7..f8dd4b33a39 100644 --- a/lib/Object/SymbolicFile.cpp +++ b/lib/Object/SymbolicFile.cpp @@ -19,23 +19,21 @@ using namespace llvm; using namespace object; -SymbolicFile::SymbolicFile(unsigned int Type, - std::unique_ptr Source) - : Binary(Type, std::move(Source)) {} +SymbolicFile::SymbolicFile(unsigned int Type, MemoryBufferRef Source) + : Binary(Type, Source) {} SymbolicFile::~SymbolicFile() {} -ErrorOr> -SymbolicFile::createSymbolicFile(std::unique_ptr &Object, - sys::fs::file_magic Type, - LLVMContext *Context) { +ErrorOr> SymbolicFile::createSymbolicFile( + MemoryBufferRef Object, sys::fs::file_magic Type, LLVMContext *Context) { + StringRef Data = Object.getBuffer(); if (Type == sys::fs::file_magic::unknown) - Type = sys::fs::identify_magic(Object->getBuffer()); + Type = sys::fs::identify_magic(Data); switch (Type) { case sys::fs::file_magic::bitcode: if (Context) - return IRObjectFile::createIRObjectFile(std::move(Object), *Context); + return IRObjectFile::createIRObjectFile(Object, *Context); // Fallthrough case sys::fs::file_magic::unknown: case sys::fs::file_magic::archive: diff --git a/lib/ProfileData/CoverageMappingReader.cpp b/lib/ProfileData/CoverageMappingReader.cpp index c8108d4ce99..965e085f9d9 100644 --- a/lib/ProfileData/CoverageMappingReader.cpp +++ b/lib/ProfileData/CoverageMappingReader.cpp @@ -292,11 +292,13 @@ ObjectFileCoverageMappingReader::ObjectFileCoverageMappingReader( ObjectFileCoverageMappingReader::ObjectFileCoverageMappingReader( std::unique_ptr &ObjectBuffer, sys::fs::file_magic Type) : CurrentRecord(0) { - auto File = llvm::object::ObjectFile::createObjectFile(ObjectBuffer, Type); + auto File = object::ObjectFile::createObjectFile( + ObjectBuffer->getMemBufferRef(), Type); if (!File) error(File.getError()); else - Object = std::move(File.get()); + Object = OwningBinary(std::move(File.get()), + std::move(ObjectBuffer)); } namespace { @@ -429,16 +431,17 @@ std::error_code readCoverageMappingData( } std::error_code ObjectFileCoverageMappingReader::readHeader() { - if (!Object) + ObjectFile *OF = Object.getBinary().get(); + if (!OF) return getError(); - auto BytesInAddress = Object->getBytesInAddress(); + auto BytesInAddress = OF->getBytesInAddress(); if (BytesInAddress != 4 && BytesInAddress != 8) return error(instrprof_error::malformed); // Look for the sections that we are interested in. int FoundSectionCount = 0; SectionRef ProfileNames, CoverageMapping; - for (const auto &Section : Object->sections()) { + for (const auto &Section : OF->sections()) { StringRef Name; if (auto Err = Section.getName(Name)) return Err; diff --git a/lib/Support/MemoryBuffer.cpp b/lib/Support/MemoryBuffer.cpp index 9506da77704..27edce67361 100644 --- a/lib/Support/MemoryBuffer.cpp +++ b/lib/Support/MemoryBuffer.cpp @@ -416,3 +416,9 @@ ErrorOr> MemoryBuffer::getSTDIN() { return getMemoryBufferForStream(0, ""); } + +MemoryBufferRef MemoryBuffer::getMemBufferRef() const { + StringRef Data = getBuffer(); + StringRef Identifier = getBufferIdentifier(); + return MemoryBufferRef(Data, Identifier); +} diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp index f833f63fc6c..c8edf552945 100644 --- a/tools/lli/lli.cpp +++ b/tools/lli/lli.cpp @@ -263,7 +263,7 @@ public: } virtual ~LLIObjectCache() {} - void notifyObjectCompiled(const Module *M, const MemoryBuffer *Obj) override { + void notifyObjectCompiled(const Module *M, MemoryBufferRef Obj) override { const std::string ModuleID = M->getModuleIdentifier(); std::string CacheName; if (!getCacheFilename(ModuleID, CacheName)) @@ -275,7 +275,7 @@ public: sys::fs::create_directories(Twine(dir)); } raw_fd_ostream outfile(CacheName.c_str(), errStr, sys::fs::F_None); - outfile.write(Obj->getBufferStart(), Obj->getBufferSize()); + outfile.write(Obj.getBufferStart(), Obj.getBufferSize()); outfile.close(); } @@ -530,30 +530,35 @@ int main(int argc, char **argv, char * const *envp) { } for (unsigned i = 0, e = ExtraObjects.size(); i != e; ++i) { - ErrorOr> Obj = + ErrorOr> Obj = object::ObjectFile::createObjectFile(ExtraObjects[i]); if (!Obj) { Err.print(argv[0], errs()); return 1; } - EE->addObjectFile(std::move(Obj.get())); + EE->addObjectFile(std::move(Obj.get().getBinary())); } for (unsigned i = 0, e = ExtraArchives.size(); i != e; ++i) { - ErrorOr> ArBuf = + ErrorOr> ArBufOrErr = MemoryBuffer::getFileOrSTDIN(ExtraArchives[i]); - if (!ArBuf) { + if (!ArBufOrErr) { Err.print(argv[0], errs()); return 1; } + std::unique_ptr &ArBuf = ArBufOrErr.get(); ErrorOr> ArOrErr = - object::Archive::create(std::move(ArBuf.get())); + object::Archive::create(ArBuf->getMemBufferRef()); if (std::error_code EC = ArOrErr.getError()) { errs() << EC.message(); return 1; } - EE->addArchive(std::move(ArOrErr.get())); + std::unique_ptr &Ar = ArOrErr.get(); + + object::OwningBinary OB(std::move(Ar), std::move(ArBuf)); + + EE->addArchive(std::move(OB)); } // If the target is Cygwin/MingW and we are generating remote code, we diff --git a/tools/llvm-ar/llvm-ar.cpp b/tools/llvm-ar/llvm-ar.cpp index 3d87597f39b..2b32098a490 100644 --- a/tools/llvm-ar/llvm-ar.cpp +++ b/tools/llvm-ar/llvm-ar.cpp @@ -686,7 +686,7 @@ static void writeStringTable(raw_fd_ostream &Out, static void writeSymbolTable(raw_fd_ostream &Out, ArrayRef Members, - MutableArrayRef> Buffers, + ArrayRef Buffers, std::vector> &MemberOffsetRefs) { unsigned StartOffset = 0; unsigned MemberNum = 0; @@ -697,7 +697,7 @@ writeSymbolTable(raw_fd_ostream &Out, ArrayRef Members, for (ArrayRef::iterator I = Members.begin(), E = Members.end(); I != E; ++I, ++MemberNum) { - std::unique_ptr &MemberBuffer = Buffers[MemberNum]; + MemoryBufferRef MemberBuffer = Buffers[MemberNum]; ErrorOr> ObjOrErr = object::SymbolicFile::createSymbolicFile( MemberBuffer, sys::fs::file_magic::unknown, &Context); @@ -725,7 +725,6 @@ writeSymbolTable(raw_fd_ostream &Out, ArrayRef Members, MemberOffsetRefs.push_back(std::make_pair(Out.tell(), MemberNum)); print32BE(Out, 0); } - MemberBuffer.reset(Obj.releaseBuffer()); } Out << NameOS.str(); @@ -759,12 +758,12 @@ static void performWriteOperation(ArchiveOperation Operation, std::vector > MemberOffsetRefs; - std::vector> MemberBuffers; - MemberBuffers.resize(NewMembers.size()); + std::vector> Buffers; + std::vector Members; for (unsigned I = 0, N = NewMembers.size(); I < N; ++I) { - std::unique_ptr &MemberBuffer = MemberBuffers[I]; NewArchiveIterator &Member = NewMembers[I]; + MemoryBufferRef MemberRef; if (Member.isNewMember()) { const char *Filename = Member.getNew(); @@ -773,18 +772,20 @@ static void performWriteOperation(ArchiveOperation Operation, ErrorOr> MemberBufferOrErr = MemoryBuffer::getOpenFile(FD, Filename, Status.getSize(), false); failIfError(MemberBufferOrErr.getError(), Filename); - MemberBuffer = std::move(MemberBufferOrErr.get()); + Buffers.push_back(std::move(MemberBufferOrErr.get())); + MemberRef = Buffers.back()->getMemBufferRef(); } else { object::Archive::child_iterator OldMember = Member.getOld(); - ErrorOr> MemberBufferOrErr = - OldMember->getMemoryBuffer(); + ErrorOr MemberBufferOrErr = + OldMember->getMemoryBufferRef(); failIfError(MemberBufferOrErr.getError()); - MemberBuffer = std::move(MemberBufferOrErr.get()); + MemberRef = MemberBufferOrErr.get(); } + Members.push_back(MemberRef); } if (Symtab) { - writeSymbolTable(Out, NewMembers, MemberBuffers, MemberOffsetRefs); + writeSymbolTable(Out, NewMembers, Members, MemberOffsetRefs); } std::vector StringMapIndexes; @@ -808,7 +809,7 @@ static void performWriteOperation(ArchiveOperation Operation, } Out.seek(Pos); - const MemoryBuffer *File = MemberBuffers[MemberNum].get(); + MemoryBufferRef File = Members[MemberNum]; if (I->isNewMember()) { const char *FileName = I->getNew(); const sys::fs::file_status &Status = I->getStatus(); @@ -838,7 +839,7 @@ static void performWriteOperation(ArchiveOperation Operation, OldMember->getSize()); } - Out << File->getBuffer(); + Out << File.getBuffer(); if (Out.tell() % 2) Out << '\n'; @@ -943,7 +944,7 @@ static int performOperation(ArchiveOperation Operation) { } if (!EC) { - object::Archive Archive(std::move(Buf.get()), EC); + object::Archive Archive(Buf.get()->getMemBufferRef(), EC); if (EC) { errs() << ToolName << ": error loading '" << ArchiveName diff --git a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp index 4e65d444fc8..6af827683e1 100644 --- a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -66,16 +66,17 @@ DumpType("debug-dump", cl::init(DIDT_All), clEnumValEnd)); static void DumpInput(const StringRef &Filename) { - ErrorOr> Buff = + ErrorOr> BuffOrErr = MemoryBuffer::getFileOrSTDIN(Filename); - if (std::error_code EC = Buff.getError()) { + if (std::error_code EC = BuffOrErr.getError()) { errs() << Filename << ": " << EC.message() << "\n"; return; } + std::unique_ptr Buff = std::move(BuffOrErr.get()); ErrorOr> ObjOrErr = - ObjectFile::createObjectFile(Buff.get()); + ObjectFile::createObjectFile(Buff->getMemBufferRef()); if (std::error_code EC = ObjOrErr.getError()) { errs() << Filename << ": " << EC.message() << '\n'; return; diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index 84d8dd5c973..6c3a9e27b71 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -1010,7 +1010,7 @@ static void dumpSymbolNamesFromFile(std::string &Filename) { LLVMContext &Context = getGlobalContext(); ErrorOr> BinaryOrErr = - createBinary(std::move(*BufferOrErr), &Context); + createBinary(BufferOrErr.get()->getMemBufferRef(), &Context); if (error(BinaryOrErr.getError(), Filename)) return; Binary &Bin = *BinaryOrErr.get(); diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 1cf92360054..de99bea15aa 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -210,15 +210,16 @@ static void DisassembleInputMachO2(StringRef Filename, MachOObjectFile *MachOOF); void llvm::DisassembleInputMachO(StringRef Filename) { - ErrorOr> Buff = + ErrorOr> BuffOrErr = MemoryBuffer::getFileOrSTDIN(Filename); - if (std::error_code EC = Buff.getError()) { + if (std::error_code EC = BuffOrErr.getError()) { errs() << "llvm-objdump: " << Filename << ": " << EC.message() << "\n"; return; } + std::unique_ptr Buff = std::move(BuffOrErr.get()); - std::unique_ptr MachOOF = - std::move(ObjectFile::createMachOObjectFile(Buff.get()).get()); + std::unique_ptr MachOOF = std::move( + ObjectFile::createMachOObjectFile(Buff.get()->getMemBufferRef()).get()); DisassembleInputMachO2(Filename, MachOOF.get()); } @@ -352,13 +353,16 @@ static void DisassembleInputMachO2(StringRef Filename, // A separate DSym file path was specified, parse it as a macho file, // get the sections and supply it to the section name parsing machinery. if (!DSYMFile.empty()) { - ErrorOr> Buf = + ErrorOr> BufOrErr = MemoryBuffer::getFileOrSTDIN(DSYMFile); - if (std::error_code EC = Buf.getError()) { + if (std::error_code EC = BufOrErr.getError()) { errs() << "llvm-objdump: " << Filename << ": " << EC.message() << '\n'; return; } - DbgObj = ObjectFile::createMachOObjectFile(Buf.get()).get().release(); + DbgObj = + ObjectFile::createMachOObjectFile(BufOrErr.get()->getMemBufferRef()) + .get() + .release(); } // Setup the DIContext diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 791011ddefa..0074271ba7e 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -892,12 +892,12 @@ static void DumpInput(StringRef file) { } // Attempt to open the binary. - ErrorOr> BinaryOrErr = createBinary(file); + ErrorOr> BinaryOrErr = createBinary(file); if (std::error_code EC = BinaryOrErr.getError()) { errs() << ToolName << ": '" << file << "': " << EC.message() << ".\n"; return; } - Binary &Binary = *BinaryOrErr.get(); + Binary &Binary = *BinaryOrErr.get().getBinary(); if (Archive *a = dyn_cast(&Binary)) DumpArchive(a); diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index 5d58b0a6099..a20164a3c23 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -299,12 +299,12 @@ static void dumpInput(StringRef File) { } // Attempt to open the binary. - ErrorOr> BinaryOrErr = createBinary(File); + ErrorOr> BinaryOrErr = createBinary(File); if (std::error_code EC = BinaryOrErr.getError()) { reportError(File, EC); return; } - Binary &Binary = *BinaryOrErr.get(); + Binary &Binary = *BinaryOrErr.get().getBinary(); if (Archive *Arc = dyn_cast(&Binary)) dumpArchive(Arc); diff --git a/tools/llvm-size/llvm-size.cpp b/tools/llvm-size/llvm-size.cpp index d5e9956e04b..0b0b00b05cf 100644 --- a/tools/llvm-size/llvm-size.cpp +++ b/tools/llvm-size/llvm-size.cpp @@ -453,12 +453,12 @@ static void PrintFileSectionSizes(StringRef file) { } // Attempt to open the binary. - ErrorOr> BinaryOrErr = createBinary(file); + ErrorOr> BinaryOrErr = createBinary(file); if (std::error_code EC = BinaryOrErr.getError()) { errs() << ToolName << ": " << file << ": " << EC.message() << ".\n"; return; } - Binary &Bin = *BinaryOrErr.get(); + Binary &Bin = *BinaryOrErr.get().getBinary(); if (Archive *a = dyn_cast(&Bin)) { // This is an archive. Iterate over each member and display its sizes. diff --git a/tools/llvm-symbolizer/LLVMSymbolize.cpp b/tools/llvm-symbolizer/LLVMSymbolize.cpp index 14e193a5373..2606beac17b 100644 --- a/tools/llvm-symbolizer/LLVMSymbolize.cpp +++ b/tools/llvm-symbolizer/LLVMSymbolize.cpp @@ -300,12 +300,12 @@ LLVMSymbolizer::getOrCreateBinary(const std::string &Path) { return I->second; Binary *Bin = nullptr; Binary *DbgBin = nullptr; - ErrorOr> BinaryOrErr = createBinary(Path); + ErrorOr> BinaryOrErr = createBinary(Path); if (!error(BinaryOrErr.getError())) { - std::unique_ptr &ParsedBinary = BinaryOrErr.get(); + OwningBinary &ParsedBinary = BinaryOrErr.get(); // Check if it's a universal binary. - Bin = ParsedBinary.get(); - ParsedBinariesAndObjects.push_back(std::move(ParsedBinary)); + Bin = ParsedBinary.getBinary().get(); + addOwningBinary(std::move(ParsedBinary)); if (Bin->isMachO() || Bin->isMachOUniversalBinary()) { // On Darwin we may find DWARF in separate object file in // resource directory. @@ -314,8 +314,9 @@ LLVMSymbolizer::getOrCreateBinary(const std::string &Path) { BinaryOrErr = createBinary(ResourcePath); std::error_code EC = BinaryOrErr.getError(); if (EC != errc::no_such_file_or_directory && !error(EC)) { - DbgBin = BinaryOrErr.get().get(); - ParsedBinariesAndObjects.push_back(std::move(BinaryOrErr.get())); + OwningBinary B = std::move(BinaryOrErr.get()); + DbgBin = B.getBinary().get(); + addOwningBinary(std::move(B)); } } // Try to locate the debug binary using .gnu_debuglink section. @@ -327,8 +328,9 @@ LLVMSymbolizer::getOrCreateBinary(const std::string &Path) { findDebugBinary(Path, DebuglinkName, CRCHash, DebugBinaryPath)) { BinaryOrErr = createBinary(DebugBinaryPath); if (!error(BinaryOrErr.getError())) { - DbgBin = BinaryOrErr.get().get(); - ParsedBinariesAndObjects.push_back(std::move(BinaryOrErr.get())); + OwningBinary B = std::move(BinaryOrErr.get()); + DbgBin = B.getBinary().get(); + addOwningBinary(std::move(B)); } } } diff --git a/tools/llvm-symbolizer/LLVMSymbolize.h b/tools/llvm-symbolizer/LLVMSymbolize.h index cd11e656e79..a56f1329fd6 100644 --- a/tools/llvm-symbolizer/LLVMSymbolize.h +++ b/tools/llvm-symbolizer/LLVMSymbolize.h @@ -75,6 +75,12 @@ private: // Owns all the parsed binaries and object files. SmallVector, 4> ParsedBinariesAndObjects; + SmallVector, 4> MemoryBuffers; + void addOwningBinary(OwningBinary Bin) { + ParsedBinariesAndObjects.push_back(std::move(Bin.getBinary())); + MemoryBuffers.push_back(std::move(Bin.getBuffer())); + } + // Owns module info objects. typedef std::map ModuleMapTy; ModuleMapTy Modules; diff --git a/tools/llvm-vtabledump/llvm-vtabledump.cpp b/tools/llvm-vtabledump/llvm-vtabledump.cpp index 2f6ccb0620a..f089d586c49 100644 --- a/tools/llvm-vtabledump/llvm-vtabledump.cpp +++ b/tools/llvm-vtabledump/llvm-vtabledump.cpp @@ -164,12 +164,12 @@ static void dumpInput(StringRef File) { } // Attempt to open the binary. - ErrorOr> BinaryOrErr = createBinary(File); + ErrorOr> BinaryOrErr = createBinary(File); if (std::error_code EC = BinaryOrErr.getError()) { reportError(File, EC); return; } - Binary &Binary = *BinaryOrErr.get(); + Binary &Binary = *BinaryOrErr.get().getBinary(); if (Archive *Arc = dyn_cast(&Binary)) dumpArchive(Arc); diff --git a/tools/macho-dump/macho-dump.cpp b/tools/macho-dump/macho-dump.cpp index 787aebc058d..a457a4bf8f1 100644 --- a/tools/macho-dump/macho-dump.cpp +++ b/tools/macho-dump/macho-dump.cpp @@ -403,10 +403,10 @@ int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv, "llvm Mach-O dumping tool\n"); - ErrorOr> BinaryOrErr = createBinary(InputFile); + ErrorOr> BinaryOrErr = createBinary(InputFile); if (std::error_code EC = BinaryOrErr.getError()) return Error("unable to read input: '" + EC.message() + "'"); - Binary &Binary = *BinaryOrErr.get(); + Binary &Binary = *BinaryOrErr.get().getBinary(); const MachOObjectFile *InputObject = dyn_cast(&Binary); if (!InputObject) diff --git a/tools/obj2yaml/obj2yaml.cpp b/tools/obj2yaml/obj2yaml.cpp index dbf5a4acd16..b64096d75fa 100644 --- a/tools/obj2yaml/obj2yaml.cpp +++ b/tools/obj2yaml/obj2yaml.cpp @@ -32,11 +32,11 @@ static std::error_code dumpInput(StringRef File) { if (File != "-" && !sys::fs::exists(File)) return obj2yaml_error::file_not_found; - ErrorOr> BinaryOrErr = createBinary(File); + ErrorOr> BinaryOrErr = createBinary(File); if (std::error_code EC = BinaryOrErr.getError()) return EC; - Binary &Binary = *BinaryOrErr.get(); + Binary &Binary = *BinaryOrErr.get().getBinary(); // TODO: If this is an archive, then burst it and dump each entry if (ObjectFile *Obj = dyn_cast(&Binary)) return dumpObject(*Obj); diff --git a/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp index 5eebddb4969..f230fb82434 100644 --- a/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp +++ b/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp @@ -25,7 +25,7 @@ class TestObjectCache : public ObjectCache { public: TestObjectCache() : DuplicateInserted(false) { } - virtual void notifyObjectCompiled(const Module *M, const MemoryBuffer *Obj) { + void notifyObjectCompiled(const Module *M, MemoryBufferRef Obj) override { // If we've seen this module before, note that. const std::string ModuleID = M->getModuleIdentifier(); if (ObjMap.find(ModuleID) != ObjMap.end()) @@ -63,10 +63,10 @@ public: } private: - MemoryBuffer *copyBuffer(const MemoryBuffer *Buf) { + MemoryBuffer *copyBuffer(MemoryBufferRef Buf) { // Create a local copy of the buffer. std::unique_ptr NewBuffer( - MemoryBuffer::getMemBufferCopy(Buf->getBuffer())); + MemoryBuffer::getMemBufferCopy(Buf.getBuffer())); MemoryBuffer *Ret = NewBuffer.get(); AllocatedBuffers.push_back(std::move(NewBuffer)); return Ret; -- 2.34.1