SymbolicFile.h 5.9 KB

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