/usr/include/llvm-3.9/llvm/Object/SymbolicFile.h is in llvm-3.9-dev 1:3.9.1-19ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 | //===- SymbolicFile.h - Interface that only provides symbols ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares the SymbolicFile interface.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_OBJECT_SYMBOLICFILE_H
#define LLVM_OBJECT_SYMBOLICFILE_H
#include "llvm/Object/Binary.h"
#include "llvm/Support/Format.h"
#include <utility>
namespace llvm {
namespace object {
union DataRefImpl {
// This entire union should probably be a
// char[max(8, sizeof(uintptr_t))] and require the impl to cast.
struct {
uint32_t a, b;
} d;
uintptr_t p;
DataRefImpl() { std::memset(this, 0, sizeof(DataRefImpl)); }
};
template <typename OStream>
OStream& operator<<(OStream &OS, const DataRefImpl &D) {
OS << "(" << format("0x%x8", D.p) << " (" << format("0x%x8", D.d.a) << ", " << format("0x%x8", D.d.b) << "))";
return OS;
}
inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) {
// Check bitwise identical. This is the only legal way to compare a union w/o
// knowing which member is in use.
return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
}
inline bool operator!=(const DataRefImpl &a, const DataRefImpl &b) {
return !operator==(a, b);
}
inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) {
// Check bitwise identical. This is the only legal way to compare a union w/o
// knowing which member is in use.
return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0;
}
template <class content_type>
class content_iterator
: public std::iterator<std::forward_iterator_tag, content_type> {
content_type Current;
public:
content_iterator(content_type symb) : Current(std::move(symb)) {}
const content_type *operator->() const { return &Current; }
const content_type &operator*() const { return Current; }
bool operator==(const content_iterator &other) const {
return Current == other.Current;
}
bool operator!=(const content_iterator &other) const {
return !(*this == other);
}
content_iterator &operator++() { // preincrement
Current.moveNext();
return *this;
}
};
class SymbolicFile;
/// This is a value type class that represents a single symbol in the list of
/// symbols in the object file.
class BasicSymbolRef {
DataRefImpl SymbolPimpl;
const SymbolicFile *OwningObject;
public:
// FIXME: should we add a SF_Text?
enum Flags : unsigned {
SF_None = 0,
SF_Undefined = 1U << 0, // Symbol is defined in another object file
SF_Global = 1U << 1, // Global symbol
SF_Weak = 1U << 2, // Weak symbol
SF_Absolute = 1U << 3, // Absolute symbol
SF_Common = 1U << 4, // Symbol has common linkage
SF_Indirect = 1U << 5, // Symbol is an alias to another symbol
SF_Exported = 1U << 6, // Symbol is visible to other DSOs
SF_FormatSpecific = 1U << 7, // Specific to the object file format
// (e.g. section symbols)
SF_Thumb = 1U << 8, // Thumb symbol in a 32-bit ARM binary
SF_Hidden = 1U << 9, // Symbol has hidden visibility
SF_Const = 1U << 10, // Symbol value is constant
};
BasicSymbolRef() : OwningObject(nullptr) { }
BasicSymbolRef(DataRefImpl SymbolP, const SymbolicFile *Owner);
bool operator==(const BasicSymbolRef &Other) const;
bool operator<(const BasicSymbolRef &Other) const;
void moveNext();
std::error_code printName(raw_ostream &OS) const;
/// Get symbol flags (bitwise OR of SymbolRef::Flags)
uint32_t getFlags() const;
DataRefImpl getRawDataRefImpl() const;
const SymbolicFile *getObject() const;
};
typedef content_iterator<BasicSymbolRef> basic_symbol_iterator;
class SymbolicFile : public Binary {
public:
~SymbolicFile() override;
SymbolicFile(unsigned int Type, MemoryBufferRef Source);
// virtual interface.
virtual void moveSymbolNext(DataRefImpl &Symb) const = 0;
virtual std::error_code printSymbolName(raw_ostream &OS,
DataRefImpl Symb) const = 0;
virtual uint32_t getSymbolFlags(DataRefImpl Symb) const = 0;
virtual basic_symbol_iterator symbol_begin_impl() const = 0;
virtual basic_symbol_iterator symbol_end_impl() const = 0;
// convenience wrappers.
basic_symbol_iterator symbol_begin() const {
return symbol_begin_impl();
}
basic_symbol_iterator symbol_end() const {
return symbol_end_impl();
}
typedef iterator_range<basic_symbol_iterator> basic_symbol_iterator_range;
basic_symbol_iterator_range symbols() const {
return basic_symbol_iterator_range(symbol_begin(), symbol_end());
}
// construction aux.
static Expected<std::unique_ptr<SymbolicFile>>
createSymbolicFile(MemoryBufferRef Object, sys::fs::file_magic Type,
LLVMContext *Context);
static Expected<std::unique_ptr<SymbolicFile>>
createSymbolicFile(MemoryBufferRef Object) {
return createSymbolicFile(Object, sys::fs::file_magic::unknown, nullptr);
}
static Expected<OwningBinary<SymbolicFile>>
createSymbolicFile(StringRef ObjectPath);
static inline bool classof(const Binary *v) {
return v->isSymbolic();
}
};
inline BasicSymbolRef::BasicSymbolRef(DataRefImpl SymbolP,
const SymbolicFile *Owner)
: SymbolPimpl(SymbolP), OwningObject(Owner) {}
inline bool BasicSymbolRef::operator==(const BasicSymbolRef &Other) const {
return SymbolPimpl == Other.SymbolPimpl;
}
inline bool BasicSymbolRef::operator<(const BasicSymbolRef &Other) const {
return SymbolPimpl < Other.SymbolPimpl;
}
inline void BasicSymbolRef::moveNext() {
return OwningObject->moveSymbolNext(SymbolPimpl);
}
inline std::error_code BasicSymbolRef::printName(raw_ostream &OS) const {
return OwningObject->printSymbolName(OS, SymbolPimpl);
}
inline uint32_t BasicSymbolRef::getFlags() const {
return OwningObject->getSymbolFlags(SymbolPimpl);
}
inline DataRefImpl BasicSymbolRef::getRawDataRefImpl() const {
return SymbolPimpl;
}
inline const SymbolicFile *BasicSymbolRef::getObject() const {
return OwningObject;
}
}
}
#endif
|