1 //===-- DWARFDebugLoc.cpp -------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "DWARFDebugLoc.h"
11 #include "llvm/Support/Compiler.h"
12 #include "llvm/Support/Format.h"
13 #include "llvm/Support/raw_ostream.h"
14 #include "llvm/Support/Dwarf.h"
18 void DWARFDebugLoc::dump(raw_ostream
&OS
) const {
19 for (const LocationList
&L
: Locations
) {
20 OS
<< format("0x%8.8x: ", L
.Offset
);
21 const unsigned Indent
= 12;
22 for (const Entry
&E
: L
.Entries
) {
23 if (&E
!= L
.Entries
.begin())
25 OS
<< "Beginning address offset: " << format("0x%016" PRIx64
, E
.Begin
)
27 OS
.indent(Indent
) << " Ending address offset: "
28 << format("0x%016" PRIx64
, E
.End
) << '\n';
29 OS
.indent(Indent
) << " Location description: ";
30 for (unsigned char Loc
: E
.Loc
) {
31 OS
<< format("%2.2x ", Loc
);
38 void DWARFDebugLoc::parse(DataExtractor data
, unsigned AddressSize
) {
40 while (data
.isValidOffset(Offset
+AddressSize
-1)) {
41 Locations
.resize(Locations
.size() + 1);
42 LocationList
&Loc
= Locations
.back();
44 // 2.6.2 Location Lists
45 // A location list entry consists of:
48 RelocAddrMap::const_iterator AI
= RelocMap
.find(Offset
);
49 // 1. A beginning address offset. ...
50 E
.Begin
= data
.getUnsigned(&Offset
, AddressSize
);
51 if (AI
!= RelocMap
.end())
52 E
.Begin
+= AI
->second
.second
;
54 AI
= RelocMap
.find(Offset
);
55 // 2. An ending address offset. ...
56 E
.End
= data
.getUnsigned(&Offset
, AddressSize
);
57 if (AI
!= RelocMap
.end())
58 E
.End
+= AI
->second
.second
;
60 // The end of any given location list is marked by an end of list entry,
61 // which consists of a 0 for the beginning address offset and a 0 for the
62 // ending address offset.
63 if (E
.Begin
== 0 && E
.End
== 0)
66 unsigned Bytes
= data
.getU16(&Offset
);
67 // A single location description describing the location of the object...
68 StringRef str
= data
.getData().substr(Offset
, Bytes
);
70 E
.Loc
.reserve(str
.size());
71 std::copy(str
.begin(), str
.end(), std::back_inserter(E
.Loc
));
72 Loc
.Entries
.push_back(std::move(E
));
75 if (data
.isValidOffset(Offset
))
76 llvm::errs() << "error: failed to consume entire .debug_loc section\n";
79 void DWARFDebugLocDWO::parse(DataExtractor data
) {
81 while (data
.isValidOffset(Offset
)) {
82 Locations
.resize(Locations
.size() + 1);
83 LocationList
&Loc
= Locations
.back();
85 dwarf::LocationListEntry Kind
;
86 while ((Kind
= static_cast<dwarf::LocationListEntry
>(
87 data
.getU8(&Offset
))) != dwarf::DW_LLE_end_of_list_entry
) {
89 if (Kind
!= dwarf::DW_LLE_start_length_entry
) {
90 llvm::errs() << "error: dumping support for LLE of kind " << (int)Kind
91 << " not implemented\n";
97 E
.Start
= data
.getULEB128(&Offset
);
98 E
.Length
= data
.getU32(&Offset
);
100 unsigned Bytes
= data
.getU16(&Offset
);
101 // A single location description describing the location of the object...
102 StringRef str
= data
.getData().substr(Offset
, Bytes
);
104 E
.Loc
.resize(str
.size());
105 std::copy(str
.begin(), str
.end(), E
.Loc
.begin());
107 Loc
.Entries
.push_back(std::move(E
));
112 void DWARFDebugLocDWO::dump(raw_ostream
&OS
) const {
113 for (const LocationList
&L
: Locations
) {
114 OS
<< format("0x%8.8x: ", L
.Offset
);
115 const unsigned Indent
= 12;
116 for (const Entry
&E
: L
.Entries
) {
117 if (&E
!= L
.Entries
.begin())
119 OS
<< "Beginning address index: " << E
.Start
<< '\n';
120 OS
.indent(Indent
) << " Length: " << E
.Length
<< '\n';
121 OS
.indent(Indent
) << " Location description: ";
122 for (unsigned char Loc
: E
.Loc
)
123 OS
<< format("%2.2x ", Loc
);