83
|
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/Object/Archive.h"
|
|
18 #include "llvm/Object/Error.h"
|
|
19 #include "llvm/Object/ObjectFile.h"
|
|
20 #include "llvm/Support/Errc.h"
|
|
21 #include "llvm/Support/ErrorOr.h"
|
|
22
|
|
23 namespace llvm {
|
|
24 namespace dsymutil {
|
|
25
|
|
26 /// \brief The BinaryHolder class is responsible for creating and
|
|
27 /// owning ObjectFile objects and their underlying MemoryBuffer. This
|
|
28 /// is different from a simple OwningBinary in that it handles
|
|
29 /// accessing to archive members.
|
|
30 ///
|
|
31 /// As an optimization, this class will reuse an already mapped and
|
|
32 /// parsed Archive object if 2 successive requests target the same
|
|
33 /// archive file (Which is always the case in debug maps).
|
|
34 /// Currently it only owns one memory buffer at any given time,
|
|
35 /// meaning that a mapping request will invalidate the previous memory
|
|
36 /// mapping.
|
|
37 class BinaryHolder {
|
|
38 std::unique_ptr<object::Archive> CurrentArchive;
|
|
39 std::unique_ptr<MemoryBuffer> CurrentMemoryBuffer;
|
|
40 std::unique_ptr<object::ObjectFile> CurrentObjectFile;
|
|
41 bool Verbose;
|
|
42
|
|
43 /// \brief Get the MemoryBufferRef for the file specification in \p
|
|
44 /// Filename from the current archive.
|
|
45 ///
|
|
46 /// This function performs no system calls, it just looks up a
|
|
47 /// potential match for the given \p Filename in the currently
|
|
48 /// mapped archive if there is one.
|
|
49 ErrorOr<MemoryBufferRef> GetArchiveMemberBuffer(StringRef Filename);
|
|
50
|
|
51 /// \brief Interpret Filename as an archive member specification,
|
|
52 /// map the corresponding archive to memory and return the
|
|
53 /// MemoryBufferRef corresponding to the described member.
|
|
54 ErrorOr<MemoryBufferRef> MapArchiveAndGetMemberBuffer(StringRef Filename);
|
|
55
|
|
56 /// \brief Return the MemoryBufferRef that holds the memory
|
|
57 /// mapping for the given \p Filename. This function will try to
|
|
58 /// parse archive member specifications of the form
|
|
59 /// /path/to/archive.a(member.o).
|
|
60 ///
|
|
61 /// The returned MemoryBufferRef points to a buffer owned by this
|
|
62 /// object. The buffer is valid until the next call to
|
|
63 /// GetMemoryBufferForFile() on this object.
|
|
64 ErrorOr<MemoryBufferRef> GetMemoryBufferForFile(StringRef Filename);
|
|
65
|
|
66 public:
|
|
67 BinaryHolder(bool Verbose) : Verbose(Verbose) {}
|
|
68
|
|
69 /// \brief Get the ObjectFile designated by the \p Filename. This
|
|
70 /// might be an archive member specification of the form
|
|
71 /// /path/to/archive.a(member.o).
|
|
72 ///
|
|
73 /// Calling this function invalidates the previous mapping owned by
|
|
74 /// the BinaryHolder.
|
|
75 ErrorOr<const object::ObjectFile &> GetObjectFile(StringRef Filename);
|
|
76
|
|
77 /// \brief Wraps GetObjectFile() to return a derived ObjectFile type.
|
|
78 template <typename ObjectFileType>
|
|
79 ErrorOr<const ObjectFileType &> GetFileAs(StringRef Filename) {
|
|
80 auto ErrOrObjFile = GetObjectFile(Filename);
|
|
81 if (auto Err = ErrOrObjFile.getError())
|
|
82 return Err;
|
|
83 if (const auto *Derived = dyn_cast<ObjectFileType>(CurrentObjectFile.get()))
|
|
84 return *Derived;
|
|
85 return make_error_code(object::object_error::invalid_file_type);
|
|
86 }
|
|
87
|
|
88 /// \brief Access the currently owned ObjectFile. As successfull
|
|
89 /// call to GetObjectFile() or GetFileAs() must have been performed
|
|
90 /// before calling this.
|
|
91 const object::ObjectFile &Get() {
|
|
92 assert(CurrentObjectFile);
|
|
93 return *CurrentObjectFile;
|
|
94 }
|
|
95
|
|
96 /// \brief Access to a derived version of the currently owned
|
|
97 /// ObjectFile. The conversion must be known to be valid.
|
|
98 template <typename ObjectFileType> const ObjectFileType &GetAs() {
|
|
99 return cast<ObjectFileType>(*CurrentObjectFile);
|
|
100 }
|
|
101 };
|
|
102 }
|
|
103 }
|
|
104 #endif
|