1*9880d681SAndroid Build Coastguard Worker //===-- BinaryHolder.h - Utility class for accessing binaries -------------===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker // This program is a utility that aims to be a dropin replacement for 11*9880d681SAndroid Build Coastguard Worker // Darwin's dsymutil. 12*9880d681SAndroid Build Coastguard Worker // 13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 14*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_TOOLS_DSYMUTIL_BINARYHOLDER_H 15*9880d681SAndroid Build Coastguard Worker #define LLVM_TOOLS_DSYMUTIL_BINARYHOLDER_H 16*9880d681SAndroid Build Coastguard Worker 17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Triple.h" 18*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/Archive.h" 19*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/Error.h" 20*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/MachOUniversal.h" 21*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/ObjectFile.h" 22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Errc.h" 23*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorOr.h" 24*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TimeValue.h" 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Worker namespace llvm { 27*9880d681SAndroid Build Coastguard Worker namespace dsymutil { 28*9880d681SAndroid Build Coastguard Worker 29*9880d681SAndroid Build Coastguard Worker /// \brief The BinaryHolder class is responsible for creating and 30*9880d681SAndroid Build Coastguard Worker /// owning ObjectFile objects and their underlying MemoryBuffer. This 31*9880d681SAndroid Build Coastguard Worker /// is different from a simple OwningBinary in that it handles 32*9880d681SAndroid Build Coastguard Worker /// accessing to archive members. 33*9880d681SAndroid Build Coastguard Worker /// 34*9880d681SAndroid Build Coastguard Worker /// As an optimization, this class will reuse an already mapped and 35*9880d681SAndroid Build Coastguard Worker /// parsed Archive object if 2 successive requests target the same 36*9880d681SAndroid Build Coastguard Worker /// archive file (Which is always the case in debug maps). 37*9880d681SAndroid Build Coastguard Worker /// Currently it only owns one memory buffer at any given time, 38*9880d681SAndroid Build Coastguard Worker /// meaning that a mapping request will invalidate the previous memory 39*9880d681SAndroid Build Coastguard Worker /// mapping. 40*9880d681SAndroid Build Coastguard Worker class BinaryHolder { 41*9880d681SAndroid Build Coastguard Worker std::vector<std::unique_ptr<object::Archive>> CurrentArchives; 42*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MemoryBuffer> CurrentMemoryBuffer; 43*9880d681SAndroid Build Coastguard Worker std::vector<std::unique_ptr<object::ObjectFile>> CurrentObjectFiles; 44*9880d681SAndroid Build Coastguard Worker std::unique_ptr<object::MachOUniversalBinary> CurrentFatBinary; 45*9880d681SAndroid Build Coastguard Worker std::string CurrentFatBinaryName; 46*9880d681SAndroid Build Coastguard Worker bool Verbose; 47*9880d681SAndroid Build Coastguard Worker 48*9880d681SAndroid Build Coastguard Worker /// Get the MemoryBufferRefs for the file specification in \p 49*9880d681SAndroid Build Coastguard Worker /// Filename from the current archive. Multiple buffers are returned 50*9880d681SAndroid Build Coastguard Worker /// when there are multiple architectures available for the 51*9880d681SAndroid Build Coastguard Worker /// requested file. 52*9880d681SAndroid Build Coastguard Worker /// 53*9880d681SAndroid Build Coastguard Worker /// This function performs no system calls, it just looks up a 54*9880d681SAndroid Build Coastguard Worker /// potential match for the given \p Filename in the currently 55*9880d681SAndroid Build Coastguard Worker /// mapped archive if there is one. 56*9880d681SAndroid Build Coastguard Worker ErrorOr<std::vector<MemoryBufferRef>> 57*9880d681SAndroid Build Coastguard Worker GetArchiveMemberBuffers(StringRef Filename, sys::TimeValue Timestamp); 58*9880d681SAndroid Build Coastguard Worker 59*9880d681SAndroid Build Coastguard Worker /// Interpret Filename as an archive member specification map the 60*9880d681SAndroid Build Coastguard Worker /// corresponding archive to memory and return the MemoryBufferRefs 61*9880d681SAndroid Build Coastguard Worker /// corresponding to the described member. Multiple buffers are 62*9880d681SAndroid Build Coastguard Worker /// returned when there are multiple architectures available for the 63*9880d681SAndroid Build Coastguard Worker /// requested file. 64*9880d681SAndroid Build Coastguard Worker ErrorOr<std::vector<MemoryBufferRef>> 65*9880d681SAndroid Build Coastguard Worker MapArchiveAndGetMemberBuffers(StringRef Filename, sys::TimeValue Timestamp); 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Worker /// Return the MemoryBufferRef that holds the memory mapping for the 68*9880d681SAndroid Build Coastguard Worker /// given \p Filename. This function will try to parse archive 69*9880d681SAndroid Build Coastguard Worker /// member specifications of the form /path/to/archive.a(member.o). 70*9880d681SAndroid Build Coastguard Worker /// 71*9880d681SAndroid Build Coastguard Worker /// The returned MemoryBufferRefs points to a buffer owned by this 72*9880d681SAndroid Build Coastguard Worker /// object. The buffer is valid until the next call to 73*9880d681SAndroid Build Coastguard Worker /// GetMemoryBufferForFile() on this object. 74*9880d681SAndroid Build Coastguard Worker /// Multiple buffers are returned when there are multiple 75*9880d681SAndroid Build Coastguard Worker /// architectures available for the requested file. 76*9880d681SAndroid Build Coastguard Worker ErrorOr<std::vector<MemoryBufferRef>> 77*9880d681SAndroid Build Coastguard Worker GetMemoryBuffersForFile(StringRef Filename, sys::TimeValue Timestamp); 78*9880d681SAndroid Build Coastguard Worker 79*9880d681SAndroid Build Coastguard Worker void changeBackingMemoryBuffer(std::unique_ptr<MemoryBuffer> &&MemBuf); 80*9880d681SAndroid Build Coastguard Worker ErrorOr<const object::ObjectFile &> getObjfileForArch(const Triple &T); 81*9880d681SAndroid Build Coastguard Worker 82*9880d681SAndroid Build Coastguard Worker public: BinaryHolder(bool Verbose)83*9880d681SAndroid Build Coastguard Worker BinaryHolder(bool Verbose) : Verbose(Verbose) {} 84*9880d681SAndroid Build Coastguard Worker 85*9880d681SAndroid Build Coastguard Worker /// Get the ObjectFiles designated by the \p Filename. This 86*9880d681SAndroid Build Coastguard Worker /// might be an archive member specification of the form 87*9880d681SAndroid Build Coastguard Worker /// /path/to/archive.a(member.o). 88*9880d681SAndroid Build Coastguard Worker /// 89*9880d681SAndroid Build Coastguard Worker /// Calling this function invalidates the previous mapping owned by 90*9880d681SAndroid Build Coastguard Worker /// the BinaryHolder. Multiple buffers are returned when there are 91*9880d681SAndroid Build Coastguard Worker /// multiple architectures available for the requested file. 92*9880d681SAndroid Build Coastguard Worker ErrorOr<std::vector<const object::ObjectFile *>> 93*9880d681SAndroid Build Coastguard Worker GetObjectFiles(StringRef Filename, 94*9880d681SAndroid Build Coastguard Worker sys::TimeValue Timestamp = sys::TimeValue::PosixZeroTime()); 95*9880d681SAndroid Build Coastguard Worker 96*9880d681SAndroid Build Coastguard Worker /// Wraps GetObjectFiles() to return a derived ObjectFile type. 97*9880d681SAndroid Build Coastguard Worker template <typename ObjectFileType> 98*9880d681SAndroid Build Coastguard Worker ErrorOr<std::vector<const ObjectFileType *>> 99*9880d681SAndroid Build Coastguard Worker GetFilesAs(StringRef Filename, 100*9880d681SAndroid Build Coastguard Worker sys::TimeValue Timestamp = sys::TimeValue::PosixZeroTime()) { 101*9880d681SAndroid Build Coastguard Worker auto ErrOrObjFile = GetObjectFiles(Filename, Timestamp); 102*9880d681SAndroid Build Coastguard Worker if (auto Err = ErrOrObjFile.getError()) 103*9880d681SAndroid Build Coastguard Worker return Err; 104*9880d681SAndroid Build Coastguard Worker 105*9880d681SAndroid Build Coastguard Worker std::vector<const ObjectFileType *> Objects; 106*9880d681SAndroid Build Coastguard Worker Objects.reserve((*ErrOrObjFile).size()); 107*9880d681SAndroid Build Coastguard Worker for (const auto &Obj : *ErrOrObjFile) { 108*9880d681SAndroid Build Coastguard Worker const auto *Derived = dyn_cast<ObjectFileType>(Obj); 109*9880d681SAndroid Build Coastguard Worker if (!Derived) 110*9880d681SAndroid Build Coastguard Worker return make_error_code(object::object_error::invalid_file_type); 111*9880d681SAndroid Build Coastguard Worker Objects.push_back(Derived); 112*9880d681SAndroid Build Coastguard Worker } 113*9880d681SAndroid Build Coastguard Worker return std::move(Objects); 114*9880d681SAndroid Build Coastguard Worker } 115*9880d681SAndroid Build Coastguard Worker 116*9880d681SAndroid Build Coastguard Worker /// Access the currently owned ObjectFile with architecture \p T. As 117*9880d681SAndroid Build Coastguard Worker /// successfull call to GetObjectFiles() or GetFilesAs() must have 118*9880d681SAndroid Build Coastguard Worker /// been performed before calling this. Get(const Triple & T)119*9880d681SAndroid Build Coastguard Worker ErrorOr<const object::ObjectFile &> Get(const Triple &T) { 120*9880d681SAndroid Build Coastguard Worker return getObjfileForArch(T); 121*9880d681SAndroid Build Coastguard Worker } 122*9880d681SAndroid Build Coastguard Worker 123*9880d681SAndroid Build Coastguard Worker /// Access to a derived version of the currently owned 124*9880d681SAndroid Build Coastguard Worker /// ObjectFile. The conversion must be known to be valid. 125*9880d681SAndroid Build Coastguard Worker template <typename ObjectFileType> GetAs(const Triple & T)126*9880d681SAndroid Build Coastguard Worker ErrorOr<const ObjectFileType &> GetAs(const Triple &T) { 127*9880d681SAndroid Build Coastguard Worker auto ErrOrObj = Get(T); 128*9880d681SAndroid Build Coastguard Worker if (auto Err = ErrOrObj.getError()) 129*9880d681SAndroid Build Coastguard Worker return Err; 130*9880d681SAndroid Build Coastguard Worker return cast<ObjectFileType>(*ErrOrObj); 131*9880d681SAndroid Build Coastguard Worker } 132*9880d681SAndroid Build Coastguard Worker }; 133*9880d681SAndroid Build Coastguard Worker } 134*9880d681SAndroid Build Coastguard Worker } 135*9880d681SAndroid Build Coastguard Worker #endif 136