aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/Object/SymbolicFile.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Object/SymbolicFile.h')
-rw-r--r--include/llvm/Object/SymbolicFile.h194
1 files changed, 194 insertions, 0 deletions
diff --git a/include/llvm/Object/SymbolicFile.h b/include/llvm/Object/SymbolicFile.h
new file mode 100644
index 0000000..bead2c3
--- /dev/null
+++ b/include/llvm/Object/SymbolicFile.h
@@ -0,0 +1,194 @@
+//===- 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_SYMBOLIC_FILE_H
+#define LLVM_OBJECT_SYMBOLIC_FILE_H
+
+#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;
+}
+
+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 {
+ 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?
+ 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_FormatSpecific = 1U << 5 // Specific to the object file format
+ // (e.g. section symbols)
+ };
+
+ BasicSymbolRef() : OwningObject(NULL) { }
+ BasicSymbolRef(DataRefImpl SymbolP, const SymbolicFile *Owner);
+
+ bool operator==(const BasicSymbolRef &Other) const;
+ bool operator<(const BasicSymbolRef &Other) const;
+
+ void moveNext();
+
+ 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;
+
+const uint64_t UnknownAddressOrSize = ~0ULL;
+
+class SymbolicFile : public Binary {
+public:
+ virtual ~SymbolicFile();
+ SymbolicFile(unsigned int Type, MemoryBuffer *Source, bool BufferOwned);
+
+ // virtual interface.
+ virtual void moveSymbolNext(DataRefImpl &Symb) const = 0;
+
+ virtual 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();
+ }
+
+ // construction aux.
+ static ErrorOr<SymbolicFile *> createIRObjectFile(MemoryBuffer *Object,
+ LLVMContext &Context,
+ bool BufferOwned = true);
+
+ static ErrorOr<SymbolicFile *> createSymbolicFile(MemoryBuffer *Object,
+ bool BufferOwned,
+ sys::fs::file_magic Type,
+ LLVMContext *Context);
+
+ static ErrorOr<SymbolicFile *> createSymbolicFile(MemoryBuffer *Object) {
+ return createSymbolicFile(Object, true, sys::fs::file_magic::unknown, 0);
+ }
+ static ErrorOr<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 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