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

          Line data    Source code
       1             : //===- IRSymtab.h - data definitions for IR symbol tables -------*- 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 contains data definitions and a reader and builder for a symbol
      11             : // table for LLVM IR. Its purpose is to allow linkers and other consumers of
      12             : // bitcode files to efficiently read the symbol table for symbol resolution
      13             : // purposes without needing to construct a module in memory.
      14             : //
      15             : // As with most object files the symbol table has two parts: the symbol table
      16             : // itself and a string table which is referenced by the symbol table.
      17             : //
      18             : // A symbol table corresponds to a single bitcode file, which may consist of
      19             : // multiple modules, so symbol tables may likewise contain symbols for multiple
      20             : // modules.
      21             : //
      22             : //===----------------------------------------------------------------------===//
      23             : 
      24             : #ifndef LLVM_OBJECT_IRSYMTAB_H
      25             : #define LLVM_OBJECT_IRSYMTAB_H
      26             : 
      27             : #include "llvm/ADT/ArrayRef.h"
      28             : #include "llvm/ADT/StringRef.h"
      29             : #include "llvm/ADT/iterator_range.h"
      30             : #include "llvm/IR/GlobalValue.h"
      31             : #include "llvm/Object/SymbolicFile.h"
      32             : #include "llvm/Support/Endian.h"
      33             : #include "llvm/Support/Error.h"
      34             : #include <cassert>
      35             : #include <cstdint>
      36             : #include <vector>
      37             : 
      38             : namespace llvm {
      39             : 
      40             : struct BitcodeFileContents;
      41             : class StringTableBuilder;
      42             : 
      43             : namespace irsymtab {
      44             : 
      45             : namespace storage {
      46             : 
      47             : // The data structures in this namespace define the low-level serialization
      48             : // format. Clients that just want to read a symbol table should use the
      49             : // irsymtab::Reader class.
      50             : 
      51             : using Word = support::ulittle32_t;
      52             : 
      53             : /// A reference to a string in the string table.
      54             : struct Str {
      55             :   Word Offset, Size;
      56             : 
      57             :   StringRef get(StringRef Strtab) const {
      58       17670 :     return {Strtab.data() + Offset, Size};
      59             :   }
      60             : };
      61             : 
      62             : /// A reference to a range of objects in the symbol table.
      63             : template <typename T> struct Range {
      64             :   Word Offset, Size;
      65             : 
      66             :   ArrayRef<T> get(StringRef Symtab) const {
      67        7968 :     return {reinterpret_cast<const T *>(Symtab.data() + Offset), Size};
      68             :   }
      69             : };
      70             : 
      71             : /// Describes the range of a particular module's symbols within the symbol
      72             : /// table.
      73             : struct Module {
      74             :   Word Begin, End;
      75             : 
      76             :   /// The index of the first Uncommon for this Module.
      77             :   Word UncBegin;
      78             : };
      79             : 
      80             : /// This is equivalent to an IR comdat.
      81             : struct Comdat {
      82             :   Str Name;
      83             : };
      84             : 
      85             : /// Contains the information needed by linkers for symbol resolution, as well as
      86             : /// by the LTO implementation itself.
      87             : struct Symbol {
      88             :   /// The mangled symbol name.
      89             :   Str Name;
      90             : 
      91             :   /// The unmangled symbol name, or the empty string if this is not an IR
      92             :   /// symbol.
      93             :   Str IRName;
      94             : 
      95             :   /// The index into Header::Comdats, or -1 if not a comdat member.
      96             :   Word ComdatIndex;
      97             : 
      98             :   Word Flags;
      99             :   enum FlagBits {
     100             :     FB_visibility, // 2 bits
     101             :     FB_has_uncommon = FB_visibility + 2,
     102             :     FB_undefined,
     103             :     FB_weak,
     104             :     FB_common,
     105             :     FB_indirect,
     106             :     FB_used,
     107             :     FB_tls,
     108             :     FB_may_omit,
     109             :     FB_global,
     110             :     FB_format_specific,
     111             :     FB_unnamed_addr,
     112             :     FB_executable,
     113             :   };
     114             : };
     115             : 
     116             : /// This data structure contains rarely used symbol fields and is optionally
     117             : /// referenced by a Symbol.
     118             : struct Uncommon {
     119             :   Word CommonSize, CommonAlign;
     120             : 
     121             :   /// COFF-specific: the name of the symbol that a weak external resolves to
     122             :   /// if not defined.
     123             :   Str COFFWeakExternFallbackName;
     124             : 
     125             :   /// Specified section name, if any.
     126             :   Str SectionName;
     127             : };
     128             : 
     129             : struct Header {
     130             :   /// Version number of the symtab format. This number should be incremented
     131             :   /// when the format changes, but it does not need to be incremented if a
     132             :   /// change to LLVM would cause it to create a different symbol table.
     133             :   Word Version;
     134             :   enum { kCurrentVersion = 1 };
     135             : 
     136             :   /// The producer's version string (LLVM_VERSION_STRING " " LLVM_REVISION).
     137             :   /// Consumers should rebuild the symbol table from IR if the producer's
     138             :   /// version does not match the consumer's version due to potential differences
     139             :   /// in symbol table format, symbol enumeration order and so on.
     140             :   Str Producer;
     141             : 
     142             :   Range<Module> Modules;
     143             :   Range<Comdat> Comdats;
     144             :   Range<Symbol> Symbols;
     145             :   Range<Uncommon> Uncommons;
     146             : 
     147             :   Str TargetTriple, SourceFileName;
     148             : 
     149             :   /// COFF-specific: linker directives.
     150             :   Str COFFLinkerOpts;
     151             : };
     152             : 
     153             : } // end namespace storage
     154             : 
     155             : /// Fills in Symtab and StrtabBuilder with a valid symbol and string table for
     156             : /// Mods.
     157             : Error build(ArrayRef<Module *> Mods, SmallVector<char, 0> &Symtab,
     158             :             StringTableBuilder &StrtabBuilder, BumpPtrAllocator &Alloc);
     159             : 
     160             : /// This represents a symbol that has been read from a storage::Symbol and
     161             : /// possibly a storage::Uncommon.
     162        6730 : struct Symbol {
     163             :   // Copied from storage::Symbol.
     164             :   StringRef Name, IRName;
     165             :   int ComdatIndex;
     166             :   uint32_t Flags;
     167             : 
     168             :   // Copied from storage::Uncommon.
     169             :   uint32_t CommonSize, CommonAlign;
     170             :   StringRef COFFWeakExternFallbackName;
     171             :   StringRef SectionName;
     172             : 
     173             :   /// Returns the mangled symbol name.
     174             :   StringRef getName() const { return Name; }
     175             : 
     176             :   /// Returns the unmangled symbol name, or the empty string if this is not an
     177             :   /// IR symbol.
     178             :   StringRef getIRName() const { return IRName; }
     179             : 
     180             :   /// Returns the index into the comdat table (see Reader::getComdatTable()), or
     181             :   /// -1 if not a comdat member.
     182             :   int getComdatIndex() const { return ComdatIndex; }
     183             : 
     184             :   using S = storage::Symbol;
     185             : 
     186             :   GlobalValue::VisibilityTypes getVisibility() const {
     187         615 :     return GlobalValue::VisibilityTypes((Flags >> S::FB_visibility) & 3);
     188             :   }
     189             : 
     190        1552 :   bool isUndefined() const { return (Flags >> S::FB_undefined) & 1; }
     191         692 :   bool isWeak() const { return (Flags >> S::FB_weak) & 1; }
     192        1216 :   bool isCommon() const { return (Flags >> S::FB_common) & 1; }
     193          49 :   bool isIndirect() const { return (Flags >> S::FB_indirect) & 1; }
     194         770 :   bool isUsed() const { return (Flags >> S::FB_used) & 1; }
     195         302 :   bool isTLS() const { return (Flags >> S::FB_tls) & 1; }
     196             : 
     197             :   bool canBeOmittedFromSymbolTable() const {
     198         615 :     return (Flags >> S::FB_may_omit) & 1;
     199             :   }
     200             : 
     201        1505 :   bool isGlobal() const { return (Flags >> S::FB_global) & 1; }
     202        1415 :   bool isFormatSpecific() const { return (Flags >> S::FB_format_specific) & 1; }
     203        1003 :   bool isUnnamedAddr() const { return (Flags >> S::FB_unnamed_addr) & 1; }
     204          29 :   bool isExecutable() const { return (Flags >> S::FB_executable) & 1; }
     205             : 
     206             :   uint64_t getCommonSize() const {
     207             :     assert(isCommon());
     208          39 :     return CommonSize;
     209             :   }
     210             : 
     211             :   uint32_t getCommonAlignment() const {
     212             :     assert(isCommon());
     213             :     return CommonAlign;
     214             :   }
     215             : 
     216             :   /// COFF-specific: for weak externals, returns the name of the symbol that is
     217             :   /// used as a fallback if the weak external remains undefined.
     218             :   StringRef getCOFFWeakExternalFallback() const {
     219             :     assert(isWeak() && isIndirect());
     220             :     return COFFWeakExternFallbackName;
     221             :   }
     222             : 
     223             :   StringRef getSectionName() const { return SectionName; }
     224             : };
     225             : 
     226             : /// This class can be used to read a Symtab and Strtab produced by
     227             : /// irsymtab::build.
     228             : class Reader {
     229             :   StringRef Symtab, Strtab;
     230             : 
     231             :   ArrayRef<storage::Module> Modules;
     232             :   ArrayRef<storage::Comdat> Comdats;
     233             :   ArrayRef<storage::Symbol> Symbols;
     234             :   ArrayRef<storage::Uncommon> Uncommons;
     235             : 
     236       10470 :   StringRef str(storage::Str S) const { return S.get(Strtab); }
     237             : 
     238             :   template <typename T> ArrayRef<T> range(storage::Range<T> R) const {
     239        5312 :     return R.get(Symtab);
     240             :   }
     241             : 
     242             :   const storage::Header &header() const {
     243        5976 :     return *reinterpret_cast<const storage::Header *>(Symtab.data());
     244             :   }
     245             : 
     246             : public:
     247             :   class SymbolRef;
     248             : 
     249        9401 :   Reader() = default;
     250         664 :   Reader(StringRef Symtab, StringRef Strtab) : Symtab(Symtab), Strtab(Strtab) {
     251        1328 :     Modules = range(header().Modules);
     252        1328 :     Comdats = range(header().Comdats);
     253        1328 :     Symbols = range(header().Symbols);
     254        1328 :     Uncommons = range(header().Uncommons);
     255         664 :   }
     256             : 
     257             :   using symbol_range = iterator_range<object::content_iterator<SymbolRef>>;
     258             : 
     259             :   /// Returns the symbol table for the entire bitcode file.
     260             :   /// The symbols enumerated by this method are ephemeral, but they can be
     261             :   /// copied into an irsymtab::Symbol object.
     262             :   symbol_range symbols() const;
     263             : 
     264         648 :   size_t getNumModules() const { return Modules.size(); }
     265             : 
     266             :   /// Returns a slice of the symbol table for the I'th module in the file.
     267             :   /// The symbols enumerated by this method are ephemeral, but they can be
     268             :   /// copied into an irsymtab::Symbol object.
     269             :   symbol_range module_symbols(unsigned I) const;
     270             : 
     271        1328 :   StringRef getTargetTriple() const { return str(header().TargetTriple); }
     272             : 
     273             :   /// Returns the source file path specified at compile time.
     274        1328 :   StringRef getSourceFileName() const { return str(header().SourceFileName); }
     275             : 
     276             :   /// Returns a table with all the comdats used by this file.
     277         664 :   std::vector<StringRef> getComdatTable() const {
     278         664 :     std::vector<StringRef> ComdatTable;
     279         664 :     ComdatTable.reserve(Comdats.size());
     280        1377 :     for (auto C : Comdats)
     281          98 :       ComdatTable.push_back(str(C.Name));
     282         664 :     return ComdatTable;
     283             :   }
     284             : 
     285             :   /// COFF-specific: returns linker options specified in the input file.
     286        1328 :   StringRef getCOFFLinkerOpts() const { return str(header().COFFLinkerOpts); }
     287             : };
     288             : 
     289             : /// Ephemeral symbols produced by Reader::symbols() and
     290             : /// Reader::module_symbols().
     291             : class Reader::SymbolRef : public Symbol {
     292             :   const storage::Symbol *SymI, *SymE;
     293             :   const storage::Uncommon *UncI;
     294             :   const Reader *R;
     295             : 
     296        2851 :   void read() {
     297        2851 :     if (SymI == SymE)
     298             :       return;
     299             : 
     300        3010 :     Name = R->str(SymI->Name);
     301        3010 :     IRName = R->str(SymI->IRName);
     302        3010 :     ComdatIndex = SymI->ComdatIndex;
     303        3010 :     Flags = SymI->Flags;
     304             : 
     305        1505 :     if (Flags & (1 << storage::Symbol::FB_has_uncommon)) {
     306         184 :       CommonSize = UncI->CommonSize;
     307         184 :       CommonAlign = UncI->CommonAlign;
     308         184 :       COFFWeakExternFallbackName = R->str(UncI->COFFWeakExternFallbackName);
     309         184 :       SectionName = R->str(UncI->SectionName);
     310             :     } else
     311             :       // Reset this field so it can be queried unconditionally for all symbols.
     312        1413 :       SectionName = "";
     313             :   }
     314             : 
     315             : public:
     316             :   SymbolRef(const storage::Symbol *SymI, const storage::Symbol *SymE,
     317             :             const storage::Uncommon *UncI, const Reader *R)
     318        2692 :       : SymI(SymI), SymE(SymE), UncI(UncI), R(R) {
     319        1346 :     read();
     320             :   }
     321             : 
     322        1505 :   void moveNext() {
     323        1505 :     ++SymI;
     324        1505 :     if (Flags & (1 << storage::Symbol::FB_has_uncommon))
     325          92 :       ++UncI;
     326        1505 :     read();
     327        1505 :   }
     328             : 
     329             :   bool operator==(const SymbolRef &Other) const { return SymI == Other.SymI; }
     330             : };
     331             : 
     332             : inline Reader::symbol_range Reader::symbols() const {
     333             :   return {SymbolRef(Symbols.begin(), Symbols.end(), Uncommons.begin(), this),
     334             :           SymbolRef(Symbols.end(), Symbols.end(), nullptr, this)};
     335             : }
     336             : 
     337         673 : inline Reader::symbol_range Reader::module_symbols(unsigned I) const {
     338        1346 :   const storage::Module &M = Modules[I];
     339        1346 :   const storage::Symbol *MBegin = Symbols.begin() + M.Begin,
     340        1346 :                         *MEnd = Symbols.begin() + M.End;
     341        1346 :   return {SymbolRef(MBegin, MEnd, Uncommons.begin() + M.UncBegin, this),
     342        4038 :           SymbolRef(MEnd, MEnd, nullptr, this)};
     343             : }
     344             : 
     345             : /// The contents of the irsymtab in a bitcode file. Any underlying data for the
     346             : /// irsymtab are owned by Symtab and Strtab.
     347        8660 : struct FileContents {
     348             :   SmallVector<char, 0> Symtab, Strtab;
     349             :   Reader TheReader;
     350             : };
     351             : 
     352             : /// Reads the contents of a bitcode file, creating its irsymtab if necessary.
     353             : Expected<FileContents> readBitcode(const BitcodeFileContents &BFC);
     354             : 
     355             : } // end namespace irsymtab
     356             : } // end namespace llvm
     357             : 
     358             : #endif // LLVM_OBJECT_IRSYMTAB_H

Generated by: LCOV version 1.13