llvm.org GIT mirror llvm / 3df7d2f
llvm-dwarfdump: Add support for dumping the .debug_loc section This is a basic implementation - we still don't have any support (that I know of) for dumping DWARF expressions in a meaningful way, so the location information itself is just printed as a sequence of bytes as we do elsewhere. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184361 91177308-0d34-0410-b5e6-96231b3b80d8 David Blaikie 7 years ago
11 changed file(s) with 212 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
104104 DIDT_Info,
105105 DIDT_InfoDwo,
106106 DIDT_Line,
107 DIDT_Loc,
107108 DIDT_Ranges,
108109 DIDT_Pubnames,
109110 DIDT_Str,
88 DWARFDebugFrame.cpp
99 DWARFDebugInfoEntry.cpp
1010 DWARFDebugLine.cpp
11 DWARFDebugLoc.cpp
1112 DWARFDebugRangeList.cpp
1213 DWARFFormValue.cpp
1314 )
3232 OS << "\n.debug_info contents:\n";
3333 for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i)
3434 getCompileUnitAtIndex(i)->dump(OS);
35 }
36
37 if (DumpType == DIDT_All || DumpType == DIDT_Loc) {
38 OS << ".debug_loc contents:\n";
39 getDebugLoc()->dump(OS);
3540 }
3641
3742 if (DumpType == DIDT_All || DumpType == DIDT_Frames) {
168173 AbbrevDWO.reset(new DWARFDebugAbbrev());
169174 AbbrevDWO->parse(abbrData);
170175 return AbbrevDWO.get();
176 }
177
178 const DWARFDebugLoc *DWARFContext::getDebugLoc() {
179 if (Loc)
180 return Loc.get();
181
182 DataExtractor LocData(getLocSection(), isLittleEndian(), 0);
183 Loc.reset(new DWARFDebugLoc(locRelocMap()));
184 // assume all compile units have the same address byte size
185 if (getNumCompileUnits())
186 Loc->parse(LocData, getCompileUnitAtIndex(0)->getAddressByteSize());
187 return Loc.get();
171188 }
172189
173190 const DWARFDebugAranges *DWARFContext::getDebugAranges() {
541558 StringRef *Section = StringSwitch(name)
542559 .Case("debug_info", &InfoSection)
543560 .Case("debug_abbrev", &AbbrevSection)
561 .Case("debug_loc", &LocSection)
544562 .Case("debug_line", &LineSection)
545563 .Case("debug_aranges", &ARangeSection)
546564 .Case("debug_frame", &DebugFrameSection)
575593 // Record relocations for the debug_info and debug_line sections.
576594 RelocAddrMap *Map = StringSwitch(RelSecName)
577595 .Case("debug_info", &InfoRelocMap)
596 .Case("debug_loc", &LocRelocMap)
578597 .Case("debug_info.dwo", &InfoDWORelocMap)
579598 .Case("debug_line", &LineRelocMap)
580599 .Default(0);
1313 #include "DWARFDebugAranges.h"
1414 #include "DWARFDebugFrame.h"
1515 #include "DWARFDebugLine.h"
16 #include "DWARFDebugLoc.h"
1617 #include "DWARFDebugRangeList.h"
1718 #include "llvm/ADT/OwningPtr.h"
1819 #include "llvm/ADT/SmallVector.h"
2728 class DWARFContext : public DIContext {
2829 SmallVector CUs;
2930 OwningPtr Abbrev;
31 OwningPtr Loc;
3032 OwningPtr Aranges;
3133 OwningPtr Line;
3234 OwningPtr DebugFrame;
7880
7981 /// Get a pointer to the parsed DebugAbbrev object.
8082 const DWARFDebugAbbrev *getDebugAbbrev();
83
84 /// Get a pointer to the parsed DebugLoc object.
85 const DWARFDebugLoc *getDebugLoc();
8186
8287 /// Get a pointer to the parsed dwo abbreviations object.
8388 const DWARFDebugAbbrev *getDebugAbbrevDWO();
103108 virtual uint8_t getAddressSize() const = 0;
104109 virtual const RelocAddrMap &infoRelocMap() const = 0;
105110 virtual const RelocAddrMap &lineRelocMap() const = 0;
111 virtual const RelocAddrMap &locRelocMap() const = 0;
106112 virtual StringRef getInfoSection() = 0;
107113 virtual StringRef getAbbrevSection() = 0;
114 virtual StringRef getLocSection() = 0;
108115 virtual StringRef getARangeSection() = 0;
109116 virtual StringRef getDebugFrameSection() = 0;
110117 virtual StringRef getLineSection() = 0;
141148 bool IsLittleEndian;
142149 uint8_t AddressSize;
143150 RelocAddrMap InfoRelocMap;
151 RelocAddrMap LocRelocMap;
144152 RelocAddrMap LineRelocMap;
145153 StringRef InfoSection;
146154 StringRef AbbrevSection;
155 StringRef LocSection;
147156 StringRef ARangeSection;
148157 StringRef DebugFrameSection;
149158 StringRef LineSection;
168177 virtual bool isLittleEndian() const { return IsLittleEndian; }
169178 virtual uint8_t getAddressSize() const { return AddressSize; }
170179 virtual const RelocAddrMap &infoRelocMap() const { return InfoRelocMap; }
180 virtual const RelocAddrMap &locRelocMap() const { return LocRelocMap; }
171181 virtual const RelocAddrMap &lineRelocMap() const { return LineRelocMap; }
172182 virtual StringRef getInfoSection() { return InfoSection; }
173183 virtual StringRef getAbbrevSection() { return AbbrevSection; }
184 virtual StringRef getLocSection() { return LocSection; }
174185 virtual StringRef getARangeSection() { return ARangeSection; }
175186 virtual StringRef getDebugFrameSection() { return DebugFrameSection; }
176187 virtual StringRef getLineSection() { return LineSection; }
0 //===-- DWARFDebugLoc.cpp -------------------------------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "DWARFDebugLoc.h"
10 #include "llvm/Support/Compiler.h"
11 #include "llvm/Support/Format.h"
12 #include "llvm/Support/raw_ostream.h"
13
14 using namespace llvm;
15
16 void DWARFDebugLoc::dump(raw_ostream &OS) const {
17 for (LocationLists::const_iterator I = Locations.begin(), E = Locations.end(); I != E; ++I) {
18 OS << format("0x%8.8x: ", I->Offset);
19 const unsigned Indent = 12;
20 for (SmallVectorImpl::const_iterator I2 = I->Entries.begin(), E2 = I->Entries.end(); I2 != E2; ++I2) {
21 if (I2 != I->Entries.begin())
22 OS.indent(Indent);
23 OS << "Begining address offset: " << format("0x%016" PRIx64, I2->Begin)
24 << '\n';
25 OS.indent(Indent) << " Ending address offset: "
26 << format("0x%016" PRIx64, I2->End) << '\n';
27 OS.indent(Indent) << " Location description: ";
28 for (SmallVectorImpl::const_iterator I3 = I2->Loc.begin(), E3 = I2->Loc.end(); I3 != E3; ++I3) {
29 OS << format("%2.2x ", *I3);
30 }
31 OS << "\n\n";
32 }
33 }
34 }
35
36 void DWARFDebugLoc::parse(DataExtractor data, unsigned AddressSize) {
37 uint32_t Offset = 0;
38 while (data.isValidOffset(Offset)) {
39 Locations.resize(Locations.size() + 1);
40 LocationList &Loc = Locations.back();
41 Loc.Offset = Offset;
42 // 2.6.2 Location Lists
43 // A location list entry consists of:
44 while (true) {
45 Entry E;
46 RelocAddrMap::const_iterator AI = RelocMap.find(Offset);
47 // 1. A beginning address offset. ...
48 E.Begin = data.getUnsigned(&Offset, AddressSize);
49 if (AI != RelocMap.end())
50 E.Begin += AI->second.second;
51
52 AI = RelocMap.find(Offset);
53 // 2. An ending address offset. ...
54 E.End = data.getUnsigned(&Offset, AddressSize);
55 if (AI != RelocMap.end())
56 E.End += AI->second.second;
57
58 // The end of any given location list is marked by an end of list entry,
59 // which consists of a 0 for the beginning address offset and a 0 for the
60 // ending address offset.
61 if (E.Begin == 0 && E.End == 0)
62 break;
63
64 unsigned Bytes = data.getU16(&Offset);
65 // A single location description describing the location of the object...
66 StringRef str = data.getData().substr(Offset, Bytes);
67 Offset += Bytes;
68 E.Loc.reserve(str.size());
69 std::copy(str.begin(), str.end(), std::back_inserter(E.Loc));
70 Loc.Entries.push_back(llvm_move(E));
71 }
72 }
73 }
0 //===-- DWARFDebugLoc.h -----------------------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_DEBUGINFO_DWARFDEBUGLOC_H
10 #define LLVM_DEBUGINFO_DWARFDEBUGLOC_H
11
12 #include "DWARFRelocMap.h"
13 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/Support/DataExtractor.h"
15
16 namespace llvm {
17
18 class raw_ostream;
19
20 class DWARFDebugLoc {
21 /// A single location within a location list.
22 struct Entry {
23 /// The beginning address of the instruction range.
24 uint64_t Begin;
25 /// The ending address of the instruction range.
26 uint64_t End;
27 /// The location of the variable within the specified range.
28 SmallVector Loc;
29 };
30
31 /// A list of locations that contain one variable.
32 struct LocationList {
33 /// The beginning offset where this location list is stored in the debug_loc
34 /// section.
35 unsigned Offset;
36 /// All the locations in which the variable is stored.
37 SmallVector Entries;
38 };
39
40 typedef SmallVector LocationLists;
41
42 /// A list of all the variables in the debug_loc section, each one describing
43 /// the locations in which the variable is stored.
44 LocationLists Locations;
45
46 /// A map used to resolve binary relocations.
47 const RelocAddrMap &RelocMap;
48
49 public:
50 DWARFDebugLoc(const RelocAddrMap &LocRelocMap) : RelocMap(LocRelocMap) {}
51 /// Print the location lists found within the debug_loc section.
52 void dump(raw_ostream &OS) const;
53 /// Parse the debug_loc section accessible via the 'data' parameter using the
54 /// specified address size to interpret the address ranges.
55 void parse(DataExtractor data, unsigned AddressSize);
56 };
57 }
58
59 #endif
125125 Value.uval = data.getU16(offset_ptr);
126126 break;
127127 case DW_FORM_data4:
128 case DW_FORM_ref4:
128 case DW_FORM_ref4: {
129 RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr);
129130 Value.uval = data.getU32(offset_ptr);
130 break;
131 if (AI != cu->getRelocMap()->end())
132 Value.uval += AI->second.second;
133 break;
134 }
131135 case DW_FORM_data8:
132136 case DW_FORM_ref8:
133137 Value.uval = data.getU64(offset_ptr);
0 // clang -c -g -o dwarfdump-test-loc-list-32bit.elf.o -m32 dwarfdump-test-loc-list-32bit.elf.cpp
1
2 namespace pr14763 {
3 struct foo {
4 foo(const foo&);
5 };
6
7 foo func(bool b, foo f, foo g) {
8 if (b)
9 return f;
10 return g;
11 }
12 }
0 RUN: llvm-dwarfdump %p/Inputs/dwarfdump-test-loc-list-32bit.elf.o | FileCheck %s
1 Note: the input file was generated from Inputs/dwarfdump-test-loc-list-32bit.elf.cpp
2
3 CHECK: .debug_info
4 CHECK: DW_AT_name{{.*}}"f"
5 CHECK: DW_AT_location{{.*}}([[F_LOC:0x[0-9a-f]*]])
6 CHECK: DW_AT_name{{.*}}"g"
7 CHECK: DW_AT_location{{.*}}([[G_LOC:0x[0-9a-f]*]])
8 CHECK: .debug_loc contents:
9 CHECK-NEXT: [[F_LOC]]: Begining address offset: 0x0000000000000000
10 CHECK-NEXT: Ending address offset: 0x0000000000000023
11 this is actually the wrong location due to PR14763, but that doesn't matter for
12 the purposes of testing dwarfdump
13 CHECK-NEXT: Location description: 51
14 CHECK-NEXT: {{^$}}
15 CHECK-NEXT: Begining address offset: 0x0000000000000023
16 CHECK-NEXT: Ending address offset: 0x000000000000005d
17 CHECK-NEXT: Location description: 75 70
18 CHECK-NEXT: {{^$}}
19 CHECK-NEXT: [[G_LOC]]: Begining address offset: 0x0000000000000000
20 CHECK-NEXT: Ending address offset: 0x0000000000000020
21 CHECK-NEXT: Location description: 50
22 CHECK-NEXT: {{^$}}
23 CHECK-NEXT: Begining address offset: 0x0000000000000020
24 CHECK-NEXT: Ending address offset: 0x000000000000005d
25 CHECK-NEXT: Location description: 75 74
6262 clEnumValN(DIDT_Info, "info", ".debug_info"),
6363 clEnumValN(DIDT_InfoDwo, "info.dwo", ".debug_info.dwo"),
6464 clEnumValN(DIDT_Line, "line", ".debug_line"),
65 clEnumValN(DIDT_Loc, "loc", ".debug_loc"),
6566 clEnumValN(DIDT_Frames, "frames", ".debug_frame"),
6667 clEnumValN(DIDT_Ranges, "ranges", ".debug_ranges"),
6768 clEnumValN(DIDT_Pubnames, "pubnames", ".debug_pubnames"),