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