blob: d5c34216ed53efe913b0b7bccddda1dd868475b4 [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"
George Rimarf8a96422017-04-21 09:12:18 +000011#include "llvm/DebugInfo/DWARF/DWARFContext.h"
Zachary Turner82af9432015-01-30 18:07:45 +000012#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
Eugene Zelenko28db7e62017-03-01 01:14:23 +000013#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000014#include "llvm/Support/Dwarf.h"
David Blaikie18e73502013-06-19 21:37:13 +000015#include "llvm/Support/Format.h"
16#include "llvm/Support/raw_ostream.h"
Eugene Zelenko28db7e62017-03-01 01:14:23 +000017#include <algorithm>
18#include <cinttypes>
19#include <cstdint>
David Blaikie18e73502013-06-19 21:37:13 +000020
21using namespace llvm;
22
23void DWARFDebugLoc::dump(raw_ostream &OS) const {
Alexey Samsonov1eabf982014-03-13 07:52:54 +000024 for (const LocationList &L : Locations) {
25 OS << format("0x%8.8x: ", L.Offset);
David Blaikie18e73502013-06-19 21:37:13 +000026 const unsigned Indent = 12;
Alexey Samsonov1eabf982014-03-13 07:52:54 +000027 for (const Entry &E : L.Entries) {
28 if (&E != L.Entries.begin())
David Blaikie18e73502013-06-19 21:37:13 +000029 OS.indent(Indent);
Alexey Samsonov1eabf982014-03-13 07:52:54 +000030 OS << "Beginning address offset: " << format("0x%016" PRIx64, E.Begin)
David Blaikie18e73502013-06-19 21:37:13 +000031 << '\n';
David Blaikieb9a18702013-06-19 21:42:05 +000032 OS.indent(Indent) << " Ending address offset: "
Alexey Samsonov1eabf982014-03-13 07:52:54 +000033 << format("0x%016" PRIx64, E.End) << '\n';
David Blaikieb9a18702013-06-19 21:42:05 +000034 OS.indent(Indent) << " Location description: ";
Alexey Samsonov1eabf982014-03-13 07:52:54 +000035 for (unsigned char Loc : E.Loc) {
36 OS << format("%2.2x ", Loc);
David Blaikie18e73502013-06-19 21:37:13 +000037 }
38 OS << "\n\n";
39 }
40 }
41}
42
43void DWARFDebugLoc::parse(DataExtractor data, unsigned AddressSize) {
44 uint32_t Offset = 0;
Adrian Prantl6f84d312014-02-11 21:22:53 +000045 while (data.isValidOffset(Offset+AddressSize-1)) {
David Blaikie18e73502013-06-19 21:37:13 +000046 Locations.resize(Locations.size() + 1);
47 LocationList &Loc = Locations.back();
48 Loc.Offset = Offset;
49 // 2.6.2 Location Lists
50 // A location list entry consists of:
51 while (true) {
George Rimarf8a96422017-04-21 09:12:18 +000052 // A beginning and ending address offsets.
David Blaikie18e73502013-06-19 21:37:13 +000053 Entry E;
George Rimarf8a96422017-04-21 09:12:18 +000054 E.Begin = getRelocatedValue(data, AddressSize, &Offset, &RelocMap);
55 E.End = getRelocatedValue(data, AddressSize, &Offset, &RelocMap);
David Blaikie18e73502013-06-19 21:37:13 +000056
57 // The end of any given location list is marked by an end of list entry,
58 // which consists of a 0 for the beginning address offset and a 0 for the
59 // ending address offset.
60 if (E.Begin == 0 && E.End == 0)
61 break;
62
63 unsigned Bytes = data.getU16(&Offset);
64 // A single location description describing the location of the object...
65 StringRef str = data.getData().substr(Offset, Bytes);
66 Offset += Bytes;
Benjamin Kramer4f6ac162015-02-28 10:11:12 +000067 E.Loc.append(str.begin(), str.end());
Chandler Carruth002da5d2014-03-02 04:08:41 +000068 Loc.Entries.push_back(std::move(E));
David Blaikie18e73502013-06-19 21:37:13 +000069 }
70 }
Adrian Prantl6f84d312014-02-11 21:22:53 +000071 if (data.isValidOffset(Offset))
Eugene Zelenko28db7e62017-03-01 01:14:23 +000072 errs() << "error: failed to consume entire .debug_loc section\n";
David Blaikie18e73502013-06-19 21:37:13 +000073}
David Blaikie9c550ac2014-03-25 01:44:02 +000074
75void DWARFDebugLocDWO::parse(DataExtractor data) {
76 uint32_t Offset = 0;
77 while (data.isValidOffset(Offset)) {
78 Locations.resize(Locations.size() + 1);
79 LocationList &Loc = Locations.back();
80 Loc.Offset = Offset;
81 dwarf::LocationListEntry Kind;
82 while ((Kind = static_cast<dwarf::LocationListEntry>(
Adrian Prantlc4fbbcf2016-10-28 17:59:50 +000083 data.getU8(&Offset))) != dwarf::DW_LLE_end_of_list) {
David Blaikie9c550ac2014-03-25 01:44:02 +000084
Adrian Prantlc4fbbcf2016-10-28 17:59:50 +000085 if (Kind != dwarf::DW_LLE_startx_length) {
Eugene Zelenko28db7e62017-03-01 01:14:23 +000086 errs() << "error: dumping support for LLE of kind " << (int)Kind
87 << " not implemented\n";
David Blaikie9c550ac2014-03-25 01:44:02 +000088 return;
89 }
90
91 Entry E;
92
93 E.Start = data.getULEB128(&Offset);
94 E.Length = data.getU32(&Offset);
95
96 unsigned Bytes = data.getU16(&Offset);
97 // A single location description describing the location of the object...
98 StringRef str = data.getData().substr(Offset, Bytes);
99 Offset += Bytes;
100 E.Loc.resize(str.size());
101 std::copy(str.begin(), str.end(), E.Loc.begin());
102
103 Loc.Entries.push_back(std::move(E));
104 }
105 }
106}
107
108void DWARFDebugLocDWO::dump(raw_ostream &OS) const {
109 for (const LocationList &L : Locations) {
110 OS << format("0x%8.8x: ", L.Offset);
111 const unsigned Indent = 12;
112 for (const Entry &E : L.Entries) {
113 if (&E != L.Entries.begin())
114 OS.indent(Indent);
115 OS << "Beginning address index: " << E.Start << '\n';
116 OS.indent(Indent) << " Length: " << E.Length << '\n';
117 OS.indent(Indent) << " Location description: ";
118 for (unsigned char Loc : E.Loc)
119 OS << format("%2.2x ", Loc);
120 OS << "\n\n";
121 }
122 }
123}