[mips] Add initial release notes for MIPS32.
[oota-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/Errc.h"
23 #include "llvm/Support/ErrorOr.h"
24 #include "llvm/Support/TimeValue.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   bool Verbose;
46
47   /// Get the MemoryBufferRefs for the file specification in \p
48   /// Filename from the current archive. Multiple buffers are returned
49   /// when there are multiple architectures available for the
50   /// requested file.
51   ///
52   /// This function performs no system calls, it just looks up a
53   /// potential match for the given \p Filename in the currently
54   /// mapped archive if there is one.
55   ErrorOr<std::vector<MemoryBufferRef>>
56   GetArchiveMemberBuffers(StringRef Filename, sys::TimeValue Timestamp);
57
58   /// Interpret Filename as an archive member specification map the
59   /// corresponding archive to memory and return the MemoryBufferRefs
60   /// corresponding to the described member. Multiple buffers are
61   /// returned when there are multiple architectures available for the
62   /// requested file.
63   ErrorOr<std::vector<MemoryBufferRef>>
64   MapArchiveAndGetMemberBuffers(StringRef Filename, sys::TimeValue Timestamp);
65
66   /// Return the MemoryBufferRef that holds the memory mapping for the
67   /// given \p Filename. This function will try to parse archive
68   /// member specifications of the form /path/to/archive.a(member.o).
69   ///
70   /// The returned MemoryBufferRefs points to a buffer owned by this
71   /// object. The buffer is valid until the next call to
72   /// GetMemoryBufferForFile() on this object.
73   /// Multiple buffers are returned when there are multiple
74   /// architectures available for the requested file.
75   ErrorOr<std::vector<MemoryBufferRef>>
76   GetMemoryBuffersForFile(StringRef Filename, sys::TimeValue Timestamp);
77
78   void changeBackingMemoryBuffer(std::unique_ptr<MemoryBuffer> &&MemBuf);
79   ErrorOr<const object::ObjectFile &> getObjfileForArch(const Triple &T);
80
81 public:
82   BinaryHolder(bool Verbose) : Verbose(Verbose) {}
83
84   /// Get the ObjectFiles designated by the \p Filename. This
85   /// might be an archive member specification of the form
86   /// /path/to/archive.a(member.o).
87   ///
88   /// Calling this function invalidates the previous mapping owned by
89   /// the BinaryHolder. Multiple buffers are returned when there are
90   /// multiple architectures available for the requested file.
91   ErrorOr<std::vector<const object::ObjectFile *>>
92   GetObjectFiles(StringRef Filename,
93                  sys::TimeValue Timestamp = sys::TimeValue::PosixZeroTime());
94
95   /// Wraps GetObjectFiles() to return a derived ObjectFile type.
96   template <typename ObjectFileType>
97   ErrorOr<std::vector<const ObjectFileType *>>
98   GetFilesAs(StringRef Filename,
99              sys::TimeValue Timestamp = sys::TimeValue::PosixZeroTime()) {
100     auto ErrOrObjFile = GetObjectFiles(Filename, Timestamp);
101     if (auto Err = ErrOrObjFile.getError())
102       return Err;
103
104     std::vector<const ObjectFileType *> Objects;
105     Objects.reserve((*ErrOrObjFile).size());
106     for (const auto &Obj : *ErrOrObjFile) {
107       const auto *Derived = dyn_cast<ObjectFileType>(Obj);
108       if (!Derived)
109         return make_error_code(object::object_error::invalid_file_type);
110       Objects.push_back(Derived);
111     }
112     return std::move(Objects);
113   }
114
115   /// Access the currently owned ObjectFile with architecture \p T. As
116   /// successfull call to GetObjectFiles() or GetFilesAs() must have
117   /// been performed before calling this.
118   ErrorOr<const object::ObjectFile &> Get(const Triple &T) {
119     return getObjfileForArch(T);
120   }
121
122   /// Access to a derived version of the currently owned
123   /// ObjectFile. The conversion must be known to be valid.
124   template <typename ObjectFileType>
125   ErrorOr<const ObjectFileType &> GetAs(const Triple &T) {
126     auto ErrOrObj = Get(T);
127     if (auto Err = ErrOrObj.getError())
128       return Err;
129     return cast<ObjectFileType>(*ErrOrObj);
130   }
131
132   static Triple getTriple(const object::MachOObjectFile &Obj);
133 };
134 }
135 }
136 #endif