LCOV - code coverage report
Current view: top level - lib/DebugInfo/DWARF - DWARFUnitIndex.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 92 97 94.8 %
Date: 2017-09-14 15:23:50 Functions: 10 10 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- DWARFUnitIndex.cpp -------------------------------------------------===//
       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 "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
      11             : #include "llvm/ADT/STLExtras.h"
      12             : #include "llvm/ADT/StringRef.h"
      13             : #include "llvm/Support/ErrorHandling.h"
      14             : #include "llvm/Support/Format.h"
      15             : #include "llvm/Support/raw_ostream.h"
      16             : #include <cinttypes>
      17             : #include <cstdint>
      18             : 
      19             : using namespace llvm;
      20             : 
      21        1017 : bool DWARFUnitIndex::Header::parse(DataExtractor IndexData,
      22             :                                    uint32_t *OffsetPtr) {
      23        1044 :   if (!IndexData.isValidOffsetForDataOfSize(*OffsetPtr, 16))
      24             :     return false;
      25          27 :   Version = IndexData.getU32(OffsetPtr);
      26          27 :   NumColumns = IndexData.getU32(OffsetPtr);
      27          27 :   NumUnits = IndexData.getU32(OffsetPtr);
      28          27 :   NumBuckets = IndexData.getU32(OffsetPtr);
      29          27 :   return Version <= 2;
      30             : }
      31             : 
      32          14 : void DWARFUnitIndex::Header::dump(raw_ostream &OS) const {
      33          28 :   OS << format("version = %u slots = %u\n\n", Version, NumBuckets);
      34          14 : }
      35             : 
      36        1017 : bool DWARFUnitIndex::parse(DataExtractor IndexData) {
      37        1017 :   bool b = parseImpl(IndexData);
      38        1017 :   if (!b) {
      39             :     // Make sure we don't try to dump anything
      40         990 :     Header.NumBuckets = 0;
      41             :     // Release any partially initialized data.
      42        1980 :     ColumnKinds.reset();
      43         990 :     Rows.reset();
      44             :   }
      45        1017 :   return b;
      46             : }
      47             : 
      48        1017 : bool DWARFUnitIndex::parseImpl(DataExtractor IndexData) {
      49        1017 :   uint32_t Offset = 0;
      50        1017 :   if (!Header.parse(IndexData, &Offset))
      51             :     return false;
      52             : 
      53          54 :   if (!IndexData.isValidOffsetForDataOfSize(
      54          27 :           Offset, Header.NumBuckets * (8 + 4) +
      55          27 :                       (2 * Header.NumUnits + 1) * 4 * Header.NumColumns))
      56             :     return false;
      57             : 
      58          81 :   Rows = llvm::make_unique<Entry[]>(Header.NumBuckets);
      59             :   auto Contribs =
      60          27 :       llvm::make_unique<Entry::SectionContribution *[]>(Header.NumUnits);
      61          81 :   ColumnKinds = llvm::make_unique<DWARFSectionKind[]>(Header.NumColumns);
      62             : 
      63             :   // Read Hash Table of Signatures
      64         161 :   for (unsigned i = 0; i != Header.NumBuckets; ++i)
      65         268 :     Rows[i].Signature = IndexData.getU64(&Offset);
      66             : 
      67             :   // Read Parallel Table of Indexes
      68         295 :   for (unsigned i = 0; i != Header.NumBuckets; ++i) {
      69         134 :     auto Index = IndexData.getU32(&Offset);
      70         134 :     if (!Index)
      71          79 :       continue;
      72         110 :     Rows[i].Index = this;
      73         165 :     Rows[i].Contributions =
      74         165 :         llvm::make_unique<Entry::SectionContribution[]>(Header.NumColumns);
      75         220 :     Contribs[Index - 1] = Rows[i].Contributions.get();
      76             :   }
      77             : 
      78             :   // Read the Column Headers
      79         235 :   for (unsigned i = 0; i != Header.NumColumns; ++i) {
      80         208 :     ColumnKinds[i] = static_cast<DWARFSectionKind>(IndexData.getU32(&Offset));
      81         208 :     if (ColumnKinds[i] == InfoColumnKind) {
      82          27 :       if (InfoColumn != -1)
      83             :         return false;
      84          27 :       InfoColumn = i;
      85             :     }
      86             :   }
      87             : 
      88          27 :   if (InfoColumn == -1)
      89             :     return false;
      90             : 
      91             :   // Read Table of Section Offsets
      92         137 :   for (unsigned i = 0; i != Header.NumUnits; ++i) {
      93         110 :     auto *Contrib = Contribs[i];
      94         268 :     for (unsigned i = 0; i != Header.NumColumns; ++i)
      95         213 :       Contrib[i].Offset = IndexData.getU32(&Offset);
      96             :   }
      97             : 
      98             :   // Read Table of Section Sizes
      99         137 :   for (unsigned i = 0; i != Header.NumUnits; ++i) {
     100         110 :     auto *Contrib = Contribs[i];
     101         268 :     for (unsigned i = 0; i != Header.NumColumns; ++i)
     102         213 :       Contrib[i].Length = IndexData.getU32(&Offset);
     103             :   }
     104             : 
     105             :   return true;
     106             : }
     107             : 
     108          52 : StringRef DWARFUnitIndex::getColumnHeader(DWARFSectionKind DS) {
     109             : #define CASE(DS)                                                               \
     110             :   case DW_SECT_##DS:                                                           \
     111             :     return #DS;
     112          52 :   switch (DS) {
     113           9 :     CASE(INFO);
     114           5 :     CASE(TYPES);
     115          14 :     CASE(ABBREV);
     116          12 :     CASE(LINE);
     117           0 :     CASE(LOC);
     118          12 :     CASE(STR_OFFSETS);
     119           0 :     CASE(MACINFO);
     120           0 :     CASE(MACRO);
     121             :   }
     122           0 :   llvm_unreachable("unknown DWARFSectionKind");
     123             : }
     124             : 
     125         332 : void DWARFUnitIndex::dump(raw_ostream &OS) const {
     126         332 :   if (!*this)
     127             :     return;
     128             : 
     129          14 :   Header.dump(OS);
     130          14 :   OS << "Index Signature         ";
     131          66 :   for (unsigned i = 0; i != Header.NumColumns; ++i)
     132         156 :     OS << ' ' << left_justify(getColumnHeader(ColumnKinds[i]), 24);
     133          14 :   OS << "\n----- ------------------";
     134          66 :   for (unsigned i = 0; i != Header.NumColumns; ++i)
     135          52 :     OS << " ------------------------";
     136             :   OS << '\n';
     137         190 :   for (unsigned i = 0; i != Header.NumBuckets; ++i) {
     138         176 :     auto &Row = Rows[i];
     139         176 :     if (auto *Contribs = Row.Contributions.get()) {
     140          64 :       OS << format("%5u 0x%016" PRIx64 " ", i + 1, Row.Signature);
     141         153 :       for (unsigned i = 0; i != Header.NumColumns; ++i) {
     142         121 :         auto &Contrib = Contribs[i];
     143         242 :         OS << format("[0x%08x, 0x%08x) ", Contrib.Offset,
     144         121 :                      Contrib.Offset + Contrib.Length);
     145             :       }
     146             :       OS << '\n';
     147             :     }
     148             :   }
     149             : }
     150             : 
     151             : const DWARFUnitIndex::Entry::SectionContribution *
     152         123 : DWARFUnitIndex::Entry::getOffset(DWARFSectionKind Sec) const {
     153         123 :   uint32_t i = 0;
     154         539 :   for (; i != Index->Header.NumColumns; ++i)
     155         656 :     if (Index->ColumnKinds[i] == Sec)
     156         240 :       return &Contributions[i];
     157             :   return nullptr;
     158             : }
     159             : 
     160             : const DWARFUnitIndex::Entry::SectionContribution *
     161          40 : DWARFUnitIndex::Entry::getOffset() const {
     162          80 :   return &Contributions[Index->InfoColumn];
     163             : }
     164             : 
     165             : const DWARFUnitIndex::Entry *
     166       27502 : DWARFUnitIndex::getFromOffset(uint32_t Offset) const {
     167       27622 :   for (uint32_t i = 0; i != Header.NumBuckets; ++i)
     168         480 :     if (const auto &Contribs = Rows[i].Contributions)
     169         142 :       if (Contribs[InfoColumn].Offset == Offset)
     170             :         return &Rows[i];
     171             :   return nullptr;
     172             : }
     173             : 
     174           4 : const DWARFUnitIndex::Entry *DWARFUnitIndex::getFromHash(uint64_t S) const {
     175           4 :   uint64_t Mask = Header.NumBuckets - 1;
     176             : 
     177           4 :   auto H = S & Mask;
     178           4 :   auto HP = ((S >> 32) & Mask) | 1;
     179           8 :   while (Rows[H].getSignature() != S && Rows[H].getSignature() != 0)
     180           0 :     H = (H + HP) & Mask;
     181             : 
     182           8 :   if (Rows[H].getSignature() != S)
     183             :     return nullptr;
     184             : 
     185           8 :   return &Rows[H];
     186             : }

Generated by: LCOV version 1.13