blob: 0f2a48bd509c498cae79dc0f59fdf9ab530d0070 [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();
Greg Claytonc8c10322016-12-13 18:25:19 +0000159 auto CUDIE = CU->getUnitDIE();
160 if (!CUDIE)
Alexey Samsonov7a18c062015-05-19 21:54:32 +0000161 continue;
Greg Clayton52fe1f62016-12-14 22:38:08 +0000162 if (auto StmtOffset =
163 CUDIE.getAttributeValueAsSectionOffset(DW_AT_stmt_list)) {
David Blaikie1b5ee5d2013-09-23 17:42:01 +0000164 DataExtractor lineData(getLineSection().Data, isLittleEndian(),
Eli Bendersky7a94daa2013-01-25 20:26:43 +0000165 savedAddressByteSize);
Alexey Samsonov110d5952014-04-30 00:09:19 +0000166 DWARFDebugLine::LineTable LineTable;
Greg Clayton52fe1f62016-12-14 22:38:08 +0000167 uint32_t Offset = *StmtOffset;
168 LineTable.parse(lineData, &getLineSection().Relocs, &Offset);
Alexey Samsonov110d5952014-04-30 00:09:19 +0000169 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
Greg Claytonc8c10322016-12-13 18:25:19 +0000415 auto UnitDIE = U->getUnitDIE();
416 if (!UnitDIE)
Alexey Samsonov7a18c062015-05-19 21:54:32 +0000417 return nullptr;
David Blaikiec4e2bed2015-11-17 21:08:05 +0000418
Greg Clayton52fe1f62016-12-14 22:38:08 +0000419 auto Offset = UnitDIE.getAttributeValueAsSectionOffset(DW_AT_stmt_list);
420 if (!Offset)
Craig Topper2617dcc2014-04-15 06:32:26 +0000421 return nullptr; // No line table for this compile unit.
Benjamin Kramer5acab502011-09-15 02:12:05 +0000422
Greg Clayton52fe1f62016-12-14 22:38:08 +0000423 uint32_t stmtOffset = *Offset + U->getLineTableOffset();
Benjamin Kramer679e1752011-09-15 20:43:18 +0000424 // See if the line table is cached.
Eric Christopher494109b2012-10-16 23:46:25 +0000425 if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
Benjamin Kramer679e1752011-09-15 20:43:18 +0000426 return lt;
427
428 // We have to parse it first.
David Blaikiec4e2bed2015-11-17 21:08:05 +0000429 DataExtractor lineData(U->getLineSection(), isLittleEndian(),
Alexey Samsonov7a18c062015-05-19 21:54:32 +0000430 U->getAddressByteSize());
Benjamin Kramer679e1752011-09-15 20:43:18 +0000431 return Line->getOrParseLineTable(lineData, stmtOffset);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000432}
433
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000434void DWARFContext::parseCompileUnits() {
Alexey Samsonov8cd4c9d2014-10-08 00:07:53 +0000435 CUs.parse(*this, getInfoSection());
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000436}
Benjamin Kramer2602ca62011-09-15 20:43:22 +0000437
David Blaikie03c089c2013-09-23 22:44:47 +0000438void DWARFContext::parseTypeUnits() {
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000439 if (!TUs.empty())
440 return;
441 for (const auto &I : getTypesSections()) {
Benjamin Kramerf5e2fc42015-05-29 19:43:39 +0000442 TUs.emplace_back();
Alexey Samsonov8cd4c9d2014-10-08 00:07:53 +0000443 TUs.back().parse(*this, I.second);
David Blaikie03c089c2013-09-23 22:44:47 +0000444 }
445}
446
Eric Christopherda4b2192013-01-02 23:52:13 +0000447void DWARFContext::parseDWOCompileUnits() {
Alexey Samsonov8cd4c9d2014-10-08 00:07:53 +0000448 DWOCUs.parseDWO(*this, getInfoDWOSection());
Eric Christopherda4b2192013-01-02 23:52:13 +0000449}
450
David Blaikie92d9d622014-01-09 05:08:24 +0000451void DWARFContext::parseDWOTypeUnits() {
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000452 if (!DWOTUs.empty())
453 return;
454 for (const auto &I : getTypesDWOSections()) {
Benjamin Kramerf5e2fc42015-05-29 19:43:39 +0000455 DWOTUs.emplace_back();
Alexey Samsonov8cd4c9d2014-10-08 00:07:53 +0000456 DWOTUs.back().parseDWO(*this, I.second);
David Blaikie92d9d622014-01-09 05:08:24 +0000457 }
458}
459
Alexey Samsonov45be7932012-08-30 07:49:50 +0000460DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000461 parseCompileUnits();
Frederic Riss4e126a02014-09-15 07:50:27 +0000462 return CUs.getUnitForOffset(Offset);
Benjamin Kramer2602ca62011-09-15 20:43:22 +0000463}
464
Alexey Samsonov45be7932012-08-30 07:49:50 +0000465DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
Benjamin Kramer112ec172011-09-15 21:59:13 +0000466 // First, get the offset of the compile unit.
Alexey Samsonov45be7932012-08-30 07:49:50 +0000467 uint32_t CUOffset = getDebugAranges()->findAddress(Address);
Benjamin Kramer2602ca62011-09-15 20:43:22 +0000468 // Retrieve the compile unit.
Alexey Samsonov45be7932012-08-30 07:49:50 +0000469 return getCompileUnitForOffset(CUOffset);
470}
471
Alexey Samsonovd0109992014-04-18 21:36:39 +0000472static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address,
Alexey Samsonovdce67342014-05-15 21:24:32 +0000473 FunctionNameKind Kind,
Alexey Samsonovd0109992014-04-18 21:36:39 +0000474 std::string &FunctionName) {
Alexey Samsonovdce67342014-05-15 21:24:32 +0000475 if (Kind == FunctionNameKind::None)
476 return false;
Alexey Samsonovd0109992014-04-18 21:36:39 +0000477 // The address may correspond to instruction in some inlined function,
478 // so we have to build the chain of inlined functions and take the
Greg Claytonc8c10322016-12-13 18:25:19 +0000479 // name of the topmost function in it.SmallVectorImpl<DWARFDie> &InlinedChain
480 SmallVector<DWARFDie, 4> InlinedChain;
481 CU->getInlinedChainForAddress(Address, InlinedChain);
482 if (InlinedChain.size() == 0)
Alexey Samsonovd0109992014-04-18 21:36:39 +0000483 return false;
Greg Claytonc8c10322016-12-13 18:25:19 +0000484 if (const char *Name = InlinedChain[0].getSubroutineName(Kind)) {
Alexey Samsonovd0109992014-04-18 21:36:39 +0000485 FunctionName = Name;
486 return true;
487 }
488 return false;
489}
490
Alexey Samsonov45be7932012-08-30 07:49:50 +0000491DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
Alexey Samsonovdce67342014-05-15 21:24:32 +0000492 DILineInfoSpecifier Spec) {
Alexey Samsonovd0109992014-04-18 21:36:39 +0000493 DILineInfo Result;
494
Alexey Samsonov45be7932012-08-30 07:49:50 +0000495 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
496 if (!CU)
Alexey Samsonovd0109992014-04-18 21:36:39 +0000497 return Result;
Alexey Samsonovdce67342014-05-15 21:24:32 +0000498 getFunctionNameForAddress(CU, Address, Spec.FNKind, Result.FunctionName);
499 if (Spec.FLIKind != FileLineInfoKind::None) {
Frederic Riss101b5e22014-09-19 15:11:51 +0000500 if (const DWARFLineTable *LineTable = getLineTableForUnit(CU))
501 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
502 Spec.FLIKind, Result);
Alexey Samsonovf4462fa2012-07-02 05:54:45 +0000503 }
Alexey Samsonovd0109992014-04-18 21:36:39 +0000504 return Result;
Benjamin Kramer2602ca62011-09-15 20:43:22 +0000505}
David Blaikiea379b1812011-12-20 02:50:00 +0000506
Alexey Samsonovdce67342014-05-15 21:24:32 +0000507DILineInfoTable
508DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
509 DILineInfoSpecifier Spec) {
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000510 DILineInfoTable Lines;
511 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
512 if (!CU)
513 return Lines;
514
515 std::string FunctionName = "<invalid>";
Alexey Samsonovdce67342014-05-15 21:24:32 +0000516 getFunctionNameForAddress(CU, Address, Spec.FNKind, FunctionName);
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000517
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000518 // If the Specifier says we don't need FileLineInfo, just
519 // return the top-most function at the starting address.
Alexey Samsonovdce67342014-05-15 21:24:32 +0000520 if (Spec.FLIKind == FileLineInfoKind::None) {
Alexey Samsonovd0109992014-04-18 21:36:39 +0000521 DILineInfo Result;
522 Result.FunctionName = FunctionName;
523 Lines.push_back(std::make_pair(Address, Result));
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000524 return Lines;
525 }
526
Frederic Rissec8a5ba2014-09-04 06:14:40 +0000527 const DWARFLineTable *LineTable = getLineTableForUnit(CU);
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000528
529 // Get the index of row we're looking for in the line table.
530 std::vector<uint32_t> RowVector;
531 if (!LineTable->lookupAddressRange(Address, Size, RowVector))
532 return Lines;
533
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000534 for (uint32_t RowIndex : RowVector) {
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000535 // Take file number and line/column from the row.
536 const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
Alexey Samsonovd0109992014-04-18 21:36:39 +0000537 DILineInfo Result;
Frederic Riss101b5e22014-09-19 15:11:51 +0000538 LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(),
539 Spec.FLIKind, Result.FileName);
Alexey Samsonovd0109992014-04-18 21:36:39 +0000540 Result.FunctionName = FunctionName;
541 Result.Line = Row.Line;
542 Result.Column = Row.Column;
543 Lines.push_back(std::make_pair(Row.Address, Result));
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000544 }
545
546 return Lines;
547}
548
Alexey Samsonovdce67342014-05-15 21:24:32 +0000549DIInliningInfo
550DWARFContext::getInliningInfoForAddress(uint64_t Address,
551 DILineInfoSpecifier Spec) {
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000552 DIInliningInfo InliningInfo;
553
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000554 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
555 if (!CU)
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000556 return InliningInfo;
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000557
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000558 const DWARFLineTable *LineTable = nullptr;
Greg Claytonc8c10322016-12-13 18:25:19 +0000559 SmallVector<DWARFDie, 4> InlinedChain;
560 CU->getInlinedChainForAddress(Address, InlinedChain);
561 if (InlinedChain.size() == 0) {
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000562 // If there is no DIE for address (e.g. it is in unavailable .dwo file),
563 // try to at least get file/line info from symbol table.
Alexey Samsonovdce67342014-05-15 21:24:32 +0000564 if (Spec.FLIKind != FileLineInfoKind::None) {
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000565 DILineInfo Frame;
Frederic Rissec8a5ba2014-09-04 06:14:40 +0000566 LineTable = getLineTableForUnit(CU);
Frederic Riss101b5e22014-09-19 15:11:51 +0000567 if (LineTable &&
568 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
569 Spec.FLIKind, Frame))
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000570 InliningInfo.addFrame(Frame);
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000571 }
572 return InliningInfo;
573 }
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000574
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000575 uint32_t CallFile = 0, CallLine = 0, CallColumn = 0;
Greg Claytonc8c10322016-12-13 18:25:19 +0000576 for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) {
577 DWARFDie &FunctionDIE = InlinedChain[i];
Alexey Samsonovd0109992014-04-18 21:36:39 +0000578 DILineInfo Frame;
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000579 // Get function name if necessary.
Greg Claytonc8c10322016-12-13 18:25:19 +0000580 if (const char *Name = FunctionDIE.getSubroutineName(Spec.FNKind))
Alexey Samsonovdce67342014-05-15 21:24:32 +0000581 Frame.FunctionName = Name;
582 if (Spec.FLIKind != FileLineInfoKind::None) {
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000583 if (i == 0) {
584 // For the topmost frame, initialize the line table of this
585 // compile unit and fetch file/line info from it.
Frederic Rissec8a5ba2014-09-04 06:14:40 +0000586 LineTable = getLineTableForUnit(CU);
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000587 // For the topmost routine, get file/line info from line table.
Frederic Riss101b5e22014-09-19 15:11:51 +0000588 if (LineTable)
589 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
590 Spec.FLIKind, Frame);
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000591 } else {
592 // Otherwise, use call file, call line and call column from
593 // previous DIE in inlined chain.
Frederic Riss101b5e22014-09-19 15:11:51 +0000594 if (LineTable)
595 LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(),
596 Spec.FLIKind, Frame.FileName);
Alexey Samsonovd0109992014-04-18 21:36:39 +0000597 Frame.Line = CallLine;
598 Frame.Column = CallColumn;
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000599 }
600 // Get call file/line/column of a current DIE.
601 if (i + 1 < n) {
Greg Claytonc8c10322016-12-13 18:25:19 +0000602 FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn);
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000603 }
604 }
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000605 InliningInfo.addFrame(Frame);
606 }
607 return InliningInfo;
608}
609
George Rimar401e4e52016-05-24 12:48:46 +0000610static bool consumeCompressedGnuHeader(StringRef &data,
611 uint64_t &OriginalSize) {
Alexey Samsonov068fc8a2013-04-23 10:17:34 +0000612 // Consume "ZLIB" prefix.
613 if (!data.startswith("ZLIB"))
614 return false;
615 data = data.substr(4);
616 // Consume uncompressed section size (big-endian 8 bytes).
617 DataExtractor extractor(data, false, 8);
618 uint32_t Offset = 0;
619 OriginalSize = extractor.getU64(&Offset);
620 if (Offset == 0)
621 return false;
622 data = data.substr(Offset);
623 return true;
624}
625
George Rimar401e4e52016-05-24 12:48:46 +0000626static bool consumeCompressedZLibHeader(StringRef &Data, uint64_t &OriginalSize,
627 bool IsLE, bool Is64Bit) {
628 using namespace ELF;
629 uint64_t HdrSize = Is64Bit ? sizeof(Elf64_Chdr) : sizeof(Elf32_Chdr);
630 if (Data.size() < HdrSize)
631 return false;
632
633 DataExtractor Extractor(Data, IsLE, 0);
634 uint32_t Offset = 0;
635 if (Extractor.getUnsigned(&Offset, Is64Bit ? sizeof(Elf64_Word)
636 : sizeof(Elf32_Word)) !=
637 ELFCOMPRESS_ZLIB)
638 return false;
639
640 // Skip Elf64_Chdr::ch_reserved field.
641 if (Is64Bit)
642 Offset += sizeof(Elf64_Word);
643
644 OriginalSize = Extractor.getUnsigned(&Offset, Is64Bit ? sizeof(Elf64_Xword)
645 : sizeof(Elf32_Word));
646 Data = Data.substr(HdrSize);
647 return true;
648}
649
650static bool tryDecompress(StringRef &Name, StringRef &Data,
651 SmallString<32> &Out, bool ZLibStyle, bool IsLE,
652 bool Is64Bit) {
653 if (!zlib::isAvailable())
654 return false;
655
656 uint64_t OriginalSize;
657 bool Result =
658 ZLibStyle ? consumeCompressedZLibHeader(Data, OriginalSize, IsLE, Is64Bit)
659 : consumeCompressedGnuHeader(Data, OriginalSize);
660
661 if (!Result || zlib::uncompress(Data, Out, OriginalSize) != zlib::StatusOK)
662 return false;
663
664 // gnu-style names are started from "z", consume that.
665 if (!ZLibStyle)
666 Name = Name.substr(1);
667 return true;
668}
669
Keno Fischerc780e8e2015-05-21 21:24:32 +0000670DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
671 const LoadedObjectInfo *L)
Rafael Espindolaa04bb5b2014-07-31 20:19:36 +0000672 : IsLittleEndian(Obj.isLittleEndian()),
673 AddressSize(Obj.getBytesInAddress()) {
674 for (const SectionRef &Section : Obj.sections()) {
Eric Christopher7370b552012-11-12 21:40:38 +0000675 StringRef name;
Alexey Samsonov063eb3f2014-03-13 13:52:54 +0000676 Section.getName(name);
David Majnemerdac39852014-09-26 22:32:16 +0000677 // Skip BSS and Virtual sections, they aren't interesting.
Rafael Espindola80291272014-10-08 15:28:58 +0000678 bool IsBSS = Section.isBSS();
David Majnemerdac39852014-09-26 22:32:16 +0000679 if (IsBSS)
680 continue;
Rafael Espindola80291272014-10-08 15:28:58 +0000681 bool IsVirtual = Section.isVirtual();
David Majnemerdac39852014-09-26 22:32:16 +0000682 if (IsVirtual)
683 continue;
Eric Christopher7370b552012-11-12 21:40:38 +0000684 StringRef data;
Keno Fischerc780e8e2015-05-21 21:24:32 +0000685
Lang Hames2e88f4f2015-07-28 17:52:11 +0000686 section_iterator RelocatedSection = Section.getRelocatedSection();
Keno Fischerc780e8e2015-05-21 21:24:32 +0000687 // Try to obtain an already relocated version of this section.
688 // Else use the unrelocated section from the object file. We'll have to
689 // apply relocations ourselves later.
Lang Hames2e88f4f2015-07-28 17:52:11 +0000690 if (!L || !L->getLoadedSectionContents(*RelocatedSection,data))
Keno Fischerc780e8e2015-05-21 21:24:32 +0000691 Section.getContents(data);
Eric Christopher7370b552012-11-12 21:40:38 +0000692
Eric Christopher7370b552012-11-12 21:40:38 +0000693 name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes.
Alexey Samsonov3d0e3ed2013-04-17 14:27:04 +0000694
George Rimar401e4e52016-05-24 12:48:46 +0000695 bool ZLibStyleCompressed = Section.isCompressed();
696 if (ZLibStyleCompressed || name.startswith("zdebug_")) {
697 SmallString<32> Out;
698 if (!tryDecompress(name, data, Out, ZLibStyleCompressed, IsLittleEndian,
699 AddressSize == 8))
Alexey Samsonov068fc8a2013-04-23 10:17:34 +0000700 continue;
George Rimar401e4e52016-05-24 12:48:46 +0000701 UncompressedSections.emplace_back(std::move(Out));
David Blaikiea505f242014-04-05 21:26:44 +0000702 data = UncompressedSections.back();
Alexey Samsonov068fc8a2013-04-23 10:17:34 +0000703 }
704
Alexey Samsonov063eb3f2014-03-13 13:52:54 +0000705 StringRef *SectionData =
Eric Christopher4c7e6ba2013-09-25 23:02:41 +0000706 StringSwitch<StringRef *>(name)
707 .Case("debug_info", &InfoSection.Data)
708 .Case("debug_abbrev", &AbbrevSection)
709 .Case("debug_loc", &LocSection.Data)
710 .Case("debug_line", &LineSection.Data)
711 .Case("debug_aranges", &ARangeSection)
712 .Case("debug_frame", &DebugFrameSection)
Igor Laevsky03a670c2016-01-26 15:09:42 +0000713 .Case("eh_frame", &EHFrameSection)
Eric Christopher4c7e6ba2013-09-25 23:02:41 +0000714 .Case("debug_str", &StringSection)
715 .Case("debug_ranges", &RangeSection)
Amjad Aboude59cc3e2015-11-12 09:38:54 +0000716 .Case("debug_macinfo", &MacinfoSection)
Eric Christopher4c7e6ba2013-09-25 23:02:41 +0000717 .Case("debug_pubnames", &PubNamesSection)
718 .Case("debug_pubtypes", &PubTypesSection)
719 .Case("debug_gnu_pubnames", &GnuPubNamesSection)
720 .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
721 .Case("debug_info.dwo", &InfoDWOSection.Data)
722 .Case("debug_abbrev.dwo", &AbbrevDWOSection)
David Blaikie9c550ac2014-03-25 01:44:02 +0000723 .Case("debug_loc.dwo", &LocDWOSection.Data)
David Blaikie1d4736e2014-02-24 23:58:54 +0000724 .Case("debug_line.dwo", &LineDWOSection.Data)
Eric Christopher4c7e6ba2013-09-25 23:02:41 +0000725 .Case("debug_str.dwo", &StringDWOSection)
726 .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
727 .Case("debug_addr", &AddrSection)
Frederic Riss7c500472014-11-14 19:30:08 +0000728 .Case("apple_names", &AppleNamesSection.Data)
729 .Case("apple_types", &AppleTypesSection.Data)
730 .Case("apple_namespaces", &AppleNamespacesSection.Data)
731 .Case("apple_namespac", &AppleNamespacesSection.Data)
732 .Case("apple_objc", &AppleObjCSection.Data)
David Blaikie65a8efe2015-11-11 19:28:21 +0000733 .Case("debug_cu_index", &CUIndexSection)
David Blaikie51c40282015-11-11 19:40:49 +0000734 .Case("debug_tu_index", &TUIndexSection)
George Rimar4f82df52016-09-23 11:01:53 +0000735 .Case("gdb_index", &GdbIndexSection)
Eric Christopher4c7e6ba2013-09-25 23:02:41 +0000736 // Any more debug info sections go here.
Craig Topper2617dcc2014-04-15 06:32:26 +0000737 .Default(nullptr);
Alexey Samsonov063eb3f2014-03-13 13:52:54 +0000738 if (SectionData) {
739 *SectionData = data;
Rafael Espindola4f60a382013-05-30 03:05:14 +0000740 if (name == "debug_ranges") {
741 // FIXME: Use the other dwo range section when we emit it.
742 RangeDWOSection = data;
743 }
David Blaikie03c089c2013-09-23 22:44:47 +0000744 } else if (name == "debug_types") {
David Blaikie427e4352013-09-23 23:39:55 +0000745 // Find debug_types data by section rather than name as there are
746 // multiple, comdat grouped, debug_types sections.
Alexey Samsonov063eb3f2014-03-13 13:52:54 +0000747 TypesSections[Section].Data = data;
David Blaikie92d9d622014-01-09 05:08:24 +0000748 } else if (name == "debug_types.dwo") {
Alexey Samsonov063eb3f2014-03-13 13:52:54 +0000749 TypesDWOSections[Section].Data = data;
Eric Christopherda4b2192013-01-02 23:52:13 +0000750 }
Eric Christopher7370b552012-11-12 21:40:38 +0000751
Rafael Espindolaa04bb5b2014-07-31 20:19:36 +0000752 if (RelocatedSection == Obj.section_end())
Rafael Espindola4f60a382013-05-30 03:05:14 +0000753 continue;
754
755 StringRef RelSecName;
Keno Fischerc780e8e2015-05-21 21:24:32 +0000756 StringRef RelSecData;
Rafael Espindola4f60a382013-05-30 03:05:14 +0000757 RelocatedSection->getName(RelSecName);
Keno Fischerc780e8e2015-05-21 21:24:32 +0000758
759 // If the section we're relocating was relocated already by the JIT,
760 // then we used the relocated version above, so we do not need to process
761 // relocations for it now.
Lang Hames2e88f4f2015-07-28 17:52:11 +0000762 if (L && L->getLoadedSectionContents(*RelocatedSection,RelSecData))
Keno Fischerc780e8e2015-05-21 21:24:32 +0000763 continue;
764
Frederic Riss7bb12262015-08-23 04:44:21 +0000765 // In Mach-o files, the relocations do not need to be applied if
766 // there is no load offset to apply. The value read at the
767 // relocation point already factors in the section address
768 // (actually applying the relocations will produce wrong results
769 // as the section address will be added twice).
Craig Topper66059c92015-11-18 07:07:59 +0000770 if (!L && isa<MachOObjectFile>(&Obj))
Frederic Riss7bb12262015-08-23 04:44:21 +0000771 continue;
772
Rafael Espindola4f60a382013-05-30 03:05:14 +0000773 RelSecName = RelSecName.substr(
774 RelSecName.find_first_not_of("._")); // Skip . and _ prefixes.
775
Andrew Kaylord55d7012013-01-25 22:50:58 +0000776 // TODO: Add support for relocations in other sections as needed.
777 // Record relocations for the debug_info and debug_line sections.
Rafael Espindola4f60a382013-05-30 03:05:14 +0000778 RelocAddrMap *Map = StringSwitch<RelocAddrMap*>(RelSecName)
David Blaikie1b5ee5d2013-09-23 17:42:01 +0000779 .Case("debug_info", &InfoSection.Relocs)
780 .Case("debug_loc", &LocSection.Relocs)
781 .Case("debug_info.dwo", &InfoDWOSection.Relocs)
782 .Case("debug_line", &LineSection.Relocs)
Frederic Riss7c500472014-11-14 19:30:08 +0000783 .Case("apple_names", &AppleNamesSection.Relocs)
784 .Case("apple_types", &AppleTypesSection.Relocs)
785 .Case("apple_namespaces", &AppleNamespacesSection.Relocs)
786 .Case("apple_namespac", &AppleNamespacesSection.Relocs)
787 .Case("apple_objc", &AppleObjCSection.Relocs)
Craig Topper2617dcc2014-04-15 06:32:26 +0000788 .Default(nullptr);
David Blaikie03c089c2013-09-23 22:44:47 +0000789 if (!Map) {
David Blaikie427e4352013-09-23 23:39:55 +0000790 // Find debug_types relocs by section rather than name as there are
791 // multiple, comdat grouped, debug_types sections.
David Blaikie92d9d622014-01-09 05:08:24 +0000792 if (RelSecName == "debug_types")
793 Map = &TypesSections[*RelocatedSection].Relocs;
794 else if (RelSecName == "debug_types.dwo")
795 Map = &TypesDWOSections[*RelocatedSection].Relocs;
796 else
797 continue;
David Blaikie03c089c2013-09-23 22:44:47 +0000798 }
Eric Christopher7370b552012-11-12 21:40:38 +0000799
Alexey Samsonov063eb3f2014-03-13 13:52:54 +0000800 if (Section.relocation_begin() != Section.relocation_end()) {
Rafael Espindola80291272014-10-08 15:28:58 +0000801 uint64_t SectionSize = RelocatedSection->getSize();
Alexey Samsonovaa4d2952014-03-14 14:22:49 +0000802 for (const RelocationRef &Reloc : Section.relocations()) {
Rafael Espindola96d071c2015-06-29 23:29:12 +0000803 uint64_t Address = Reloc.getOffset();
Rafael Espindola99c041b2015-06-30 01:53:01 +0000804 uint64_t Type = Reloc.getType();
Andrew Kaylord55d7012013-01-25 22:50:58 +0000805 uint64_t SymAddr = 0;
Keno Fischerc780e8e2015-05-21 21:24:32 +0000806 uint64_t SectionLoadAddress = 0;
David Majnemer5fbe3242014-10-08 06:38:50 +0000807 object::symbol_iterator Sym = Reloc.getSymbol();
Rafael Espindola63a88ce2015-06-19 17:54:28 +0000808 object::section_iterator RSec = Obj.section_end();
Keno Fischerc780e8e2015-05-21 21:24:32 +0000809
810 // First calculate the address of the symbol or section as it appears
811 // in the objct file
812 if (Sym != Obj.symbol_end()) {
Kevin Enderby931cb652016-06-24 18:24:42 +0000813 Expected<uint64_t> SymAddrOrErr = Sym->getAddress();
814 if (!SymAddrOrErr) {
815 std::string Buf;
816 raw_string_ostream OS(Buf);
817 logAllUnhandledErrors(SymAddrOrErr.takeError(), OS, "");
818 OS.flush();
Rafael Espindolaed067c42015-07-03 18:19:00 +0000819 errs() << "error: failed to compute symbol address: "
Kevin Enderby931cb652016-06-24 18:24:42 +0000820 << Buf << '\n';
Rafael Espindolaed067c42015-07-03 18:19:00 +0000821 continue;
822 }
823 SymAddr = *SymAddrOrErr;
Keno Fischerc780e8e2015-05-21 21:24:32 +0000824 // Also remember what section this symbol is in for later
Kevin Enderby7bd8d992016-05-02 20:28:12 +0000825 auto SectOrErr = Sym->getSection();
826 if (!SectOrErr) {
827 std::string Buf;
828 raw_string_ostream OS(Buf);
829 logAllUnhandledErrors(SectOrErr.takeError(), OS, "");
830 OS.flush();
831 errs() << "error: failed to get symbol section: "
832 << Buf << '\n';
833 continue;
834 }
835 RSec = *SectOrErr;
Rafael Espindola63a88ce2015-06-19 17:54:28 +0000836 } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
837 // MachO also has relocations that point to sections and
838 // scattered relocations.
Frederic Rissf6402bf2015-07-31 20:22:50 +0000839 auto RelocInfo = MObj->getRelocation(Reloc.getRawDataRefImpl());
840 if (MObj->isRelocationScattered(RelocInfo)) {
841 // FIXME: it's not clear how to correctly handle scattered
842 // relocations.
843 continue;
844 } else {
845 RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
846 SymAddr = RSec->getAddress();
847 }
Rafael Espindola63a88ce2015-06-19 17:54:28 +0000848 }
Keno Fischerc780e8e2015-05-21 21:24:32 +0000849
850 // If we are given load addresses for the sections, we need to adjust:
851 // SymAddr = (Address of Symbol Or Section in File) -
852 // (Address of Section in File) +
853 // (Load Address of Section)
854 if (L != nullptr && RSec != Obj.section_end()) {
Benjamin Kramerdf005cb2015-08-08 18:27:36 +0000855 // RSec is now either the section being targeted or the section
856 // containing the symbol being targeted. In either case,
Keno Fischerc780e8e2015-05-21 21:24:32 +0000857 // we need to perform the same computation.
858 StringRef SecName;
859 RSec->getName(SecName);
Lang Hames2e88f4f2015-07-28 17:52:11 +0000860// llvm::dbgs() << "Name: '" << SecName
861// << "', RSec: " << RSec->getRawDataRefImpl()
862// << ", Section: " << Section.getRawDataRefImpl() << "\n";
863 SectionLoadAddress = L->getSectionLoadAddress(*RSec);
Keno Fischerc780e8e2015-05-21 21:24:32 +0000864 if (SectionLoadAddress != 0)
865 SymAddr += SectionLoadAddress - RSec->getAddress();
866 }
Eric Christopher7370b552012-11-12 21:40:38 +0000867
Eric Christopher47e079d2014-10-06 06:55:55 +0000868 object::RelocVisitor V(Obj);
David Majnemer5fbe3242014-10-08 06:38:50 +0000869 object::RelocToApply R(V.visit(Type, Reloc, SymAddr));
Eric Christopher7370b552012-11-12 21:40:38 +0000870 if (V.error()) {
871 SmallString<32> Name;
Rafael Espindola41bb4322015-06-30 04:08:37 +0000872 Reloc.getTypeName(Name);
Eric Christopher7370b552012-11-12 21:40:38 +0000873 errs() << "error: failed to compute relocation: "
874 << Name << "\n";
875 continue;
876 }
877
878 if (Address + R.Width > SectionSize) {
879 errs() << "error: " << R.Width << "-byte relocation starting "
880 << Address << " bytes into section " << name << " which is "
881 << SectionSize << " bytes long.\n";
882 continue;
883 }
884 if (R.Width > 8) {
885 errs() << "error: can't handle a relocation of more than 8 bytes at "
886 "a time.\n";
887 continue;
888 }
889 DEBUG(dbgs() << "Writing " << format("%p", R.Value)
890 << " at " << format("%p", Address)
891 << " with width " << format("%d", R.Width)
892 << "\n");
Eric Christopherda4b2192013-01-02 23:52:13 +0000893 Map->insert(std::make_pair(Address, std::make_pair(R.Width, R.Value)));
Eric Christopher7370b552012-11-12 21:40:38 +0000894 }
895 }
896 }
897}
898
David Blaikiea379b1812011-12-20 02:50:00 +0000899void DWARFContextInMemory::anchor() { }