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