OSDN Git Service

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