blob: adcbff78d1c2a3a2fc35a2d3611a5487fa41a12c [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"
David Blaikie65a8efe2015-11-11 19:28:21 +000015#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
Reid Klecknerdafc5d72016-07-06 16:56:42 +000016#include "llvm/Object/MachO.h"
17#include "llvm/Object/RelocVisitor.h"
Alexey Samsonov068fc8a2013-04-23 10:17:34 +000018#include "llvm/Support/Compression.h"
Benjamin Kramer6dda0322011-09-15 18:02:20 +000019#include "llvm/Support/Dwarf.h"
George Rimar401e4e52016-05-24 12:48:46 +000020#include "llvm/Support/ELF.h"
Benjamin Kramer07d4b1c2011-09-15 16:57:13 +000021#include "llvm/Support/Format.h"
Alexey Samsonove16e16a2012-07-19 07:03:58 +000022#include "llvm/Support/Path.h"
Benjamin Kramera6002fd2011-09-14 01:09:52 +000023#include "llvm/Support/raw_ostream.h"
Benjamin Kramer2602ca62011-09-15 20:43:22 +000024#include <algorithm>
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000025using namespace llvm;
Benjamin Kramer6dda0322011-09-15 18:02:20 +000026using namespace dwarf;
Rafael Espindola4f60a382013-05-30 03:05:14 +000027using namespace object;
Benjamin Krameraa2f78f2011-09-13 19:42:23 +000028
Chandler Carruthe96dd892014-04-21 22:55:11 +000029#define DEBUG_TYPE "dwarf"
30
Eric Christopher494109b2012-10-16 23:46:25 +000031typedef DWARFDebugLine::LineTable DWARFLineTable;
Alexey Samsonovdce67342014-05-15 21:24:32 +000032typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
33typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
Eric Christopher494109b2012-10-16 23:46:25 +000034
David Blaikieecd21ff2013-09-24 19:50:00 +000035static void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data,
Eric Christopher0de53592013-09-25 23:02:36 +000036 bool LittleEndian, bool GnuStyle) {
David Blaikieecd21ff2013-09-24 19:50:00 +000037 OS << "\n." << Name << " contents:\n";
38 DataExtractor pubNames(Data, LittleEndian, 0);
39 uint32_t offset = 0;
David Blaikie8a263cb2013-11-26 00:22:37 +000040 while (pubNames.isValidOffset(offset)) {
41 OS << "length = " << format("0x%08x", pubNames.getU32(&offset));
42 OS << " version = " << format("0x%04x", pubNames.getU16(&offset));
43 OS << " unit_offset = " << format("0x%08x", pubNames.getU32(&offset));
44 OS << " unit_size = " << format("0x%08x", pubNames.getU32(&offset)) << '\n';
45 if (GnuStyle)
46 OS << "Offset Linkage Kind Name\n";
47 else
48 OS << "Offset Name\n";
Eric Christopher0de53592013-09-25 23:02:36 +000049
David Blaikie8a263cb2013-11-26 00:22:37 +000050 while (offset < Data.size()) {
51 uint32_t dieRef = pubNames.getU32(&offset);
52 if (dieRef == 0)
53 break;
54 OS << format("0x%8.8x ", dieRef);
55 if (GnuStyle) {
56 PubIndexEntryDescriptor desc(pubNames.getU8(&offset));
Mehdi Amini149f6ea2016-10-05 05:59:29 +000057 OS << format("%-8s",
58 dwarf::GDBIndexEntryLinkageString(desc.Linkage).data())
59 << ' '
60 << format("%-8s", dwarf::GDBIndexEntryKindString(desc.Kind).data())
David Blaikie8a263cb2013-11-26 00:22:37 +000061 << ' ';
62 }
63 OS << '\"' << pubNames.getCStr(&offset) << "\"\n";
Eric Christopher0de53592013-09-25 23:02:36 +000064 }
David Blaikieecd21ff2013-09-24 19:50:00 +000065 }
66}
67
Frederic Riss7c500472014-11-14 19:30:08 +000068static void dumpAccelSection(raw_ostream &OS, StringRef Name,
69 const DWARFSection& Section, StringRef StringSection,
70 bool LittleEndian) {
71 DataExtractor AccelSection(Section.Data, LittleEndian, 0);
Frederic Risse837ec22014-11-14 16:15:53 +000072 DataExtractor StrData(StringSection, LittleEndian, 0);
73 OS << "\n." << Name << " contents:\n";
Frederic Riss7c500472014-11-14 19:30:08 +000074 DWARFAcceleratorTable Accel(AccelSection, StrData, Section.Relocs);
Frederic Risse837ec22014-11-14 16:15:53 +000075 if (!Accel.extract())
76 return;
77 Accel.dump(OS);
78}
79
David Blaikie50cc27e2016-10-18 21:09:48 +000080void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType, bool DumpEH,
81 bool SummarizeTypes) {
Eli Bendersky7a94daa2013-01-25 20:26:43 +000082 if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) {
83 OS << ".debug_abbrev contents:\n";
84 getDebugAbbrev()->dump(OS);
85 }
Benjamin Kramera6002fd2011-09-14 01:09:52 +000086
David Blaikie66865d62014-01-09 00:13:35 +000087 if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo)
88 if (const DWARFDebugAbbrev *D = getDebugAbbrevDWO()) {
David Blaikie622dce42014-01-08 23:29:59 +000089 OS << "\n.debug_abbrev.dwo contents:\n";
David Blaikie66865d62014-01-09 00:13:35 +000090 D->dump(OS);
David Blaikie622dce42014-01-08 23:29:59 +000091 }
David Blaikie622dce42014-01-08 23:29:59 +000092
Eli Bendersky7a94daa2013-01-25 20:26:43 +000093 if (DumpType == DIDT_All || DumpType == DIDT_Info) {
94 OS << "\n.debug_info contents:\n";
Alexey Samsonov1eabf982014-03-13 07:52:54 +000095 for (const auto &CU : compile_units())
96 CU->dump(OS);
Eli Bendersky7a94daa2013-01-25 20:26:43 +000097 }
Benjamin Kramera6002fd2011-09-14 01:09:52 +000098
David Blaikie66865d62014-01-09 00:13:35 +000099 if ((DumpType == DIDT_All || DumpType == DIDT_InfoDwo) &&
100 getNumDWOCompileUnits()) {
101 OS << "\n.debug_info.dwo contents:\n";
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000102 for (const auto &DWOCU : dwo_compile_units())
103 DWOCU->dump(OS);
David Blaikie66865d62014-01-09 00:13:35 +0000104 }
David Blaikie622dce42014-01-08 23:29:59 +0000105
David Blaikie66865d62014-01-09 00:13:35 +0000106 if ((DumpType == DIDT_All || DumpType == DIDT_Types) && getNumTypeUnits()) {
David Blaikie03c089c2013-09-23 22:44:47 +0000107 OS << "\n.debug_types contents:\n";
Frederic Riss312a02e2014-09-29 13:56:39 +0000108 for (const auto &TUS : type_unit_sections())
109 for (const auto &TU : TUS)
David Blaikie50cc27e2016-10-18 21:09:48 +0000110 TU->dump(OS, SummarizeTypes);
David Blaikie03c089c2013-09-23 22:44:47 +0000111 }
112
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000113 if ((DumpType == DIDT_All || DumpType == DIDT_TypesDwo) &&
114 getNumDWOTypeUnits()) {
115 OS << "\n.debug_types.dwo contents:\n";
Frederic Riss312a02e2014-09-29 13:56:39 +0000116 for (const auto &DWOTUS : dwo_type_unit_sections())
117 for (const auto &DWOTU : DWOTUS)
David Blaikie50cc27e2016-10-18 21:09:48 +0000118 DWOTU->dump(OS, SummarizeTypes);
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000119 }
David Blaikie92d9d622014-01-09 05:08:24 +0000120
David Blaikie18e73502013-06-19 21:37:13 +0000121 if (DumpType == DIDT_All || DumpType == DIDT_Loc) {
David Blaikie03c089c2013-09-23 22:44:47 +0000122 OS << "\n.debug_loc contents:\n";
David Blaikie18e73502013-06-19 21:37:13 +0000123 getDebugLoc()->dump(OS);
124 }
125
David Blaikie9c550ac2014-03-25 01:44:02 +0000126 if (DumpType == DIDT_All || DumpType == DIDT_LocDwo) {
127 OS << "\n.debug_loc.dwo contents:\n";
128 getDebugLocDWO()->dump(OS);
129 }
130
Eli Benderskyfd08bc12013-02-05 23:30:58 +0000131 if (DumpType == DIDT_All || DumpType == DIDT_Frames) {
132 OS << "\n.debug_frame contents:\n";
133 getDebugFrame()->dump(OS);
Igor Laevsky03a670c2016-01-26 15:09:42 +0000134 if (DumpEH) {
135 OS << "\n.eh_frame contents:\n";
136 getEHFrame()->dump(OS);
137 }
Eli Benderskyfd08bc12013-02-05 23:30:58 +0000138 }
139
Amjad Aboude59cc3e2015-11-12 09:38:54 +0000140 if (DumpType == DIDT_All || DumpType == DIDT_Macro) {
141 OS << "\n.debug_macinfo contents:\n";
142 getDebugMacro()->dump(OS);
143 }
144
Benjamin Kramera6002fd2011-09-14 01:09:52 +0000145 uint32_t offset = 0;
Eli Bendersky7a94daa2013-01-25 20:26:43 +0000146 if (DumpType == DIDT_All || DumpType == DIDT_Aranges) {
147 OS << "\n.debug_aranges contents:\n";
148 DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
149 DWARFDebugArangeSet set;
150 while (set.extract(arangesData, &offset))
151 set.dump(OS);
152 }
Benjamin Kramer5acab502011-09-15 02:12:05 +0000153
Alexey Samsonov034e57a2012-08-27 07:17:47 +0000154 uint8_t savedAddressByteSize = 0;
Eli Bendersky7a94daa2013-01-25 20:26:43 +0000155 if (DumpType == DIDT_All || DumpType == DIDT_Line) {
156 OS << "\n.debug_line contents:\n";
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000157 for (const auto &CU : compile_units()) {
158 savedAddressByteSize = CU->getAddressByteSize();
Alexey Samsonov7a18c062015-05-19 21:54:32 +0000159 const auto *CUDIE = CU->getUnitDIE();
160 if (CUDIE == nullptr)
161 continue;
162 unsigned stmtOffset = CUDIE->getAttributeValueAsSectionOffset(
163 CU.get(), DW_AT_stmt_list, -1U);
Eli Bendersky7a94daa2013-01-25 20:26:43 +0000164 if (stmtOffset != -1U) {
David Blaikie1b5ee5d2013-09-23 17:42:01 +0000165 DataExtractor lineData(getLineSection().Data, isLittleEndian(),
Eli Bendersky7a94daa2013-01-25 20:26:43 +0000166 savedAddressByteSize);
Alexey Samsonov110d5952014-04-30 00:09:19 +0000167 DWARFDebugLine::LineTable LineTable;
168 LineTable.parse(lineData, &getLineSection().Relocs, &stmtOffset);
169 LineTable.dump(OS);
Eli Bendersky7a94daa2013-01-25 20:26:43 +0000170 }
Benjamin Kramer6dda0322011-09-15 18:02:20 +0000171 }
172 }
Benjamin Kramer07d4b1c2011-09-15 16:57:13 +0000173
David Blaikie65a8efe2015-11-11 19:28:21 +0000174 if (DumpType == DIDT_All || DumpType == DIDT_CUIndex) {
175 OS << "\n.debug_cu_index contents:\n";
David Blaikieb073cb92015-12-02 06:21:34 +0000176 getCUIndex().dump(OS);
David Blaikie65a8efe2015-11-11 19:28:21 +0000177 }
178
David Blaikie51c40282015-11-11 19:40:49 +0000179 if (DumpType == DIDT_All || DumpType == DIDT_TUIndex) {
180 OS << "\n.debug_tu_index contents:\n";
David Blaikieb073cb92015-12-02 06:21:34 +0000181 getTUIndex().dump(OS);
David Blaikie51c40282015-11-11 19:40:49 +0000182 }
183
David Blaikie1d4736e2014-02-24 23:58:54 +0000184 if (DumpType == DIDT_All || DumpType == DIDT_LineDwo) {
185 OS << "\n.debug_line.dwo contents:\n";
186 unsigned stmtOffset = 0;
187 DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(),
188 savedAddressByteSize);
Alexey Samsonov110d5952014-04-30 00:09:19 +0000189 DWARFDebugLine::LineTable LineTable;
190 while (LineTable.Prologue.parse(lineData, &stmtOffset)) {
191 LineTable.dump(OS);
192 LineTable.clear();
193 }
David Blaikie1d4736e2014-02-24 23:58:54 +0000194 }
195
Eli Bendersky7a94daa2013-01-25 20:26:43 +0000196 if (DumpType == DIDT_All || DumpType == DIDT_Str) {
197 OS << "\n.debug_str contents:\n";
198 DataExtractor strData(getStringSection(), isLittleEndian(), 0);
199 offset = 0;
200 uint32_t strOffset = 0;
201 while (const char *s = strData.getCStr(&offset)) {
202 OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
203 strOffset = offset;
204 }
Benjamin Kramer07d4b1c2011-09-15 16:57:13 +0000205 }
Alexey Samsonov034e57a2012-08-27 07:17:47 +0000206
David Blaikie66865d62014-01-09 00:13:35 +0000207 if ((DumpType == DIDT_All || DumpType == DIDT_StrDwo) &&
208 !getStringDWOSection().empty()) {
209 OS << "\n.debug_str.dwo contents:\n";
210 DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
211 offset = 0;
212 uint32_t strDWOOffset = 0;
213 while (const char *s = strDWOData.getCStr(&offset)) {
214 OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
215 strDWOOffset = offset;
David Blaikie622dce42014-01-08 23:29:59 +0000216 }
David Blaikie66865d62014-01-09 00:13:35 +0000217 }
David Blaikie622dce42014-01-08 23:29:59 +0000218
Eli Bendersky7a94daa2013-01-25 20:26:43 +0000219 if (DumpType == DIDT_All || DumpType == DIDT_Ranges) {
220 OS << "\n.debug_ranges contents:\n";
221 // In fact, different compile units may have different address byte
222 // sizes, but for simplicity we just use the address byte size of the last
223 // compile unit (there is no easy and fast way to associate address range
224 // list and the compile unit it describes).
225 DataExtractor rangesData(getRangeSection(), isLittleEndian(),
226 savedAddressByteSize);
227 offset = 0;
228 DWARFDebugRangeList rangeList;
229 while (rangeList.extract(rangesData, &offset))
230 rangeList.dump(OS);
Eric Christopherda4b2192013-01-02 23:52:13 +0000231 }
Eric Christopher962c9082013-01-15 23:56:56 +0000232
Eric Christopher0de53592013-09-25 23:02:36 +0000233 if (DumpType == DIDT_All || DumpType == DIDT_Pubnames)
234 dumpPubSection(OS, "debug_pubnames", getPubNamesSection(),
235 isLittleEndian(), false);
Krzysztof Parzyszek97438dc2013-02-12 16:20:28 +0000236
Eric Christopher4c7e6ba2013-09-25 23:02:41 +0000237 if (DumpType == DIDT_All || DumpType == DIDT_Pubtypes)
238 dumpPubSection(OS, "debug_pubtypes", getPubTypesSection(),
239 isLittleEndian(), false);
240
David Blaikieecd21ff2013-09-24 19:50:00 +0000241 if (DumpType == DIDT_All || DumpType == DIDT_GnuPubnames)
242 dumpPubSection(OS, "debug_gnu_pubnames", getGnuPubNamesSection(),
Eric Christopher0de53592013-09-25 23:02:36 +0000243 isLittleEndian(), true /* GnuStyle */);
David Blaikieecd21ff2013-09-24 19:50:00 +0000244
245 if (DumpType == DIDT_All || DumpType == DIDT_GnuPubtypes)
246 dumpPubSection(OS, "debug_gnu_pubtypes", getGnuPubTypesSection(),
Eric Christopher0de53592013-09-25 23:02:36 +0000247 isLittleEndian(), true /* GnuStyle */);
David Blaikie404d3042013-09-19 23:01:29 +0000248
David Blaikie66865d62014-01-09 00:13:35 +0000249 if ((DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) &&
250 !getStringOffsetDWOSection().empty()) {
251 OS << "\n.debug_str_offsets.dwo contents:\n";
252 DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(),
253 0);
254 offset = 0;
255 uint64_t size = getStringOffsetDWOSection().size();
256 while (offset < size) {
257 OS << format("0x%8.8x: ", offset);
258 OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
Eric Christopher92f3c0b2013-05-06 17:50:42 +0000259 }
David Blaikie66865d62014-01-09 00:13:35 +0000260 }
Frederic Risse837ec22014-11-14 16:15:53 +0000261
George Rimar4f82df52016-09-23 11:01:53 +0000262 if ((DumpType == DIDT_All || DumpType == DIDT_GdbIndex) &&
263 !getGdbIndexSection().empty()) {
264 OS << "\n.gnu_index contents:\n";
265 getGdbIndex().dump(OS);
266 }
267
Frederic Risse837ec22014-11-14 16:15:53 +0000268 if (DumpType == DIDT_All || DumpType == DIDT_AppleNames)
269 dumpAccelSection(OS, "apple_names", getAppleNamesSection(),
270 getStringSection(), isLittleEndian());
271
272 if (DumpType == DIDT_All || DumpType == DIDT_AppleTypes)
273 dumpAccelSection(OS, "apple_types", getAppleTypesSection(),
274 getStringSection(), isLittleEndian());
275
276 if (DumpType == DIDT_All || DumpType == DIDT_AppleNamespaces)
277 dumpAccelSection(OS, "apple_namespaces", getAppleNamespacesSection(),
278 getStringSection(), isLittleEndian());
279
280 if (DumpType == DIDT_All || DumpType == DIDT_AppleObjC)
281 dumpAccelSection(OS, "apple_objc", getAppleObjCSection(),
282 getStringSection(), isLittleEndian());
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000283}
284
David Blaikie82641be2015-11-17 00:39:55 +0000285const DWARFUnitIndex &DWARFContext::getCUIndex() {
286 if (CUIndex)
287 return *CUIndex;
288
289 DataExtractor CUIndexData(getCUIndexSection(), isLittleEndian(), 0);
290
David Blaikieb073cb92015-12-02 06:21:34 +0000291 CUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
David Blaikie82641be2015-11-17 00:39:55 +0000292 CUIndex->parse(CUIndexData);
293 return *CUIndex;
294}
295
296const DWARFUnitIndex &DWARFContext::getTUIndex() {
297 if (TUIndex)
298 return *TUIndex;
299
300 DataExtractor TUIndexData(getTUIndexSection(), isLittleEndian(), 0);
301
David Blaikieb073cb92015-12-02 06:21:34 +0000302 TUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_TYPES);
David Blaikie82641be2015-11-17 00:39:55 +0000303 TUIndex->parse(TUIndexData);
304 return *TUIndex;
305}
306
George Rimar4f82df52016-09-23 11:01:53 +0000307DWARFGdbIndex &DWARFContext::getGdbIndex() {
308 if (GdbIndex)
309 return *GdbIndex;
310
311 DataExtractor GdbIndexData(getGdbIndexSection(), true /*LE*/, 0);
312 GdbIndex = llvm::make_unique<DWARFGdbIndex>();
313 GdbIndex->parse(GdbIndexData);
314 return *GdbIndex;
315}
316
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000317const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
318 if (Abbrev)
319 return Abbrev.get();
320
321 DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0);
322
323 Abbrev.reset(new DWARFDebugAbbrev());
Alexey Samsonov4316df52014-04-25 21:10:56 +0000324 Abbrev->extract(abbrData);
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000325 return Abbrev.get();
326}
327
Eric Christopherda4b2192013-01-02 23:52:13 +0000328const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
329 if (AbbrevDWO)
330 return AbbrevDWO.get();
331
332 DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0);
333 AbbrevDWO.reset(new DWARFDebugAbbrev());
Alexey Samsonov4316df52014-04-25 21:10:56 +0000334 AbbrevDWO->extract(abbrData);
Eric Christopherda4b2192013-01-02 23:52:13 +0000335 return AbbrevDWO.get();
336}
337
David Blaikie18e73502013-06-19 21:37:13 +0000338const DWARFDebugLoc *DWARFContext::getDebugLoc() {
339 if (Loc)
340 return Loc.get();
341
David Blaikie1b5ee5d2013-09-23 17:42:01 +0000342 DataExtractor LocData(getLocSection().Data, isLittleEndian(), 0);
343 Loc.reset(new DWARFDebugLoc(getLocSection().Relocs));
David Blaikie18e73502013-06-19 21:37:13 +0000344 // assume all compile units have the same address byte size
345 if (getNumCompileUnits())
346 Loc->parse(LocData, getCompileUnitAtIndex(0)->getAddressByteSize());
347 return Loc.get();
348}
349
David Blaikie9c550ac2014-03-25 01:44:02 +0000350const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() {
351 if (LocDWO)
352 return LocDWO.get();
353
354 DataExtractor LocData(getLocDWOSection().Data, isLittleEndian(), 0);
355 LocDWO.reset(new DWARFDebugLocDWO());
356 LocDWO->parse(LocData);
357 return LocDWO.get();
358}
359
Benjamin Kramera6002fd2011-09-14 01:09:52 +0000360const DWARFDebugAranges *DWARFContext::getDebugAranges() {
361 if (Aranges)
362 return Aranges.get();
363
Benjamin Kramera6002fd2011-09-14 01:09:52 +0000364 Aranges.reset(new DWARFDebugAranges());
Alexey Samsonova1694c12012-11-16 08:36:25 +0000365 Aranges->generate(this);
Benjamin Kramera6002fd2011-09-14 01:09:52 +0000366 return Aranges.get();
367}
368
Eli Benderskyfd08bc12013-02-05 23:30:58 +0000369const DWARFDebugFrame *DWARFContext::getDebugFrame() {
370 if (DebugFrame)
371 return DebugFrame.get();
372
373 // There's a "bug" in the DWARFv3 standard with respect to the target address
374 // size within debug frame sections. While DWARF is supposed to be independent
375 // of its container, FDEs have fields with size being "target address size",
376 // which isn't specified in DWARF in general. It's only specified for CUs, but
377 // .eh_frame can appear without a .debug_info section. Follow the example of
378 // other tools (libdwarf) and extract this from the container (ObjectFile
379 // provides this information). This problem is fixed in DWARFv4
380 // See this dwarf-discuss discussion for more details:
381 // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
382 DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(),
383 getAddressSize());
Igor Laevsky03a670c2016-01-26 15:09:42 +0000384 DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */));
385 DebugFrame->parse(debugFrameData);
386 return DebugFrame.get();
387}
388
389const DWARFDebugFrame *DWARFContext::getEHFrame() {
390 if (EHFrame)
391 return EHFrame.get();
392
393 DataExtractor debugFrameData(getEHFrameSection(), isLittleEndian(),
394 getAddressSize());
395 DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */));
Eli Benderskyfd08bc12013-02-05 23:30:58 +0000396 DebugFrame->parse(debugFrameData);
397 return DebugFrame.get();
398}
399
Amjad Aboude59cc3e2015-11-12 09:38:54 +0000400const DWARFDebugMacro *DWARFContext::getDebugMacro() {
401 if (Macro)
402 return Macro.get();
403
404 DataExtractor MacinfoData(getMacinfoSection(), isLittleEndian(), 0);
405 Macro.reset(new DWARFDebugMacro());
406 Macro->parse(MacinfoData);
407 return Macro.get();
408}
409
Eric Christopher494109b2012-10-16 23:46:25 +0000410const DWARFLineTable *
Alexey Samsonov7a18c062015-05-19 21:54:32 +0000411DWARFContext::getLineTableForUnit(DWARFUnit *U) {
Benjamin Kramer679e1752011-09-15 20:43:18 +0000412 if (!Line)
David Blaikie1b5ee5d2013-09-23 17:42:01 +0000413 Line.reset(new DWARFDebugLine(&getLineSection().Relocs));
David Blaikiec4e2bed2015-11-17 21:08:05 +0000414
Alexey Samsonov7a18c062015-05-19 21:54:32 +0000415 const auto *UnitDIE = U->getUnitDIE();
416 if (UnitDIE == nullptr)
417 return nullptr;
David Blaikiec4e2bed2015-11-17 21:08:05 +0000418
Benjamin Kramer679e1752011-09-15 20:43:18 +0000419 unsigned stmtOffset =
Alexey Samsonov7a18c062015-05-19 21:54:32 +0000420 UnitDIE->getAttributeValueAsSectionOffset(U, DW_AT_stmt_list, -1U);
Benjamin Kramer679e1752011-09-15 20:43:18 +0000421 if (stmtOffset == -1U)
Craig Topper2617dcc2014-04-15 06:32:26 +0000422 return nullptr; // No line table for this compile unit.
Benjamin Kramer5acab502011-09-15 02:12:05 +0000423
David Blaikiec4e2bed2015-11-17 21:08:05 +0000424 stmtOffset += U->getLineTableOffset();
Benjamin Kramer679e1752011-09-15 20:43:18 +0000425 // See if the line table is cached.
Eric Christopher494109b2012-10-16 23:46:25 +0000426 if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
Benjamin Kramer679e1752011-09-15 20:43:18 +0000427 return lt;
428
429 // We have to parse it first.
David Blaikiec4e2bed2015-11-17 21:08:05 +0000430 DataExtractor lineData(U->getLineSection(), isLittleEndian(),
Alexey Samsonov7a18c062015-05-19 21:54:32 +0000431 U->getAddressByteSize());
Benjamin Kramer679e1752011-09-15 20:43:18 +0000432 return Line->getOrParseLineTable(lineData, stmtOffset);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000433}
434
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000435void DWARFContext::parseCompileUnits() {
Alexey Samsonov8cd4c9d2014-10-08 00:07:53 +0000436 CUs.parse(*this, getInfoSection());
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000437}
Benjamin Kramer2602ca62011-09-15 20:43:22 +0000438
David Blaikie03c089c2013-09-23 22:44:47 +0000439void DWARFContext::parseTypeUnits() {
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000440 if (!TUs.empty())
441 return;
442 for (const auto &I : getTypesSections()) {
Benjamin Kramerf5e2fc42015-05-29 19:43:39 +0000443 TUs.emplace_back();
Alexey Samsonov8cd4c9d2014-10-08 00:07:53 +0000444 TUs.back().parse(*this, I.second);
David Blaikie03c089c2013-09-23 22:44:47 +0000445 }
446}
447
Eric Christopherda4b2192013-01-02 23:52:13 +0000448void DWARFContext::parseDWOCompileUnits() {
Alexey Samsonov8cd4c9d2014-10-08 00:07:53 +0000449 DWOCUs.parseDWO(*this, getInfoDWOSection());
Eric Christopherda4b2192013-01-02 23:52:13 +0000450}
451
David Blaikie92d9d622014-01-09 05:08:24 +0000452void DWARFContext::parseDWOTypeUnits() {
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000453 if (!DWOTUs.empty())
454 return;
455 for (const auto &I : getTypesDWOSections()) {
Benjamin Kramerf5e2fc42015-05-29 19:43:39 +0000456 DWOTUs.emplace_back();
Alexey Samsonov8cd4c9d2014-10-08 00:07:53 +0000457 DWOTUs.back().parseDWO(*this, I.second);
David Blaikie92d9d622014-01-09 05:08:24 +0000458 }
459}
460
Alexey Samsonov45be7932012-08-30 07:49:50 +0000461DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000462 parseCompileUnits();
Frederic Riss4e126a02014-09-15 07:50:27 +0000463 return CUs.getUnitForOffset(Offset);
Benjamin Kramer2602ca62011-09-15 20:43:22 +0000464}
465
Alexey Samsonov45be7932012-08-30 07:49:50 +0000466DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
Benjamin Kramer112ec172011-09-15 21:59:13 +0000467 // First, get the offset of the compile unit.
Alexey Samsonov45be7932012-08-30 07:49:50 +0000468 uint32_t CUOffset = getDebugAranges()->findAddress(Address);
Benjamin Kramer2602ca62011-09-15 20:43:22 +0000469 // Retrieve the compile unit.
Alexey Samsonov45be7932012-08-30 07:49:50 +0000470 return getCompileUnitForOffset(CUOffset);
471}
472
Alexey Samsonovd0109992014-04-18 21:36:39 +0000473static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address,
Alexey Samsonovdce67342014-05-15 21:24:32 +0000474 FunctionNameKind Kind,
Alexey Samsonovd0109992014-04-18 21:36:39 +0000475 std::string &FunctionName) {
Alexey Samsonovdce67342014-05-15 21:24:32 +0000476 if (Kind == FunctionNameKind::None)
477 return false;
Alexey Samsonovd0109992014-04-18 21:36:39 +0000478 // The address may correspond to instruction in some inlined function,
479 // so we have to build the chain of inlined functions and take the
480 // name of the topmost function in it.
481 const DWARFDebugInfoEntryInlinedChain &InlinedChain =
482 CU->getInlinedChainForAddress(Address);
483 if (InlinedChain.DIEs.size() == 0)
484 return false;
485 const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
Alexey Samsonovdce67342014-05-15 21:24:32 +0000486 if (const char *Name =
487 TopFunctionDIE.getSubroutineName(InlinedChain.U, Kind)) {
Alexey Samsonovd0109992014-04-18 21:36:39 +0000488 FunctionName = Name;
489 return true;
490 }
491 return false;
492}
493
Alexey Samsonov45be7932012-08-30 07:49:50 +0000494DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
Alexey Samsonovdce67342014-05-15 21:24:32 +0000495 DILineInfoSpecifier Spec) {
Alexey Samsonovd0109992014-04-18 21:36:39 +0000496 DILineInfo Result;
497
Alexey Samsonov45be7932012-08-30 07:49:50 +0000498 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
499 if (!CU)
Alexey Samsonovd0109992014-04-18 21:36:39 +0000500 return Result;
Alexey Samsonovdce67342014-05-15 21:24:32 +0000501 getFunctionNameForAddress(CU, Address, Spec.FNKind, Result.FunctionName);
502 if (Spec.FLIKind != FileLineInfoKind::None) {
Frederic Riss101b5e22014-09-19 15:11:51 +0000503 if (const DWARFLineTable *LineTable = getLineTableForUnit(CU))
504 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
505 Spec.FLIKind, Result);
Alexey Samsonovf4462fa2012-07-02 05:54:45 +0000506 }
Alexey Samsonovd0109992014-04-18 21:36:39 +0000507 return Result;
Benjamin Kramer2602ca62011-09-15 20:43:22 +0000508}
David Blaikiea379b1812011-12-20 02:50:00 +0000509
Alexey Samsonovdce67342014-05-15 21:24:32 +0000510DILineInfoTable
511DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
512 DILineInfoSpecifier Spec) {
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000513 DILineInfoTable Lines;
514 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
515 if (!CU)
516 return Lines;
517
518 std::string FunctionName = "<invalid>";
Alexey Samsonovdce67342014-05-15 21:24:32 +0000519 getFunctionNameForAddress(CU, Address, Spec.FNKind, FunctionName);
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000520
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000521 // If the Specifier says we don't need FileLineInfo, just
522 // return the top-most function at the starting address.
Alexey Samsonovdce67342014-05-15 21:24:32 +0000523 if (Spec.FLIKind == FileLineInfoKind::None) {
Alexey Samsonovd0109992014-04-18 21:36:39 +0000524 DILineInfo Result;
525 Result.FunctionName = FunctionName;
526 Lines.push_back(std::make_pair(Address, Result));
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000527 return Lines;
528 }
529
Frederic Rissec8a5ba2014-09-04 06:14:40 +0000530 const DWARFLineTable *LineTable = getLineTableForUnit(CU);
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000531
532 // Get the index of row we're looking for in the line table.
533 std::vector<uint32_t> RowVector;
534 if (!LineTable->lookupAddressRange(Address, Size, RowVector))
535 return Lines;
536
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000537 for (uint32_t RowIndex : RowVector) {
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000538 // Take file number and line/column from the row.
539 const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
Alexey Samsonovd0109992014-04-18 21:36:39 +0000540 DILineInfo Result;
Frederic Riss101b5e22014-09-19 15:11:51 +0000541 LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(),
542 Spec.FLIKind, Result.FileName);
Alexey Samsonovd0109992014-04-18 21:36:39 +0000543 Result.FunctionName = FunctionName;
544 Result.Line = Row.Line;
545 Result.Column = Row.Column;
546 Lines.push_back(std::make_pair(Row.Address, Result));
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000547 }
548
549 return Lines;
550}
551
Alexey Samsonovdce67342014-05-15 21:24:32 +0000552DIInliningInfo
553DWARFContext::getInliningInfoForAddress(uint64_t Address,
554 DILineInfoSpecifier Spec) {
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000555 DIInliningInfo InliningInfo;
556
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000557 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
558 if (!CU)
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000559 return InliningInfo;
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000560
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000561 const DWARFLineTable *LineTable = nullptr;
Alexey Samsonov3211e612013-08-06 10:49:15 +0000562 const DWARFDebugInfoEntryInlinedChain &InlinedChain =
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000563 CU->getInlinedChainForAddress(Address);
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000564 if (InlinedChain.DIEs.size() == 0) {
565 // If there is no DIE for address (e.g. it is in unavailable .dwo file),
566 // try to at least get file/line info from symbol table.
Alexey Samsonovdce67342014-05-15 21:24:32 +0000567 if (Spec.FLIKind != FileLineInfoKind::None) {
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000568 DILineInfo Frame;
Frederic Rissec8a5ba2014-09-04 06:14:40 +0000569 LineTable = getLineTableForUnit(CU);
Frederic Riss101b5e22014-09-19 15:11:51 +0000570 if (LineTable &&
571 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
572 Spec.FLIKind, Frame))
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000573 InliningInfo.addFrame(Frame);
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000574 }
575 return InliningInfo;
576 }
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000577
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000578 uint32_t CallFile = 0, CallLine = 0, CallColumn = 0;
Alexey Samsonov3211e612013-08-06 10:49:15 +0000579 for (uint32_t i = 0, n = InlinedChain.DIEs.size(); i != n; i++) {
580 const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i];
Alexey Samsonovd0109992014-04-18 21:36:39 +0000581 DILineInfo Frame;
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000582 // Get function name if necessary.
Alexey Samsonovdce67342014-05-15 21:24:32 +0000583 if (const char *Name =
584 FunctionDIE.getSubroutineName(InlinedChain.U, Spec.FNKind))
585 Frame.FunctionName = Name;
586 if (Spec.FLIKind != FileLineInfoKind::None) {
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000587 if (i == 0) {
588 // For the topmost frame, initialize the line table of this
589 // compile unit and fetch file/line info from it.
Frederic Rissec8a5ba2014-09-04 06:14:40 +0000590 LineTable = getLineTableForUnit(CU);
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000591 // For the topmost routine, get file/line info from line table.
Frederic Riss101b5e22014-09-19 15:11:51 +0000592 if (LineTable)
593 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
594 Spec.FLIKind, Frame);
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000595 } else {
596 // Otherwise, use call file, call line and call column from
597 // previous DIE in inlined chain.
Frederic Riss101b5e22014-09-19 15:11:51 +0000598 if (LineTable)
599 LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(),
600 Spec.FLIKind, Frame.FileName);
Alexey Samsonovd0109992014-04-18 21:36:39 +0000601 Frame.Line = CallLine;
602 Frame.Column = CallColumn;
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000603 }
604 // Get call file/line/column of a current DIE.
605 if (i + 1 < n) {
David Blaikie07e22442013-09-23 22:44:40 +0000606 FunctionDIE.getCallerFrame(InlinedChain.U, CallFile, CallLine,
Alexey Samsonov3211e612013-08-06 10:49:15 +0000607 CallColumn);
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000608 }
609 }
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000610 InliningInfo.addFrame(Frame);
611 }
612 return InliningInfo;
613}
614
George Rimar401e4e52016-05-24 12:48:46 +0000615static bool consumeCompressedGnuHeader(StringRef &data,
616 uint64_t &OriginalSize) {
Alexey Samsonov068fc8a2013-04-23 10:17:34 +0000617 // Consume "ZLIB" prefix.
618 if (!data.startswith("ZLIB"))
619 return false;
620 data = data.substr(4);
621 // Consume uncompressed section size (big-endian 8 bytes).
622 DataExtractor extractor(data, false, 8);
623 uint32_t Offset = 0;
624 OriginalSize = extractor.getU64(&Offset);
625 if (Offset == 0)
626 return false;
627 data = data.substr(Offset);
628 return true;
629}
630
George Rimar401e4e52016-05-24 12:48:46 +0000631static bool consumeCompressedZLibHeader(StringRef &Data, uint64_t &OriginalSize,
632 bool IsLE, bool Is64Bit) {
633 using namespace ELF;
634 uint64_t HdrSize = Is64Bit ? sizeof(Elf64_Chdr) : sizeof(Elf32_Chdr);
635 if (Data.size() < HdrSize)
636 return false;
637
638 DataExtractor Extractor(Data, IsLE, 0);
639 uint32_t Offset = 0;
640 if (Extractor.getUnsigned(&Offset, Is64Bit ? sizeof(Elf64_Word)
641 : sizeof(Elf32_Word)) !=
642 ELFCOMPRESS_ZLIB)
643 return false;
644
645 // Skip Elf64_Chdr::ch_reserved field.
646 if (Is64Bit)
647 Offset += sizeof(Elf64_Word);
648
649 OriginalSize = Extractor.getUnsigned(&Offset, Is64Bit ? sizeof(Elf64_Xword)
650 : sizeof(Elf32_Word));
651 Data = Data.substr(HdrSize);
652 return true;
653}
654
655static bool tryDecompress(StringRef &Name, StringRef &Data,
656 SmallString<32> &Out, bool ZLibStyle, bool IsLE,
657 bool Is64Bit) {
658 if (!zlib::isAvailable())
659 return false;
660
661 uint64_t OriginalSize;
662 bool Result =
663 ZLibStyle ? consumeCompressedZLibHeader(Data, OriginalSize, IsLE, Is64Bit)
664 : consumeCompressedGnuHeader(Data, OriginalSize);
665
666 if (!Result || zlib::uncompress(Data, Out, OriginalSize) != zlib::StatusOK)
667 return false;
668
669 // gnu-style names are started from "z", consume that.
670 if (!ZLibStyle)
671 Name = Name.substr(1);
672 return true;
673}
674
Keno Fischerc780e8e2015-05-21 21:24:32 +0000675DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
676 const LoadedObjectInfo *L)
Rafael Espindolaa04bb5b2014-07-31 20:19:36 +0000677 : IsLittleEndian(Obj.isLittleEndian()),
678 AddressSize(Obj.getBytesInAddress()) {
679 for (const SectionRef &Section : Obj.sections()) {
Eric Christopher7370b552012-11-12 21:40:38 +0000680 StringRef name;
Alexey Samsonov063eb3f2014-03-13 13:52:54 +0000681 Section.getName(name);
David Majnemerdac39852014-09-26 22:32:16 +0000682 // Skip BSS and Virtual sections, they aren't interesting.
Rafael Espindola80291272014-10-08 15:28:58 +0000683 bool IsBSS = Section.isBSS();
David Majnemerdac39852014-09-26 22:32:16 +0000684 if (IsBSS)
685 continue;
Rafael Espindola80291272014-10-08 15:28:58 +0000686 bool IsVirtual = Section.isVirtual();
David Majnemerdac39852014-09-26 22:32:16 +0000687 if (IsVirtual)
688 continue;
Eric Christopher7370b552012-11-12 21:40:38 +0000689 StringRef data;
Keno Fischerc780e8e2015-05-21 21:24:32 +0000690
Lang Hames2e88f4f2015-07-28 17:52:11 +0000691 section_iterator RelocatedSection = Section.getRelocatedSection();
Keno Fischerc780e8e2015-05-21 21:24:32 +0000692 // Try to obtain an already relocated version of this section.
693 // Else use the unrelocated section from the object file. We'll have to
694 // apply relocations ourselves later.
Lang Hames2e88f4f2015-07-28 17:52:11 +0000695 if (!L || !L->getLoadedSectionContents(*RelocatedSection,data))
Keno Fischerc780e8e2015-05-21 21:24:32 +0000696 Section.getContents(data);
Eric Christopher7370b552012-11-12 21:40:38 +0000697
Eric Christopher7370b552012-11-12 21:40:38 +0000698 name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes.
Alexey Samsonov3d0e3ed2013-04-17 14:27:04 +0000699
George Rimar401e4e52016-05-24 12:48:46 +0000700 bool ZLibStyleCompressed = Section.isCompressed();
701 if (ZLibStyleCompressed || name.startswith("zdebug_")) {
702 SmallString<32> Out;
703 if (!tryDecompress(name, data, Out, ZLibStyleCompressed, IsLittleEndian,
704 AddressSize == 8))
Alexey Samsonov068fc8a2013-04-23 10:17:34 +0000705 continue;
George Rimar401e4e52016-05-24 12:48:46 +0000706 UncompressedSections.emplace_back(std::move(Out));
David Blaikiea505f242014-04-05 21:26:44 +0000707 data = UncompressedSections.back();
Alexey Samsonov068fc8a2013-04-23 10:17:34 +0000708 }
709
Alexey Samsonov063eb3f2014-03-13 13:52:54 +0000710 StringRef *SectionData =
Eric Christopher4c7e6ba2013-09-25 23:02:41 +0000711 StringSwitch<StringRef *>(name)
712 .Case("debug_info", &InfoSection.Data)
713 .Case("debug_abbrev", &AbbrevSection)
714 .Case("debug_loc", &LocSection.Data)
715 .Case("debug_line", &LineSection.Data)
716 .Case("debug_aranges", &ARangeSection)
717 .Case("debug_frame", &DebugFrameSection)
Igor Laevsky03a670c2016-01-26 15:09:42 +0000718 .Case("eh_frame", &EHFrameSection)
Eric Christopher4c7e6ba2013-09-25 23:02:41 +0000719 .Case("debug_str", &StringSection)
720 .Case("debug_ranges", &RangeSection)
Amjad Aboude59cc3e2015-11-12 09:38:54 +0000721 .Case("debug_macinfo", &MacinfoSection)
Eric Christopher4c7e6ba2013-09-25 23:02:41 +0000722 .Case("debug_pubnames", &PubNamesSection)
723 .Case("debug_pubtypes", &PubTypesSection)
724 .Case("debug_gnu_pubnames", &GnuPubNamesSection)
725 .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
726 .Case("debug_info.dwo", &InfoDWOSection.Data)
727 .Case("debug_abbrev.dwo", &AbbrevDWOSection)
David Blaikie9c550ac2014-03-25 01:44:02 +0000728 .Case("debug_loc.dwo", &LocDWOSection.Data)
David Blaikie1d4736e2014-02-24 23:58:54 +0000729 .Case("debug_line.dwo", &LineDWOSection.Data)
Eric Christopher4c7e6ba2013-09-25 23:02:41 +0000730 .Case("debug_str.dwo", &StringDWOSection)
731 .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
732 .Case("debug_addr", &AddrSection)
Frederic Riss7c500472014-11-14 19:30:08 +0000733 .Case("apple_names", &AppleNamesSection.Data)
734 .Case("apple_types", &AppleTypesSection.Data)
735 .Case("apple_namespaces", &AppleNamespacesSection.Data)
736 .Case("apple_namespac", &AppleNamespacesSection.Data)
737 .Case("apple_objc", &AppleObjCSection.Data)
David Blaikie65a8efe2015-11-11 19:28:21 +0000738 .Case("debug_cu_index", &CUIndexSection)
David Blaikie51c40282015-11-11 19:40:49 +0000739 .Case("debug_tu_index", &TUIndexSection)
George Rimar4f82df52016-09-23 11:01:53 +0000740 .Case("gdb_index", &GdbIndexSection)
Eric Christopher4c7e6ba2013-09-25 23:02:41 +0000741 // Any more debug info sections go here.
Craig Topper2617dcc2014-04-15 06:32:26 +0000742 .Default(nullptr);
Alexey Samsonov063eb3f2014-03-13 13:52:54 +0000743 if (SectionData) {
744 *SectionData = data;
Rafael Espindola4f60a382013-05-30 03:05:14 +0000745 if (name == "debug_ranges") {
746 // FIXME: Use the other dwo range section when we emit it.
747 RangeDWOSection = data;
748 }
David Blaikie03c089c2013-09-23 22:44:47 +0000749 } else if (name == "debug_types") {
David Blaikie427e4352013-09-23 23:39:55 +0000750 // Find debug_types data by section rather than name as there are
751 // multiple, comdat grouped, debug_types sections.
Alexey Samsonov063eb3f2014-03-13 13:52:54 +0000752 TypesSections[Section].Data = data;
David Blaikie92d9d622014-01-09 05:08:24 +0000753 } else if (name == "debug_types.dwo") {
Alexey Samsonov063eb3f2014-03-13 13:52:54 +0000754 TypesDWOSections[Section].Data = data;
Eric Christopherda4b2192013-01-02 23:52:13 +0000755 }
Eric Christopher7370b552012-11-12 21:40:38 +0000756
Rafael Espindolaa04bb5b2014-07-31 20:19:36 +0000757 if (RelocatedSection == Obj.section_end())
Rafael Espindola4f60a382013-05-30 03:05:14 +0000758 continue;
759
760 StringRef RelSecName;
Keno Fischerc780e8e2015-05-21 21:24:32 +0000761 StringRef RelSecData;
Rafael Espindola4f60a382013-05-30 03:05:14 +0000762 RelocatedSection->getName(RelSecName);
Keno Fischerc780e8e2015-05-21 21:24:32 +0000763
764 // If the section we're relocating was relocated already by the JIT,
765 // then we used the relocated version above, so we do not need to process
766 // relocations for it now.
Lang Hames2e88f4f2015-07-28 17:52:11 +0000767 if (L && L->getLoadedSectionContents(*RelocatedSection,RelSecData))
Keno Fischerc780e8e2015-05-21 21:24:32 +0000768 continue;
769
Frederic Riss7bb12262015-08-23 04:44:21 +0000770 // In Mach-o files, the relocations do not need to be applied if
771 // there is no load offset to apply. The value read at the
772 // relocation point already factors in the section address
773 // (actually applying the relocations will produce wrong results
774 // as the section address will be added twice).
Craig Topper66059c92015-11-18 07:07:59 +0000775 if (!L && isa<MachOObjectFile>(&Obj))
Frederic Riss7bb12262015-08-23 04:44:21 +0000776 continue;
777
Rafael Espindola4f60a382013-05-30 03:05:14 +0000778 RelSecName = RelSecName.substr(
779 RelSecName.find_first_not_of("._")); // Skip . and _ prefixes.
780
Andrew Kaylord55d7012013-01-25 22:50:58 +0000781 // TODO: Add support for relocations in other sections as needed.
782 // Record relocations for the debug_info and debug_line sections.
Rafael Espindola4f60a382013-05-30 03:05:14 +0000783 RelocAddrMap *Map = StringSwitch<RelocAddrMap*>(RelSecName)
David Blaikie1b5ee5d2013-09-23 17:42:01 +0000784 .Case("debug_info", &InfoSection.Relocs)
785 .Case("debug_loc", &LocSection.Relocs)
786 .Case("debug_info.dwo", &InfoDWOSection.Relocs)
787 .Case("debug_line", &LineSection.Relocs)
Frederic Riss7c500472014-11-14 19:30:08 +0000788 .Case("apple_names", &AppleNamesSection.Relocs)
789 .Case("apple_types", &AppleTypesSection.Relocs)
790 .Case("apple_namespaces", &AppleNamespacesSection.Relocs)
791 .Case("apple_namespac", &AppleNamespacesSection.Relocs)
792 .Case("apple_objc", &AppleObjCSection.Relocs)
Craig Topper2617dcc2014-04-15 06:32:26 +0000793 .Default(nullptr);
David Blaikie03c089c2013-09-23 22:44:47 +0000794 if (!Map) {
David Blaikie427e4352013-09-23 23:39:55 +0000795 // Find debug_types relocs by section rather than name as there are
796 // multiple, comdat grouped, debug_types sections.
David Blaikie92d9d622014-01-09 05:08:24 +0000797 if (RelSecName == "debug_types")
798 Map = &TypesSections[*RelocatedSection].Relocs;
799 else if (RelSecName == "debug_types.dwo")
800 Map = &TypesDWOSections[*RelocatedSection].Relocs;
801 else
802 continue;
David Blaikie03c089c2013-09-23 22:44:47 +0000803 }
Eric Christopher7370b552012-11-12 21:40:38 +0000804
Alexey Samsonov063eb3f2014-03-13 13:52:54 +0000805 if (Section.relocation_begin() != Section.relocation_end()) {
Rafael Espindola80291272014-10-08 15:28:58 +0000806 uint64_t SectionSize = RelocatedSection->getSize();
Alexey Samsonovaa4d2952014-03-14 14:22:49 +0000807 for (const RelocationRef &Reloc : Section.relocations()) {
Rafael Espindola96d071c2015-06-29 23:29:12 +0000808 uint64_t Address = Reloc.getOffset();
Rafael Espindola99c041b2015-06-30 01:53:01 +0000809 uint64_t Type = Reloc.getType();
Andrew Kaylord55d7012013-01-25 22:50:58 +0000810 uint64_t SymAddr = 0;
Keno Fischerc780e8e2015-05-21 21:24:32 +0000811 uint64_t SectionLoadAddress = 0;
David Majnemer5fbe3242014-10-08 06:38:50 +0000812 object::symbol_iterator Sym = Reloc.getSymbol();
Rafael Espindola63a88ce2015-06-19 17:54:28 +0000813 object::section_iterator RSec = Obj.section_end();
Keno Fischerc780e8e2015-05-21 21:24:32 +0000814
815 // First calculate the address of the symbol or section as it appears
816 // in the objct file
817 if (Sym != Obj.symbol_end()) {
Kevin Enderby931cb652016-06-24 18:24:42 +0000818 Expected<uint64_t> SymAddrOrErr = Sym->getAddress();
819 if (!SymAddrOrErr) {
820 std::string Buf;
821 raw_string_ostream OS(Buf);
822 logAllUnhandledErrors(SymAddrOrErr.takeError(), OS, "");
823 OS.flush();
Rafael Espindolaed067c42015-07-03 18:19:00 +0000824 errs() << "error: failed to compute symbol address: "
Kevin Enderby931cb652016-06-24 18:24:42 +0000825 << Buf << '\n';
Rafael Espindolaed067c42015-07-03 18:19:00 +0000826 continue;
827 }
828 SymAddr = *SymAddrOrErr;
Keno Fischerc780e8e2015-05-21 21:24:32 +0000829 // Also remember what section this symbol is in for later
Kevin Enderby7bd8d992016-05-02 20:28:12 +0000830 auto SectOrErr = Sym->getSection();
831 if (!SectOrErr) {
832 std::string Buf;
833 raw_string_ostream OS(Buf);
834 logAllUnhandledErrors(SectOrErr.takeError(), OS, "");
835 OS.flush();
836 errs() << "error: failed to get symbol section: "
837 << Buf << '\n';
838 continue;
839 }
840 RSec = *SectOrErr;
Rafael Espindola63a88ce2015-06-19 17:54:28 +0000841 } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
842 // MachO also has relocations that point to sections and
843 // scattered relocations.
Frederic Rissf6402bf2015-07-31 20:22:50 +0000844 auto RelocInfo = MObj->getRelocation(Reloc.getRawDataRefImpl());
845 if (MObj->isRelocationScattered(RelocInfo)) {
846 // FIXME: it's not clear how to correctly handle scattered
847 // relocations.
848 continue;
849 } else {
850 RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
851 SymAddr = RSec->getAddress();
852 }
Rafael Espindola63a88ce2015-06-19 17:54:28 +0000853 }
Keno Fischerc780e8e2015-05-21 21:24:32 +0000854
855 // If we are given load addresses for the sections, we need to adjust:
856 // SymAddr = (Address of Symbol Or Section in File) -
857 // (Address of Section in File) +
858 // (Load Address of Section)
859 if (L != nullptr && RSec != Obj.section_end()) {
Benjamin Kramerdf005cb2015-08-08 18:27:36 +0000860 // RSec is now either the section being targeted or the section
861 // containing the symbol being targeted. In either case,
Keno Fischerc780e8e2015-05-21 21:24:32 +0000862 // we need to perform the same computation.
863 StringRef SecName;
864 RSec->getName(SecName);
Lang Hames2e88f4f2015-07-28 17:52:11 +0000865// llvm::dbgs() << "Name: '" << SecName
866// << "', RSec: " << RSec->getRawDataRefImpl()
867// << ", Section: " << Section.getRawDataRefImpl() << "\n";
868 SectionLoadAddress = L->getSectionLoadAddress(*RSec);
Keno Fischerc780e8e2015-05-21 21:24:32 +0000869 if (SectionLoadAddress != 0)
870 SymAddr += SectionLoadAddress - RSec->getAddress();
871 }
Eric Christopher7370b552012-11-12 21:40:38 +0000872
Eric Christopher47e079d2014-10-06 06:55:55 +0000873 object::RelocVisitor V(Obj);
David Majnemer5fbe3242014-10-08 06:38:50 +0000874 object::RelocToApply R(V.visit(Type, Reloc, SymAddr));
Eric Christopher7370b552012-11-12 21:40:38 +0000875 if (V.error()) {
876 SmallString<32> Name;
Rafael Espindola41bb4322015-06-30 04:08:37 +0000877 Reloc.getTypeName(Name);
Eric Christopher7370b552012-11-12 21:40:38 +0000878 errs() << "error: failed to compute relocation: "
879 << Name << "\n";
880 continue;
881 }
882
883 if (Address + R.Width > SectionSize) {
884 errs() << "error: " << R.Width << "-byte relocation starting "
885 << Address << " bytes into section " << name << " which is "
886 << SectionSize << " bytes long.\n";
887 continue;
888 }
889 if (R.Width > 8) {
890 errs() << "error: can't handle a relocation of more than 8 bytes at "
891 "a time.\n";
892 continue;
893 }
894 DEBUG(dbgs() << "Writing " << format("%p", R.Value)
895 << " at " << format("%p", Address)
896 << " with width " << format("%d", R.Width)
897 << "\n");
Eric Christopherda4b2192013-01-02 23:52:13 +0000898 Map->insert(std::make_pair(Address, std::make_pair(R.Width, R.Value)));
Eric Christopher7370b552012-11-12 21:40:38 +0000899 }
900 }
901 }
902}
903
David Blaikiea379b1812011-12-20 02:50:00 +0000904void DWARFContextInMemory::anchor() { }