1 //===- SymbolicFile.h - Interface that only provides symbols ----*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file declares the SymbolicFile interface.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_OBJECT_SYMBOLICFILE_H
15 #define LLVM_OBJECT_SYMBOLICFILE_H
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/ADT/iterator_range.h"
19 #include "llvm/BinaryFormat/Magic.h"
20 #include "llvm/Object/Binary.h"
21 #include "llvm/Support/Error.h"
22 #include "llvm/Support/FileSystem.h"
23 #include "llvm/Support/Format.h"
24 #include "llvm/Support/MemoryBuffer.h"
30 #include <system_error>
36 // This entire union should probably be a
37 // char[max(8, sizeof(uintptr_t))] and require the impl to cast.
43 DataRefImpl() { std::memset(this, 0, sizeof(DataRefImpl
)); }
46 template <typename OStream
>
47 OStream
& operator<<(OStream
&OS
, const DataRefImpl
&D
) {
48 OS
<< "(" << format("0x%08" PRIxPTR
, D
.p
) << " (" << format("0x%08x", D
.d
.a
)
49 << ", " << format("0x%08x", D
.d
.b
) << "))";
53 inline bool operator==(const DataRefImpl
&a
, const DataRefImpl
&b
) {
54 // Check bitwise identical. This is the only legal way to compare a union w/o
55 // knowing which member is in use.
56 return std::memcmp(&a
, &b
, sizeof(DataRefImpl
)) == 0;
59 inline bool operator!=(const DataRefImpl
&a
, const DataRefImpl
&b
) {
60 return !operator==(a
, b
);
63 inline bool operator<(const DataRefImpl
&a
, const DataRefImpl
&b
) {
64 // Check bitwise identical. This is the only legal way to compare a union w/o
65 // knowing which member is in use.
66 return std::memcmp(&a
, &b
, sizeof(DataRefImpl
)) < 0;
69 template <class content_type
>
70 class content_iterator
71 : public std::iterator
<std::forward_iterator_tag
, content_type
> {
75 content_iterator(content_type symb
) : Current(std::move(symb
)) {}
77 const content_type
*operator->() const { return &Current
; }
79 const content_type
&operator*() const { return Current
; }
81 bool operator==(const content_iterator
&other
) const {
82 return Current
== other
.Current
;
85 bool operator!=(const content_iterator
&other
) const {
86 return !(*this == other
);
89 content_iterator
&operator++() { // preincrement
97 /// This is a value type class that represents a single symbol in the list of
98 /// symbols in the object file.
99 class BasicSymbolRef
{
100 DataRefImpl SymbolPimpl
;
101 const SymbolicFile
*OwningObject
= nullptr;
104 enum Flags
: unsigned {
106 SF_Undefined
= 1U << 0, // Symbol is defined in another object file
107 SF_Global
= 1U << 1, // Global symbol
108 SF_Weak
= 1U << 2, // Weak symbol
109 SF_Absolute
= 1U << 3, // Absolute symbol
110 SF_Common
= 1U << 4, // Symbol has common linkage
111 SF_Indirect
= 1U << 5, // Symbol is an alias to another symbol
112 SF_Exported
= 1U << 6, // Symbol is visible to other DSOs
113 SF_FormatSpecific
= 1U << 7, // Specific to the object file format
114 // (e.g. section symbols)
115 SF_Thumb
= 1U << 8, // Thumb symbol in a 32-bit ARM binary
116 SF_Hidden
= 1U << 9, // Symbol has hidden visibility
117 SF_Const
= 1U << 10, // Symbol value is constant
118 SF_Executable
= 1U << 11, // Symbol points to an executable section
122 BasicSymbolRef() = default;
123 BasicSymbolRef(DataRefImpl SymbolP
, const SymbolicFile
*Owner
);
125 bool operator==(const BasicSymbolRef
&Other
) const;
126 bool operator<(const BasicSymbolRef
&Other
) const;
130 std::error_code
printName(raw_ostream
&OS
) const;
132 /// Get symbol flags (bitwise OR of SymbolRef::Flags)
133 uint32_t getFlags() const;
135 DataRefImpl
getRawDataRefImpl() const;
136 const SymbolicFile
*getObject() const;
139 using basic_symbol_iterator
= content_iterator
<BasicSymbolRef
>;
141 class SymbolicFile
: public Binary
{
143 SymbolicFile(unsigned int Type
, MemoryBufferRef Source
);
144 ~SymbolicFile() override
;
146 // virtual interface.
147 virtual void moveSymbolNext(DataRefImpl
&Symb
) const = 0;
149 virtual std::error_code
printSymbolName(raw_ostream
&OS
,
150 DataRefImpl Symb
) const = 0;
152 virtual uint32_t getSymbolFlags(DataRefImpl Symb
) const = 0;
154 virtual basic_symbol_iterator
symbol_begin() const = 0;
156 virtual basic_symbol_iterator
symbol_end() const = 0;
158 // convenience wrappers.
159 using basic_symbol_iterator_range
= iterator_range
<basic_symbol_iterator
>;
160 basic_symbol_iterator_range
symbols() const {
161 return basic_symbol_iterator_range(symbol_begin(), symbol_end());
165 static Expected
<std::unique_ptr
<SymbolicFile
>>
166 createSymbolicFile(MemoryBufferRef Object
, llvm::file_magic Type
,
167 LLVMContext
*Context
);
169 static Expected
<std::unique_ptr
<SymbolicFile
>>
170 createSymbolicFile(MemoryBufferRef Object
) {
171 return createSymbolicFile(Object
, llvm::file_magic::unknown
, nullptr);
173 static Expected
<OwningBinary
<SymbolicFile
>>
174 createSymbolicFile(StringRef ObjectPath
);
176 static bool classof(const Binary
*v
) {
177 return v
->isSymbolic();
181 inline BasicSymbolRef::BasicSymbolRef(DataRefImpl SymbolP
,
182 const SymbolicFile
*Owner
)
183 : SymbolPimpl(SymbolP
), OwningObject(Owner
) {}
185 inline bool BasicSymbolRef::operator==(const BasicSymbolRef
&Other
) const {
186 return SymbolPimpl
== Other
.SymbolPimpl
;
189 inline bool BasicSymbolRef::operator<(const BasicSymbolRef
&Other
) const {
190 return SymbolPimpl
< Other
.SymbolPimpl
;
193 inline void BasicSymbolRef::moveNext() {
194 return OwningObject
->moveSymbolNext(SymbolPimpl
);
197 inline std::error_code
BasicSymbolRef::printName(raw_ostream
&OS
) const {
198 return OwningObject
->printSymbolName(OS
, SymbolPimpl
);
201 inline uint32_t BasicSymbolRef::getFlags() const {
202 return OwningObject
->getSymbolFlags(SymbolPimpl
);
205 inline DataRefImpl
BasicSymbolRef::getRawDataRefImpl() const {
209 inline const SymbolicFile
*BasicSymbolRef::getObject() const {
213 } // end namespace object
214 } // end namespace llvm
216 #endif // LLVM_OBJECT_SYMBOLICFILE_H