LLVM API Documentation

DWARFDebugLoc.cpp
Go to the documentation of this file.
00001 //===-- DWARFDebugLoc.cpp -------------------------------------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "DWARFDebugLoc.h"
00011 #include "llvm/Support/Compiler.h"
00012 #include "llvm/Support/Format.h"
00013 #include "llvm/Support/raw_ostream.h"
00014 #include "llvm/Support/Dwarf.h"
00015 
00016 using namespace llvm;
00017 
00018 void DWARFDebugLoc::dump(raw_ostream &OS) const {
00019   for (const LocationList &L : Locations) {
00020     OS << format("0x%8.8x: ", L.Offset);
00021     const unsigned Indent = 12;
00022     for (const Entry &E : L.Entries) {
00023       if (&E != L.Entries.begin())
00024         OS.indent(Indent);
00025       OS << "Beginning address offset: " << format("0x%016" PRIx64, E.Begin)
00026          << '\n';
00027       OS.indent(Indent) << "   Ending address offset: "
00028                         << format("0x%016" PRIx64, E.End) << '\n';
00029       OS.indent(Indent) << "    Location description: ";
00030       for (unsigned char Loc : E.Loc) {
00031         OS << format("%2.2x ", Loc);
00032       }
00033       OS << "\n\n";
00034     }
00035   }
00036 }
00037 
00038 void DWARFDebugLoc::parse(DataExtractor data, unsigned AddressSize) {
00039   uint32_t Offset = 0;
00040   while (data.isValidOffset(Offset+AddressSize-1)) {
00041     Locations.resize(Locations.size() + 1);
00042     LocationList &Loc = Locations.back();
00043     Loc.Offset = Offset;
00044     // 2.6.2 Location Lists
00045     // A location list entry consists of:
00046     while (true) {
00047       Entry E;
00048       RelocAddrMap::const_iterator AI = RelocMap.find(Offset);
00049       // 1. A beginning address offset. ...
00050       E.Begin = data.getUnsigned(&Offset, AddressSize);
00051       if (AI != RelocMap.end())
00052         E.Begin += AI->second.second;
00053 
00054       AI = RelocMap.find(Offset);
00055       // 2. An ending address offset. ...
00056       E.End = data.getUnsigned(&Offset, AddressSize);
00057       if (AI != RelocMap.end())
00058         E.End += AI->second.second;
00059 
00060       // The end of any given location list is marked by an end of list entry,
00061       // which consists of a 0 for the beginning address offset and a 0 for the
00062       // ending address offset.
00063       if (E.Begin == 0 && E.End == 0)
00064         break;
00065 
00066       unsigned Bytes = data.getU16(&Offset);
00067       // A single location description describing the location of the object...
00068       StringRef str = data.getData().substr(Offset, Bytes);
00069       Offset += Bytes;
00070       E.Loc.reserve(str.size());
00071       std::copy(str.begin(), str.end(), std::back_inserter(E.Loc));
00072       Loc.Entries.push_back(std::move(E));
00073     }
00074   }
00075   if (data.isValidOffset(Offset))
00076     llvm::errs() << "error: failed to consume entire .debug_loc section\n";
00077 }
00078 
00079 void DWARFDebugLocDWO::parse(DataExtractor data) {
00080   uint32_t Offset = 0;
00081   while (data.isValidOffset(Offset)) {
00082     Locations.resize(Locations.size() + 1);
00083     LocationList &Loc = Locations.back();
00084     Loc.Offset = Offset;
00085     dwarf::LocationListEntry Kind;
00086     while ((Kind = static_cast<dwarf::LocationListEntry>(
00087                 data.getU8(&Offset))) != dwarf::DW_LLE_end_of_list_entry) {
00088 
00089       if (Kind != dwarf::DW_LLE_start_length_entry) {
00090         llvm::errs() << "error: dumping support for LLE of kind " << (int)Kind
00091                      << " not implemented\n";
00092         return;
00093       }
00094 
00095       Entry E;
00096 
00097       E.Start = data.getULEB128(&Offset);
00098       E.Length = data.getU32(&Offset);
00099 
00100       unsigned Bytes = data.getU16(&Offset);
00101       // A single location description describing the location of the object...
00102       StringRef str = data.getData().substr(Offset, Bytes);
00103       Offset += Bytes;
00104       E.Loc.resize(str.size());
00105       std::copy(str.begin(), str.end(), E.Loc.begin());
00106 
00107       Loc.Entries.push_back(std::move(E));
00108     }
00109   }
00110 }
00111 
00112 void DWARFDebugLocDWO::dump(raw_ostream &OS) const {
00113   for (const LocationList &L : Locations) {
00114     OS << format("0x%8.8x: ", L.Offset);
00115     const unsigned Indent = 12;
00116     for (const Entry &E : L.Entries) {
00117       if (&E != L.Entries.begin())
00118         OS.indent(Indent);
00119       OS << "Beginning address index: " << E.Start << '\n';
00120       OS.indent(Indent) << "                 Length: " << E.Length << '\n';
00121       OS.indent(Indent) << "   Location description: ";
00122       for (unsigned char Loc : E.Loc)
00123         OS << format("%2.2x ", Loc);
00124       OS << "\n\n";
00125     }
00126   }
00127 }
00128