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