Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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