| //===-- BinaryHolder.h - Utility class for accessing binaries -------------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This program is a utility that aims to be a dropin replacement for |
| // Darwin's dsymutil. |
| // |
| //===----------------------------------------------------------------------===// |
| #ifndef LLVM_TOOLS_DSYMUTIL_BINARYHOLDER_H |
| #define LLVM_TOOLS_DSYMUTIL_BINARYHOLDER_H |
| |
| #include "llvm/Object/Archive.h" |
| #include "llvm/Object/Error.h" |
| #include "llvm/Object/ObjectFile.h" |
| #include "llvm/Support/Errc.h" |
| #include "llvm/Support/ErrorOr.h" |
| |
| namespace llvm { |
| namespace dsymutil { |
| |
| /// \brief The BinaryHolder class is responsible for creating and |
| /// owning ObjectFile objects and their underlying MemoryBuffer. This |
| /// is different from a simple OwningBinary in that it handles |
| /// accessing to archive members. |
| /// |
| /// As an optimization, this class will reuse an already mapped and |
| /// parsed Archive object if 2 successive requests target the same |
| /// archive file (Which is always the case in debug maps). |
| /// Currently it only owns one memory buffer at any given time, |
| /// meaning that a mapping request will invalidate the previous memory |
| /// mapping. |
| class BinaryHolder { |
| std::unique_ptr<object::Archive> CurrentArchive; |
| std::unique_ptr<MemoryBuffer> CurrentMemoryBuffer; |
| std::unique_ptr<object::ObjectFile> CurrentObjectFile; |
| bool Verbose; |
| |
| /// \brief Get the MemoryBufferRef for the file specification in \p |
| /// Filename from the current archive. |
| /// |
| /// This function performs no system calls, it just looks up a |
| /// potential match for the given \p Filename in the currently |
| /// mapped archive if there is one. |
| ErrorOr<MemoryBufferRef> GetArchiveMemberBuffer(StringRef Filename); |
| |
| /// \brief Interpret Filename as an archive member specification, |
| /// map the corresponding archive to memory and return the |
| /// MemoryBufferRef corresponding to the described member. |
| ErrorOr<MemoryBufferRef> MapArchiveAndGetMemberBuffer(StringRef Filename); |
| |
| /// \brief Return the MemoryBufferRef that holds the memory |
| /// mapping for the given \p Filename. This function will try to |
| /// parse archive member specifications of the form |
| /// /path/to/archive.a(member.o). |
| /// |
| /// The returned MemoryBufferRef points to a buffer owned by this |
| /// object. The buffer is valid until the next call to |
| /// GetMemoryBufferForFile() on this object. |
| ErrorOr<MemoryBufferRef> GetMemoryBufferForFile(StringRef Filename); |
| |
| public: |
| BinaryHolder(bool Verbose) : Verbose(Verbose) {} |
| |
| /// \brief Get the ObjectFile designated by the \p Filename. This |
| /// might be an archive member specification of the form |
| /// /path/to/archive.a(member.o). |
| /// |
| /// Calling this function invalidates the previous mapping owned by |
| /// the BinaryHolder. |
| ErrorOr<const object::ObjectFile &> GetObjectFile(StringRef Filename); |
| |
| /// \brief Wraps GetObjectFile() to return a derived ObjectFile type. |
| template <typename ObjectFileType> |
| ErrorOr<const ObjectFileType &> GetFileAs(StringRef Filename) { |
| auto ErrOrObjFile = GetObjectFile(Filename); |
| if (auto Err = ErrOrObjFile.getError()) |
| return Err; |
| if (const auto *Derived = dyn_cast<ObjectFileType>(CurrentObjectFile.get())) |
| return *Derived; |
| return make_error_code(object::object_error::invalid_file_type); |
| } |
| |
| /// \brief Access the currently owned ObjectFile. As successfull |
| /// call to GetObjectFile() or GetFileAs() must have been performed |
| /// before calling this. |
| const object::ObjectFile &Get() { |
| assert(CurrentObjectFile); |
| return *CurrentObjectFile; |
| } |
| |
| /// \brief Access to a derived version of the currently owned |
| /// ObjectFile. The conversion must be known to be valid. |
| template <typename ObjectFileType> const ObjectFileType &GetAs() { |
| return cast<ObjectFileType>(*CurrentObjectFile); |
| } |
| }; |
| } |
| } |
| #endif |