LCOV - code coverage report
Current view: top level - lib/DebugInfo - DWARFAcceleratorTable.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 71 76 93.4 %
Date: 2015-01-30 11:55:44 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===--- DWARFAcceleratorTable.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/DWARFAcceleratorTable.h"
      11             : #include "llvm/Support/Dwarf.h"
      12             : #include "llvm/Support/Format.h"
      13             : #include "llvm/Support/raw_ostream.h"
      14             : 
      15             : namespace llvm {
      16             : 
      17         376 : bool DWARFAcceleratorTable::extract() {
      18         376 :   uint32_t Offset = 0;
      19             : 
      20             :   // Check that we can at least read the header.
      21         752 :   if (!AccelSection.isValidOffset(offsetof(Header, HeaderDataLength)+4))
      22             :     return false;
      23             : 
      24          72 :   Hdr.Magic = AccelSection.getU32(&Offset);
      25          72 :   Hdr.Version = AccelSection.getU16(&Offset);
      26          72 :   Hdr.HashFunction = AccelSection.getU16(&Offset);
      27          72 :   Hdr.NumBuckets = AccelSection.getU32(&Offset);
      28          72 :   Hdr.NumHashes = AccelSection.getU32(&Offset);
      29          72 :   Hdr.HeaderDataLength = AccelSection.getU32(&Offset);
      30             : 
      31             :   // Check that we can read all the hashes and offsets from the
      32             :   // section (see SourceLevelDebugging.rst for the structure of the index).
      33          72 :   if (!AccelSection.isValidOffset(sizeof(Hdr) + Hdr.HeaderDataLength +
      34          72 :                                   Hdr.NumBuckets*4 + Hdr.NumHashes*8))
      35             :     return false;
      36             : 
      37          36 :   HdrData.DIEOffsetBase = AccelSection.getU32(&Offset);
      38          36 :   uint32_t NumAtoms = AccelSection.getU32(&Offset);
      39             : 
      40         104 :   for (unsigned i = 0; i < NumAtoms; ++i) {
      41          68 :     uint16_t AtomType = AccelSection.getU16(&Offset);
      42          68 :     uint16_t AtomForm = AccelSection.getU16(&Offset);
      43         136 :     HdrData.Atoms.push_back(std::make_pair(AtomType, AtomForm));
      44             :   }
      45             : 
      46             :   return true;
      47             : }
      48             : 
      49          36 : void DWARFAcceleratorTable::dump(raw_ostream &OS) const {
      50             :   // Dump the header.
      51         108 :   OS << "Magic = " << format("0x%08x", Hdr.Magic) << '\n'
      52         108 :      << "Version = " << format("0x%04x", Hdr.Version) << '\n'
      53         108 :      << "Hash function = " << format("0x%08x", Hdr.HashFunction) << '\n'
      54         108 :      << "Bucket count = " << Hdr.NumBuckets << '\n'
      55         108 :      << "Hashes count = " << Hdr.NumHashes << '\n'
      56         108 :      << "HeaderData length = " << Hdr.HeaderDataLength << '\n'
      57         108 :      << "DIE offset base = " << HdrData.DIEOffsetBase << '\n'
      58          72 :      << "Number of atoms = " << HdrData.Atoms.size() << '\n';
      59             : 
      60          36 :   unsigned i = 0;
      61             :   SmallVector<DWARFFormValue, 3> AtomForms;
      62         104 :   for (const auto &Atom: HdrData.Atoms) {
      63         204 :     OS << format("Atom[%d] Type: ", i++);
      64          68 :     if (const char *TypeString = dwarf::AtomTypeString(Atom.first))
      65          68 :       OS << TypeString;
      66             :     else
      67           0 :       OS << format("DW_ATOM_Unknown_0x%x", Atom.first);
      68          68 :     OS << " Form: ";
      69          68 :     if (const char *FormString = dwarf::FormEncodingString(Atom.second))
      70          68 :       OS << FormString;
      71             :     else
      72           0 :       OS << format("DW_FORM_Unknown_0x%x", Atom.second);
      73          68 :     OS << '\n';
      74         136 :     AtomForms.push_back(DWARFFormValue(Atom.second));
      75             :   }
      76             : 
      77             :   // Now go through the actual tables and dump them.
      78          36 :   uint32_t Offset = sizeof(Hdr) + Hdr.HeaderDataLength;
      79          36 :   unsigned HashesBase = Offset + Hdr.NumBuckets * 4;
      80          36 :   unsigned OffsetsBase = HashesBase + Hdr.NumHashes * 4;
      81             : 
      82         140 :   for (unsigned Bucket = 0; Bucket < Hdr.NumBuckets; ++Bucket) {
      83         104 :     unsigned Index = AccelSection.getU32(&Offset);
      84             : 
      85         312 :     OS << format("Bucket[%d]\n", Bucket);
      86         104 :     if (Index == UINT32_MAX) {
      87          29 :       OS << "  EMPTY\n";
      88          29 :       continue;
      89             :     }
      90             : 
      91         126 :     for (unsigned HashIdx = Index; HashIdx < Hdr.NumHashes; ++HashIdx) {
      92         165 :       unsigned HashOffset = HashesBase + HashIdx*4;
      93         165 :       unsigned OffsetsOffset = OffsetsBase + HashIdx*4;
      94         165 :       uint32_t Hash = AccelSection.getU32(&HashOffset);
      95             : 
      96         165 :       if (Hash % Hdr.NumBuckets != Bucket)
      97             :         break;
      98             : 
      99         126 :       unsigned DataOffset = AccelSection.getU32(&OffsetsOffset);
     100         378 :       OS << format("  Hash = 0x%08x Offset = 0x%08x\n", Hash, DataOffset);
     101         252 :       if (!AccelSection.isValidOffset(DataOffset)) {
     102           0 :         OS << "    Invalid section offset\n";
     103           0 :         continue;
     104             :       }
     105         504 :       while (AccelSection.isValidOffsetForDataOfSize(DataOffset, 4)) {
     106         252 :         unsigned StringOffset = AccelSection.getU32(&DataOffset);
     107         252 :         RelocAddrMap::const_iterator Reloc = Relocs.find(DataOffset-4);
     108         756 :         if (Reloc != Relocs.end())
     109           4 :           StringOffset += Reloc->second.second;
     110         252 :         if (!StringOffset)
     111             :           break;
     112             :         OS << format("    Name: %08x \"%s\"\n", StringOffset,
     113         378 :                      StringSection.getCStr(&StringOffset));
     114         126 :         unsigned NumData = AccelSection.getU32(&DataOffset);
     115         275 :         for (unsigned Data = 0; Data < NumData; ++Data) {
     116         447 :           OS << format("    Data[%d] => ", Data);
     117         149 :           unsigned i = 0;
     118         382 :           for (auto &Atom : AtomForms) {
     119         699 :             OS << format("{Atom[%d]: ", i++);
     120         233 :             if (Atom.extractValue(AccelSection, &DataOffset, nullptr))
     121         233 :               Atom.dump(OS, nullptr);
     122             :             else
     123           0 :               OS << "Error extracting the value";
     124         233 :             OS << "} ";
     125             :           }
     126         149 :           OS << '\n';
     127             :         }
     128             :       }
     129             :     }
     130             :   }
     131          36 : }
     132             : }

Generated by: LCOV version 1.11