blob: c2602ba2196b6347b61c13c16544047f8748ab1e [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
Igor Laevsky03a670c2016-01-26 15:09:42 +000080void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType, bool DumpEH) {
Eli Bendersky7a94daa2013-01-25 20:26:43 +000081 if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) {
82 OS << ".debug_abbrev contents:\n";
83 getDebugAbbrev()->dump(OS);
84 }
Benjamin Kramera6002fd2011-09-14 01:09:52 +000085
David Blaikie66865d62014-01-09 00:13:35 +000086 if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo)
87 if (const DWARFDebugAbbrev *D = getDebugAbbrevDWO()) {
David Blaikie622dce42014-01-08 23:29:59 +000088 OS << "\n.debug_abbrev.dwo contents:\n";
David Blaikie66865d62014-01-09 00:13:35 +000089 D->dump(OS);
David Blaikie622dce42014-01-08 23:29:59 +000090 }
David Blaikie622dce42014-01-08 23:29:59 +000091
Eli Bendersky7a94daa2013-01-25 20:26:43 +000092 if (DumpType == DIDT_All || DumpType == DIDT_Info) {
93 OS << "\n.debug_info contents:\n";
Alexey Samsonov1eabf982014-03-13 07:52:54 +000094 for (const auto &CU : compile_units())
95 CU->dump(OS);
Eli Bendersky7a94daa2013-01-25 20:26:43 +000096 }
Benjamin Kramera6002fd2011-09-14 01:09:52 +000097
David Blaikie66865d62014-01-09 00:13:35 +000098 if ((DumpType == DIDT_All || DumpType == DIDT_InfoDwo) &&
99 getNumDWOCompileUnits()) {
100 OS << "\n.debug_info.dwo contents:\n";
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000101 for (const auto &DWOCU : dwo_compile_units())
102 DWOCU->dump(OS);
David Blaikie66865d62014-01-09 00:13:35 +0000103 }
David Blaikie622dce42014-01-08 23:29:59 +0000104
David Blaikie66865d62014-01-09 00:13:35 +0000105 if ((DumpType == DIDT_All || DumpType == DIDT_Types) && getNumTypeUnits()) {
David Blaikie03c089c2013-09-23 22:44:47 +0000106 OS << "\n.debug_types contents:\n";
Frederic Riss312a02e2014-09-29 13:56:39 +0000107 for (const auto &TUS : type_unit_sections())
108 for (const auto &TU : TUS)
109 TU->dump(OS);
David Blaikie03c089c2013-09-23 22:44:47 +0000110 }
111
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000112 if ((DumpType == DIDT_All || DumpType == DIDT_TypesDwo) &&
113 getNumDWOTypeUnits()) {
114 OS << "\n.debug_types.dwo contents:\n";
Frederic Riss312a02e2014-09-29 13:56:39 +0000115 for (const auto &DWOTUS : dwo_type_unit_sections())
116 for (const auto &DWOTU : DWOTUS)
117 DWOTU->dump(OS);
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000118 }
David Blaikie92d9d622014-01-09 05:08:24 +0000119
David Blaikie18e73502013-06-19 21:37:13 +0000120 if (DumpType == DIDT_All || DumpType == DIDT_Loc) {
David Blaikie03c089c2013-09-23 22:44:47 +0000121 OS << "\n.debug_loc contents:\n";
David Blaikie18e73502013-06-19 21:37:13 +0000122 getDebugLoc()->dump(OS);
123 }
124
David Blaikie9c550ac2014-03-25 01:44:02 +0000125 if (DumpType == DIDT_All || DumpType == DIDT_LocDwo) {
126 OS << "\n.debug_loc.dwo contents:\n";
127 getDebugLocDWO()->dump(OS);
128 }
129
Eli Benderskyfd08bc12013-02-05 23:30:58 +0000130 if (DumpType == DIDT_All || DumpType == DIDT_Frames) {
131 OS << "\n.debug_frame contents:\n";
132 getDebugFrame()->dump(OS);
Igor Laevsky03a670c2016-01-26 15:09:42 +0000133 if (DumpEH) {
134 OS << "\n.eh_frame contents:\n";
135 getEHFrame()->dump(OS);
136 }
Eli Benderskyfd08bc12013-02-05 23:30:58 +0000137 }
138
Amjad Aboude59cc3e2015-11-12 09:38:54 +0000139 if (DumpType == DIDT_All || DumpType == DIDT_Macro) {
140 OS << "\n.debug_macinfo contents:\n";
141 getDebugMacro()->dump(OS);
142 }
143
Benjamin Kramera6002fd2011-09-14 01:09:52 +0000144 uint32_t offset = 0;
Eli Bendersky7a94daa2013-01-25 20:26:43 +0000145 if (DumpType == DIDT_All || DumpType == DIDT_Aranges) {
146 OS << "\n.debug_aranges contents:\n";
147 DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
148 DWARFDebugArangeSet set;
149 while (set.extract(arangesData, &offset))
150 set.dump(OS);
151 }
Benjamin Kramer5acab502011-09-15 02:12:05 +0000152
Alexey Samsonov034e57a2012-08-27 07:17:47 +0000153 uint8_t savedAddressByteSize = 0;
Eli Bendersky7a94daa2013-01-25 20:26:43 +0000154 if (DumpType == DIDT_All || DumpType == DIDT_Line) {
155 OS << "\n.debug_line contents:\n";
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000156 for (const auto &CU : compile_units()) {
157 savedAddressByteSize = CU->getAddressByteSize();
Alexey Samsonov7a18c062015-05-19 21:54:32 +0000158 const auto *CUDIE = CU->getUnitDIE();
159 if (CUDIE == nullptr)
160 continue;
161 unsigned stmtOffset = CUDIE->getAttributeValueAsSectionOffset(
162 CU.get(), DW_AT_stmt_list, -1U);
Eli Bendersky7a94daa2013-01-25 20:26:43 +0000163 if (stmtOffset != -1U) {
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;
167 LineTable.parse(lineData, &getLineSection().Relocs, &stmtOffset);
168 LineTable.dump(OS);
Eli Bendersky7a94daa2013-01-25 20:26:43 +0000169 }
Benjamin Kramer6dda0322011-09-15 18:02:20 +0000170 }
171 }
Benjamin Kramer07d4b1c2011-09-15 16:57:13 +0000172
David Blaikie65a8efe2015-11-11 19:28:21 +0000173 if (DumpType == DIDT_All || DumpType == DIDT_CUIndex) {
174 OS << "\n.debug_cu_index contents:\n";
David Blaikieb073cb92015-12-02 06:21:34 +0000175 getCUIndex().dump(OS);
David Blaikie65a8efe2015-11-11 19:28:21 +0000176 }
177
David Blaikie51c40282015-11-11 19:40:49 +0000178 if (DumpType == DIDT_All || DumpType == DIDT_TUIndex) {
179 OS << "\n.debug_tu_index contents:\n";
David Blaikieb073cb92015-12-02 06:21:34 +0000180 getTUIndex().dump(OS);
David Blaikie51c40282015-11-11 19:40:49 +0000181 }
182
David Blaikie1d4736e2014-02-24 23:58:54 +0000183 if (DumpType == DIDT_All || DumpType == DIDT_LineDwo) {
184 OS << "\n.debug_line.dwo contents:\n";
185 unsigned stmtOffset = 0;
186 DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(),
187 savedAddressByteSize);
Alexey Samsonov110d5952014-04-30 00:09:19 +0000188 DWARFDebugLine::LineTable LineTable;
189 while (LineTable.Prologue.parse(lineData, &stmtOffset)) {
190 LineTable.dump(OS);
191 LineTable.clear();
192 }
David Blaikie1d4736e2014-02-24 23:58:54 +0000193 }
194
Eli Bendersky7a94daa2013-01-25 20:26:43 +0000195 if (DumpType == DIDT_All || DumpType == DIDT_Str) {
196 OS << "\n.debug_str contents:\n";
197 DataExtractor strData(getStringSection(), isLittleEndian(), 0);
198 offset = 0;
199 uint32_t strOffset = 0;
200 while (const char *s = strData.getCStr(&offset)) {
201 OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
202 strOffset = offset;
203 }
Benjamin Kramer07d4b1c2011-09-15 16:57:13 +0000204 }
Alexey Samsonov034e57a2012-08-27 07:17:47 +0000205
David Blaikie66865d62014-01-09 00:13:35 +0000206 if ((DumpType == DIDT_All || DumpType == DIDT_StrDwo) &&
207 !getStringDWOSection().empty()) {
208 OS << "\n.debug_str.dwo contents:\n";
209 DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
210 offset = 0;
211 uint32_t strDWOOffset = 0;
212 while (const char *s = strDWOData.getCStr(&offset)) {
213 OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
214 strDWOOffset = offset;
David Blaikie622dce42014-01-08 23:29:59 +0000215 }
David Blaikie66865d62014-01-09 00:13:35 +0000216 }
David Blaikie622dce42014-01-08 23:29:59 +0000217
Eli Bendersky7a94daa2013-01-25 20:26:43 +0000218 if (DumpType == DIDT_All || DumpType == DIDT_Ranges) {
219 OS << "\n.debug_ranges contents:\n";
220 // In fact, different compile units may have different address byte
221 // sizes, but for simplicity we just use the address byte size of the last
222 // compile unit (there is no easy and fast way to associate address range
223 // list and the compile unit it describes).
224 DataExtractor rangesData(getRangeSection(), isLittleEndian(),
225 savedAddressByteSize);
226 offset = 0;
227 DWARFDebugRangeList rangeList;
228 while (rangeList.extract(rangesData, &offset))
229 rangeList.dump(OS);
Eric Christopherda4b2192013-01-02 23:52:13 +0000230 }
Eric Christopher962c9082013-01-15 23:56:56 +0000231
Eric Christopher0de53592013-09-25 23:02:36 +0000232 if (DumpType == DIDT_All || DumpType == DIDT_Pubnames)
233 dumpPubSection(OS, "debug_pubnames", getPubNamesSection(),
234 isLittleEndian(), false);
Krzysztof Parzyszek97438dc2013-02-12 16:20:28 +0000235
Eric Christopher4c7e6ba2013-09-25 23:02:41 +0000236 if (DumpType == DIDT_All || DumpType == DIDT_Pubtypes)
237 dumpPubSection(OS, "debug_pubtypes", getPubTypesSection(),
238 isLittleEndian(), false);
239
David Blaikieecd21ff2013-09-24 19:50:00 +0000240 if (DumpType == DIDT_All || DumpType == DIDT_GnuPubnames)
241 dumpPubSection(OS, "debug_gnu_pubnames", getGnuPubNamesSection(),
Eric Christopher0de53592013-09-25 23:02:36 +0000242 isLittleEndian(), true /* GnuStyle */);
David Blaikieecd21ff2013-09-24 19:50:00 +0000243
244 if (DumpType == DIDT_All || DumpType == DIDT_GnuPubtypes)
245 dumpPubSection(OS, "debug_gnu_pubtypes", getGnuPubTypesSection(),
Eric Christopher0de53592013-09-25 23:02:36 +0000246 isLittleEndian(), true /* GnuStyle */);
David Blaikie404d3042013-09-19 23:01:29 +0000247
David Blaikie66865d62014-01-09 00:13:35 +0000248 if ((DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) &&
249 !getStringOffsetDWOSection().empty()) {
250 OS << "\n.debug_str_offsets.dwo contents:\n";
251 DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(),
252 0);
253 offset = 0;
254 uint64_t size = getStringOffsetDWOSection().size();
255 while (offset < size) {
256 OS << format("0x%8.8x: ", offset);
257 OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
Eric Christopher92f3c0b2013-05-06 17:50:42 +0000258 }
David Blaikie66865d62014-01-09 00:13:35 +0000259 }
Frederic Risse837ec22014-11-14 16:15:53 +0000260
George Rimar4f82df52016-09-23 11:01:53 +0000261 if ((DumpType == DIDT_All || DumpType == DIDT_GdbIndex) &&
262 !getGdbIndexSection().empty()) {
263 OS << "\n.gnu_index contents:\n";
264 getGdbIndex().dump(OS);
265 }
266
Frederic Risse837ec22014-11-14 16:15:53 +0000267 if (DumpType == DIDT_All || DumpType == DIDT_AppleNames)
268 dumpAccelSection(OS, "apple_names", getAppleNamesSection(),
269 getStringSection(), isLittleEndian());
270
271 if (DumpType == DIDT_All || DumpType == DIDT_AppleTypes)
272 dumpAccelSection(OS, "apple_types", getAppleTypesSection(),
273 getStringSection(), isLittleEndian());
274
275 if (DumpType == DIDT_All || DumpType == DIDT_AppleNamespaces)
276 dumpAccelSection(OS, "apple_namespaces", getAppleNamespacesSection(),
277 getStringSection(), isLittleEndian());
278
279 if (DumpType == DIDT_All || DumpType == DIDT_AppleObjC)
280 dumpAccelSection(OS, "apple_objc", getAppleObjCSection(),
281 getStringSection(), isLittleEndian());
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000282}
283
David Blaikie82641be2015-11-17 00:39:55 +0000284const DWARFUnitIndex &DWARFContext::getCUIndex() {
285 if (CUIndex)
286 return *CUIndex;
287
288 DataExtractor CUIndexData(getCUIndexSection(), isLittleEndian(), 0);
289
David Blaikieb073cb92015-12-02 06:21:34 +0000290 CUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
David Blaikie82641be2015-11-17 00:39:55 +0000291 CUIndex->parse(CUIndexData);
292 return *CUIndex;
293}
294
295const DWARFUnitIndex &DWARFContext::getTUIndex() {
296 if (TUIndex)
297 return *TUIndex;
298
299 DataExtractor TUIndexData(getTUIndexSection(), isLittleEndian(), 0);
300
David Blaikieb073cb92015-12-02 06:21:34 +0000301 TUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_TYPES);
David Blaikie82641be2015-11-17 00:39:55 +0000302 TUIndex->parse(TUIndexData);
303 return *TUIndex;
304}
305
George Rimar4f82df52016-09-23 11:01:53 +0000306DWARFGdbIndex &DWARFContext::getGdbIndex() {
307 if (GdbIndex)
308 return *GdbIndex;
309
310 DataExtractor GdbIndexData(getGdbIndexSection(), true /*LE*/, 0);
311 GdbIndex = llvm::make_unique<DWARFGdbIndex>();
312 GdbIndex->parse(GdbIndexData);
313 return *GdbIndex;
314}
315
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000316const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
317 if (Abbrev)
318 return Abbrev.get();
319
320 DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0);
321
322 Abbrev.reset(new DWARFDebugAbbrev());
Alexey Samsonov4316df52014-04-25 21:10:56 +0000323 Abbrev->extract(abbrData);
Benjamin Krameraa2f78f2011-09-13 19:42:23 +0000324 return Abbrev.get();
325}
326
Eric Christopherda4b2192013-01-02 23:52:13 +0000327const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
328 if (AbbrevDWO)
329 return AbbrevDWO.get();
330
331 DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0);
332 AbbrevDWO.reset(new DWARFDebugAbbrev());
Alexey Samsonov4316df52014-04-25 21:10:56 +0000333 AbbrevDWO->extract(abbrData);
Eric Christopherda4b2192013-01-02 23:52:13 +0000334 return AbbrevDWO.get();
335}
336
David Blaikie18e73502013-06-19 21:37:13 +0000337const DWARFDebugLoc *DWARFContext::getDebugLoc() {
338 if (Loc)
339 return Loc.get();
340
David Blaikie1b5ee5d2013-09-23 17:42:01 +0000341 DataExtractor LocData(getLocSection().Data, isLittleEndian(), 0);
342 Loc.reset(new DWARFDebugLoc(getLocSection().Relocs));
David Blaikie18e73502013-06-19 21:37:13 +0000343 // assume all compile units have the same address byte size
344 if (getNumCompileUnits())
345 Loc->parse(LocData, getCompileUnitAtIndex(0)->getAddressByteSize());
346 return Loc.get();
347}
348
David Blaikie9c550ac2014-03-25 01:44:02 +0000349const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() {
350 if (LocDWO)
351 return LocDWO.get();
352
353 DataExtractor LocData(getLocDWOSection().Data, isLittleEndian(), 0);
354 LocDWO.reset(new DWARFDebugLocDWO());
355 LocDWO->parse(LocData);
356 return LocDWO.get();
357}
358
Benjamin Kramera6002fd2011-09-14 01:09:52 +0000359const DWARFDebugAranges *DWARFContext::getDebugAranges() {
360 if (Aranges)
361 return Aranges.get();
362
Benjamin Kramera6002fd2011-09-14 01:09:52 +0000363 Aranges.reset(new DWARFDebugAranges());
Alexey Samsonova1694c12012-11-16 08:36:25 +0000364 Aranges->generate(this);
Benjamin Kramera6002fd2011-09-14 01:09:52 +0000365 return Aranges.get();
366}
367
Eli Benderskyfd08bc12013-02-05 23:30:58 +0000368const DWARFDebugFrame *DWARFContext::getDebugFrame() {
369 if (DebugFrame)
370 return DebugFrame.get();
371
372 // There's a "bug" in the DWARFv3 standard with respect to the target address
373 // size within debug frame sections. While DWARF is supposed to be independent
374 // of its container, FDEs have fields with size being "target address size",
375 // which isn't specified in DWARF in general. It's only specified for CUs, but
376 // .eh_frame can appear without a .debug_info section. Follow the example of
377 // other tools (libdwarf) and extract this from the container (ObjectFile
378 // provides this information). This problem is fixed in DWARFv4
379 // See this dwarf-discuss discussion for more details:
380 // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
381 DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(),
382 getAddressSize());
Igor Laevsky03a670c2016-01-26 15:09:42 +0000383 DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */));
384 DebugFrame->parse(debugFrameData);
385 return DebugFrame.get();
386}
387
388const DWARFDebugFrame *DWARFContext::getEHFrame() {
389 if (EHFrame)
390 return EHFrame.get();
391
392 DataExtractor debugFrameData(getEHFrameSection(), isLittleEndian(),
393 getAddressSize());
394 DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */));
Eli Benderskyfd08bc12013-02-05 23:30:58 +0000395 DebugFrame->parse(debugFrameData);
396 return DebugFrame.get();
397}
398
Amjad Aboude59cc3e2015-11-12 09:38:54 +0000399const DWARFDebugMacro *DWARFContext::getDebugMacro() {
400 if (Macro)
401 return Macro.get();
402
403 DataExtractor MacinfoData(getMacinfoSection(), isLittleEndian(), 0);
404 Macro.reset(new DWARFDebugMacro());
405 Macro->parse(MacinfoData);
406 return Macro.get();
407}
408
Eric Christopher494109b2012-10-16 23:46:25 +0000409const DWARFLineTable *
Alexey Samsonov7a18c062015-05-19 21:54:32 +0000410DWARFContext::getLineTableForUnit(DWARFUnit *U) {
Benjamin Kramer679e1752011-09-15 20:43:18 +0000411 if (!Line)
David Blaikie1b5ee5d2013-09-23 17:42:01 +0000412 Line.reset(new DWARFDebugLine(&getLineSection().Relocs));
David Blaikiec4e2bed2015-11-17 21:08:05 +0000413
Alexey Samsonov7a18c062015-05-19 21:54:32 +0000414 const auto *UnitDIE = U->getUnitDIE();
415 if (UnitDIE == nullptr)
416 return nullptr;
David Blaikiec4e2bed2015-11-17 21:08:05 +0000417
Benjamin Kramer679e1752011-09-15 20:43:18 +0000418 unsigned stmtOffset =
Alexey Samsonov7a18c062015-05-19 21:54:32 +0000419 UnitDIE->getAttributeValueAsSectionOffset(U, DW_AT_stmt_list, -1U);
Benjamin Kramer679e1752011-09-15 20:43:18 +0000420 if (stmtOffset == -1U)
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
David Blaikiec4e2bed2015-11-17 21:08:05 +0000423 stmtOffset += 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
479 // name of the topmost function in it.
480 const DWARFDebugInfoEntryInlinedChain &InlinedChain =
481 CU->getInlinedChainForAddress(Address);
482 if (InlinedChain.DIEs.size() == 0)
483 return false;
484 const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
Alexey Samsonovdce67342014-05-15 21:24:32 +0000485 if (const char *Name =
486 TopFunctionDIE.getSubroutineName(InlinedChain.U, Kind)) {
Alexey Samsonovd0109992014-04-18 21:36:39 +0000487 FunctionName = Name;
488 return true;
489 }
490 return false;
491}
492
Alexey Samsonov45be7932012-08-30 07:49:50 +0000493DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
Alexey Samsonovdce67342014-05-15 21:24:32 +0000494 DILineInfoSpecifier Spec) {
Alexey Samsonovd0109992014-04-18 21:36:39 +0000495 DILineInfo Result;
496
Alexey Samsonov45be7932012-08-30 07:49:50 +0000497 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
498 if (!CU)
Alexey Samsonovd0109992014-04-18 21:36:39 +0000499 return Result;
Alexey Samsonovdce67342014-05-15 21:24:32 +0000500 getFunctionNameForAddress(CU, Address, Spec.FNKind, Result.FunctionName);
501 if (Spec.FLIKind != FileLineInfoKind::None) {
Frederic Riss101b5e22014-09-19 15:11:51 +0000502 if (const DWARFLineTable *LineTable = getLineTableForUnit(CU))
503 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
504 Spec.FLIKind, Result);
Alexey Samsonovf4462fa2012-07-02 05:54:45 +0000505 }
Alexey Samsonovd0109992014-04-18 21:36:39 +0000506 return Result;
Benjamin Kramer2602ca62011-09-15 20:43:22 +0000507}
David Blaikiea379b1812011-12-20 02:50:00 +0000508
Alexey Samsonovdce67342014-05-15 21:24:32 +0000509DILineInfoTable
510DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
511 DILineInfoSpecifier Spec) {
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000512 DILineInfoTable Lines;
513 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
514 if (!CU)
515 return Lines;
516
517 std::string FunctionName = "<invalid>";
Alexey Samsonovdce67342014-05-15 21:24:32 +0000518 getFunctionNameForAddress(CU, Address, Spec.FNKind, FunctionName);
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000519
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000520 // If the Specifier says we don't need FileLineInfo, just
521 // return the top-most function at the starting address.
Alexey Samsonovdce67342014-05-15 21:24:32 +0000522 if (Spec.FLIKind == FileLineInfoKind::None) {
Alexey Samsonovd0109992014-04-18 21:36:39 +0000523 DILineInfo Result;
524 Result.FunctionName = FunctionName;
525 Lines.push_back(std::make_pair(Address, Result));
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000526 return Lines;
527 }
528
Frederic Rissec8a5ba2014-09-04 06:14:40 +0000529 const DWARFLineTable *LineTable = getLineTableForUnit(CU);
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000530
531 // Get the index of row we're looking for in the line table.
532 std::vector<uint32_t> RowVector;
533 if (!LineTable->lookupAddressRange(Address, Size, RowVector))
534 return Lines;
535
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000536 for (uint32_t RowIndex : RowVector) {
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000537 // Take file number and line/column from the row.
538 const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
Alexey Samsonovd0109992014-04-18 21:36:39 +0000539 DILineInfo Result;
Frederic Riss101b5e22014-09-19 15:11:51 +0000540 LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(),
541 Spec.FLIKind, Result.FileName);
Alexey Samsonovd0109992014-04-18 21:36:39 +0000542 Result.FunctionName = FunctionName;
543 Result.Line = Row.Line;
544 Result.Column = Row.Column;
545 Lines.push_back(std::make_pair(Row.Address, Result));
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000546 }
547
548 return Lines;
549}
550
Alexey Samsonovdce67342014-05-15 21:24:32 +0000551DIInliningInfo
552DWARFContext::getInliningInfoForAddress(uint64_t Address,
553 DILineInfoSpecifier Spec) {
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000554 DIInliningInfo InliningInfo;
555
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000556 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
557 if (!CU)
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000558 return InliningInfo;
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000559
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000560 const DWARFLineTable *LineTable = nullptr;
Alexey Samsonov3211e612013-08-06 10:49:15 +0000561 const DWARFDebugInfoEntryInlinedChain &InlinedChain =
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000562 CU->getInlinedChainForAddress(Address);
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000563 if (InlinedChain.DIEs.size() == 0) {
564 // If there is no DIE for address (e.g. it is in unavailable .dwo file),
565 // try to at least get file/line info from symbol table.
Alexey Samsonovdce67342014-05-15 21:24:32 +0000566 if (Spec.FLIKind != FileLineInfoKind::None) {
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000567 DILineInfo Frame;
Frederic Rissec8a5ba2014-09-04 06:14:40 +0000568 LineTable = getLineTableForUnit(CU);
Frederic Riss101b5e22014-09-19 15:11:51 +0000569 if (LineTable &&
570 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
571 Spec.FLIKind, Frame))
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000572 InliningInfo.addFrame(Frame);
Alexey Samsonov5c39fdf2014-04-18 22:22:44 +0000573 }
574 return InliningInfo;
575 }
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000576
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000577 uint32_t CallFile = 0, CallLine = 0, CallColumn = 0;
Alexey Samsonov3211e612013-08-06 10:49:15 +0000578 for (uint32_t i = 0, n = InlinedChain.DIEs.size(); i != n; i++) {
579 const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i];
Alexey Samsonovd0109992014-04-18 21:36:39 +0000580 DILineInfo Frame;
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000581 // Get function name if necessary.
Alexey Samsonovdce67342014-05-15 21:24:32 +0000582 if (const char *Name =
583 FunctionDIE.getSubroutineName(InlinedChain.U, Spec.FNKind))
584 Frame.FunctionName = Name;
585 if (Spec.FLIKind != FileLineInfoKind::None) {
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000586 if (i == 0) {
587 // For the topmost frame, initialize the line table of this
588 // compile unit and fetch file/line info from it.
Frederic Rissec8a5ba2014-09-04 06:14:40 +0000589 LineTable = getLineTableForUnit(CU);
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000590 // For the topmost routine, get file/line info from line table.
Frederic Riss101b5e22014-09-19 15:11:51 +0000591 if (LineTable)
592 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
593 Spec.FLIKind, Frame);
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000594 } else {
595 // Otherwise, use call file, call line and call column from
596 // previous DIE in inlined chain.
Frederic Riss101b5e22014-09-19 15:11:51 +0000597 if (LineTable)
598 LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(),
599 Spec.FLIKind, Frame.FileName);
Alexey Samsonovd0109992014-04-18 21:36:39 +0000600 Frame.Line = CallLine;
601 Frame.Column = CallColumn;
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000602 }
603 // Get call file/line/column of a current DIE.
604 if (i + 1 < n) {
David Blaikie07e22442013-09-23 22:44:40 +0000605 FunctionDIE.getCallerFrame(InlinedChain.U, CallFile, CallLine,
Alexey Samsonov3211e612013-08-06 10:49:15 +0000606 CallColumn);
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000607 }
608 }
Alexey Samsonovc942e6b2012-09-04 08:12:33 +0000609 InliningInfo.addFrame(Frame);
610 }
611 return InliningInfo;
612}
613
George Rimar401e4e52016-05-24 12:48:46 +0000614static bool consumeCompressedGnuHeader(StringRef &data,
615 uint64_t &OriginalSize) {
Alexey Samsonov068fc8a2013-04-23 10:17:34 +0000616 // Consume "ZLIB" prefix.
617 if (!data.startswith("ZLIB"))
618 return false;
619 data = data.substr(4);
620 // Consume uncompressed section size (big-endian 8 bytes).
621 DataExtractor extractor(data, false, 8);
622 uint32_t Offset = 0;
623 OriginalSize = extractor.getU64(&Offset);
624 if (Offset == 0)
625 return false;
626 data = data.substr(Offset);
627 return true;
628}
629
George Rimar401e4e52016-05-24 12:48:46 +0000630static bool consumeCompressedZLibHeader(StringRef &Data, uint64_t &OriginalSize,
631 bool IsLE, bool Is64Bit) {
632 using namespace ELF;
633 uint64_t HdrSize = Is64Bit ? sizeof(Elf64_Chdr) : sizeof(Elf32_Chdr);
634 if (Data.size() < HdrSize)
635 return false;
636
637 DataExtractor Extractor(Data, IsLE, 0);
638 uint32_t Offset = 0;
639 if (Extractor.getUnsigned(&Offset, Is64Bit ? sizeof(Elf64_Word)
640 : sizeof(Elf32_Word)) !=
641 ELFCOMPRESS_ZLIB)
642 return false;
643
644 // Skip Elf64_Chdr::ch_reserved field.
645 if (Is64Bit)
646 Offset += sizeof(Elf64_Word);
647
648 OriginalSize = Extractor.getUnsigned(&Offset, Is64Bit ? sizeof(Elf64_Xword)
649 : sizeof(Elf32_Word));
650 Data = Data.substr(HdrSize);
651 return true;
652}
653
654static bool tryDecompress(StringRef &Name, StringRef &Data,
655 SmallString<32> &Out, bool ZLibStyle, bool IsLE,
656 bool Is64Bit) {
657 if (!zlib::isAvailable())
658 return false;
659
660 uint64_t OriginalSize;
661 bool Result =
662 ZLibStyle ? consumeCompressedZLibHeader(Data, OriginalSize, IsLE, Is64Bit)
663 : consumeCompressedGnuHeader(Data, OriginalSize);
664
665 if (!Result || zlib::uncompress(Data, Out, OriginalSize) != zlib::StatusOK)
666 return false;
667
668 // gnu-style names are started from "z", consume that.
669 if (!ZLibStyle)
670 Name = Name.substr(1);
671 return true;
672}
673
Keno Fischerc780e8e2015-05-21 21:24:32 +0000674DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
675 const LoadedObjectInfo *L)
Rafael Espindolaa04bb5b2014-07-31 20:19:36 +0000676 : IsLittleEndian(Obj.isLittleEndian()),
677 AddressSize(Obj.getBytesInAddress()) {
678 for (const SectionRef &Section : Obj.sections()) {
Eric Christopher7370b552012-11-12 21:40:38 +0000679 StringRef name;
Alexey Samsonov063eb3f2014-03-13 13:52:54 +0000680 Section.getName(name);
David Majnemerdac39852014-09-26 22:32:16 +0000681 // Skip BSS and Virtual sections, they aren't interesting.
Rafael Espindola80291272014-10-08 15:28:58 +0000682 bool IsBSS = Section.isBSS();
David Majnemerdac39852014-09-26 22:32:16 +0000683 if (IsBSS)
684 continue;
Rafael Espindola80291272014-10-08 15:28:58 +0000685 bool IsVirtual = Section.isVirtual();
David Majnemerdac39852014-09-26 22:32:16 +0000686 if (IsVirtual)
687 continue;
Eric Christopher7370b552012-11-12 21:40:38 +0000688 StringRef data;
Keno Fischerc780e8e2015-05-21 21:24:32 +0000689
Lang Hames2e88f4f2015-07-28 17:52:11 +0000690 section_iterator RelocatedSection = Section.getRelocatedSection();
Keno Fischerc780e8e2015-05-21 21:24:32 +0000691 // Try to obtain an already relocated version of this section.
692 // Else use the unrelocated section from the object file. We'll have to
693 // apply relocations ourselves later.
Lang Hames2e88f4f2015-07-28 17:52:11 +0000694 if (!L || !L->getLoadedSectionContents(*RelocatedSection,data))
Keno Fischerc780e8e2015-05-21 21:24:32 +0000695 Section.getContents(data);
Eric Christopher7370b552012-11-12 21:40:38 +0000696
Eric Christopher7370b552012-11-12 21:40:38 +0000697 name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes.
Alexey Samsonov3d0e3ed2013-04-17 14:27:04 +0000698
George Rimar401e4e52016-05-24 12:48:46 +0000699 bool ZLibStyleCompressed = Section.isCompressed();
700 if (ZLibStyleCompressed || name.startswith("zdebug_")) {
701 SmallString<32> Out;
702 if (!tryDecompress(name, data, Out, ZLibStyleCompressed, IsLittleEndian,
703 AddressSize == 8))
Alexey Samsonov068fc8a2013-04-23 10:17:34 +0000704 continue;
George Rimar401e4e52016-05-24 12:48:46 +0000705 UncompressedSections.emplace_back(std::move(Out));
David Blaikiea505f242014-04-05 21:26:44 +0000706 data = UncompressedSections.back();
Alexey Samsonov068fc8a2013-04-23 10:17:34 +0000707 }
708
Alexey Samsonov063eb3f2014-03-13 13:52:54 +0000709 StringRef *SectionData =
Eric Christopher4c7e6ba2013-09-25 23:02:41 +0000710 StringSwitch<StringRef *>(name)
711 .Case("debug_info", &InfoSection.Data)
712 .Case("debug_abbrev", &AbbrevSection)
713 .Case("debug_loc", &LocSection.Data)
714 .Case("debug_line", &LineSection.Data)
715 .Case("debug_aranges", &ARangeSection)
716 .Case("debug_frame", &DebugFrameSection)
Igor Laevsky03a670c2016-01-26 15:09:42 +0000717 .Case("eh_frame", &EHFrameSection)
Eric Christopher4c7e6ba2013-09-25 23:02:41 +0000718 .Case("debug_str", &StringSection)
719 .Case("debug_ranges", &RangeSection)
Amjad Aboude59cc3e2015-11-12 09:38:54 +0000720 .Case("debug_macinfo", &MacinfoSection)
Eric Christopher4c7e6ba2013-09-25 23:02:41 +0000721 .Case("debug_pubnames", &PubNamesSection)
722 .Case("debug_pubtypes", &PubTypesSection)
723 .Case("debug_gnu_pubnames", &GnuPubNamesSection)
724 .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
725 .Case("debug_info.dwo", &InfoDWOSection.Data)
726 .Case("debug_abbrev.dwo", &AbbrevDWOSection)
David Blaikie9c550ac2014-03-25 01:44:02 +0000727 .Case("debug_loc.dwo", &LocDWOSection.Data)
David Blaikie1d4736e2014-02-24 23:58:54 +0000728 .Case("debug_line.dwo", &LineDWOSection.Data)
Eric Christopher4c7e6ba2013-09-25 23:02:41 +0000729 .Case("debug_str.dwo", &StringDWOSection)
730 .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
731 .Case("debug_addr", &AddrSection)
Frederic Riss7c500472014-11-14 19:30:08 +0000732 .Case("apple_names", &AppleNamesSection.Data)
733 .Case("apple_types", &AppleTypesSection.Data)
734 .Case("apple_namespaces", &AppleNamespacesSection.Data)
735 .Case("apple_namespac", &AppleNamespacesSection.Data)
736 .Case("apple_objc", &AppleObjCSection.Data)
David Blaikie65a8efe2015-11-11 19:28:21 +0000737 .Case("debug_cu_index", &CUIndexSection)
David Blaikie51c40282015-11-11 19:40:49 +0000738 .Case("debug_tu_index", &TUIndexSection)
George Rimar4f82df52016-09-23 11:01:53 +0000739 .Case("gdb_index", &GdbIndexSection)
Eric Christopher4c7e6ba2013-09-25 23:02:41 +0000740 // Any more debug info sections go here.
Craig Topper2617dcc2014-04-15 06:32:26 +0000741 .Default(nullptr);
Alexey Samsonov063eb3f2014-03-13 13:52:54 +0000742 if (SectionData) {
743 *SectionData = data;
Rafael Espindola4f60a382013-05-30 03:05:14 +0000744 if (name == "debug_ranges") {
745 // FIXME: Use the other dwo range section when we emit it.
746 RangeDWOSection = data;
747 }
David Blaikie03c089c2013-09-23 22:44:47 +0000748 } else if (name == "debug_types") {
David Blaikie427e4352013-09-23 23:39:55 +0000749 // Find debug_types data by section rather than name as there are
750 // multiple, comdat grouped, debug_types sections.
Alexey Samsonov063eb3f2014-03-13 13:52:54 +0000751 TypesSections[Section].Data = data;
David Blaikie92d9d622014-01-09 05:08:24 +0000752 } else if (name == "debug_types.dwo") {
Alexey Samsonov063eb3f2014-03-13 13:52:54 +0000753 TypesDWOSections[Section].Data = data;
Eric Christopherda4b2192013-01-02 23:52:13 +0000754 }
Eric Christopher7370b552012-11-12 21:40:38 +0000755
Rafael Espindolaa04bb5b2014-07-31 20:19:36 +0000756 if (RelocatedSection == Obj.section_end())
Rafael Espindola4f60a382013-05-30 03:05:14 +0000757 continue;
758
759 StringRef RelSecName;
Keno Fischerc780e8e2015-05-21 21:24:32 +0000760 StringRef RelSecData;
Rafael Espindola4f60a382013-05-30 03:05:14 +0000761 RelocatedSection->getName(RelSecName);
Keno Fischerc780e8e2015-05-21 21:24:32 +0000762
763 // If the section we're relocating was relocated already by the JIT,
764 // then we used the relocated version above, so we do not need to process
765 // relocations for it now.
Lang Hames2e88f4f2015-07-28 17:52:11 +0000766 if (L && L->getLoadedSectionContents(*RelocatedSection,RelSecData))
Keno Fischerc780e8e2015-05-21 21:24:32 +0000767 continue;
768
Frederic Riss7bb12262015-08-23 04:44:21 +0000769 // In Mach-o files, the relocations do not need to be applied if
770 // there is no load offset to apply. The value read at the
771 // relocation point already factors in the section address
772 // (actually applying the relocations will produce wrong results
773 // as the section address will be added twice).
Craig Topper66059c92015-11-18 07:07:59 +0000774 if (!L && isa<MachOObjectFile>(&Obj))
Frederic Riss7bb12262015-08-23 04:44:21 +0000775 continue;
776
Rafael Espindola4f60a382013-05-30 03:05:14 +0000777 RelSecName = RelSecName.substr(
778 RelSecName.find_first_not_of("._")); // Skip . and _ prefixes.
779
Andrew Kaylord55d7012013-01-25 22:50:58 +0000780 // TODO: Add support for relocations in other sections as needed.
781 // Record relocations for the debug_info and debug_line sections.
Rafael Espindola4f60a382013-05-30 03:05:14 +0000782 RelocAddrMap *Map = StringSwitch<RelocAddrMap*>(RelSecName)
David Blaikie1b5ee5d2013-09-23 17:42:01 +0000783 .Case("debug_info", &InfoSection.Relocs)
784 .Case("debug_loc", &LocSection.Relocs)
785 .Case("debug_info.dwo", &InfoDWOSection.Relocs)
786 .Case("debug_line", &LineSection.Relocs)
Frederic Riss7c500472014-11-14 19:30:08 +0000787 .Case("apple_names", &AppleNamesSection.Relocs)
788 .Case("apple_types", &AppleTypesSection.Relocs)
789 .Case("apple_namespaces", &AppleNamespacesSection.Relocs)
790 .Case("apple_namespac", &AppleNamespacesSection.Relocs)
791 .Case("apple_objc", &AppleObjCSection.Relocs)
Craig Topper2617dcc2014-04-15 06:32:26 +0000792 .Default(nullptr);
David Blaikie03c089c2013-09-23 22:44:47 +0000793 if (!Map) {
David Blaikie427e4352013-09-23 23:39:55 +0000794 // Find debug_types relocs by section rather than name as there are
795 // multiple, comdat grouped, debug_types sections.
David Blaikie92d9d622014-01-09 05:08:24 +0000796 if (RelSecName == "debug_types")
797 Map = &TypesSections[*RelocatedSection].Relocs;
798 else if (RelSecName == "debug_types.dwo")
799 Map = &TypesDWOSections[*RelocatedSection].Relocs;
800 else
801 continue;
David Blaikie03c089c2013-09-23 22:44:47 +0000802 }
Eric Christopher7370b552012-11-12 21:40:38 +0000803
Alexey Samsonov063eb3f2014-03-13 13:52:54 +0000804 if (Section.relocation_begin() != Section.relocation_end()) {
Rafael Espindola80291272014-10-08 15:28:58 +0000805 uint64_t SectionSize = RelocatedSection->getSize();
Alexey Samsonovaa4d2952014-03-14 14:22:49 +0000806 for (const RelocationRef &Reloc : Section.relocations()) {
Rafael Espindola96d071c2015-06-29 23:29:12 +0000807 uint64_t Address = Reloc.getOffset();
Rafael Espindola99c041b2015-06-30 01:53:01 +0000808 uint64_t Type = Reloc.getType();
Andrew Kaylord55d7012013-01-25 22:50:58 +0000809 uint64_t SymAddr = 0;
Keno Fischerc780e8e2015-05-21 21:24:32 +0000810 uint64_t SectionLoadAddress = 0;
David Majnemer5fbe3242014-10-08 06:38:50 +0000811 object::symbol_iterator Sym = Reloc.getSymbol();
Rafael Espindola63a88ce2015-06-19 17:54:28 +0000812 object::section_iterator RSec = Obj.section_end();
Keno Fischerc780e8e2015-05-21 21:24:32 +0000813
814 // First calculate the address of the symbol or section as it appears
815 // in the objct file
816 if (Sym != Obj.symbol_end()) {
Kevin Enderby931cb652016-06-24 18:24:42 +0000817 Expected<uint64_t> SymAddrOrErr = Sym->getAddress();
818 if (!SymAddrOrErr) {
819 std::string Buf;
820 raw_string_ostream OS(Buf);
821 logAllUnhandledErrors(SymAddrOrErr.takeError(), OS, "");
822 OS.flush();
Rafael Espindolaed067c42015-07-03 18:19:00 +0000823 errs() << "error: failed to compute symbol address: "
Kevin Enderby931cb652016-06-24 18:24:42 +0000824 << Buf << '\n';
Rafael Espindolaed067c42015-07-03 18:19:00 +0000825 continue;
826 }
827 SymAddr = *SymAddrOrErr;
Keno Fischerc780e8e2015-05-21 21:24:32 +0000828 // Also remember what section this symbol is in for later
Kevin Enderby7bd8d992016-05-02 20:28:12 +0000829 auto SectOrErr = Sym->getSection();
830 if (!SectOrErr) {
831 std::string Buf;
832 raw_string_ostream OS(Buf);
833 logAllUnhandledErrors(SectOrErr.takeError(), OS, "");
834 OS.flush();
835 errs() << "error: failed to get symbol section: "
836 << Buf << '\n';
837 continue;
838 }
839 RSec = *SectOrErr;
Rafael Espindola63a88ce2015-06-19 17:54:28 +0000840 } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
841 // MachO also has relocations that point to sections and
842 // scattered relocations.
Frederic Rissf6402bf2015-07-31 20:22:50 +0000843 auto RelocInfo = MObj->getRelocation(Reloc.getRawDataRefImpl());
844 if (MObj->isRelocationScattered(RelocInfo)) {
845 // FIXME: it's not clear how to correctly handle scattered
846 // relocations.
847 continue;
848 } else {
849 RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
850 SymAddr = RSec->getAddress();
851 }
Rafael Espindola63a88ce2015-06-19 17:54:28 +0000852 }
Keno Fischerc780e8e2015-05-21 21:24:32 +0000853
854 // If we are given load addresses for the sections, we need to adjust:
855 // SymAddr = (Address of Symbol Or Section in File) -
856 // (Address of Section in File) +
857 // (Load Address of Section)
858 if (L != nullptr && RSec != Obj.section_end()) {
Benjamin Kramerdf005cb2015-08-08 18:27:36 +0000859 // RSec is now either the section being targeted or the section
860 // containing the symbol being targeted. In either case,
Keno Fischerc780e8e2015-05-21 21:24:32 +0000861 // we need to perform the same computation.
862 StringRef SecName;
863 RSec->getName(SecName);
Lang Hames2e88f4f2015-07-28 17:52:11 +0000864// llvm::dbgs() << "Name: '" << SecName
865// << "', RSec: " << RSec->getRawDataRefImpl()
866// << ", Section: " << Section.getRawDataRefImpl() << "\n";
867 SectionLoadAddress = L->getSectionLoadAddress(*RSec);
Keno Fischerc780e8e2015-05-21 21:24:32 +0000868 if (SectionLoadAddress != 0)
869 SymAddr += SectionLoadAddress - RSec->getAddress();
870 }
Eric Christopher7370b552012-11-12 21:40:38 +0000871
Eric Christopher47e079d2014-10-06 06:55:55 +0000872 object::RelocVisitor V(Obj);
David Majnemer5fbe3242014-10-08 06:38:50 +0000873 object::RelocToApply R(V.visit(Type, Reloc, SymAddr));
Eric Christopher7370b552012-11-12 21:40:38 +0000874 if (V.error()) {
875 SmallString<32> Name;
Rafael Espindola41bb4322015-06-30 04:08:37 +0000876 Reloc.getTypeName(Name);
Eric Christopher7370b552012-11-12 21:40:38 +0000877 errs() << "error: failed to compute relocation: "
878 << Name << "\n";
879 continue;
880 }
881
882 if (Address + R.Width > SectionSize) {
883 errs() << "error: " << R.Width << "-byte relocation starting "
884 << Address << " bytes into section " << name << " which is "
885 << SectionSize << " bytes long.\n";
886 continue;
887 }
888 if (R.Width > 8) {
889 errs() << "error: can't handle a relocation of more than 8 bytes at "
890 "a time.\n";
891 continue;
892 }
893 DEBUG(dbgs() << "Writing " << format("%p", R.Value)
894 << " at " << format("%p", Address)
895 << " with width " << format("%d", R.Width)
896 << "\n");
Eric Christopherda4b2192013-01-02 23:52:13 +0000897 Map->insert(std::make_pair(Address, std::make_pair(R.Width, R.Value)));
Eric Christopher7370b552012-11-12 21:40:38 +0000898 }
899 }
900 }
901}
902
David Blaikiea379b1812011-12-20 02:50:00 +0000903void DWARFContextInMemory::anchor() { }