2014-02-21 20:10:59 +00:00
|
|
|
//===- 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.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2014-08-13 16:26:38 +00:00
|
|
|
#ifndef LLVM_OBJECT_SYMBOLICFILE_H
|
|
|
|
#define LLVM_OBJECT_SYMBOLICFILE_H
|
2014-02-21 20:10:59 +00:00
|
|
|
|
|
|
|
#include "llvm/Object/Binary.h"
|
|
|
|
|
|
|
|
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)); }
|
|
|
|
};
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2014-03-21 07:26:41 +00:00
|
|
|
inline bool operator!=(const DataRefImpl &a, const DataRefImpl &b) {
|
|
|
|
return !operator==(a, b);
|
|
|
|
}
|
|
|
|
|
2014-02-21 20:10:59 +00:00
|
|
|
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 {
|
|
|
|
content_type Current;
|
|
|
|
|
|
|
|
public:
|
|
|
|
content_iterator(content_type symb) : Current(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?
|
2014-03-02 03:20:38 +00:00
|
|
|
enum Flags : unsigned {
|
2014-02-21 20:10:59 +00:00
|
|
|
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
|
2014-06-05 21:21:57 +00:00
|
|
|
SF_Indirect = 1U << 5, // Symbol is an alias to another symbol
|
2014-08-18 20:21:02 +00:00
|
|
|
SF_FormatSpecific = 1U << 6, // Specific to the object file format
|
2014-02-21 20:10:59 +00:00
|
|
|
// (e.g. section symbols)
|
2014-08-18 20:21:02 +00:00
|
|
|
SF_Thumb = 1U << 7 // Thumb symbol in a 32-bit ARM binary
|
2014-02-21 20:10:59 +00:00
|
|
|
};
|
|
|
|
|
2014-04-13 04:57:38 +00:00
|
|
|
BasicSymbolRef() : OwningObject(nullptr) { }
|
2014-02-21 20:10:59 +00:00
|
|
|
BasicSymbolRef(DataRefImpl SymbolP, const SymbolicFile *Owner);
|
|
|
|
|
|
|
|
bool operator==(const BasicSymbolRef &Other) const;
|
|
|
|
bool operator<(const BasicSymbolRef &Other) const;
|
|
|
|
|
|
|
|
void moveNext();
|
|
|
|
|
2014-06-12 21:46:39 +00:00
|
|
|
std::error_code printName(raw_ostream &OS) const;
|
2014-02-21 20:10:59 +00:00
|
|
|
|
|
|
|
/// 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;
|
|
|
|
|
|
|
|
const uint64_t UnknownAddressOrSize = ~0ULL;
|
|
|
|
|
|
|
|
class SymbolicFile : public Binary {
|
|
|
|
public:
|
|
|
|
virtual ~SymbolicFile();
|
2014-08-19 18:44:46 +00:00
|
|
|
SymbolicFile(unsigned int Type, MemoryBufferRef Source);
|
2014-02-21 20:10:59 +00:00
|
|
|
|
|
|
|
// virtual interface.
|
|
|
|
virtual void moveSymbolNext(DataRefImpl &Symb) const = 0;
|
|
|
|
|
2014-06-12 21:46:39 +00:00
|
|
|
virtual std::error_code printSymbolName(raw_ostream &OS,
|
|
|
|
DataRefImpl Symb) const = 0;
|
2014-02-21 20:10:59 +00:00
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
2014-06-18 21:14:57 +00:00
|
|
|
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());
|
|
|
|
}
|
2014-02-21 20:10:59 +00:00
|
|
|
|
|
|
|
// construction aux.
|
2014-07-31 03:12:45 +00:00
|
|
|
static ErrorOr<std::unique_ptr<SymbolicFile>>
|
2014-08-19 18:44:46 +00:00
|
|
|
createSymbolicFile(MemoryBufferRef Object, sys::fs::file_magic Type,
|
|
|
|
LLVMContext *Context);
|
2014-02-21 20:10:59 +00:00
|
|
|
|
2014-07-31 03:12:45 +00:00
|
|
|
static ErrorOr<std::unique_ptr<SymbolicFile>>
|
2014-08-19 18:44:46 +00:00
|
|
|
createSymbolicFile(MemoryBufferRef Object) {
|
2014-06-23 21:53:12 +00:00
|
|
|
return createSymbolicFile(Object, sys::fs::file_magic::unknown, nullptr);
|
2014-02-21 20:10:59 +00:00
|
|
|
}
|
2014-08-19 18:44:46 +00:00
|
|
|
static ErrorOr<OwningBinary<SymbolicFile>>
|
2014-07-31 03:12:45 +00:00
|
|
|
createSymbolicFile(StringRef ObjectPath);
|
2014-02-21 20:10:59 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2014-06-12 21:46:39 +00:00
|
|
|
inline std::error_code BasicSymbolRef::printName(raw_ostream &OS) const {
|
2014-02-21 20:10:59 +00:00
|
|
|
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
|