File indexing completed on 2026-05-10 08:44:20
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_OBJECT_SYMBOLICFILE_H
0014 #define LLVM_OBJECT_SYMBOLICFILE_H
0015
0016 #include "llvm/ADT/iterator_range.h"
0017 #include "llvm/BinaryFormat/Magic.h"
0018 #include "llvm/Object/Binary.h"
0019 #include "llvm/Support/Error.h"
0020 #include "llvm/Support/Format.h"
0021 #include "llvm/Support/MemoryBufferRef.h"
0022 #include <cinttypes>
0023 #include <cstdint>
0024 #include <cstring>
0025 #include <iterator>
0026 #include <memory>
0027
0028 namespace llvm {
0029
0030 class LLVMContext;
0031 class raw_ostream;
0032
0033 namespace object {
0034
0035 union DataRefImpl {
0036
0037
0038 struct {
0039 uint32_t a, b;
0040 } d;
0041 uintptr_t p;
0042
0043 DataRefImpl() { std::memset(this, 0, sizeof(DataRefImpl)); }
0044 };
0045
0046 template <typename OStream>
0047 OStream& operator<<(OStream &OS, const DataRefImpl &D) {
0048 OS << "(" << format("0x%08" PRIxPTR, D.p) << " (" << format("0x%08x", D.d.a)
0049 << ", " << format("0x%08x", D.d.b) << "))";
0050 return OS;
0051 }
0052
0053 inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) {
0054
0055
0056 return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
0057 }
0058
0059 inline bool operator!=(const DataRefImpl &a, const DataRefImpl &b) {
0060 return !operator==(a, b);
0061 }
0062
0063 inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) {
0064
0065
0066 return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0;
0067 }
0068
0069 template <class content_type> class content_iterator {
0070 content_type Current;
0071
0072 public:
0073 using iterator_category = std::forward_iterator_tag;
0074 using value_type = const content_type;
0075 using difference_type = std::ptrdiff_t;
0076 using pointer = value_type *;
0077 using reference = value_type &;
0078
0079 content_iterator(content_type symb) : Current(std::move(symb)) {}
0080
0081 const content_type *operator->() const { return &Current; }
0082
0083 const content_type &operator*() const { return Current; }
0084
0085 bool operator==(const content_iterator &other) const {
0086 return Current == other.Current;
0087 }
0088
0089 bool operator!=(const content_iterator &other) const {
0090 return !(*this == other);
0091 }
0092
0093 content_iterator &operator++() {
0094 Current.moveNext();
0095 return *this;
0096 }
0097 };
0098
0099 class SymbolicFile;
0100
0101
0102
0103 class BasicSymbolRef {
0104 DataRefImpl SymbolPimpl;
0105 const SymbolicFile *OwningObject = nullptr;
0106
0107 public:
0108 enum Flags : unsigned {
0109 SF_None = 0,
0110 SF_Undefined = 1U << 0,
0111 SF_Global = 1U << 1,
0112 SF_Weak = 1U << 2,
0113 SF_Absolute = 1U << 3,
0114 SF_Common = 1U << 4,
0115 SF_Indirect = 1U << 5,
0116 SF_Exported = 1U << 6,
0117 SF_FormatSpecific = 1U << 7,
0118
0119 SF_Thumb = 1U << 8,
0120 SF_Hidden = 1U << 9,
0121 SF_Const = 1U << 10,
0122 SF_Executable = 1U << 11,
0123
0124 };
0125
0126 BasicSymbolRef() = default;
0127 BasicSymbolRef(DataRefImpl SymbolP, const SymbolicFile *Owner);
0128
0129 bool operator==(const BasicSymbolRef &Other) const;
0130 bool operator<(const BasicSymbolRef &Other) const;
0131
0132 void moveNext();
0133
0134 Error printName(raw_ostream &OS) const;
0135
0136
0137 Expected<uint32_t> getFlags() const;
0138
0139 DataRefImpl getRawDataRefImpl() const;
0140 const SymbolicFile *getObject() const;
0141 };
0142
0143 using basic_symbol_iterator = content_iterator<BasicSymbolRef>;
0144
0145 class SymbolicFile : public Binary {
0146 public:
0147 SymbolicFile(unsigned int Type, MemoryBufferRef Source);
0148 ~SymbolicFile() override;
0149
0150
0151 virtual void moveSymbolNext(DataRefImpl &Symb) const = 0;
0152
0153 virtual Error printSymbolName(raw_ostream &OS, DataRefImpl Symb) const = 0;
0154
0155 virtual Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const = 0;
0156
0157 virtual basic_symbol_iterator symbol_begin() const = 0;
0158
0159 virtual basic_symbol_iterator symbol_end() const = 0;
0160
0161 virtual bool is64Bit() const = 0;
0162
0163
0164 using basic_symbol_iterator_range = iterator_range<basic_symbol_iterator>;
0165 basic_symbol_iterator_range symbols() const {
0166 return basic_symbol_iterator_range(symbol_begin(), symbol_end());
0167 }
0168
0169
0170 static Expected<std::unique_ptr<SymbolicFile>>
0171 createSymbolicFile(MemoryBufferRef Object, llvm::file_magic Type,
0172 LLVMContext *Context, bool InitContent = true);
0173
0174 static Expected<std::unique_ptr<SymbolicFile>>
0175 createSymbolicFile(MemoryBufferRef Object) {
0176 return createSymbolicFile(Object, llvm::file_magic::unknown, nullptr);
0177 }
0178
0179 static bool classof(const Binary *v) {
0180 return v->isSymbolic();
0181 }
0182
0183 static bool isSymbolicFile(file_magic Type, const LLVMContext *Context);
0184 };
0185
0186 inline BasicSymbolRef::BasicSymbolRef(DataRefImpl SymbolP,
0187 const SymbolicFile *Owner)
0188 : SymbolPimpl(SymbolP), OwningObject(Owner) {}
0189
0190 inline bool BasicSymbolRef::operator==(const BasicSymbolRef &Other) const {
0191 return SymbolPimpl == Other.SymbolPimpl;
0192 }
0193
0194 inline bool BasicSymbolRef::operator<(const BasicSymbolRef &Other) const {
0195 return SymbolPimpl < Other.SymbolPimpl;
0196 }
0197
0198 inline void BasicSymbolRef::moveNext() {
0199 return OwningObject->moveSymbolNext(SymbolPimpl);
0200 }
0201
0202 inline Error BasicSymbolRef::printName(raw_ostream &OS) const {
0203 return OwningObject->printSymbolName(OS, SymbolPimpl);
0204 }
0205
0206 inline Expected<uint32_t> BasicSymbolRef::getFlags() const {
0207 return OwningObject->getSymbolFlags(SymbolPimpl);
0208 }
0209
0210 inline DataRefImpl BasicSymbolRef::getRawDataRefImpl() const {
0211 return SymbolPimpl;
0212 }
0213
0214 inline const SymbolicFile *BasicSymbolRef::getObject() const {
0215 return OwningObject;
0216 }
0217
0218 }
0219 }
0220
0221 #endif