LCOV - code coverage report
Current view: top level - lib/CodeGen/AsmPrinter - DwarfStringPool.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 51 52 98.1 %
Date: 2018-10-20 13:21:21 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- llvm/CodeGen/DwarfStringPool.cpp - Dwarf Debug Framework -----------===//
       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             : #include "DwarfStringPool.h"
      11             : #include "llvm/ADT/SmallVector.h"
      12             : #include "llvm/ADT/StringRef.h"
      13             : #include "llvm/ADT/Twine.h"
      14             : #include "llvm/CodeGen/AsmPrinter.h"
      15             : #include "llvm/MC/MCAsmInfo.h"
      16             : #include "llvm/MC/MCStreamer.h"
      17             : #include <cassert>
      18             : #include <utility>
      19             : 
      20             : using namespace llvm;
      21             : 
      22       54031 : DwarfStringPool::DwarfStringPool(BumpPtrAllocator &A, AsmPrinter &Asm,
      23       54031 :                                  StringRef Prefix)
      24             :     : Pool(A), Prefix(Prefix),
      25       54031 :       ShouldCreateSymbols(Asm.MAI->doesDwarfUseRelocationsAcrossSections()) {}
      26             : 
      27             : StringMapEntry<DwarfStringPool::EntryTy> &
      28      153198 : DwarfStringPool::getEntryImpl(AsmPrinter &Asm, StringRef Str) {
      29      153198 :   auto I = Pool.insert(std::make_pair(Str, EntryTy()));
      30             :   auto &Entry = I.first->second;
      31      153198 :   if (I.second) {
      32       87711 :     Entry.Index = EntryTy::NotIndexed;
      33       87711 :     Entry.Offset = NumBytes;
      34       87711 :     Entry.Symbol = ShouldCreateSymbols ? Asm.createTempSymbol(Prefix) : nullptr;
      35             : 
      36       87711 :     NumBytes += Str.size() + 1;
      37             :     assert(NumBytes > Entry.Offset && "Unexpected overflow");
      38             :   }
      39      153198 :   return *I.first;
      40             : }
      41             : 
      42      152245 : DwarfStringPool::EntryRef DwarfStringPool::getEntry(AsmPrinter &Asm,
      43             :                                                     StringRef Str) {
      44      152245 :   auto &MapEntry = getEntryImpl(Asm, Str);
      45      152247 :   return EntryRef(MapEntry, false);
      46             : }
      47             : 
      48         951 : DwarfStringPool::EntryRef DwarfStringPool::getIndexedEntry(AsmPrinter &Asm,
      49             :                                                            StringRef Str) {
      50         951 :   auto &MapEntry = getEntryImpl(Asm, Str);
      51         951 :   if (!MapEntry.getValue().isIndexed())
      52         848 :     MapEntry.getValue().Index = NumIndexedStrings++;
      53         951 :   return EntryRef(MapEntry, true);
      54             : }
      55             : 
      56         110 : void DwarfStringPool::emitStringOffsetsTableHeader(AsmPrinter &Asm,
      57             :                                                    MCSection *Section,
      58             :                                                    MCSymbol *StartSym) {
      59         110 :   if (getNumIndexedStrings() == 0)
      60             :     return;
      61          46 :   Asm.OutStreamer->SwitchSection(Section);
      62             :   unsigned EntrySize = 4;
      63             :   // FIXME: DWARF64
      64             :   // We are emitting the header for a contribution to the string offsets
      65             :   // table. The header consists of an entry with the contribution's
      66             :   // size (not including the size of the length field), the DWARF version and
      67             :   // 2 bytes of padding.
      68          46 :   Asm.emitInt32(getNumIndexedStrings() * EntrySize + 4);
      69          46 :   Asm.emitInt16(Asm.getDwarfVersion());
      70          46 :   Asm.emitInt16(0);
      71             :   // Define the symbol that marks the start of the contribution. It is
      72             :   // referenced by most unit headers via DW_AT_str_offsets_base.
      73             :   // Split units do not use the attribute.
      74          46 :   if (StartSym)
      75          40 :     Asm.OutStreamer->EmitLabel(StartSym);
      76             : }
      77             : 
      78        1171 : void DwarfStringPool::emit(AsmPrinter &Asm, MCSection *StrSection,
      79             :                            MCSection *OffsetSection, bool UseRelativeOffsets) {
      80        1171 :   if (Pool.empty())
      81          87 :     return;
      82             : 
      83             :   // Start the dwarf str section.
      84        1084 :   Asm.OutStreamer->SwitchSection(StrSection);
      85             : 
      86             :   // Get all of the string pool entries and sort them by their offset.
      87             :   SmallVector<const StringMapEntry<EntryTy> *, 64> Entries;
      88        1085 :   Entries.reserve(Pool.size());
      89             : 
      90       89871 :   for (const auto &E : Pool)
      91       87701 :     Entries.push_back(&E);
      92             : 
      93             :   llvm::sort(Entries, [](const StringMapEntry<EntryTy> *A,
      94             :                          const StringMapEntry<EntryTy> *B) {
      95           0 :     return A->getValue().Offset < B->getValue().Offset;
      96             :   });
      97             : 
      98       88787 :   for (const auto &Entry : Entries) {
      99             :     assert(ShouldCreateSymbols == static_cast<bool>(Entry->getValue().Symbol) &&
     100             :            "Mismatch between setting and entry");
     101             : 
     102             :     // Emit a label for reference from debug information entries.
     103       87702 :     if (ShouldCreateSymbols)
     104       85528 :       Asm.OutStreamer->EmitLabel(Entry->getValue().Symbol);
     105             : 
     106             :     // Emit the string itself with a terminating null byte.
     107       87703 :     Asm.OutStreamer->AddComment("string offset=" +
     108      175406 :                                 Twine(Entry->getValue().Offset));
     109       87703 :     Asm.OutStreamer->EmitBytes(
     110       87703 :         StringRef(Entry->getKeyData(), Entry->getKeyLength() + 1));
     111             :   }
     112             : 
     113             :   // If we've got an offset section go ahead and emit that now as well.
     114        1085 :   if (OffsetSection) {
     115             :     // Now only take the indexed entries and put them in an array by their ID so
     116             :     // we can emit them in order.
     117         105 :     Entries.resize(NumIndexedStrings);
     118        1221 :     for (const auto &Entry : Pool) {
     119        1011 :       if (Entry.getValue().isIndexed())
     120        1696 :         Entries[Entry.getValue().Index] = &Entry;
     121             :     }
     122             : 
     123         105 :     Asm.OutStreamer->SwitchSection(OffsetSection);
     124             :     unsigned size = 4; // FIXME: DWARF64 is 8.
     125         953 :     for (const auto &Entry : Entries)
     126         848 :       if (UseRelativeOffsets)
     127        1026 :         Asm.emitDwarfStringOffset(Entry->getValue());
     128             :       else
     129         335 :         Asm.OutStreamer->EmitIntValue(Entry->getValue().Offset, size);
     130             :   }
     131             : }

Generated by: LCOV version 1.13