blob: 4d620915b3df26dcdf8ce5d27a45b927c6bfb92d [file] [log] [blame]
Benjamin Krameraa2f78f2011-09-13 19:42:23 +00001//===-- DWARFContext.cpp --------------------------------------------------===//
2//
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
Zachary Turner82af9432015-01-30 18:07:45 +000010#include "llvm/DebugInfo/DWARF/DWARFContext.h"
Alexey Samsonove16e16a2012-07-19 07:03:58 +000011#include "llvm/ADT/SmallString.h"
Alexey Samsonov3d0e3ed2013-04-17 14:27:04 +000012#include "llvm/ADT/StringSwitch.h"
Zachary Turner82af9432015-01-30 18:07:45 +000013#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
14#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
George Rimare71e33f2016-12-17 09:10:32 +000015#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
David Blaikie65a8efe2015-11-11 19:28:21 +000016#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
George Rimar4bf30832017-01-11 15:26:41 +000017#include "llvm/Object/Decompressor.h"
Reid Klecknerdafc5d72016-07-06 16:56:42 +000018#include "llvm/Object/MachO.h"
19#include "llvm/Object/RelocVisitor.h"
Alexey Samsonov068fc8a2013-04-23 10:17:34 +000020#include "llvm/Support/Compression.h"
Benjamin Kramer6dda0322011-09-15 18:02:20 +000021#include "llvm/Support/Dwarf.h"
George Rimar401e4e52016-05-24 12:48:46 +000022#include "llvm/Support/ELF.h"
Benjamin Kramer07d4b1c2011-09-15 16:57:13 +000023#include "llvm/Support/Format.h"
Alexey Samsonove16e16a2012-07-19 07:03:58 +000024#include "llvm/Support/Path.h"
Benjamin Kramera6002fd2011-09-14 01:09:52 +000025#include "llvm/Support/raw_ostream.h"
Benjamin Kramer2602ca62011-09-15 20:43:22 +000026#include <algorithm>
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000027using namespace llvm;
Benjamin Kramer6dda0322011-09-15 18:02:20 +000028using namespace dwarf;
Rafael Espindola4f60a382013-05-30 03:05:14 +000029using namespace object;
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000030
Chandler Carruthe96dd892014-04-21 22:55:11 +000031#define DEBUG_TYPE "dwarf"
32
Eric Christopher494109b2012-10-16 23:46:25 +000033typedef DWARFDebugLine::LineTable DWARFLineTable;
Alexey Samsonovdce67342014-05-15 21:24:32 +000034typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
35typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
Eric Christopher494109b2012-10-16 23:46:25 +000036
Frederic Riss7c500472014-11-14 19:30:08 +000037static void dumpAccelSection(raw_ostream &OS, StringRef Name,
38 const DWARFSection& Section, StringRef StringSection,
39 bool LittleEndian) {
40 DataExtractor AccelSection(Section.Data, LittleEndian, 0);
Frederic Risse837ec22014-11-14 16:15:53 +000041 DataExtractor StrData(StringSection, LittleEndian, 0);
42 OS << "\n." << Name << " contents:\n";
Frederic Riss7c500472014-11-14 19:30:08 +000043 DWARFAcceleratorTable Accel(AccelSection, StrData, Section.Relocs);
Frederic Risse837ec22014-11-14 16:15:53 +000044 if (!Accel.extract())
45 return;
46 Accel.dump(OS);
47}
48
David Blaikie50cc27e2016-10-18 21:09:48 +000049void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType, bool DumpEH,
50 bool SummarizeTypes) {
Eli Bendersky7a94daa2013-01-25 20:26:43 +000051 if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) {
52 OS << ".debug_abbrev contents:\n";
53 getDebugAbbrev()->dump(OS);
54 }
Benjamin Kramera6002fd2011-09-14 01:09:52 +000055
David Blaikie66865d62014-01-09 00:13:35 +000056 if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo)
57 if (const DWARFDebugAbbrev *D = getDebugAbbrevDWO()) {
David Blaikie622dce42014-01-08 23:29:59 +000058 OS << "\n.debug_abbrev.dwo contents:\n";
David Blaikie66865d62014-01-09 00:13:35 +000059 D->dump(OS);
David Blaikie622dce42014-01-08 23:29:59 +000060 }
David Blaikie622dce42014-01-08 23:29:59 +000061
Eli Bendersky7a94daa2013-01-25 20:26:43 +000062 if (DumpType == DIDT_All || DumpType == DIDT_Info) {
63 OS << "\n.debug_info contents:\n";
Alexey Samsonov1eabf982014-03-13 07:52:54 +000064 for (const auto &CU : compile_units())
65 CU->dump(OS);
Eli Bendersky7a94daa2013-01-25 20:26:43 +000066 }
Benjamin Kramera6002fd2011-09-14 01:09:52 +000067
David Blaikie66865d62014-01-09 00:13:35 +000068 if ((DumpType == DIDT_All || DumpType == DIDT_InfoDwo) &&
69 getNumDWOCompileUnits()) {
70 OS << "\n.debug_info.dwo contents:\n";
Alexey Samsonov1eabf982014-03-13 07:52:54 +000071 for (const auto &DWOCU : dwo_compile_units())
72 DWOCU->dump(OS);
David Blaikie66865d62014-01-09 00:13:35 +000073 }
David Blaikie622dce42014-01-08 23:29:59 +000074
David Blaikie66865d62014-01-09 00:13:35 +000075 if ((DumpType == DIDT_All || DumpType == DIDT_Types) && getNumTypeUnits()) {
David Blaikie03c089c2013-09-23 22:44:47 +000076 OS << "\n.debug_types contents:\n";
Frederic Riss312a02e2014-09-29 13:56:39 +000077 for (const auto &TUS : type_unit_sections())
78 for (const auto &TU : TUS)
David Blaikie50cc27e2016-10-18 21:09:48 +000079 TU->dump(OS, SummarizeTypes);
David Blaikie03c089c2013-09-23 22:44:47 +000080 }
81
Alexey Samsonov1eabf982014-03-13 07:52:54 +000082 if ((DumpType == DIDT_All || DumpType == DIDT_TypesDwo) &&
83 getNumDWOTypeUnits()) {
84 OS << "\n.debug_types.dwo contents:\n";
Frederic Riss312a02e2014-09-29 13:56:39 +000085 for (const auto &DWOTUS : dwo_type_unit_sections())
86 for (const auto &DWOTU : DWOTUS)
David Blaikie50cc27e2016-10-18 21:09:48 +000087 DWOTU->dump(OS, SummarizeTypes);
Alexey Samsonov1eabf982014-03-13 07:52:54 +000088 }
David Blaikie92d9d622014-01-09 05:08:24 +000089
David Blaikie18e73502013-06-19 21:37:13 +000090 if (DumpType == DIDT_All || DumpType == DIDT_Loc) {
David Blaikie03c089c2013-09-23 22:44:47 +000091 OS << "\n.debug_loc contents:\n";
David Blaikie18e73502013-06-19 21:37:13 +000092 getDebugLoc()->dump(OS);
93 }
94
David Blaikie9c550ac2014-03-25 01:44:02 +000095 if (DumpType == DIDT_All || DumpType == DIDT_LocDwo) {
96 OS << "\n.debug_loc.dwo contents:\n";
97 getDebugLocDWO()->dump(OS);
98 }
99
Eli Benderskyfd08bc12013-02-05 23:30:58 +0000100 if (DumpType == DIDT_All || DumpType == DIDT_Frames) {
101 OS << "\n.debug_frame contents:\n";
102 getDebugFrame()->dump(OS);
Igor Laevsky03a670c2016-01-26 15:09:42 +0000103 if (DumpEH) {
104 OS << "\n.eh_frame contents:\n";
105 getEHFrame()->dump(OS);
106 }
Eli Benderskyfd08bc12013-02-05 23:30:58 +0000107 }
108
Amjad Aboude59cc3e2015-11-12 09:38:54 +0000109 if (DumpType == DIDT_All || DumpType == DIDT_Macro) {
110 OS << "\n.debug_macinfo contents:\n";
111 getDebugMacro()->dump(OS);
112 }
113
Benjamin Kramera6002fd2011-09-14 01:09:52 +0000114 uint32_t offset = 0;
Eli Bendersky7a94daa2013-01-25 20:26:43 +0000115 if (DumpType == DIDT_All || DumpType == DIDT_Aranges) {
116 OS << "\n.debug_aranges contents:\n";
117 DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
118 DWARFDebugArangeSet set;
119 while (set.extract(arangesData, &offset))
120 set.dump(OS);
121 }
Benjamin Kramer5acab502011-09-15 02:12:05 +0000122
Alexey Samsonov034e57a2012-08-27 07:17:47 +0000123 uint8_t savedAddressByteSize = 0;
Eli Bendersky7a94daa2013-01-25 20:26:43 +0000124 if (DumpType == DIDT_All || DumpType == DIDT_Line) {
125 OS << "\n.debug_line contents:\n";
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000126 for (const auto &CU : compile_units()) {
127 savedAddressByteSize = CU->getAddressByteSize();
Greg Claytonc8c10322016-12-13 18:25:19 +0000128 auto CUDIE = CU->getUnitDIE();
129 if (!CUDIE)
Alexey Samsonov7a18c062015-05-19 21:54:32 +0000130 continue;
Greg Clayton97d22182017-01-13 21:08:18 +0000131 if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list))) {
David Blaikie1b5ee5d2013-09-23 17:42:01 +0000132 DataExtractor lineData(getLineSection().Data, isLittleEndian(),
Eli Bendersky7a94daa2013-01-25 20:26:43 +0000133 savedAddressByteSize);
Alexey Samsonov110d5952014-04-30 00:09:19 +0000134 DWARFDebugLine::LineTable LineTable;
Greg Clayton52fe1f62016-12-14 22:38:08 +0000135 uint32_t Offset = *StmtOffset;
136 LineTable.parse(lineData, &getLineSection().Relocs, &Offset);
Alexey Samsonov110d5952014-04-30 00:09:19 +0000137 LineTable.dump(OS);
Eli Bendersky7a94daa2013-01-25 20:26:43 +0000138 }
Benjamin Kramer6dda0322011-09-15 18:02:20 +0000139 }
140 }
Benjamin Kramer07d4b1c2011-09-15 16:57:13 +0000141
David Blaikie65a8efe2015-11-11 19:28:21 +0000142 if (DumpType == DIDT_All || DumpType == DIDT_CUIndex) {
143 OS << "\n.debug_cu_index contents:\n";
David Blaikieb073cb92015-12-02 06:21:34 +0000144 getCUIndex().dump(OS);
David Blaikie65a8efe2015-11-11 19:28:21 +0000145 }
146
David Blaikie51c40282015-11-11 19:40:49 +0000147 if (DumpType == DIDT_All || DumpType == DIDT_TUIndex) {
148 OS << "\n.debug_tu_index contents:\n";
David Blaikieb073cb92015-12-02 06:21:34 +0000149 getTUIndex().dump(OS);
David Blaikie51c40282015-11-11 19:40:49 +0000150 }
151
David Blaikie1d4736e2014-02-24 23:58:54 +0000152 if (DumpType == DIDT_All || DumpType == DIDT_LineDwo) {
153 OS << "\n.debug_line.dwo contents:\n";
154 unsigned stmtOffset = 0;
155 DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(),
156 savedAddressByteSize);
Alexey Samsonov110d5952014-04-30 00:09:19 +0000157 DWARFDebugLine::LineTable LineTable;
158 while (LineTable.Prologue.parse(lineData, &stmtOffset)) {
159 LineTable.dump(OS);
160 LineTable.clear();
161 }
David Blaikie1d4736e2014-02-24 23:58:54 +0000162 }
163
Eli Bendersky7a94daa2013-01-25 20:26:43 +0000164 if (DumpType == DIDT_All || DumpType == DIDT_Str) {
165 OS << "\n.debug_str contents:\n";
166 DataExtractor strData(getStringSection(), isLittleEndian(), 0);
167 offset = 0;
168 uint32_t strOffset = 0;
169 while (const char *s = strData.getCStr(&offset)) {
170 OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
171 strOffset = offset;
172 }
Benjamin Kramer07d4b1c2011-09-15 16:57:13 +0000173 }
Alexey Samsonov034e57a2012-08-27 07:17:47 +0000174
David Blaikie66865d62014-01-09 00:13:35 +0000175 if ((DumpType == DIDT_All || DumpType == DIDT_StrDwo) &&
176 !getStringDWOSection().empty()) {
177 OS << "\n.debug_str.dwo contents:\n";
178 DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
179 offset = 0;
180 uint32_t strDWOOffset = 0;
181 while (const char *s = strDWOData.getCStr(&offset)) {
182 OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
183 strDWOOffset = offset;
David Blaikie622dce42014-01-08 23:29:59 +0000184 }
David Blaikie66865d62014-01-09 00:13:35 +0000185 }
David Blaikie622dce42014-01-08 23:29:59 +0000186
Eli Bendersky7a94daa2013-01-25 20:26:43 +0000187 if (DumpType == DIDT_All || DumpType == DIDT_Ranges) {
188 OS << "\n.debug_ranges contents:\n";
189 // In fact, different compile units may have different address byte
190 // sizes, but for simplicity we just use the address byte size of the last
191 // compile unit (there is no easy and fast way to associate address range
192 // list and the compile unit it describes).
193 DataExtractor rangesData(getRangeSection(), isLittleEndian(),
194 savedAddressByteSize);
195 offset = 0;
196 DWARFDebugRangeList rangeList;
197 while (rangeList.extract(rangesData, &offset))
198 rangeList.dump(OS);
Eric Christopherda4b2192013-01-02 23:52:13 +0000199 }
Eric Christopher962c9082013-01-15 23:56:56 +0000200
Eric Christopher0de53592013-09-25 23:02:36 +0000201 if (DumpType == DIDT_All || DumpType == DIDT_Pubnames)
George Rimare71e33f2016-12-17 09:10:32 +0000202 DWARFDebugPubTable(getPubNamesSection(), isLittleEndian(), false)
203 .dump("debug_pubnames", OS);
Krzysztof Parzyszek97438dc2013-02-12 16:20:28 +0000204
Eric Christopher4c7e6ba2013-09-25 23:02:41 +0000205 if (DumpType == DIDT_All || DumpType == DIDT_Pubtypes)
George Rimare71e33f2016-12-17 09:10:32 +0000206 DWARFDebugPubTable(getPubTypesSection(), isLittleEndian(), false)
207 .dump("debug_pubtypes", OS);
Eric Christopher4c7e6ba2013-09-25 23:02:41 +0000208
David Blaikieecd21ff2013-09-24 19:50:00 +0000209 if (DumpType == DIDT_All || DumpType == DIDT_GnuPubnames)
George Rimare71e33f2016-12-17 09:10:32 +0000210 DWARFDebugPubTable(getGnuPubNamesSection(), isLittleEndian(),
211 true /* GnuStyle */)
212 .dump("debug_gnu_pubnames", OS);
David Blaikieecd21ff2013-09-24 19:50:00 +0000213
214 if (DumpType == DIDT_All || DumpType == DIDT_GnuPubtypes)
George Rimare71e33f2016-12-17 09:10:32 +0000215 DWARFDebugPubTable(getGnuPubTypesSection(), isLittleEndian(),
216 true /* GnuStyle */)
217 .dump("debug_gnu_pubtypes", OS);
David Blaikie404d3042013-09-19 23:01:29 +0000218
David Blaikie66865d62014-01-09 00:13:35 +0000219 if ((DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) &&
220 !getStringOffsetDWOSection().empty()) {
221 OS << "\n.debug_str_offsets.dwo contents:\n";
222 DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(),
223 0);
224 offset = 0;
225 uint64_t size = getStringOffsetDWOSection().size();
226 while (offset < size) {
227 OS << format("0x%8.8x: ", offset);
228 OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
Eric Christopher92f3c0b2013-05-06 17:50:42 +0000229 }
David Blaikie66865d62014-01-09 00:13:35 +0000230 }
Frederic Risse837ec22014-11-14 16:15:53 +0000231
George Rimar4f82df52016-09-23 11:01:53 +0000232 if ((DumpType == DIDT_All || DumpType == DIDT_GdbIndex) &&
233 !getGdbIndexSection().empty()) {
234 OS << "\n.gnu_index contents:\n";
235 getGdbIndex().dump(OS);
236 }
237
Frederic Risse837ec22014-11-14 16:15:53 +0000238 if (DumpType == DIDT_All || DumpType == DIDT_AppleNames)
239 dumpAccelSection(OS, "apple_names", getAppleNamesSection(),
240 getStringSection(), isLittleEndian());
241
242 if (DumpType == DIDT_All || DumpType == DIDT_AppleTypes)
243 dumpAccelSection(OS, "apple_types", getAppleTypesSection(),
244 getStringSection(), isLittleEndian());
245
246 if (DumpType == DIDT_All || DumpType == DIDT_AppleNamespaces)
247 dumpAccelSection(OS, "apple_namespaces", getAppleNamespacesSection(),
248 getStringSection(), isLittleEndian());
249
250 if (DumpType == DIDT_All || DumpType == DIDT_AppleObjC)
251 dumpAccelSection(OS, "apple_objc", getAppleObjCSection(),
252 getStringSection(), isLittleEndian());
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000253}
254
David Blaikie82641be2015-11-17 00:39:55 +0000255const DWARFUnitIndex &DWARFContext::getCUIndex() {
256 if (CUIndex)
257 return *CUIndex;
258
259 DataExtractor CUIndexData(getCUIndexSection(), isLittleEndian(), 0);
260
David Blaikieb073cb92015-12-02 06:21:34 +0000261 CUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
David Blaikie82641be2015-11-17 00:39:55 +0000262 CUIndex->parse(CUIndexData);
263 return *CUIndex;
264}
265
266const DWARFUnitIndex &DWARFContext::getTUIndex() {
267 if (TUIndex)
268 return *TUIndex;
269
270 DataExtractor TUIndexData(getTUIndexSection(), isLittleEndian(), 0);
271
David Blaikieb073cb92015-12-02 06:21:34 +0000272 TUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_TYPES);
David Blaikie82641be2015-11-17 00:39:55 +0000273 TUIndex->parse(TUIndexData);
274 return *TUIndex;
275}
276
George Rimar4f82df52016-09-23 11:01:53 +0000277DWARFGdbIndex &DWARFContext::getGdbIndex() {
278 if (GdbIndex)
279 return *GdbIndex;
280
281 DataExtractor GdbIndexData(getGdbIndexSection(), true /*LE*/, 0);
282 GdbIndex = llvm::make_unique<DWARFGdbIndex>();
283 GdbIndex->parse(GdbIndexData);
284 return *GdbIndex;
285}
286
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000287const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
288 if (Abbrev)
289 return Abbrev.get();
290
291 DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0);
292
293 Abbrev.reset(new DWARFDebugAbbrev());
Alexey Samsonov4316df52014-04-25 21:10:56 +0000294 Abbrev->extract(abbrData);
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000295 return Abbrev.get();
296}
297
Eric Christopherda4b2192013-01-02 23:52:13 +0000298const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
299 if (AbbrevDWO)
300 return AbbrevDWO.get();
301
302 DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0);
303 AbbrevDWO.reset(new DWARFDebugAbbrev());
Alexey Samsonov4316df52014-04-25 21:10:56 +0000304 AbbrevDWO->extract(abbrData);
Eric Christopherda4b2192013-01-02 23:52:13 +0000305 return AbbrevDWO.get();
306}
307
David Blaikie18e73502013-06-19 21:37:13 +0000308const DWARFDebugLoc *DWARFContext::getDebugLoc() {
309 if (Loc)
310 return Loc.get();
311
David Blaikie1b5ee5d2013-09-23 17:42:01 +0000312 DataExtractor LocData(getLocSection().Data, isLittleEndian(), 0);
313 Loc.reset(new DWARFDebugLoc(getLocSection().Relocs));
David Blaikie18e73502013-06-19 21:37:13 +0000314 // assume all compile units have the same address byte size
315 if (getNumCompileUnits())
316 Loc->parse(LocData, getCompileUnitAtIndex(0)->getAddressByteSize());
317 return Loc.get();
318}
319
David Blaikie9c550ac2014-03-25 01:44:02 +0000320const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() {
321 if (LocDWO)
322 return LocDWO.get();
323
324 DataExtractor LocData(getLocDWOSection().Data, isLittleEndian(), 0);
325 LocDWO.reset(new DWARFDebugLocDWO());
326 LocDWO->parse(LocData);
327 return LocDWO.get();
328}
329
Benjamin Kramera6002fd2011-09-14 01:09:52 +0000330const DWARFDebugAranges *DWARFContext::getDebugAranges() {
331 if (Aranges)
332 return Aranges.get();
333
Benjamin Kramera6002fd2011-09-14 01:09:52 +0000334 Aranges.reset(new DWARFDebugAranges());
Alexey Samsonova1694c12012-11-16 08:36:25 +0000335 Aranges->generate(this);
Benjamin Kramera6002fd2011-09-14 01:09:52 +0000336 return Aranges.get();
337}
338
Eli Benderskyfd08bc12013-02-05 23:30:58 +0000339const DWARFDebugFrame *DWARFContext::getDebugFrame() {
340 if (DebugFrame)
341 return DebugFrame.get();
342
343 // There's a "bug" in the DWARFv3 standard with respect to the target address
344 // size within debug frame sections. While DWARF is supposed to be independent
345 // of its container, FDEs have fields with size being "target address size",
346 // which isn't specified in DWARF in general. It's only specified for CUs, but
347 // .eh_frame can appear without a .debug_info section. Follow the example of
348 // other tools (libdwarf) and extract this from the container (ObjectFile
349 // provides this information). This problem is fixed in DWARFv4
350 // See this dwarf-discuss discussion for more details:
351 // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
352 DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(),
353 getAddressSize());
Igor Laevsky03a670c2016-01-26 15:09:42 +0000354 DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */));
355 DebugFrame->parse(debugFrameData);
356 return DebugFrame.get();
357}
358
359const DWARFDebugFrame *DWARFContext::getEHFrame() {
360 if (EHFrame)
361 return EHFrame.get();
362
363 DataExtractor debugFrameData(getEHFrameSection(), isLittleEndian(),
364 getAddressSize());
365 DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */));
Eli Benderskyfd08bc12013-02-05 23:30:58 +0000366 DebugFrame->parse(debugFrameData);
367 return DebugFrame.get();
368}
369
Amjad Aboude59cc3e2015-11-12 09:38:54 +0000370const DWARFDebugMacro *DWARFContext::getDebugMacro() {
371 if (Macro)
372 return Macro.get();
373
374 DataExtractor MacinfoData(getMacinfoSection(), isLittleEndian(), 0);
375 Macro.reset(new DWARFDebugMacro());
376 Macro->parse(MacinfoData);
377 return Macro.get();
378}
379
Eric Christopher494109b2012-10-16 23:46:25 +0000380const DWARFLineTable *
Alexey Samsonov7a18c062015-05-19 21:54:32 +0000381DWARFContext::getLineTableForUnit(DWARFUnit *U) {
Benjamin Kramer679e1752011-09-15 20:43:18 +0000382 if (!Line)
David Blaikie1b5ee5d2013-09-23 17:42:01 +0000383 Line.reset(new DWARFDebugLine(&getLineSection().Relocs));
David Blaikiec4e2bed2015-11-17 21:08:05 +0000384
Greg Claytonc8c10322016-12-13 18:25:19 +0000385 auto UnitDIE = U->getUnitDIE();
386 if (!UnitDIE)
Alexey Samsonov7a18c062015-05-19 21:54:32 +0000387 return nullptr;
David Blaikiec4e2bed2015-11-17 21:08:05 +0000388
Greg Clayton97d22182017-01-13 21:08:18 +0000389 auto Offset = toSectionOffset(UnitDIE.find(DW_AT_stmt_list));
Greg Clayton52fe1f62016-12-14 22:38:08 +0000390 if (!Offset)
Craig Topper2617dcc2014-04-15 06:32:26 +0000391 return nullptr; // No line table for this compile unit.
Benjamin Kramer5acab502011-09-15 02:12:05 +0000392
Greg Clayton52fe1f62016-12-14 22:38:08 +0000393 uint32_t stmtOffset = *Offset + U->getLineTableOffset();
Benjamin Kramer679e1752011-09-15 20:43:18 +0000394 // See if the line table is cached.
Eric Christopher494109b2012-10-16 23:46:25 +0000395 if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
Benjamin Kramer679e1752011-09-15 20:43:18 +0000396 return lt;
397
398 // We have to parse it first.
David Blaikiec4e2bed2015-11-17 21:08:05 +0000399 DataExtractor lineData(U->getLineSection(), isLittleEndian(),
Alexey Samsonov7a18c062015-05-19 21:54:32 +0000400 U->getAddressByteSize());
Benjamin Kramer679e1752011-09-15 20:43:18 +0000401 return Line->getOrParseLineTable(lineData, stmtOffset);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000402}
403
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000404void DWARFContext::parseCompileUnits() {
Alexey Samsonov8cd4c9d2014-10-08 00:07:53 +0000405 CUs.parse(*this, getInfoSection());
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000406}
Benjamin Kramer2602ca62011-09-15 20:43:22 +0000407
David Blaikie03c089c2013-09-23 22:44:47 +0000408void DWARFContext::parseTypeUnits() {
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000409 if (!TUs.empty())
410 return;
411 for (const auto &I : getTypesSections()) {
Benjamin Kramerf5e2fc42015-05-29 19:43:39 +0000412 TUs.emplace_back();
Alexey Samsonov8cd4c9d2014-10-08 00:07:53 +0000413 TUs.back().parse(*this, I.second);
David Blaikie03c089c2013-09-23 22:44:47 +0000414 }
415}
416
Eric Christopherda4b2192013-01-02 23:52:13 +0000417void DWARFContext::parseDWOCompileUnits() {
Alexey Samsonov8cd4c9d2014-10-08 00:07:53 +0000418 DWOCUs.parseDWO(*this, getInfoDWOSection());
Eric Christopherda4b2192013-01-02 23:52:13 +0000419}
420
David Blaikie92d9d622014-01-09 05:08:24 +0000421void DWARFContext::parseDWOTypeUnits() {
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000422 if (!DWOTUs.empty())
423 return;
424 for (const auto &I : getTypesDWOSections()) {
Benjamin Kramerf5e2fc42015-05-29 19:43:39 +0000425 DWOTUs.emplace_back();
Alexey Samsonov8cd4c9d2014-10-08 00:07:53 +0000426 DWOTUs.back().parseDWO(*this, I.second);
David Blaikie92d9d622014-01-09 05:08:24 +0000427 }
428}
429
Alexey Samsonov45be7932012-08-30 07:49:50 +0000430DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000431 parseCompileUnits();
Frederic Riss4e126a02014-09-15 07:50:27 +0000432 return CUs.getUnitForOffset(Offset);
Benjamin Kramer2602ca62011-09-15 20:43:22 +0000433}
434
Alexey Samsonov45be7932012-08-30 07:49:50 +0000435DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
Benjamin Kramer112ec172011-09-15 21:59:13 +0000436 // First, get the offset of the compile unit.
Alexey Samsonov45be7932012-08-30 07:49:50 +0000437 uint32_t CUOffset = getDebugAranges()->findAddress(Address);
Benjamin Kramer2602ca62011-09-15 20:43:22 +0000438 // Retrieve the compile unit.
Alexey Samsonov45be7932012-08-30 07:49:50 +0000439 return getCompileUnitForOffset(CUOffset);
440}
441
David Blaikieefc4eba2017-02-06 20:19:02 +0000442static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU,
443 uint64_t Address,
444 FunctionNameKind Kind,
445 std::string &FunctionName,
446 uint32_t &StartLine) {
Alexey Samsonovd0109992014-04-18 21:36:39 +0000447 // The address may correspond to instruction in some inlined function,
448 // so we have to build the chain of inlined functions and take the
David Blaikieefc4eba2017-02-06 20:19:02 +0000449 // name of the topmost function in it.
Greg Claytonc8c10322016-12-13 18:25:19 +0000450 SmallVector<DWARFDie, 4> InlinedChain;
451 CU->getInlinedChainForAddress(Address, InlinedChain);
David Blaikieefc4eba2017-02-06 20:19:02 +0000452 if (InlinedChain.empty())
Alexey Samsonovd0109992014-04-18 21:36:39 +0000453 return false;
David Blaikieefc4eba2017-02-06 20:19:02 +0000454
455 const DWARFDie &DIE = InlinedChain[0];
456 bool FoundResult = false;
457 const char *Name = nullptr;
458 if (Kind != FunctionNameKind::None && (Name = DIE.getSubroutineName(Kind))) {
Alexey Samsonovd0109992014-04-18 21:36:39 +0000459 FunctionName = Name;
David Blaikieefc4eba2017-02-06 20:19:02 +0000460 FoundResult = true;
Alexey Samsonovd0109992014-04-18 21:36:39 +0000461 }
David Blaikieefc4eba2017-02-06 20:19:02 +0000462 if (auto DeclLineResult = DIE.getDeclLine()) {
463 StartLine = DeclLineResult;
464 FoundResult = true;
465 }
466
467 return FoundResult;
Alexey Samsonovd0109992014-04-18 21:36:39 +0000468}
469
Alexey Samsonov45be7932012-08-30 07:49:50 +0000470DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
Alexey Samsonovdce67342014-05-15 21:24:32 +0000471 DILineInfoSpecifier Spec) {
Alexey Samsonovd0109992014-04-18 21:36:39 +0000472 DILineInfo Result;
473
Alexey Samsonov45be7932012-08-30 07:49:50 +0000474 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
475 if (!CU)
Alexey Samsonovd0109992014-04-18 21:36:39 +0000476 return Result;
David Blaikieefc4eba2017-02-06 20:19:02 +0000477 getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind,
478 Result.FunctionName,
479 Result.StartLine);
Alexey Samsonovdce67342014-05-15 21:24:32 +0000480 if (Spec.FLIKind != FileLineInfoKind::None) {
Frederic Riss101b5e22014-09-19 15:11:51 +0000481 if (const DWARFLineTable *LineTable = getLineTableForUnit(CU))
482 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
483 Spec.FLIKind, Result);
Alexey Samsonovf4462fa2012-07-02 05:54:45 +0000484 }
Alexey Samsonovd0109992014-04-18 21:36:39 +0000485 return Result;
Benjamin Kramer2602ca62011-09-15 20:43:22 +0000486}
David Blaikiea379b1812011-12-20 02:50:00 +0000487
Alexey Samsonovdce67342014-05-15 21:24:32 +0000488DILineInfoTable
489DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
490 DILineInfoSpecifier Spec) {
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000491 DILineInfoTable Lines;
492 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
493 if (!CU)
494 return Lines;
495
496 std::string FunctionName = "<invalid>";
David Blaikieefc4eba2017-02-06 20:19:02 +0000497 uint32_t StartLine = 0;
498 getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind, FunctionName,
499 StartLine);
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000500
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000501 // If the Specifier says we don't need FileLineInfo, just
502 // return the top-most function at the starting address.
Alexey Samsonovdce67342014-05-15 21:24:32 +0000503 if (Spec.FLIKind == FileLineInfoKind::None) {
Alexey Samsonovd0109992014-04-18 21:36:39 +0000504 DILineInfo Result;
505 Result.FunctionName = FunctionName;
David Blaikieefc4eba2017-02-06 20:19:02 +0000506 Result.StartLine = StartLine;
Alexey Samsonovd0109992014-04-18 21:36:39 +0000507 Lines.push_back(std::make_pair(Address, Result));
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000508 return Lines;
509 }
510
Frederic Rissec8a5ba2014-09-04 06:14:40 +0000511 const DWARFLineTable *LineTable = getLineTableForUnit(CU);
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000512
513 // Get the index of row we're looking for in the line table.
514 std::vector<uint32_t> RowVector;
515 if (!LineTable->lookupAddressRange(Address, Size, RowVector))
516 return Lines;
517
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000518 for (uint32_t RowIndex : RowVector) {
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000519 // Take file number and line/column from the row.
520 const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
Alexey Samsonovd0109992014-04-18 21:36:39 +0000521 DILineInfo Result;
Frederic Riss101b5e22014-09-19 15:11:51 +0000522 LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(),
523 Spec.FLIKind, Result.FileName);
Alexey Samsonovd0109992014-04-18 21:36:39 +0000524 Result.FunctionName = FunctionName;
525 Result.Line = Row.Line;
526 Result.Column = Row.Column;
David Blaikieefc4eba2017-02-06 20:19:02 +0000527 Result.StartLine = StartLine;
Alexey Samsonovd0109992014-04-18 21:36:39 +0000528 Lines.push_back(std::make_pair(Row.Address, Result));
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000529 }
530
531 return Lines;
532}
533
Alexey Samsonovdce67342014-05-15 21:24:32 +0000534DIInliningInfo
535DWARFContext::getInliningInfoForAddress(uint64_t Address,
536 DILineInfoSpecifier Spec) {
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000537 DIInliningInfo InliningInfo;
538
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000539 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
540 if (!CU)
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000541 return InliningInfo;
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000542
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000543 const DWARFLineTable *LineTable = nullptr;
Greg Claytonc8c10322016-12-13 18:25:19 +0000544 SmallVector<DWARFDie, 4> InlinedChain;
545 CU->getInlinedChainForAddress(Address, InlinedChain);
546 if (InlinedChain.size() == 0) {
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000547 // If there is no DIE for address (e.g. it is in unavailable .dwo file),
548 // try to at least get file/line info from symbol table.
Alexey Samsonovdce67342014-05-15 21:24:32 +0000549 if (Spec.FLIKind != FileLineInfoKind::None) {
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000550 DILineInfo Frame;
Frederic Rissec8a5ba2014-09-04 06:14:40 +0000551 LineTable = getLineTableForUnit(CU);
Frederic Riss101b5e22014-09-19 15:11:51 +0000552 if (LineTable &&
553 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
554 Spec.FLIKind, Frame))
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000555 InliningInfo.addFrame(Frame);
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000556 }
557 return InliningInfo;
558 }
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000559
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000560 uint32_t CallFile = 0, CallLine = 0, CallColumn = 0;
Greg Claytonc8c10322016-12-13 18:25:19 +0000561 for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) {
562 DWARFDie &FunctionDIE = InlinedChain[i];
Alexey Samsonovd0109992014-04-18 21:36:39 +0000563 DILineInfo Frame;
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000564 // Get function name if necessary.
Greg Claytonc8c10322016-12-13 18:25:19 +0000565 if (const char *Name = FunctionDIE.getSubroutineName(Spec.FNKind))
Alexey Samsonovdce67342014-05-15 21:24:32 +0000566 Frame.FunctionName = Name;
David Blaikieefc4eba2017-02-06 20:19:02 +0000567 if (auto DeclLineResult = FunctionDIE.getDeclLine())
568 Frame.StartLine = DeclLineResult;
Alexey Samsonovdce67342014-05-15 21:24:32 +0000569 if (Spec.FLIKind != FileLineInfoKind::None) {
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000570 if (i == 0) {
571 // For the topmost frame, initialize the line table of this
572 // compile unit and fetch file/line info from it.
Frederic Rissec8a5ba2014-09-04 06:14:40 +0000573 LineTable = getLineTableForUnit(CU);
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000574 // For the topmost routine, get file/line info from line table.
Frederic Riss101b5e22014-09-19 15:11:51 +0000575 if (LineTable)
576 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
577 Spec.FLIKind, Frame);
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000578 } else {
579 // Otherwise, use call file, call line and call column from
580 // previous DIE in inlined chain.
Frederic Riss101b5e22014-09-19 15:11:51 +0000581 if (LineTable)
582 LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(),
583 Spec.FLIKind, Frame.FileName);
Alexey Samsonovd0109992014-04-18 21:36:39 +0000584 Frame.Line = CallLine;
585 Frame.Column = CallColumn;
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000586 }
587 // Get call file/line/column of a current DIE.
588 if (i + 1 < n) {
Greg Claytonc8c10322016-12-13 18:25:19 +0000589 FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn);
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000590 }
591 }
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000592 InliningInfo.addFrame(Frame);
593 }
594 return InliningInfo;
595}
596
Keno Fischerc780e8e2015-05-21 21:24:32 +0000597DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
598 const LoadedObjectInfo *L)
Rafael Espindolaa04bb5b2014-07-31 20:19:36 +0000599 : IsLittleEndian(Obj.isLittleEndian()),
600 AddressSize(Obj.getBytesInAddress()) {
601 for (const SectionRef &Section : Obj.sections()) {
Eric Christopher7370b552012-11-12 21:40:38 +0000602 StringRef name;
Alexey Samsonov063eb3f2014-03-13 13:52:54 +0000603 Section.getName(name);
David Majnemerdac39852014-09-26 22:32:16 +0000604 // Skip BSS and Virtual sections, they aren't interesting.
Rafael Espindola80291272014-10-08 15:28:58 +0000605 bool IsBSS = Section.isBSS();
David Majnemerdac39852014-09-26 22:32:16 +0000606 if (IsBSS)
607 continue;
Rafael Espindola80291272014-10-08 15:28:58 +0000608 bool IsVirtual = Section.isVirtual();
David Majnemerdac39852014-09-26 22:32:16 +0000609 if (IsVirtual)
610 continue;
Eric Christopher7370b552012-11-12 21:40:38 +0000611 StringRef data;
Keno Fischerc780e8e2015-05-21 21:24:32 +0000612
Lang Hames2e88f4f2015-07-28 17:52:11 +0000613 section_iterator RelocatedSection = Section.getRelocatedSection();
Keno Fischerc780e8e2015-05-21 21:24:32 +0000614 // Try to obtain an already relocated version of this section.
615 // Else use the unrelocated section from the object file. We'll have to
616 // apply relocations ourselves later.
Lang Hames2e88f4f2015-07-28 17:52:11 +0000617 if (!L || !L->getLoadedSectionContents(*RelocatedSection,data))
Keno Fischerc780e8e2015-05-21 21:24:32 +0000618 Section.getContents(data);
Eric Christopher7370b552012-11-12 21:40:38 +0000619
George Rimar4bf30832017-01-11 15:26:41 +0000620 if (Decompressor::isCompressed(Section)) {
621 Expected<Decompressor> Decompressor =
622 Decompressor::create(name, data, IsLittleEndian, AddressSize == 8);
623 if (!Decompressor)
624 continue;
George Rimar401e4e52016-05-24 12:48:46 +0000625 SmallString<32> Out;
George Rimar4bf30832017-01-11 15:26:41 +0000626 if (auto Err = Decompressor->decompress(Out))
Alexey Samsonov068fc8a2013-04-23 10:17:34 +0000627 continue;
George Rimar401e4e52016-05-24 12:48:46 +0000628 UncompressedSections.emplace_back(std::move(Out));
David Blaikiea505f242014-04-05 21:26:44 +0000629 data = UncompressedSections.back();
Alexey Samsonov068fc8a2013-04-23 10:17:34 +0000630 }
631
George Rimar4bf30832017-01-11 15:26:41 +0000632 // Compressed sections names in GNU style starts from ".z",
633 // at this point section is decompressed and we drop compression prefix.
634 name = name.substr(
635 name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes.
636
Chris Bieneman2e752db2017-01-20 19:03:14 +0000637 if (StringRef *SectionData = MapSectionToMember(name)) {
Alexey Samsonov063eb3f2014-03-13 13:52:54 +0000638 *SectionData = data;
Rafael Espindola4f60a382013-05-30 03:05:14 +0000639 if (name == "debug_ranges") {
640 // FIXME: Use the other dwo range section when we emit it.
641 RangeDWOSection = data;
642 }
David Blaikie03c089c2013-09-23 22:44:47 +0000643 } else if (name == "debug_types") {
David Blaikie427e4352013-09-23 23:39:55 +0000644 // Find debug_types data by section rather than name as there are
645 // multiple, comdat grouped, debug_types sections.
Alexey Samsonov063eb3f2014-03-13 13:52:54 +0000646 TypesSections[Section].Data = data;
David Blaikie92d9d622014-01-09 05:08:24 +0000647 } else if (name == "debug_types.dwo") {
Alexey Samsonov063eb3f2014-03-13 13:52:54 +0000648 TypesDWOSections[Section].Data = data;
Eric Christopherda4b2192013-01-02 23:52:13 +0000649 }
Eric Christopher7370b552012-11-12 21:40:38 +0000650
Rafael Espindolaa04bb5b2014-07-31 20:19:36 +0000651 if (RelocatedSection == Obj.section_end())
Rafael Espindola4f60a382013-05-30 03:05:14 +0000652 continue;
653
654 StringRef RelSecName;
Keno Fischerc780e8e2015-05-21 21:24:32 +0000655 StringRef RelSecData;
Rafael Espindola4f60a382013-05-30 03:05:14 +0000656 RelocatedSection->getName(RelSecName);
Keno Fischerc780e8e2015-05-21 21:24:32 +0000657
658 // If the section we're relocating was relocated already by the JIT,
659 // then we used the relocated version above, so we do not need to process
660 // relocations for it now.
Lang Hames2e88f4f2015-07-28 17:52:11 +0000661 if (L && L->getLoadedSectionContents(*RelocatedSection,RelSecData))
Keno Fischerc780e8e2015-05-21 21:24:32 +0000662 continue;
663
Frederic Riss7bb12262015-08-23 04:44:21 +0000664 // In Mach-o files, the relocations do not need to be applied if
665 // there is no load offset to apply. The value read at the
666 // relocation point already factors in the section address
667 // (actually applying the relocations will produce wrong results
668 // as the section address will be added twice).
Craig Topper66059c92015-11-18 07:07:59 +0000669 if (!L && isa<MachOObjectFile>(&Obj))
Frederic Riss7bb12262015-08-23 04:44:21 +0000670 continue;
671
Rafael Espindola4f60a382013-05-30 03:05:14 +0000672 RelSecName = RelSecName.substr(
673 RelSecName.find_first_not_of("._")); // Skip . and _ prefixes.
674
Andrew Kaylord55d7012013-01-25 22:50:58 +0000675 // TODO: Add support for relocations in other sections as needed.
676 // Record relocations for the debug_info and debug_line sections.
Rafael Espindola4f60a382013-05-30 03:05:14 +0000677 RelocAddrMap *Map = StringSwitch<RelocAddrMap*>(RelSecName)
David Blaikie1b5ee5d2013-09-23 17:42:01 +0000678 .Case("debug_info", &InfoSection.Relocs)
679 .Case("debug_loc", &LocSection.Relocs)
680 .Case("debug_info.dwo", &InfoDWOSection.Relocs)
681 .Case("debug_line", &LineSection.Relocs)
Frederic Riss7c500472014-11-14 19:30:08 +0000682 .Case("apple_names", &AppleNamesSection.Relocs)
683 .Case("apple_types", &AppleTypesSection.Relocs)
684 .Case("apple_namespaces", &AppleNamespacesSection.Relocs)
685 .Case("apple_namespac", &AppleNamespacesSection.Relocs)
686 .Case("apple_objc", &AppleObjCSection.Relocs)
Craig Topper2617dcc2014-04-15 06:32:26 +0000687 .Default(nullptr);
David Blaikie03c089c2013-09-23 22:44:47 +0000688 if (!Map) {
David Blaikie427e4352013-09-23 23:39:55 +0000689 // Find debug_types relocs by section rather than name as there are
690 // multiple, comdat grouped, debug_types sections.
David Blaikie92d9d622014-01-09 05:08:24 +0000691 if (RelSecName == "debug_types")
692 Map = &TypesSections[*RelocatedSection].Relocs;
693 else if (RelSecName == "debug_types.dwo")
694 Map = &TypesDWOSections[*RelocatedSection].Relocs;
695 else
696 continue;
David Blaikie03c089c2013-09-23 22:44:47 +0000697 }
Eric Christopher7370b552012-11-12 21:40:38 +0000698
Alexey Samsonov063eb3f2014-03-13 13:52:54 +0000699 if (Section.relocation_begin() != Section.relocation_end()) {
Rafael Espindola80291272014-10-08 15:28:58 +0000700 uint64_t SectionSize = RelocatedSection->getSize();
Alexey Samsonovaa4d2952014-03-14 14:22:49 +0000701 for (const RelocationRef &Reloc : Section.relocations()) {
Rafael Espindola96d071c2015-06-29 23:29:12 +0000702 uint64_t Address = Reloc.getOffset();
Rafael Espindola99c041b2015-06-30 01:53:01 +0000703 uint64_t Type = Reloc.getType();
Andrew Kaylord55d7012013-01-25 22:50:58 +0000704 uint64_t SymAddr = 0;
Keno Fischerc780e8e2015-05-21 21:24:32 +0000705 uint64_t SectionLoadAddress = 0;
David Majnemer5fbe3242014-10-08 06:38:50 +0000706 object::symbol_iterator Sym = Reloc.getSymbol();
Rafael Espindola63a88ce2015-06-19 17:54:28 +0000707 object::section_iterator RSec = Obj.section_end();
Keno Fischerc780e8e2015-05-21 21:24:32 +0000708
709 // First calculate the address of the symbol or section as it appears
710 // in the objct file
711 if (Sym != Obj.symbol_end()) {
Kevin Enderby931cb652016-06-24 18:24:42 +0000712 Expected<uint64_t> SymAddrOrErr = Sym->getAddress();
713 if (!SymAddrOrErr) {
714 std::string Buf;
715 raw_string_ostream OS(Buf);
716 logAllUnhandledErrors(SymAddrOrErr.takeError(), OS, "");
717 OS.flush();
Rafael Espindolaed067c42015-07-03 18:19:00 +0000718 errs() << "error: failed to compute symbol address: "
Kevin Enderby931cb652016-06-24 18:24:42 +0000719 << Buf << '\n';
Rafael Espindolaed067c42015-07-03 18:19:00 +0000720 continue;
721 }
722 SymAddr = *SymAddrOrErr;
Keno Fischerc780e8e2015-05-21 21:24:32 +0000723 // Also remember what section this symbol is in for later
Kevin Enderby7bd8d992016-05-02 20:28:12 +0000724 auto SectOrErr = Sym->getSection();
725 if (!SectOrErr) {
726 std::string Buf;
727 raw_string_ostream OS(Buf);
728 logAllUnhandledErrors(SectOrErr.takeError(), OS, "");
729 OS.flush();
730 errs() << "error: failed to get symbol section: "
731 << Buf << '\n';
732 continue;
733 }
734 RSec = *SectOrErr;
Rafael Espindola63a88ce2015-06-19 17:54:28 +0000735 } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
736 // MachO also has relocations that point to sections and
737 // scattered relocations.
Frederic Rissf6402bf2015-07-31 20:22:50 +0000738 auto RelocInfo = MObj->getRelocation(Reloc.getRawDataRefImpl());
739 if (MObj->isRelocationScattered(RelocInfo)) {
740 // FIXME: it's not clear how to correctly handle scattered
741 // relocations.
742 continue;
743 } else {
744 RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
745 SymAddr = RSec->getAddress();
746 }
Rafael Espindola63a88ce2015-06-19 17:54:28 +0000747 }
Keno Fischerc780e8e2015-05-21 21:24:32 +0000748
749 // If we are given load addresses for the sections, we need to adjust:
750 // SymAddr = (Address of Symbol Or Section in File) -
751 // (Address of Section in File) +
752 // (Load Address of Section)
753 if (L != nullptr && RSec != Obj.section_end()) {
Benjamin Kramerdf005cb2015-08-08 18:27:36 +0000754 // RSec is now either the section being targeted or the section
755 // containing the symbol being targeted. In either case,
Keno Fischerc780e8e2015-05-21 21:24:32 +0000756 // we need to perform the same computation.
757 StringRef SecName;
758 RSec->getName(SecName);
Lang Hames2e88f4f2015-07-28 17:52:11 +0000759// llvm::dbgs() << "Name: '" << SecName
760// << "', RSec: " << RSec->getRawDataRefImpl()
761// << ", Section: " << Section.getRawDataRefImpl() << "\n";
762 SectionLoadAddress = L->getSectionLoadAddress(*RSec);
Keno Fischerc780e8e2015-05-21 21:24:32 +0000763 if (SectionLoadAddress != 0)
764 SymAddr += SectionLoadAddress - RSec->getAddress();
765 }
Eric Christopher7370b552012-11-12 21:40:38 +0000766
Eric Christopher47e079d2014-10-06 06:55:55 +0000767 object::RelocVisitor V(Obj);
David Majnemer5fbe3242014-10-08 06:38:50 +0000768 object::RelocToApply R(V.visit(Type, Reloc, SymAddr));
Eric Christopher7370b552012-11-12 21:40:38 +0000769 if (V.error()) {
770 SmallString<32> Name;
Rafael Espindola41bb4322015-06-30 04:08:37 +0000771 Reloc.getTypeName(Name);
Eric Christopher7370b552012-11-12 21:40:38 +0000772 errs() << "error: failed to compute relocation: "
773 << Name << "\n";
774 continue;
775 }
776
777 if (Address + R.Width > SectionSize) {
778 errs() << "error: " << R.Width << "-byte relocation starting "
779 << Address << " bytes into section " << name << " which is "
780 << SectionSize << " bytes long.\n";
781 continue;
782 }
783 if (R.Width > 8) {
784 errs() << "error: can't handle a relocation of more than 8 bytes at "
785 "a time.\n";
786 continue;
787 }
788 DEBUG(dbgs() << "Writing " << format("%p", R.Value)
789 << " at " << format("%p", Address)
790 << " with width " << format("%d", R.Width)
791 << "\n");
Eric Christopherda4b2192013-01-02 23:52:13 +0000792 Map->insert(std::make_pair(Address, std::make_pair(R.Width, R.Value)));
Eric Christopher7370b552012-11-12 21:40:38 +0000793 }
794 }
795 }
796}
797
Chris Bieneman2e752db2017-01-20 19:03:14 +0000798DWARFContextInMemory::DWARFContextInMemory(
799 const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, uint8_t AddrSize,
800 bool isLittleEndian)
801 : IsLittleEndian(isLittleEndian), AddressSize(AddrSize) {
802 for (const auto &SecIt : Sections) {
803 if (StringRef *SectionData = MapSectionToMember(SecIt.first()))
804 *SectionData = SecIt.second->getBuffer();
805 }
806}
807
808StringRef *DWARFContextInMemory::MapSectionToMember(StringRef Name) {
809 return StringSwitch<StringRef *>(Name)
810 .Case("debug_info", &InfoSection.Data)
811 .Case("debug_abbrev", &AbbrevSection)
812 .Case("debug_loc", &LocSection.Data)
813 .Case("debug_line", &LineSection.Data)
814 .Case("debug_aranges", &ARangeSection)
815 .Case("debug_frame", &DebugFrameSection)
816 .Case("eh_frame", &EHFrameSection)
817 .Case("debug_str", &StringSection)
818 .Case("debug_ranges", &RangeSection)
819 .Case("debug_macinfo", &MacinfoSection)
820 .Case("debug_pubnames", &PubNamesSection)
821 .Case("debug_pubtypes", &PubTypesSection)
822 .Case("debug_gnu_pubnames", &GnuPubNamesSection)
823 .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
824 .Case("debug_info.dwo", &InfoDWOSection.Data)
825 .Case("debug_abbrev.dwo", &AbbrevDWOSection)
826 .Case("debug_loc.dwo", &LocDWOSection.Data)
827 .Case("debug_line.dwo", &LineDWOSection.Data)
828 .Case("debug_str.dwo", &StringDWOSection)
829 .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
830 .Case("debug_addr", &AddrSection)
831 .Case("apple_names", &AppleNamesSection.Data)
832 .Case("apple_types", &AppleTypesSection.Data)
833 .Case("apple_namespaces", &AppleNamespacesSection.Data)
834 .Case("apple_namespac", &AppleNamespacesSection.Data)
835 .Case("apple_objc", &AppleObjCSection.Data)
836 .Case("debug_cu_index", &CUIndexSection)
837 .Case("debug_tu_index", &TUIndexSection)
838 .Case("gdb_index", &GdbIndexSection)
839 // Any more debug info sections go here.
840 .Default(nullptr);
841}
842
David Blaikiea379b1812011-12-20 02:50:00 +0000843void DWARFContextInMemory::anchor() { }