LCOV - code coverage report
Current view: top level - include/llvm/Object - SymbolicFile.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 27 27 100.0 %
Date: 2017-09-14 15:23:50 Functions: 3 4 75.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : 
      14             : #ifndef LLVM_OBJECT_SYMBOLICFILE_H
      15             : #define LLVM_OBJECT_SYMBOLICFILE_H
      16             : 
      17             : #include "llvm/ADT/StringRef.h"
      18             : #include "llvm/ADT/iterator_range.h"
      19             : #include "llvm/BinaryFormat/Magic.h"
      20             : #include "llvm/Object/Binary.h"
      21             : #include "llvm/Support/Error.h"
      22             : #include "llvm/Support/FileSystem.h"
      23             : #include "llvm/Support/Format.h"
      24             : #include "llvm/Support/MemoryBuffer.h"
      25             : #include <cinttypes>
      26             : #include <cstdint>
      27             : #include <cstring>
      28             : #include <iterator>
      29             : #include <memory>
      30             : #include <system_error>
      31             : 
      32             : namespace llvm {
      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      263446 :   DataRefImpl() { std::memset(this, 0, sizeof(DataRefImpl)); }
      44             : };
      45             : 
      46             : template <typename OStream>
      47           1 : OStream& operator<<(OStream &OS, const DataRefImpl &D) {
      48           5 :   OS << "(" << format("0x%08" PRIxPTR, D.p) << " (" << format("0x%08x", D.d.a)
      49           3 :      << ", " << format("0x%08x", D.d.b) << "))";
      50           1 :   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     8461391 :   return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
      57             : }
      58             : 
      59             : inline bool operator!=(const DataRefImpl &a, const DataRefImpl &b) {
      60           2 :   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       98661 :   return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0;
      67             : }
      68             : 
      69             : template <class content_type>
      70         322 : class content_iterator
      71             :     : public std::iterator<std::forward_iterator_tag, content_type> {
      72             :   content_type Current;
      73             : 
      74             : public:
      75      159349 :   content_iterator(content_type symb) : Current(std::move(symb)) {}
      76             : 
      77          72 :   const content_type *operator->() const { return &Current; }
      78             : 
      79       12400 :   const content_type &operator*() const { return Current; }
      80             : 
      81             :   bool operator==(const content_iterator &other) const {
      82    16922875 :     return Current == other.Current;
      83             :   }
      84             : 
      85             :   bool operator!=(const content_iterator &other) const {
      86     8426601 :     return !(*this == other);
      87             :   }
      88             : 
      89             :   content_iterator &operator++() { // preincrement
      90    16747061 :     Current.moveNext();
      91             :     return *this;
      92             :   }
      93             : };
      94             : 
      95             : class SymbolicFile;
      96             : 
      97             : /// This is a value type class that represents a single symbol in the list of
      98             : /// symbols in the object file.
      99             : class BasicSymbolRef {
     100             :   DataRefImpl SymbolPimpl;
     101             :   const SymbolicFile *OwningObject = nullptr;
     102             : 
     103             : public:
     104             :   enum Flags : unsigned {
     105             :     SF_None = 0,
     106             :     SF_Undefined = 1U << 0,      // Symbol is defined in another object file
     107             :     SF_Global = 1U << 1,         // Global symbol
     108             :     SF_Weak = 1U << 2,           // Weak symbol
     109             :     SF_Absolute = 1U << 3,       // Absolute symbol
     110             :     SF_Common = 1U << 4,         // Symbol has common linkage
     111             :     SF_Indirect = 1U << 5,       // Symbol is an alias to another symbol
     112             :     SF_Exported = 1U << 6,       // Symbol is visible to other DSOs
     113             :     SF_FormatSpecific = 1U << 7, // Specific to the object file format
     114             :                                  // (e.g. section symbols)
     115             :     SF_Thumb = 1U << 8,          // Thumb symbol in a 32-bit ARM binary
     116             :     SF_Hidden = 1U << 9,         // Symbol has hidden visibility
     117             :     SF_Const = 1U << 10,         // Symbol value is constant
     118             :     SF_Executable = 1U << 11,    // Symbol points to an executable section
     119             :                                  // (IR only)
     120             :   };
     121             : 
     122        6662 :   BasicSymbolRef() = default;
     123             :   BasicSymbolRef(DataRefImpl SymbolP, const SymbolicFile *Owner);
     124             : 
     125             :   bool operator==(const BasicSymbolRef &Other) const;
     126             :   bool operator<(const BasicSymbolRef &Other) const;
     127             : 
     128             :   void moveNext();
     129             : 
     130             :   std::error_code printName(raw_ostream &OS) const;
     131             : 
     132             :   /// Get symbol flags (bitwise OR of SymbolRef::Flags)
     133             :   uint32_t getFlags() const;
     134             : 
     135             :   DataRefImpl getRawDataRefImpl() const;
     136             :   const SymbolicFile *getObject() const;
     137             : };
     138             : 
     139             : using basic_symbol_iterator = content_iterator<BasicSymbolRef>;
     140             : 
     141        6544 : class SymbolicFile : public Binary {
     142             : public:
     143             :   SymbolicFile(unsigned int Type, MemoryBufferRef Source);
     144             :   ~SymbolicFile() override;
     145             : 
     146             :   // virtual interface.
     147             :   virtual void moveSymbolNext(DataRefImpl &Symb) const = 0;
     148             : 
     149             :   virtual std::error_code printSymbolName(raw_ostream &OS,
     150             :                                           DataRefImpl Symb) const = 0;
     151             : 
     152             :   virtual uint32_t getSymbolFlags(DataRefImpl Symb) const = 0;
     153             : 
     154             :   virtual basic_symbol_iterator symbol_begin() const = 0;
     155             : 
     156             :   virtual basic_symbol_iterator symbol_end() const = 0;
     157             : 
     158             :   // convenience wrappers.
     159             :   using basic_symbol_iterator_range = iterator_range<basic_symbol_iterator>;
     160         804 :   basic_symbol_iterator_range symbols() const {
     161        1608 :     return basic_symbol_iterator_range(symbol_begin(), symbol_end());
     162             :   }
     163             : 
     164             :   // construction aux.
     165             :   static Expected<std::unique_ptr<SymbolicFile>>
     166             :   createSymbolicFile(MemoryBufferRef Object, llvm::file_magic Type,
     167             :                      LLVMContext *Context);
     168             : 
     169             :   static Expected<std::unique_ptr<SymbolicFile>>
     170             :   createSymbolicFile(MemoryBufferRef Object) {
     171             :     return createSymbolicFile(Object, llvm::file_magic::unknown, nullptr);
     172             :   }
     173             :   static Expected<OwningBinary<SymbolicFile>>
     174             :   createSymbolicFile(StringRef ObjectPath);
     175             : 
     176             :   static bool classof(const Binary *v) {
     177             :     return v->isSymbolic();
     178             :   }
     179             : };
     180             : 
     181             : inline BasicSymbolRef::BasicSymbolRef(DataRefImpl SymbolP,
     182       33059 :                                       const SymbolicFile *Owner)
     183       33059 :     : SymbolPimpl(SymbolP), OwningObject(Owner) {}
     184             : 
     185             : inline bool BasicSymbolRef::operator==(const BasicSymbolRef &Other) const {
     186    16488232 :   return SymbolPimpl == Other.SymbolPimpl;
     187             : }
     188             : 
     189             : inline bool BasicSymbolRef::operator<(const BasicSymbolRef &Other) const {
     190       26122 :   return SymbolPimpl < Other.SymbolPimpl;
     191             : }
     192             : 
     193             : inline void BasicSymbolRef::moveNext() {
     194     8230934 :   return OwningObject->moveSymbolNext(SymbolPimpl);
     195             : }
     196             : 
     197             : inline std::error_code BasicSymbolRef::printName(raw_ostream &OS) const {
     198        2022 :   return OwningObject->printSymbolName(OS, SymbolPimpl);
     199             : }
     200             : 
     201             : inline uint32_t BasicSymbolRef::getFlags() const {
     202      127287 :   return OwningObject->getSymbolFlags(SymbolPimpl);
     203             : }
     204             : 
     205             : inline DataRefImpl BasicSymbolRef::getRawDataRefImpl() const {
     206    32626723 :   return SymbolPimpl;
     207             : }
     208             : 
     209             : inline const SymbolicFile *BasicSymbolRef::getObject() const {
     210             :   return OwningObject;
     211             : }
     212             : 
     213             : } // end namespace object
     214             : } // end namespace llvm
     215             : 
     216             : #endif // LLVM_OBJECT_SYMBOLICFILE_H

Generated by: LCOV version 1.13