xref: /aosp_15_r20/external/llvm/tools/dsymutil/BinaryHolder.h (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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