blob: e2799ab2d243da40dfc70a604ef86a4c7f163679 [file] [log] [blame]
Eugene Zelenko28db7e62017-03-01 01:14:23 +00001//===- DWARFDebugLoc.cpp --------------------------------------------------===//
David Blaikie18e73502013-06-19 21:37:13 +00002//
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
Eugene Zelenko28db7e62017-03-01 01:14:23 +000010#include "llvm/ADT/StringRef.h"
Zachary Turner82af9432015-01-30 18:07:45 +000011#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
Eugene Zelenko28db7e62017-03-01 01:14:23 +000012#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000013#include "llvm/Support/Dwarf.h"
David Blaikie18e73502013-06-19 21:37:13 +000014#include "llvm/Support/Format.h"
15#include "llvm/Support/raw_ostream.h"
Eugene Zelenko28db7e62017-03-01 01:14:23 +000016#include <algorithm>
17#include <cinttypes>
18#include <cstdint>
David Blaikie18e73502013-06-19 21:37:13 +000019
20using namespace llvm;
21
22void DWARFDebugLoc::dump(raw_ostream &OS) const {
Alexey Samsonov1eabf982014-03-13 07:52:54 +000023 for (const LocationList &L : Locations) {
24 OS << format("0x%8.8x: ", L.Offset);
David Blaikie18e73502013-06-19 21:37:13 +000025 const unsigned Indent = 12;
Alexey Samsonov1eabf982014-03-13 07:52:54 +000026 for (const Entry &E : L.Entries) {
27 if (&E != L.Entries.begin())
David Blaikie18e73502013-06-19 21:37:13 +000028 OS.indent(Indent);
Alexey Samsonov1eabf982014-03-13 07:52:54 +000029 OS << "Beginning address offset: " << format("0x%016" PRIx64, E.Begin)
David Blaikie18e73502013-06-19 21:37:13 +000030 << '\n';
David Blaikieb9a18702013-06-19 21:42:05 +000031 OS.indent(Indent) << " Ending address offset: "
Alexey Samsonov1eabf982014-03-13 07:52:54 +000032 << format("0x%016" PRIx64, E.End) << '\n';
David Blaikieb9a18702013-06-19 21:42:05 +000033 OS.indent(Indent) << " Location description: ";
Alexey Samsonov1eabf982014-03-13 07:52:54 +000034 for (unsigned char Loc : E.Loc) {
35 OS << format("%2.2x ", Loc);
David Blaikie18e73502013-06-19 21:37:13 +000036 }
37 OS << "\n\n";
38 }
39 }
40}
41
42void DWARFDebugLoc::parse(DataExtractor data, unsigned AddressSize) {
43 uint32_t Offset = 0;
Adrian Prantl6f84d312014-02-11 21:22:53 +000044 while (data.isValidOffset(Offset+AddressSize-1)) {
David Blaikie18e73502013-06-19 21:37:13 +000045 Locations.resize(Locations.size() + 1);
46 LocationList &Loc = Locations.back();
47 Loc.Offset = Offset;
48 // 2.6.2 Location Lists
49 // A location list entry consists of:
50 while (true) {
51 Entry E;
52 RelocAddrMap::const_iterator AI = RelocMap.find(Offset);
53 // 1. A beginning address offset. ...
54 E.Begin = data.getUnsigned(&Offset, AddressSize);
55 if (AI != RelocMap.end())
56 E.Begin += AI->second.second;
57
58 AI = RelocMap.find(Offset);
59 // 2. An ending address offset. ...
60 E.End = data.getUnsigned(&Offset, AddressSize);
61 if (AI != RelocMap.end())
62 E.End += AI->second.second;
63
64 // The end of any given location list is marked by an end of list entry,
65 // which consists of a 0 for the beginning address offset and a 0 for the
66 // ending address offset.
67 if (E.Begin == 0 && E.End == 0)
68 break;
69
70 unsigned Bytes = data.getU16(&Offset);
71 // A single location description describing the location of the object...
72 StringRef str = data.getData().substr(Offset, Bytes);
73 Offset += Bytes;
Benjamin Kramer4f6ac162015-02-28 10:11:12 +000074 E.Loc.append(str.begin(), str.end());
Chandler Carruth002da5d2014-03-02 04:08:41 +000075 Loc.Entries.push_back(std::move(E));
David Blaikie18e73502013-06-19 21:37:13 +000076 }
77 }
Adrian Prantl6f84d312014-02-11 21:22:53 +000078 if (data.isValidOffset(Offset))
Eugene Zelenko28db7e62017-03-01 01:14:23 +000079 errs() << "error: failed to consume entire .debug_loc section\n";
David Blaikie18e73502013-06-19 21:37:13 +000080}
David Blaikie9c550ac2014-03-25 01:44:02 +000081
82void DWARFDebugLocDWO::parse(DataExtractor data) {
83 uint32_t Offset = 0;
84 while (data.isValidOffset(Offset)) {
85 Locations.resize(Locations.size() + 1);
86 LocationList &Loc = Locations.back();
87 Loc.Offset = Offset;
88 dwarf::LocationListEntry Kind;
89 while ((Kind = static_cast<dwarf::LocationListEntry>(
Adrian Prantlc4fbbcf2016-10-28 17:59:50 +000090 data.getU8(&Offset))) != dwarf::DW_LLE_end_of_list) {
David Blaikie9c550ac2014-03-25 01:44:02 +000091
Adrian Prantlc4fbbcf2016-10-28 17:59:50 +000092 if (Kind != dwarf::DW_LLE_startx_length) {
Eugene Zelenko28db7e62017-03-01 01:14:23 +000093 errs() << "error: dumping support for LLE of kind " << (int)Kind
94 << " not implemented\n";
David Blaikie9c550ac2014-03-25 01:44:02 +000095 return;
96 }
97
98 Entry E;
99
100 E.Start = data.getULEB128(&Offset);
101 E.Length = data.getU32(&Offset);
102
103 unsigned Bytes = data.getU16(&Offset);
104 // A single location description describing the location of the object...
105 StringRef str = data.getData().substr(Offset, Bytes);
106 Offset += Bytes;
107 E.Loc.resize(str.size());
108 std::copy(str.begin(), str.end(), E.Loc.begin());
109
110 Loc.Entries.push_back(std::move(E));
111 }
112 }
113}
114
115void DWARFDebugLocDWO::dump(raw_ostream &OS) const {
116 for (const LocationList &L : Locations) {
117 OS << format("0x%8.8x: ", L.Offset);
118 const unsigned Indent = 12;
119 for (const Entry &E : L.Entries) {
120 if (&E != L.Entries.begin())
121 OS.indent(Indent);
122 OS << "Beginning address index: " << E.Start << '\n';
123 OS.indent(Indent) << " Length: " << E.Length << '\n';
124 OS.indent(Indent) << " Location description: ";
125 for (unsigned char Loc : E.Loc)
126 OS << format("%2.2x ", Loc);
127 OS << "\n\n";
128 }
129 }
130}