Home | History | Annotate | Download | only in DWARF
      1 //===-- DWARFDebugLoc.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/DWARFDebugLoc.h"
     11 #include "llvm/Support/Dwarf.h"
     12 #include "llvm/Support/Format.h"
     13 #include "llvm/Support/raw_ostream.h"
     14 
     15 using namespace llvm;
     16 
     17 void DWARFDebugLoc::dump(raw_ostream &OS) const {
     18   for (const LocationList &L : Locations) {
     19     OS << format("0x%8.8x: ", L.Offset);
     20     const unsigned Indent = 12;
     21     for (const Entry &E : L.Entries) {
     22       if (&E != L.Entries.begin())
     23         OS.indent(Indent);
     24       OS << "Beginning address offset: " << format("0x%016" PRIx64, E.Begin)
     25          << '\n';
     26       OS.indent(Indent) << "   Ending address offset: "
     27                         << format("0x%016" PRIx64, E.End) << '\n';
     28       OS.indent(Indent) << "    Location description: ";
     29       for (unsigned char Loc : E.Loc) {
     30         OS << format("%2.2x ", Loc);
     31       }
     32       OS << "\n\n";
     33     }
     34   }
     35 }
     36 
     37 void DWARFDebugLoc::parse(DataExtractor data, unsigned AddressSize) {
     38   uint32_t Offset = 0;
     39   while (data.isValidOffset(Offset+AddressSize-1)) {
     40     Locations.resize(Locations.size() + 1);
     41     LocationList &Loc = Locations.back();
     42     Loc.Offset = Offset;
     43     // 2.6.2 Location Lists
     44     // A location list entry consists of:
     45     while (true) {
     46       Entry E;
     47       RelocAddrMap::const_iterator AI = RelocMap.find(Offset);
     48       // 1. A beginning address offset. ...
     49       E.Begin = data.getUnsigned(&Offset, AddressSize);
     50       if (AI != RelocMap.end())
     51         E.Begin += AI->second.second;
     52 
     53       AI = RelocMap.find(Offset);
     54       // 2. An ending address offset. ...
     55       E.End = data.getUnsigned(&Offset, AddressSize);
     56       if (AI != RelocMap.end())
     57         E.End += AI->second.second;
     58 
     59       // The end of any given location list is marked by an end of list entry,
     60       // which consists of a 0 for the beginning address offset and a 0 for the
     61       // ending address offset.
     62       if (E.Begin == 0 && E.End == 0)
     63         break;
     64 
     65       unsigned Bytes = data.getU16(&Offset);
     66       // A single location description describing the location of the object...
     67       StringRef str = data.getData().substr(Offset, Bytes);
     68       Offset += Bytes;
     69       E.Loc.append(str.begin(), str.end());
     70       Loc.Entries.push_back(std::move(E));
     71     }
     72   }
     73   if (data.isValidOffset(Offset))
     74     llvm::errs() << "error: failed to consume entire .debug_loc section\n";
     75 }
     76 
     77 void DWARFDebugLocDWO::parse(DataExtractor data) {
     78   uint32_t Offset = 0;
     79   while (data.isValidOffset(Offset)) {
     80     Locations.resize(Locations.size() + 1);
     81     LocationList &Loc = Locations.back();
     82     Loc.Offset = Offset;
     83     dwarf::LocationListEntry Kind;
     84     while ((Kind = static_cast<dwarf::LocationListEntry>(
     85                 data.getU8(&Offset))) != dwarf::DW_LLE_end_of_list_entry) {
     86 
     87       if (Kind != dwarf::DW_LLE_start_length_entry) {
     88         llvm::errs() << "error: dumping support for LLE of kind " << (int)Kind
     89                      << " not implemented\n";
     90         return;
     91       }
     92 
     93       Entry E;
     94 
     95       E.Start = data.getULEB128(&Offset);
     96       E.Length = data.getU32(&Offset);
     97 
     98       unsigned Bytes = data.getU16(&Offset);
     99       // A single location description describing the location of the object...
    100       StringRef str = data.getData().substr(Offset, Bytes);
    101       Offset += Bytes;
    102       E.Loc.resize(str.size());
    103       std::copy(str.begin(), str.end(), E.Loc.begin());
    104 
    105       Loc.Entries.push_back(std::move(E));
    106     }
    107   }
    108 }
    109 
    110 void DWARFDebugLocDWO::dump(raw_ostream &OS) const {
    111   for (const LocationList &L : Locations) {
    112     OS << format("0x%8.8x: ", L.Offset);
    113     const unsigned Indent = 12;
    114     for (const Entry &E : L.Entries) {
    115       if (&E != L.Entries.begin())
    116         OS.indent(Indent);
    117       OS << "Beginning address index: " << E.Start << '\n';
    118       OS.indent(Indent) << "                 Length: " << E.Length << '\n';
    119       OS.indent(Indent) << "   Location description: ";
    120       for (unsigned char Loc : E.Loc)
    121         OS << format("%2.2x ", Loc);
    122       OS << "\n\n";
    123     }
    124   }
    125 }
    126 
    127