137 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			137 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===-- 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/ADT/Triple.h"
 | |
| #include "llvm/Object/Archive.h"
 | |
| #include "llvm/Object/Error.h"
 | |
| #include "llvm/Object/MachOUniversal.h"
 | |
| #include "llvm/Object/ObjectFile.h"
 | |
| #include "llvm/Support/Errc.h"
 | |
| #include "llvm/Support/ErrorOr.h"
 | |
| #include "llvm/Support/TimeValue.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::vector<std::unique_ptr<object::Archive>> CurrentArchives;
 | |
|   std::unique_ptr<MemoryBuffer> CurrentMemoryBuffer;
 | |
|   std::vector<std::unique_ptr<object::ObjectFile>> CurrentObjectFiles;
 | |
|   std::unique_ptr<object::MachOUniversalBinary> CurrentFatBinary;
 | |
|   bool Verbose;
 | |
| 
 | |
|   /// Get the MemoryBufferRefs for the file specification in \p
 | |
|   /// Filename from the current archive. Multiple buffers are returned
 | |
|   /// when there are multiple architectures available for the
 | |
|   /// requested file.
 | |
|   ///
 | |
|   /// 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<std::vector<MemoryBufferRef>>
 | |
|   GetArchiveMemberBuffers(StringRef Filename, sys::TimeValue Timestamp);
 | |
| 
 | |
|   /// Interpret Filename as an archive member specification map the
 | |
|   /// corresponding archive to memory and return the MemoryBufferRefs
 | |
|   /// corresponding to the described member. Multiple buffers are
 | |
|   /// returned when there are multiple architectures available for the
 | |
|   /// requested file.
 | |
|   ErrorOr<std::vector<MemoryBufferRef>>
 | |
|   MapArchiveAndGetMemberBuffers(StringRef Filename, sys::TimeValue Timestamp);
 | |
| 
 | |
|   /// 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 MemoryBufferRefs points to a buffer owned by this
 | |
|   /// object. The buffer is valid until the next call to
 | |
|   /// GetMemoryBufferForFile() on this object.
 | |
|   /// Multiple buffers are returned when there are multiple
 | |
|   /// architectures available for the requested file.
 | |
|   ErrorOr<std::vector<MemoryBufferRef>>
 | |
|   GetMemoryBuffersForFile(StringRef Filename, sys::TimeValue Timestamp);
 | |
| 
 | |
|   void changeBackingMemoryBuffer(std::unique_ptr<MemoryBuffer> &&MemBuf);
 | |
|   ErrorOr<const object::ObjectFile &> getObjfileForArch(const Triple &T);
 | |
| 
 | |
| public:
 | |
|   BinaryHolder(bool Verbose) : Verbose(Verbose) {}
 | |
| 
 | |
|   /// Get the ObjectFiles 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. Multiple buffers are returned when there are
 | |
|   /// multiple architectures available for the requested file.
 | |
|   ErrorOr<std::vector<const object::ObjectFile *>>
 | |
|   GetObjectFiles(StringRef Filename,
 | |
|                  sys::TimeValue Timestamp = sys::TimeValue::PosixZeroTime());
 | |
| 
 | |
|   /// Wraps GetObjectFiles() to return a derived ObjectFile type.
 | |
|   template <typename ObjectFileType>
 | |
|   ErrorOr<std::vector<const ObjectFileType *>>
 | |
|   GetFilesAs(StringRef Filename,
 | |
|              sys::TimeValue Timestamp = sys::TimeValue::PosixZeroTime()) {
 | |
|     auto ErrOrObjFile = GetObjectFiles(Filename, Timestamp);
 | |
|     if (auto Err = ErrOrObjFile.getError())
 | |
|       return Err;
 | |
| 
 | |
|     std::vector<const ObjectFileType *> Objects;
 | |
|     Objects.reserve((*ErrOrObjFile).size());
 | |
|     for (const auto &Obj : *ErrOrObjFile) {
 | |
|       const auto *Derived = dyn_cast<ObjectFileType>(Obj);
 | |
|       if (!Derived)
 | |
|         return make_error_code(object::object_error::invalid_file_type);
 | |
|       Objects.push_back(Derived);
 | |
|     }
 | |
|     return std::move(Objects);
 | |
|   }
 | |
| 
 | |
|   /// Access the currently owned ObjectFile with architecture \p T. As
 | |
|   /// successfull call to GetObjectFiles() or GetFilesAs() must have
 | |
|   /// been performed before calling this.
 | |
|   ErrorOr<const object::ObjectFile &> Get(const Triple &T) {
 | |
|     return getObjfileForArch(T);
 | |
|   }
 | |
| 
 | |
|   /// Access to a derived version of the currently owned
 | |
|   /// ObjectFile. The conversion must be known to be valid.
 | |
|   template <typename ObjectFileType>
 | |
|   ErrorOr<const ObjectFileType &> GetAs(const Triple &T) {
 | |
|     auto ErrOrObj = Get(T);
 | |
|     if (auto Err = ErrOrObj.getError())
 | |
|       return Err;
 | |
|     return cast<ObjectFileType>(*ErrOrObj);
 | |
|   }
 | |
| 
 | |
|   static Triple getTriple(const object::MachOObjectFile &Obj);
 | |
| };
 | |
| }
 | |
| }
 | |
| #endif
 |