1*9880d681SAndroid Build Coastguard Worker //===-- DWARFContext.cpp --------------------------------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/DWARF/DWARFContext.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallString.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringSwitch.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/MachO.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/RelocVisitor.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Compression.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Dwarf.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ELF.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Format.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Path.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
24*9880d681SAndroid Build Coastguard Worker #include <algorithm>
25*9880d681SAndroid Build Coastguard Worker using namespace llvm;
26*9880d681SAndroid Build Coastguard Worker using namespace dwarf;
27*9880d681SAndroid Build Coastguard Worker using namespace object;
28*9880d681SAndroid Build Coastguard Worker
29*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "dwarf"
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Worker typedef DWARFDebugLine::LineTable DWARFLineTable;
32*9880d681SAndroid Build Coastguard Worker typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
33*9880d681SAndroid Build Coastguard Worker typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
34*9880d681SAndroid Build Coastguard Worker
dumpPubSection(raw_ostream & OS,StringRef Name,StringRef Data,bool LittleEndian,bool GnuStyle)35*9880d681SAndroid Build Coastguard Worker static void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data,
36*9880d681SAndroid Build Coastguard Worker bool LittleEndian, bool GnuStyle) {
37*9880d681SAndroid Build Coastguard Worker OS << "\n." << Name << " contents:\n";
38*9880d681SAndroid Build Coastguard Worker DataExtractor pubNames(Data, LittleEndian, 0);
39*9880d681SAndroid Build Coastguard Worker uint32_t offset = 0;
40*9880d681SAndroid Build Coastguard Worker while (pubNames.isValidOffset(offset)) {
41*9880d681SAndroid Build Coastguard Worker OS << "length = " << format("0x%08x", pubNames.getU32(&offset));
42*9880d681SAndroid Build Coastguard Worker OS << " version = " << format("0x%04x", pubNames.getU16(&offset));
43*9880d681SAndroid Build Coastguard Worker OS << " unit_offset = " << format("0x%08x", pubNames.getU32(&offset));
44*9880d681SAndroid Build Coastguard Worker OS << " unit_size = " << format("0x%08x", pubNames.getU32(&offset)) << '\n';
45*9880d681SAndroid Build Coastguard Worker if (GnuStyle)
46*9880d681SAndroid Build Coastguard Worker OS << "Offset Linkage Kind Name\n";
47*9880d681SAndroid Build Coastguard Worker else
48*9880d681SAndroid Build Coastguard Worker OS << "Offset Name\n";
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Worker while (offset < Data.size()) {
51*9880d681SAndroid Build Coastguard Worker uint32_t dieRef = pubNames.getU32(&offset);
52*9880d681SAndroid Build Coastguard Worker if (dieRef == 0)
53*9880d681SAndroid Build Coastguard Worker break;
54*9880d681SAndroid Build Coastguard Worker OS << format("0x%8.8x ", dieRef);
55*9880d681SAndroid Build Coastguard Worker if (GnuStyle) {
56*9880d681SAndroid Build Coastguard Worker PubIndexEntryDescriptor desc(pubNames.getU8(&offset));
57*9880d681SAndroid Build Coastguard Worker OS << format("%-8s", dwarf::GDBIndexEntryLinkageString(desc.Linkage))
58*9880d681SAndroid Build Coastguard Worker << ' ' << format("%-8s", dwarf::GDBIndexEntryKindString(desc.Kind))
59*9880d681SAndroid Build Coastguard Worker << ' ';
60*9880d681SAndroid Build Coastguard Worker }
61*9880d681SAndroid Build Coastguard Worker OS << '\"' << pubNames.getCStr(&offset) << "\"\n";
62*9880d681SAndroid Build Coastguard Worker }
63*9880d681SAndroid Build Coastguard Worker }
64*9880d681SAndroid Build Coastguard Worker }
65*9880d681SAndroid Build Coastguard Worker
dumpAccelSection(raw_ostream & OS,StringRef Name,const DWARFSection & Section,StringRef StringSection,bool LittleEndian)66*9880d681SAndroid Build Coastguard Worker static void dumpAccelSection(raw_ostream &OS, StringRef Name,
67*9880d681SAndroid Build Coastguard Worker const DWARFSection& Section, StringRef StringSection,
68*9880d681SAndroid Build Coastguard Worker bool LittleEndian) {
69*9880d681SAndroid Build Coastguard Worker DataExtractor AccelSection(Section.Data, LittleEndian, 0);
70*9880d681SAndroid Build Coastguard Worker DataExtractor StrData(StringSection, LittleEndian, 0);
71*9880d681SAndroid Build Coastguard Worker OS << "\n." << Name << " contents:\n";
72*9880d681SAndroid Build Coastguard Worker DWARFAcceleratorTable Accel(AccelSection, StrData, Section.Relocs);
73*9880d681SAndroid Build Coastguard Worker if (!Accel.extract())
74*9880d681SAndroid Build Coastguard Worker return;
75*9880d681SAndroid Build Coastguard Worker Accel.dump(OS);
76*9880d681SAndroid Build Coastguard Worker }
77*9880d681SAndroid Build Coastguard Worker
dump(raw_ostream & OS,DIDumpType DumpType,bool DumpEH)78*9880d681SAndroid Build Coastguard Worker void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType, bool DumpEH) {
79*9880d681SAndroid Build Coastguard Worker if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) {
80*9880d681SAndroid Build Coastguard Worker OS << ".debug_abbrev contents:\n";
81*9880d681SAndroid Build Coastguard Worker getDebugAbbrev()->dump(OS);
82*9880d681SAndroid Build Coastguard Worker }
83*9880d681SAndroid Build Coastguard Worker
84*9880d681SAndroid Build Coastguard Worker if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo)
85*9880d681SAndroid Build Coastguard Worker if (const DWARFDebugAbbrev *D = getDebugAbbrevDWO()) {
86*9880d681SAndroid Build Coastguard Worker OS << "\n.debug_abbrev.dwo contents:\n";
87*9880d681SAndroid Build Coastguard Worker D->dump(OS);
88*9880d681SAndroid Build Coastguard Worker }
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Worker if (DumpType == DIDT_All || DumpType == DIDT_Info) {
91*9880d681SAndroid Build Coastguard Worker OS << "\n.debug_info contents:\n";
92*9880d681SAndroid Build Coastguard Worker for (const auto &CU : compile_units())
93*9880d681SAndroid Build Coastguard Worker CU->dump(OS);
94*9880d681SAndroid Build Coastguard Worker }
95*9880d681SAndroid Build Coastguard Worker
96*9880d681SAndroid Build Coastguard Worker if ((DumpType == DIDT_All || DumpType == DIDT_InfoDwo) &&
97*9880d681SAndroid Build Coastguard Worker getNumDWOCompileUnits()) {
98*9880d681SAndroid Build Coastguard Worker OS << "\n.debug_info.dwo contents:\n";
99*9880d681SAndroid Build Coastguard Worker for (const auto &DWOCU : dwo_compile_units())
100*9880d681SAndroid Build Coastguard Worker DWOCU->dump(OS);
101*9880d681SAndroid Build Coastguard Worker }
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Worker if ((DumpType == DIDT_All || DumpType == DIDT_Types) && getNumTypeUnits()) {
104*9880d681SAndroid Build Coastguard Worker OS << "\n.debug_types contents:\n";
105*9880d681SAndroid Build Coastguard Worker for (const auto &TUS : type_unit_sections())
106*9880d681SAndroid Build Coastguard Worker for (const auto &TU : TUS)
107*9880d681SAndroid Build Coastguard Worker TU->dump(OS);
108*9880d681SAndroid Build Coastguard Worker }
109*9880d681SAndroid Build Coastguard Worker
110*9880d681SAndroid Build Coastguard Worker if ((DumpType == DIDT_All || DumpType == DIDT_TypesDwo) &&
111*9880d681SAndroid Build Coastguard Worker getNumDWOTypeUnits()) {
112*9880d681SAndroid Build Coastguard Worker OS << "\n.debug_types.dwo contents:\n";
113*9880d681SAndroid Build Coastguard Worker for (const auto &DWOTUS : dwo_type_unit_sections())
114*9880d681SAndroid Build Coastguard Worker for (const auto &DWOTU : DWOTUS)
115*9880d681SAndroid Build Coastguard Worker DWOTU->dump(OS);
116*9880d681SAndroid Build Coastguard Worker }
117*9880d681SAndroid Build Coastguard Worker
118*9880d681SAndroid Build Coastguard Worker if (DumpType == DIDT_All || DumpType == DIDT_Loc) {
119*9880d681SAndroid Build Coastguard Worker OS << "\n.debug_loc contents:\n";
120*9880d681SAndroid Build Coastguard Worker getDebugLoc()->dump(OS);
121*9880d681SAndroid Build Coastguard Worker }
122*9880d681SAndroid Build Coastguard Worker
123*9880d681SAndroid Build Coastguard Worker if (DumpType == DIDT_All || DumpType == DIDT_LocDwo) {
124*9880d681SAndroid Build Coastguard Worker OS << "\n.debug_loc.dwo contents:\n";
125*9880d681SAndroid Build Coastguard Worker getDebugLocDWO()->dump(OS);
126*9880d681SAndroid Build Coastguard Worker }
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Worker if (DumpType == DIDT_All || DumpType == DIDT_Frames) {
129*9880d681SAndroid Build Coastguard Worker OS << "\n.debug_frame contents:\n";
130*9880d681SAndroid Build Coastguard Worker getDebugFrame()->dump(OS);
131*9880d681SAndroid Build Coastguard Worker if (DumpEH) {
132*9880d681SAndroid Build Coastguard Worker OS << "\n.eh_frame contents:\n";
133*9880d681SAndroid Build Coastguard Worker getEHFrame()->dump(OS);
134*9880d681SAndroid Build Coastguard Worker }
135*9880d681SAndroid Build Coastguard Worker }
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Worker if (DumpType == DIDT_All || DumpType == DIDT_Macro) {
138*9880d681SAndroid Build Coastguard Worker OS << "\n.debug_macinfo contents:\n";
139*9880d681SAndroid Build Coastguard Worker getDebugMacro()->dump(OS);
140*9880d681SAndroid Build Coastguard Worker }
141*9880d681SAndroid Build Coastguard Worker
142*9880d681SAndroid Build Coastguard Worker uint32_t offset = 0;
143*9880d681SAndroid Build Coastguard Worker if (DumpType == DIDT_All || DumpType == DIDT_Aranges) {
144*9880d681SAndroid Build Coastguard Worker OS << "\n.debug_aranges contents:\n";
145*9880d681SAndroid Build Coastguard Worker DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
146*9880d681SAndroid Build Coastguard Worker DWARFDebugArangeSet set;
147*9880d681SAndroid Build Coastguard Worker while (set.extract(arangesData, &offset))
148*9880d681SAndroid Build Coastguard Worker set.dump(OS);
149*9880d681SAndroid Build Coastguard Worker }
150*9880d681SAndroid Build Coastguard Worker
151*9880d681SAndroid Build Coastguard Worker uint8_t savedAddressByteSize = 0;
152*9880d681SAndroid Build Coastguard Worker if (DumpType == DIDT_All || DumpType == DIDT_Line) {
153*9880d681SAndroid Build Coastguard Worker OS << "\n.debug_line contents:\n";
154*9880d681SAndroid Build Coastguard Worker for (const auto &CU : compile_units()) {
155*9880d681SAndroid Build Coastguard Worker savedAddressByteSize = CU->getAddressByteSize();
156*9880d681SAndroid Build Coastguard Worker const auto *CUDIE = CU->getUnitDIE();
157*9880d681SAndroid Build Coastguard Worker if (CUDIE == nullptr)
158*9880d681SAndroid Build Coastguard Worker continue;
159*9880d681SAndroid Build Coastguard Worker unsigned stmtOffset = CUDIE->getAttributeValueAsSectionOffset(
160*9880d681SAndroid Build Coastguard Worker CU.get(), DW_AT_stmt_list, -1U);
161*9880d681SAndroid Build Coastguard Worker if (stmtOffset != -1U) {
162*9880d681SAndroid Build Coastguard Worker DataExtractor lineData(getLineSection().Data, isLittleEndian(),
163*9880d681SAndroid Build Coastguard Worker savedAddressByteSize);
164*9880d681SAndroid Build Coastguard Worker DWARFDebugLine::LineTable LineTable;
165*9880d681SAndroid Build Coastguard Worker LineTable.parse(lineData, &getLineSection().Relocs, &stmtOffset);
166*9880d681SAndroid Build Coastguard Worker LineTable.dump(OS);
167*9880d681SAndroid Build Coastguard Worker }
168*9880d681SAndroid Build Coastguard Worker }
169*9880d681SAndroid Build Coastguard Worker }
170*9880d681SAndroid Build Coastguard Worker
171*9880d681SAndroid Build Coastguard Worker if (DumpType == DIDT_All || DumpType == DIDT_CUIndex) {
172*9880d681SAndroid Build Coastguard Worker OS << "\n.debug_cu_index contents:\n";
173*9880d681SAndroid Build Coastguard Worker getCUIndex().dump(OS);
174*9880d681SAndroid Build Coastguard Worker }
175*9880d681SAndroid Build Coastguard Worker
176*9880d681SAndroid Build Coastguard Worker if (DumpType == DIDT_All || DumpType == DIDT_TUIndex) {
177*9880d681SAndroid Build Coastguard Worker OS << "\n.debug_tu_index contents:\n";
178*9880d681SAndroid Build Coastguard Worker getTUIndex().dump(OS);
179*9880d681SAndroid Build Coastguard Worker }
180*9880d681SAndroid Build Coastguard Worker
181*9880d681SAndroid Build Coastguard Worker if (DumpType == DIDT_All || DumpType == DIDT_LineDwo) {
182*9880d681SAndroid Build Coastguard Worker OS << "\n.debug_line.dwo contents:\n";
183*9880d681SAndroid Build Coastguard Worker unsigned stmtOffset = 0;
184*9880d681SAndroid Build Coastguard Worker DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(),
185*9880d681SAndroid Build Coastguard Worker savedAddressByteSize);
186*9880d681SAndroid Build Coastguard Worker DWARFDebugLine::LineTable LineTable;
187*9880d681SAndroid Build Coastguard Worker while (LineTable.Prologue.parse(lineData, &stmtOffset)) {
188*9880d681SAndroid Build Coastguard Worker LineTable.dump(OS);
189*9880d681SAndroid Build Coastguard Worker LineTable.clear();
190*9880d681SAndroid Build Coastguard Worker }
191*9880d681SAndroid Build Coastguard Worker }
192*9880d681SAndroid Build Coastguard Worker
193*9880d681SAndroid Build Coastguard Worker if (DumpType == DIDT_All || DumpType == DIDT_Str) {
194*9880d681SAndroid Build Coastguard Worker OS << "\n.debug_str contents:\n";
195*9880d681SAndroid Build Coastguard Worker DataExtractor strData(getStringSection(), isLittleEndian(), 0);
196*9880d681SAndroid Build Coastguard Worker offset = 0;
197*9880d681SAndroid Build Coastguard Worker uint32_t strOffset = 0;
198*9880d681SAndroid Build Coastguard Worker while (const char *s = strData.getCStr(&offset)) {
199*9880d681SAndroid Build Coastguard Worker OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
200*9880d681SAndroid Build Coastguard Worker strOffset = offset;
201*9880d681SAndroid Build Coastguard Worker }
202*9880d681SAndroid Build Coastguard Worker }
203*9880d681SAndroid Build Coastguard Worker
204*9880d681SAndroid Build Coastguard Worker if ((DumpType == DIDT_All || DumpType == DIDT_StrDwo) &&
205*9880d681SAndroid Build Coastguard Worker !getStringDWOSection().empty()) {
206*9880d681SAndroid Build Coastguard Worker OS << "\n.debug_str.dwo contents:\n";
207*9880d681SAndroid Build Coastguard Worker DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
208*9880d681SAndroid Build Coastguard Worker offset = 0;
209*9880d681SAndroid Build Coastguard Worker uint32_t strDWOOffset = 0;
210*9880d681SAndroid Build Coastguard Worker while (const char *s = strDWOData.getCStr(&offset)) {
211*9880d681SAndroid Build Coastguard Worker OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
212*9880d681SAndroid Build Coastguard Worker strDWOOffset = offset;
213*9880d681SAndroid Build Coastguard Worker }
214*9880d681SAndroid Build Coastguard Worker }
215*9880d681SAndroid Build Coastguard Worker
216*9880d681SAndroid Build Coastguard Worker if (DumpType == DIDT_All || DumpType == DIDT_Ranges) {
217*9880d681SAndroid Build Coastguard Worker OS << "\n.debug_ranges contents:\n";
218*9880d681SAndroid Build Coastguard Worker // In fact, different compile units may have different address byte
219*9880d681SAndroid Build Coastguard Worker // sizes, but for simplicity we just use the address byte size of the last
220*9880d681SAndroid Build Coastguard Worker // compile unit (there is no easy and fast way to associate address range
221*9880d681SAndroid Build Coastguard Worker // list and the compile unit it describes).
222*9880d681SAndroid Build Coastguard Worker DataExtractor rangesData(getRangeSection(), isLittleEndian(),
223*9880d681SAndroid Build Coastguard Worker savedAddressByteSize);
224*9880d681SAndroid Build Coastguard Worker offset = 0;
225*9880d681SAndroid Build Coastguard Worker DWARFDebugRangeList rangeList;
226*9880d681SAndroid Build Coastguard Worker while (rangeList.extract(rangesData, &offset))
227*9880d681SAndroid Build Coastguard Worker rangeList.dump(OS);
228*9880d681SAndroid Build Coastguard Worker }
229*9880d681SAndroid Build Coastguard Worker
230*9880d681SAndroid Build Coastguard Worker if (DumpType == DIDT_All || DumpType == DIDT_Pubnames)
231*9880d681SAndroid Build Coastguard Worker dumpPubSection(OS, "debug_pubnames", getPubNamesSection(),
232*9880d681SAndroid Build Coastguard Worker isLittleEndian(), false);
233*9880d681SAndroid Build Coastguard Worker
234*9880d681SAndroid Build Coastguard Worker if (DumpType == DIDT_All || DumpType == DIDT_Pubtypes)
235*9880d681SAndroid Build Coastguard Worker dumpPubSection(OS, "debug_pubtypes", getPubTypesSection(),
236*9880d681SAndroid Build Coastguard Worker isLittleEndian(), false);
237*9880d681SAndroid Build Coastguard Worker
238*9880d681SAndroid Build Coastguard Worker if (DumpType == DIDT_All || DumpType == DIDT_GnuPubnames)
239*9880d681SAndroid Build Coastguard Worker dumpPubSection(OS, "debug_gnu_pubnames", getGnuPubNamesSection(),
240*9880d681SAndroid Build Coastguard Worker isLittleEndian(), true /* GnuStyle */);
241*9880d681SAndroid Build Coastguard Worker
242*9880d681SAndroid Build Coastguard Worker if (DumpType == DIDT_All || DumpType == DIDT_GnuPubtypes)
243*9880d681SAndroid Build Coastguard Worker dumpPubSection(OS, "debug_gnu_pubtypes", getGnuPubTypesSection(),
244*9880d681SAndroid Build Coastguard Worker isLittleEndian(), true /* GnuStyle */);
245*9880d681SAndroid Build Coastguard Worker
246*9880d681SAndroid Build Coastguard Worker if ((DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) &&
247*9880d681SAndroid Build Coastguard Worker !getStringOffsetDWOSection().empty()) {
248*9880d681SAndroid Build Coastguard Worker OS << "\n.debug_str_offsets.dwo contents:\n";
249*9880d681SAndroid Build Coastguard Worker DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(),
250*9880d681SAndroid Build Coastguard Worker 0);
251*9880d681SAndroid Build Coastguard Worker offset = 0;
252*9880d681SAndroid Build Coastguard Worker uint64_t size = getStringOffsetDWOSection().size();
253*9880d681SAndroid Build Coastguard Worker while (offset < size) {
254*9880d681SAndroid Build Coastguard Worker OS << format("0x%8.8x: ", offset);
255*9880d681SAndroid Build Coastguard Worker OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
256*9880d681SAndroid Build Coastguard Worker }
257*9880d681SAndroid Build Coastguard Worker }
258*9880d681SAndroid Build Coastguard Worker
259*9880d681SAndroid Build Coastguard Worker if (DumpType == DIDT_All || DumpType == DIDT_AppleNames)
260*9880d681SAndroid Build Coastguard Worker dumpAccelSection(OS, "apple_names", getAppleNamesSection(),
261*9880d681SAndroid Build Coastguard Worker getStringSection(), isLittleEndian());
262*9880d681SAndroid Build Coastguard Worker
263*9880d681SAndroid Build Coastguard Worker if (DumpType == DIDT_All || DumpType == DIDT_AppleTypes)
264*9880d681SAndroid Build Coastguard Worker dumpAccelSection(OS, "apple_types", getAppleTypesSection(),
265*9880d681SAndroid Build Coastguard Worker getStringSection(), isLittleEndian());
266*9880d681SAndroid Build Coastguard Worker
267*9880d681SAndroid Build Coastguard Worker if (DumpType == DIDT_All || DumpType == DIDT_AppleNamespaces)
268*9880d681SAndroid Build Coastguard Worker dumpAccelSection(OS, "apple_namespaces", getAppleNamespacesSection(),
269*9880d681SAndroid Build Coastguard Worker getStringSection(), isLittleEndian());
270*9880d681SAndroid Build Coastguard Worker
271*9880d681SAndroid Build Coastguard Worker if (DumpType == DIDT_All || DumpType == DIDT_AppleObjC)
272*9880d681SAndroid Build Coastguard Worker dumpAccelSection(OS, "apple_objc", getAppleObjCSection(),
273*9880d681SAndroid Build Coastguard Worker getStringSection(), isLittleEndian());
274*9880d681SAndroid Build Coastguard Worker }
275*9880d681SAndroid Build Coastguard Worker
getCUIndex()276*9880d681SAndroid Build Coastguard Worker const DWARFUnitIndex &DWARFContext::getCUIndex() {
277*9880d681SAndroid Build Coastguard Worker if (CUIndex)
278*9880d681SAndroid Build Coastguard Worker return *CUIndex;
279*9880d681SAndroid Build Coastguard Worker
280*9880d681SAndroid Build Coastguard Worker DataExtractor CUIndexData(getCUIndexSection(), isLittleEndian(), 0);
281*9880d681SAndroid Build Coastguard Worker
282*9880d681SAndroid Build Coastguard Worker CUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
283*9880d681SAndroid Build Coastguard Worker CUIndex->parse(CUIndexData);
284*9880d681SAndroid Build Coastguard Worker return *CUIndex;
285*9880d681SAndroid Build Coastguard Worker }
286*9880d681SAndroid Build Coastguard Worker
getTUIndex()287*9880d681SAndroid Build Coastguard Worker const DWARFUnitIndex &DWARFContext::getTUIndex() {
288*9880d681SAndroid Build Coastguard Worker if (TUIndex)
289*9880d681SAndroid Build Coastguard Worker return *TUIndex;
290*9880d681SAndroid Build Coastguard Worker
291*9880d681SAndroid Build Coastguard Worker DataExtractor TUIndexData(getTUIndexSection(), isLittleEndian(), 0);
292*9880d681SAndroid Build Coastguard Worker
293*9880d681SAndroid Build Coastguard Worker TUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_TYPES);
294*9880d681SAndroid Build Coastguard Worker TUIndex->parse(TUIndexData);
295*9880d681SAndroid Build Coastguard Worker return *TUIndex;
296*9880d681SAndroid Build Coastguard Worker }
297*9880d681SAndroid Build Coastguard Worker
getDebugAbbrev()298*9880d681SAndroid Build Coastguard Worker const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
299*9880d681SAndroid Build Coastguard Worker if (Abbrev)
300*9880d681SAndroid Build Coastguard Worker return Abbrev.get();
301*9880d681SAndroid Build Coastguard Worker
302*9880d681SAndroid Build Coastguard Worker DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0);
303*9880d681SAndroid Build Coastguard Worker
304*9880d681SAndroid Build Coastguard Worker Abbrev.reset(new DWARFDebugAbbrev());
305*9880d681SAndroid Build Coastguard Worker Abbrev->extract(abbrData);
306*9880d681SAndroid Build Coastguard Worker return Abbrev.get();
307*9880d681SAndroid Build Coastguard Worker }
308*9880d681SAndroid Build Coastguard Worker
getDebugAbbrevDWO()309*9880d681SAndroid Build Coastguard Worker const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
310*9880d681SAndroid Build Coastguard Worker if (AbbrevDWO)
311*9880d681SAndroid Build Coastguard Worker return AbbrevDWO.get();
312*9880d681SAndroid Build Coastguard Worker
313*9880d681SAndroid Build Coastguard Worker DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0);
314*9880d681SAndroid Build Coastguard Worker AbbrevDWO.reset(new DWARFDebugAbbrev());
315*9880d681SAndroid Build Coastguard Worker AbbrevDWO->extract(abbrData);
316*9880d681SAndroid Build Coastguard Worker return AbbrevDWO.get();
317*9880d681SAndroid Build Coastguard Worker }
318*9880d681SAndroid Build Coastguard Worker
getDebugLoc()319*9880d681SAndroid Build Coastguard Worker const DWARFDebugLoc *DWARFContext::getDebugLoc() {
320*9880d681SAndroid Build Coastguard Worker if (Loc)
321*9880d681SAndroid Build Coastguard Worker return Loc.get();
322*9880d681SAndroid Build Coastguard Worker
323*9880d681SAndroid Build Coastguard Worker DataExtractor LocData(getLocSection().Data, isLittleEndian(), 0);
324*9880d681SAndroid Build Coastguard Worker Loc.reset(new DWARFDebugLoc(getLocSection().Relocs));
325*9880d681SAndroid Build Coastguard Worker // assume all compile units have the same address byte size
326*9880d681SAndroid Build Coastguard Worker if (getNumCompileUnits())
327*9880d681SAndroid Build Coastguard Worker Loc->parse(LocData, getCompileUnitAtIndex(0)->getAddressByteSize());
328*9880d681SAndroid Build Coastguard Worker return Loc.get();
329*9880d681SAndroid Build Coastguard Worker }
330*9880d681SAndroid Build Coastguard Worker
getDebugLocDWO()331*9880d681SAndroid Build Coastguard Worker const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() {
332*9880d681SAndroid Build Coastguard Worker if (LocDWO)
333*9880d681SAndroid Build Coastguard Worker return LocDWO.get();
334*9880d681SAndroid Build Coastguard Worker
335*9880d681SAndroid Build Coastguard Worker DataExtractor LocData(getLocDWOSection().Data, isLittleEndian(), 0);
336*9880d681SAndroid Build Coastguard Worker LocDWO.reset(new DWARFDebugLocDWO());
337*9880d681SAndroid Build Coastguard Worker LocDWO->parse(LocData);
338*9880d681SAndroid Build Coastguard Worker return LocDWO.get();
339*9880d681SAndroid Build Coastguard Worker }
340*9880d681SAndroid Build Coastguard Worker
getDebugAranges()341*9880d681SAndroid Build Coastguard Worker const DWARFDebugAranges *DWARFContext::getDebugAranges() {
342*9880d681SAndroid Build Coastguard Worker if (Aranges)
343*9880d681SAndroid Build Coastguard Worker return Aranges.get();
344*9880d681SAndroid Build Coastguard Worker
345*9880d681SAndroid Build Coastguard Worker Aranges.reset(new DWARFDebugAranges());
346*9880d681SAndroid Build Coastguard Worker Aranges->generate(this);
347*9880d681SAndroid Build Coastguard Worker return Aranges.get();
348*9880d681SAndroid Build Coastguard Worker }
349*9880d681SAndroid Build Coastguard Worker
getDebugFrame()350*9880d681SAndroid Build Coastguard Worker const DWARFDebugFrame *DWARFContext::getDebugFrame() {
351*9880d681SAndroid Build Coastguard Worker if (DebugFrame)
352*9880d681SAndroid Build Coastguard Worker return DebugFrame.get();
353*9880d681SAndroid Build Coastguard Worker
354*9880d681SAndroid Build Coastguard Worker // There's a "bug" in the DWARFv3 standard with respect to the target address
355*9880d681SAndroid Build Coastguard Worker // size within debug frame sections. While DWARF is supposed to be independent
356*9880d681SAndroid Build Coastguard Worker // of its container, FDEs have fields with size being "target address size",
357*9880d681SAndroid Build Coastguard Worker // which isn't specified in DWARF in general. It's only specified for CUs, but
358*9880d681SAndroid Build Coastguard Worker // .eh_frame can appear without a .debug_info section. Follow the example of
359*9880d681SAndroid Build Coastguard Worker // other tools (libdwarf) and extract this from the container (ObjectFile
360*9880d681SAndroid Build Coastguard Worker // provides this information). This problem is fixed in DWARFv4
361*9880d681SAndroid Build Coastguard Worker // See this dwarf-discuss discussion for more details:
362*9880d681SAndroid Build Coastguard Worker // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
363*9880d681SAndroid Build Coastguard Worker DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(),
364*9880d681SAndroid Build Coastguard Worker getAddressSize());
365*9880d681SAndroid Build Coastguard Worker DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */));
366*9880d681SAndroid Build Coastguard Worker DebugFrame->parse(debugFrameData);
367*9880d681SAndroid Build Coastguard Worker return DebugFrame.get();
368*9880d681SAndroid Build Coastguard Worker }
369*9880d681SAndroid Build Coastguard Worker
getEHFrame()370*9880d681SAndroid Build Coastguard Worker const DWARFDebugFrame *DWARFContext::getEHFrame() {
371*9880d681SAndroid Build Coastguard Worker if (EHFrame)
372*9880d681SAndroid Build Coastguard Worker return EHFrame.get();
373*9880d681SAndroid Build Coastguard Worker
374*9880d681SAndroid Build Coastguard Worker DataExtractor debugFrameData(getEHFrameSection(), isLittleEndian(),
375*9880d681SAndroid Build Coastguard Worker getAddressSize());
376*9880d681SAndroid Build Coastguard Worker DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */));
377*9880d681SAndroid Build Coastguard Worker DebugFrame->parse(debugFrameData);
378*9880d681SAndroid Build Coastguard Worker return DebugFrame.get();
379*9880d681SAndroid Build Coastguard Worker }
380*9880d681SAndroid Build Coastguard Worker
getDebugMacro()381*9880d681SAndroid Build Coastguard Worker const DWARFDebugMacro *DWARFContext::getDebugMacro() {
382*9880d681SAndroid Build Coastguard Worker if (Macro)
383*9880d681SAndroid Build Coastguard Worker return Macro.get();
384*9880d681SAndroid Build Coastguard Worker
385*9880d681SAndroid Build Coastguard Worker DataExtractor MacinfoData(getMacinfoSection(), isLittleEndian(), 0);
386*9880d681SAndroid Build Coastguard Worker Macro.reset(new DWARFDebugMacro());
387*9880d681SAndroid Build Coastguard Worker Macro->parse(MacinfoData);
388*9880d681SAndroid Build Coastguard Worker return Macro.get();
389*9880d681SAndroid Build Coastguard Worker }
390*9880d681SAndroid Build Coastguard Worker
391*9880d681SAndroid Build Coastguard Worker const DWARFLineTable *
getLineTableForUnit(DWARFUnit * U)392*9880d681SAndroid Build Coastguard Worker DWARFContext::getLineTableForUnit(DWARFUnit *U) {
393*9880d681SAndroid Build Coastguard Worker if (!Line)
394*9880d681SAndroid Build Coastguard Worker Line.reset(new DWARFDebugLine(&getLineSection().Relocs));
395*9880d681SAndroid Build Coastguard Worker
396*9880d681SAndroid Build Coastguard Worker const auto *UnitDIE = U->getUnitDIE();
397*9880d681SAndroid Build Coastguard Worker if (UnitDIE == nullptr)
398*9880d681SAndroid Build Coastguard Worker return nullptr;
399*9880d681SAndroid Build Coastguard Worker
400*9880d681SAndroid Build Coastguard Worker unsigned stmtOffset =
401*9880d681SAndroid Build Coastguard Worker UnitDIE->getAttributeValueAsSectionOffset(U, DW_AT_stmt_list, -1U);
402*9880d681SAndroid Build Coastguard Worker if (stmtOffset == -1U)
403*9880d681SAndroid Build Coastguard Worker return nullptr; // No line table for this compile unit.
404*9880d681SAndroid Build Coastguard Worker
405*9880d681SAndroid Build Coastguard Worker stmtOffset += U->getLineTableOffset();
406*9880d681SAndroid Build Coastguard Worker // See if the line table is cached.
407*9880d681SAndroid Build Coastguard Worker if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
408*9880d681SAndroid Build Coastguard Worker return lt;
409*9880d681SAndroid Build Coastguard Worker
410*9880d681SAndroid Build Coastguard Worker // We have to parse it first.
411*9880d681SAndroid Build Coastguard Worker DataExtractor lineData(U->getLineSection(), isLittleEndian(),
412*9880d681SAndroid Build Coastguard Worker U->getAddressByteSize());
413*9880d681SAndroid Build Coastguard Worker return Line->getOrParseLineTable(lineData, stmtOffset);
414*9880d681SAndroid Build Coastguard Worker }
415*9880d681SAndroid Build Coastguard Worker
parseCompileUnits()416*9880d681SAndroid Build Coastguard Worker void DWARFContext::parseCompileUnits() {
417*9880d681SAndroid Build Coastguard Worker CUs.parse(*this, getInfoSection());
418*9880d681SAndroid Build Coastguard Worker }
419*9880d681SAndroid Build Coastguard Worker
parseTypeUnits()420*9880d681SAndroid Build Coastguard Worker void DWARFContext::parseTypeUnits() {
421*9880d681SAndroid Build Coastguard Worker if (!TUs.empty())
422*9880d681SAndroid Build Coastguard Worker return;
423*9880d681SAndroid Build Coastguard Worker for (const auto &I : getTypesSections()) {
424*9880d681SAndroid Build Coastguard Worker TUs.emplace_back();
425*9880d681SAndroid Build Coastguard Worker TUs.back().parse(*this, I.second);
426*9880d681SAndroid Build Coastguard Worker }
427*9880d681SAndroid Build Coastguard Worker }
428*9880d681SAndroid Build Coastguard Worker
parseDWOCompileUnits()429*9880d681SAndroid Build Coastguard Worker void DWARFContext::parseDWOCompileUnits() {
430*9880d681SAndroid Build Coastguard Worker DWOCUs.parseDWO(*this, getInfoDWOSection());
431*9880d681SAndroid Build Coastguard Worker }
432*9880d681SAndroid Build Coastguard Worker
parseDWOTypeUnits()433*9880d681SAndroid Build Coastguard Worker void DWARFContext::parseDWOTypeUnits() {
434*9880d681SAndroid Build Coastguard Worker if (!DWOTUs.empty())
435*9880d681SAndroid Build Coastguard Worker return;
436*9880d681SAndroid Build Coastguard Worker for (const auto &I : getTypesDWOSections()) {
437*9880d681SAndroid Build Coastguard Worker DWOTUs.emplace_back();
438*9880d681SAndroid Build Coastguard Worker DWOTUs.back().parseDWO(*this, I.second);
439*9880d681SAndroid Build Coastguard Worker }
440*9880d681SAndroid Build Coastguard Worker }
441*9880d681SAndroid Build Coastguard Worker
getCompileUnitForOffset(uint32_t Offset)442*9880d681SAndroid Build Coastguard Worker DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
443*9880d681SAndroid Build Coastguard Worker parseCompileUnits();
444*9880d681SAndroid Build Coastguard Worker return CUs.getUnitForOffset(Offset);
445*9880d681SAndroid Build Coastguard Worker }
446*9880d681SAndroid Build Coastguard Worker
getCompileUnitForAddress(uint64_t Address)447*9880d681SAndroid Build Coastguard Worker DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
448*9880d681SAndroid Build Coastguard Worker // First, get the offset of the compile unit.
449*9880d681SAndroid Build Coastguard Worker uint32_t CUOffset = getDebugAranges()->findAddress(Address);
450*9880d681SAndroid Build Coastguard Worker // Retrieve the compile unit.
451*9880d681SAndroid Build Coastguard Worker return getCompileUnitForOffset(CUOffset);
452*9880d681SAndroid Build Coastguard Worker }
453*9880d681SAndroid Build Coastguard Worker
getFunctionNameForAddress(DWARFCompileUnit * CU,uint64_t Address,FunctionNameKind Kind,std::string & FunctionName)454*9880d681SAndroid Build Coastguard Worker static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address,
455*9880d681SAndroid Build Coastguard Worker FunctionNameKind Kind,
456*9880d681SAndroid Build Coastguard Worker std::string &FunctionName) {
457*9880d681SAndroid Build Coastguard Worker if (Kind == FunctionNameKind::None)
458*9880d681SAndroid Build Coastguard Worker return false;
459*9880d681SAndroid Build Coastguard Worker // The address may correspond to instruction in some inlined function,
460*9880d681SAndroid Build Coastguard Worker // so we have to build the chain of inlined functions and take the
461*9880d681SAndroid Build Coastguard Worker // name of the topmost function in it.
462*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryInlinedChain &InlinedChain =
463*9880d681SAndroid Build Coastguard Worker CU->getInlinedChainForAddress(Address);
464*9880d681SAndroid Build Coastguard Worker if (InlinedChain.DIEs.size() == 0)
465*9880d681SAndroid Build Coastguard Worker return false;
466*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
467*9880d681SAndroid Build Coastguard Worker if (const char *Name =
468*9880d681SAndroid Build Coastguard Worker TopFunctionDIE.getSubroutineName(InlinedChain.U, Kind)) {
469*9880d681SAndroid Build Coastguard Worker FunctionName = Name;
470*9880d681SAndroid Build Coastguard Worker return true;
471*9880d681SAndroid Build Coastguard Worker }
472*9880d681SAndroid Build Coastguard Worker return false;
473*9880d681SAndroid Build Coastguard Worker }
474*9880d681SAndroid Build Coastguard Worker
getLineInfoForAddress(uint64_t Address,DILineInfoSpecifier Spec)475*9880d681SAndroid Build Coastguard Worker DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
476*9880d681SAndroid Build Coastguard Worker DILineInfoSpecifier Spec) {
477*9880d681SAndroid Build Coastguard Worker DILineInfo Result;
478*9880d681SAndroid Build Coastguard Worker
479*9880d681SAndroid Build Coastguard Worker DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
480*9880d681SAndroid Build Coastguard Worker if (!CU)
481*9880d681SAndroid Build Coastguard Worker return Result;
482*9880d681SAndroid Build Coastguard Worker getFunctionNameForAddress(CU, Address, Spec.FNKind, Result.FunctionName);
483*9880d681SAndroid Build Coastguard Worker if (Spec.FLIKind != FileLineInfoKind::None) {
484*9880d681SAndroid Build Coastguard Worker if (const DWARFLineTable *LineTable = getLineTableForUnit(CU))
485*9880d681SAndroid Build Coastguard Worker LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
486*9880d681SAndroid Build Coastguard Worker Spec.FLIKind, Result);
487*9880d681SAndroid Build Coastguard Worker }
488*9880d681SAndroid Build Coastguard Worker return Result;
489*9880d681SAndroid Build Coastguard Worker }
490*9880d681SAndroid Build Coastguard Worker
491*9880d681SAndroid Build Coastguard Worker DILineInfoTable
getLineInfoForAddressRange(uint64_t Address,uint64_t Size,DILineInfoSpecifier Spec)492*9880d681SAndroid Build Coastguard Worker DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
493*9880d681SAndroid Build Coastguard Worker DILineInfoSpecifier Spec) {
494*9880d681SAndroid Build Coastguard Worker DILineInfoTable Lines;
495*9880d681SAndroid Build Coastguard Worker DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
496*9880d681SAndroid Build Coastguard Worker if (!CU)
497*9880d681SAndroid Build Coastguard Worker return Lines;
498*9880d681SAndroid Build Coastguard Worker
499*9880d681SAndroid Build Coastguard Worker std::string FunctionName = "<invalid>";
500*9880d681SAndroid Build Coastguard Worker getFunctionNameForAddress(CU, Address, Spec.FNKind, FunctionName);
501*9880d681SAndroid Build Coastguard Worker
502*9880d681SAndroid Build Coastguard Worker // If the Specifier says we don't need FileLineInfo, just
503*9880d681SAndroid Build Coastguard Worker // return the top-most function at the starting address.
504*9880d681SAndroid Build Coastguard Worker if (Spec.FLIKind == FileLineInfoKind::None) {
505*9880d681SAndroid Build Coastguard Worker DILineInfo Result;
506*9880d681SAndroid Build Coastguard Worker Result.FunctionName = FunctionName;
507*9880d681SAndroid Build Coastguard Worker Lines.push_back(std::make_pair(Address, Result));
508*9880d681SAndroid Build Coastguard Worker return Lines;
509*9880d681SAndroid Build Coastguard Worker }
510*9880d681SAndroid Build Coastguard Worker
511*9880d681SAndroid Build Coastguard Worker const DWARFLineTable *LineTable = getLineTableForUnit(CU);
512*9880d681SAndroid Build Coastguard Worker
513*9880d681SAndroid Build Coastguard Worker // Get the index of row we're looking for in the line table.
514*9880d681SAndroid Build Coastguard Worker std::vector<uint32_t> RowVector;
515*9880d681SAndroid Build Coastguard Worker if (!LineTable->lookupAddressRange(Address, Size, RowVector))
516*9880d681SAndroid Build Coastguard Worker return Lines;
517*9880d681SAndroid Build Coastguard Worker
518*9880d681SAndroid Build Coastguard Worker for (uint32_t RowIndex : RowVector) {
519*9880d681SAndroid Build Coastguard Worker // Take file number and line/column from the row.
520*9880d681SAndroid Build Coastguard Worker const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
521*9880d681SAndroid Build Coastguard Worker DILineInfo Result;
522*9880d681SAndroid Build Coastguard Worker LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(),
523*9880d681SAndroid Build Coastguard Worker Spec.FLIKind, Result.FileName);
524*9880d681SAndroid Build Coastguard Worker Result.FunctionName = FunctionName;
525*9880d681SAndroid Build Coastguard Worker Result.Line = Row.Line;
526*9880d681SAndroid Build Coastguard Worker Result.Column = Row.Column;
527*9880d681SAndroid Build Coastguard Worker Lines.push_back(std::make_pair(Row.Address, Result));
528*9880d681SAndroid Build Coastguard Worker }
529*9880d681SAndroid Build Coastguard Worker
530*9880d681SAndroid Build Coastguard Worker return Lines;
531*9880d681SAndroid Build Coastguard Worker }
532*9880d681SAndroid Build Coastguard Worker
533*9880d681SAndroid Build Coastguard Worker DIInliningInfo
getInliningInfoForAddress(uint64_t Address,DILineInfoSpecifier Spec)534*9880d681SAndroid Build Coastguard Worker DWARFContext::getInliningInfoForAddress(uint64_t Address,
535*9880d681SAndroid Build Coastguard Worker DILineInfoSpecifier Spec) {
536*9880d681SAndroid Build Coastguard Worker DIInliningInfo InliningInfo;
537*9880d681SAndroid Build Coastguard Worker
538*9880d681SAndroid Build Coastguard Worker DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
539*9880d681SAndroid Build Coastguard Worker if (!CU)
540*9880d681SAndroid Build Coastguard Worker return InliningInfo;
541*9880d681SAndroid Build Coastguard Worker
542*9880d681SAndroid Build Coastguard Worker const DWARFLineTable *LineTable = nullptr;
543*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryInlinedChain &InlinedChain =
544*9880d681SAndroid Build Coastguard Worker CU->getInlinedChainForAddress(Address);
545*9880d681SAndroid Build Coastguard Worker if (InlinedChain.DIEs.size() == 0) {
546*9880d681SAndroid Build Coastguard Worker // If there is no DIE for address (e.g. it is in unavailable .dwo file),
547*9880d681SAndroid Build Coastguard Worker // try to at least get file/line info from symbol table.
548*9880d681SAndroid Build Coastguard Worker if (Spec.FLIKind != FileLineInfoKind::None) {
549*9880d681SAndroid Build Coastguard Worker DILineInfo Frame;
550*9880d681SAndroid Build Coastguard Worker LineTable = getLineTableForUnit(CU);
551*9880d681SAndroid Build Coastguard Worker if (LineTable &&
552*9880d681SAndroid Build Coastguard Worker LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
553*9880d681SAndroid Build Coastguard Worker Spec.FLIKind, Frame))
554*9880d681SAndroid Build Coastguard Worker InliningInfo.addFrame(Frame);
555*9880d681SAndroid Build Coastguard Worker }
556*9880d681SAndroid Build Coastguard Worker return InliningInfo;
557*9880d681SAndroid Build Coastguard Worker }
558*9880d681SAndroid Build Coastguard Worker
559*9880d681SAndroid Build Coastguard Worker uint32_t CallFile = 0, CallLine = 0, CallColumn = 0;
560*9880d681SAndroid Build Coastguard Worker for (uint32_t i = 0, n = InlinedChain.DIEs.size(); i != n; i++) {
561*9880d681SAndroid Build Coastguard Worker const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i];
562*9880d681SAndroid Build Coastguard Worker DILineInfo Frame;
563*9880d681SAndroid Build Coastguard Worker // Get function name if necessary.
564*9880d681SAndroid Build Coastguard Worker if (const char *Name =
565*9880d681SAndroid Build Coastguard Worker FunctionDIE.getSubroutineName(InlinedChain.U, Spec.FNKind))
566*9880d681SAndroid Build Coastguard Worker Frame.FunctionName = Name;
567*9880d681SAndroid Build Coastguard Worker if (Spec.FLIKind != FileLineInfoKind::None) {
568*9880d681SAndroid Build Coastguard Worker if (i == 0) {
569*9880d681SAndroid Build Coastguard Worker // For the topmost frame, initialize the line table of this
570*9880d681SAndroid Build Coastguard Worker // compile unit and fetch file/line info from it.
571*9880d681SAndroid Build Coastguard Worker LineTable = getLineTableForUnit(CU);
572*9880d681SAndroid Build Coastguard Worker // For the topmost routine, get file/line info from line table.
573*9880d681SAndroid Build Coastguard Worker if (LineTable)
574*9880d681SAndroid Build Coastguard Worker LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
575*9880d681SAndroid Build Coastguard Worker Spec.FLIKind, Frame);
576*9880d681SAndroid Build Coastguard Worker } else {
577*9880d681SAndroid Build Coastguard Worker // Otherwise, use call file, call line and call column from
578*9880d681SAndroid Build Coastguard Worker // previous DIE in inlined chain.
579*9880d681SAndroid Build Coastguard Worker if (LineTable)
580*9880d681SAndroid Build Coastguard Worker LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(),
581*9880d681SAndroid Build Coastguard Worker Spec.FLIKind, Frame.FileName);
582*9880d681SAndroid Build Coastguard Worker Frame.Line = CallLine;
583*9880d681SAndroid Build Coastguard Worker Frame.Column = CallColumn;
584*9880d681SAndroid Build Coastguard Worker }
585*9880d681SAndroid Build Coastguard Worker // Get call file/line/column of a current DIE.
586*9880d681SAndroid Build Coastguard Worker if (i + 1 < n) {
587*9880d681SAndroid Build Coastguard Worker FunctionDIE.getCallerFrame(InlinedChain.U, CallFile, CallLine,
588*9880d681SAndroid Build Coastguard Worker CallColumn);
589*9880d681SAndroid Build Coastguard Worker }
590*9880d681SAndroid Build Coastguard Worker }
591*9880d681SAndroid Build Coastguard Worker InliningInfo.addFrame(Frame);
592*9880d681SAndroid Build Coastguard Worker }
593*9880d681SAndroid Build Coastguard Worker return InliningInfo;
594*9880d681SAndroid Build Coastguard Worker }
595*9880d681SAndroid Build Coastguard Worker
consumeCompressedGnuHeader(StringRef & data,uint64_t & OriginalSize)596*9880d681SAndroid Build Coastguard Worker static bool consumeCompressedGnuHeader(StringRef &data,
597*9880d681SAndroid Build Coastguard Worker uint64_t &OriginalSize) {
598*9880d681SAndroid Build Coastguard Worker // Consume "ZLIB" prefix.
599*9880d681SAndroid Build Coastguard Worker if (!data.startswith("ZLIB"))
600*9880d681SAndroid Build Coastguard Worker return false;
601*9880d681SAndroid Build Coastguard Worker data = data.substr(4);
602*9880d681SAndroid Build Coastguard Worker // Consume uncompressed section size (big-endian 8 bytes).
603*9880d681SAndroid Build Coastguard Worker DataExtractor extractor(data, false, 8);
604*9880d681SAndroid Build Coastguard Worker uint32_t Offset = 0;
605*9880d681SAndroid Build Coastguard Worker OriginalSize = extractor.getU64(&Offset);
606*9880d681SAndroid Build Coastguard Worker if (Offset == 0)
607*9880d681SAndroid Build Coastguard Worker return false;
608*9880d681SAndroid Build Coastguard Worker data = data.substr(Offset);
609*9880d681SAndroid Build Coastguard Worker return true;
610*9880d681SAndroid Build Coastguard Worker }
611*9880d681SAndroid Build Coastguard Worker
consumeCompressedZLibHeader(StringRef & Data,uint64_t & OriginalSize,bool IsLE,bool Is64Bit)612*9880d681SAndroid Build Coastguard Worker static bool consumeCompressedZLibHeader(StringRef &Data, uint64_t &OriginalSize,
613*9880d681SAndroid Build Coastguard Worker bool IsLE, bool Is64Bit) {
614*9880d681SAndroid Build Coastguard Worker using namespace ELF;
615*9880d681SAndroid Build Coastguard Worker uint64_t HdrSize = Is64Bit ? sizeof(Elf64_Chdr) : sizeof(Elf32_Chdr);
616*9880d681SAndroid Build Coastguard Worker if (Data.size() < HdrSize)
617*9880d681SAndroid Build Coastguard Worker return false;
618*9880d681SAndroid Build Coastguard Worker
619*9880d681SAndroid Build Coastguard Worker DataExtractor Extractor(Data, IsLE, 0);
620*9880d681SAndroid Build Coastguard Worker uint32_t Offset = 0;
621*9880d681SAndroid Build Coastguard Worker if (Extractor.getUnsigned(&Offset, Is64Bit ? sizeof(Elf64_Word)
622*9880d681SAndroid Build Coastguard Worker : sizeof(Elf32_Word)) !=
623*9880d681SAndroid Build Coastguard Worker ELFCOMPRESS_ZLIB)
624*9880d681SAndroid Build Coastguard Worker return false;
625*9880d681SAndroid Build Coastguard Worker
626*9880d681SAndroid Build Coastguard Worker // Skip Elf64_Chdr::ch_reserved field.
627*9880d681SAndroid Build Coastguard Worker if (Is64Bit)
628*9880d681SAndroid Build Coastguard Worker Offset += sizeof(Elf64_Word);
629*9880d681SAndroid Build Coastguard Worker
630*9880d681SAndroid Build Coastguard Worker OriginalSize = Extractor.getUnsigned(&Offset, Is64Bit ? sizeof(Elf64_Xword)
631*9880d681SAndroid Build Coastguard Worker : sizeof(Elf32_Word));
632*9880d681SAndroid Build Coastguard Worker Data = Data.substr(HdrSize);
633*9880d681SAndroid Build Coastguard Worker return true;
634*9880d681SAndroid Build Coastguard Worker }
635*9880d681SAndroid Build Coastguard Worker
tryDecompress(StringRef & Name,StringRef & Data,SmallString<32> & Out,bool ZLibStyle,bool IsLE,bool Is64Bit)636*9880d681SAndroid Build Coastguard Worker static bool tryDecompress(StringRef &Name, StringRef &Data,
637*9880d681SAndroid Build Coastguard Worker SmallString<32> &Out, bool ZLibStyle, bool IsLE,
638*9880d681SAndroid Build Coastguard Worker bool Is64Bit) {
639*9880d681SAndroid Build Coastguard Worker if (!zlib::isAvailable())
640*9880d681SAndroid Build Coastguard Worker return false;
641*9880d681SAndroid Build Coastguard Worker
642*9880d681SAndroid Build Coastguard Worker uint64_t OriginalSize;
643*9880d681SAndroid Build Coastguard Worker bool Result =
644*9880d681SAndroid Build Coastguard Worker ZLibStyle ? consumeCompressedZLibHeader(Data, OriginalSize, IsLE, Is64Bit)
645*9880d681SAndroid Build Coastguard Worker : consumeCompressedGnuHeader(Data, OriginalSize);
646*9880d681SAndroid Build Coastguard Worker
647*9880d681SAndroid Build Coastguard Worker if (!Result || zlib::uncompress(Data, Out, OriginalSize) != zlib::StatusOK)
648*9880d681SAndroid Build Coastguard Worker return false;
649*9880d681SAndroid Build Coastguard Worker
650*9880d681SAndroid Build Coastguard Worker // gnu-style names are started from "z", consume that.
651*9880d681SAndroid Build Coastguard Worker if (!ZLibStyle)
652*9880d681SAndroid Build Coastguard Worker Name = Name.substr(1);
653*9880d681SAndroid Build Coastguard Worker return true;
654*9880d681SAndroid Build Coastguard Worker }
655*9880d681SAndroid Build Coastguard Worker
DWARFContextInMemory(const object::ObjectFile & Obj,const LoadedObjectInfo * L)656*9880d681SAndroid Build Coastguard Worker DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
657*9880d681SAndroid Build Coastguard Worker const LoadedObjectInfo *L)
658*9880d681SAndroid Build Coastguard Worker : IsLittleEndian(Obj.isLittleEndian()),
659*9880d681SAndroid Build Coastguard Worker AddressSize(Obj.getBytesInAddress()) {
660*9880d681SAndroid Build Coastguard Worker for (const SectionRef &Section : Obj.sections()) {
661*9880d681SAndroid Build Coastguard Worker StringRef name;
662*9880d681SAndroid Build Coastguard Worker Section.getName(name);
663*9880d681SAndroid Build Coastguard Worker // Skip BSS and Virtual sections, they aren't interesting.
664*9880d681SAndroid Build Coastguard Worker bool IsBSS = Section.isBSS();
665*9880d681SAndroid Build Coastguard Worker if (IsBSS)
666*9880d681SAndroid Build Coastguard Worker continue;
667*9880d681SAndroid Build Coastguard Worker bool IsVirtual = Section.isVirtual();
668*9880d681SAndroid Build Coastguard Worker if (IsVirtual)
669*9880d681SAndroid Build Coastguard Worker continue;
670*9880d681SAndroid Build Coastguard Worker StringRef data;
671*9880d681SAndroid Build Coastguard Worker
672*9880d681SAndroid Build Coastguard Worker section_iterator RelocatedSection = Section.getRelocatedSection();
673*9880d681SAndroid Build Coastguard Worker // Try to obtain an already relocated version of this section.
674*9880d681SAndroid Build Coastguard Worker // Else use the unrelocated section from the object file. We'll have to
675*9880d681SAndroid Build Coastguard Worker // apply relocations ourselves later.
676*9880d681SAndroid Build Coastguard Worker if (!L || !L->getLoadedSectionContents(*RelocatedSection,data))
677*9880d681SAndroid Build Coastguard Worker Section.getContents(data);
678*9880d681SAndroid Build Coastguard Worker
679*9880d681SAndroid Build Coastguard Worker name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes.
680*9880d681SAndroid Build Coastguard Worker
681*9880d681SAndroid Build Coastguard Worker bool ZLibStyleCompressed = Section.isCompressed();
682*9880d681SAndroid Build Coastguard Worker if (ZLibStyleCompressed || name.startswith("zdebug_")) {
683*9880d681SAndroid Build Coastguard Worker SmallString<32> Out;
684*9880d681SAndroid Build Coastguard Worker if (!tryDecompress(name, data, Out, ZLibStyleCompressed, IsLittleEndian,
685*9880d681SAndroid Build Coastguard Worker AddressSize == 8))
686*9880d681SAndroid Build Coastguard Worker continue;
687*9880d681SAndroid Build Coastguard Worker UncompressedSections.emplace_back(std::move(Out));
688*9880d681SAndroid Build Coastguard Worker data = UncompressedSections.back();
689*9880d681SAndroid Build Coastguard Worker }
690*9880d681SAndroid Build Coastguard Worker
691*9880d681SAndroid Build Coastguard Worker StringRef *SectionData =
692*9880d681SAndroid Build Coastguard Worker StringSwitch<StringRef *>(name)
693*9880d681SAndroid Build Coastguard Worker .Case("debug_info", &InfoSection.Data)
694*9880d681SAndroid Build Coastguard Worker .Case("debug_abbrev", &AbbrevSection)
695*9880d681SAndroid Build Coastguard Worker .Case("debug_loc", &LocSection.Data)
696*9880d681SAndroid Build Coastguard Worker .Case("debug_line", &LineSection.Data)
697*9880d681SAndroid Build Coastguard Worker .Case("debug_aranges", &ARangeSection)
698*9880d681SAndroid Build Coastguard Worker .Case("debug_frame", &DebugFrameSection)
699*9880d681SAndroid Build Coastguard Worker .Case("eh_frame", &EHFrameSection)
700*9880d681SAndroid Build Coastguard Worker .Case("debug_str", &StringSection)
701*9880d681SAndroid Build Coastguard Worker .Case("debug_ranges", &RangeSection)
702*9880d681SAndroid Build Coastguard Worker .Case("debug_macinfo", &MacinfoSection)
703*9880d681SAndroid Build Coastguard Worker .Case("debug_pubnames", &PubNamesSection)
704*9880d681SAndroid Build Coastguard Worker .Case("debug_pubtypes", &PubTypesSection)
705*9880d681SAndroid Build Coastguard Worker .Case("debug_gnu_pubnames", &GnuPubNamesSection)
706*9880d681SAndroid Build Coastguard Worker .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
707*9880d681SAndroid Build Coastguard Worker .Case("debug_info.dwo", &InfoDWOSection.Data)
708*9880d681SAndroid Build Coastguard Worker .Case("debug_abbrev.dwo", &AbbrevDWOSection)
709*9880d681SAndroid Build Coastguard Worker .Case("debug_loc.dwo", &LocDWOSection.Data)
710*9880d681SAndroid Build Coastguard Worker .Case("debug_line.dwo", &LineDWOSection.Data)
711*9880d681SAndroid Build Coastguard Worker .Case("debug_str.dwo", &StringDWOSection)
712*9880d681SAndroid Build Coastguard Worker .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
713*9880d681SAndroid Build Coastguard Worker .Case("debug_addr", &AddrSection)
714*9880d681SAndroid Build Coastguard Worker .Case("apple_names", &AppleNamesSection.Data)
715*9880d681SAndroid Build Coastguard Worker .Case("apple_types", &AppleTypesSection.Data)
716*9880d681SAndroid Build Coastguard Worker .Case("apple_namespaces", &AppleNamespacesSection.Data)
717*9880d681SAndroid Build Coastguard Worker .Case("apple_namespac", &AppleNamespacesSection.Data)
718*9880d681SAndroid Build Coastguard Worker .Case("apple_objc", &AppleObjCSection.Data)
719*9880d681SAndroid Build Coastguard Worker .Case("debug_cu_index", &CUIndexSection)
720*9880d681SAndroid Build Coastguard Worker .Case("debug_tu_index", &TUIndexSection)
721*9880d681SAndroid Build Coastguard Worker // Any more debug info sections go here.
722*9880d681SAndroid Build Coastguard Worker .Default(nullptr);
723*9880d681SAndroid Build Coastguard Worker if (SectionData) {
724*9880d681SAndroid Build Coastguard Worker *SectionData = data;
725*9880d681SAndroid Build Coastguard Worker if (name == "debug_ranges") {
726*9880d681SAndroid Build Coastguard Worker // FIXME: Use the other dwo range section when we emit it.
727*9880d681SAndroid Build Coastguard Worker RangeDWOSection = data;
728*9880d681SAndroid Build Coastguard Worker }
729*9880d681SAndroid Build Coastguard Worker } else if (name == "debug_types") {
730*9880d681SAndroid Build Coastguard Worker // Find debug_types data by section rather than name as there are
731*9880d681SAndroid Build Coastguard Worker // multiple, comdat grouped, debug_types sections.
732*9880d681SAndroid Build Coastguard Worker TypesSections[Section].Data = data;
733*9880d681SAndroid Build Coastguard Worker } else if (name == "debug_types.dwo") {
734*9880d681SAndroid Build Coastguard Worker TypesDWOSections[Section].Data = data;
735*9880d681SAndroid Build Coastguard Worker }
736*9880d681SAndroid Build Coastguard Worker
737*9880d681SAndroid Build Coastguard Worker if (RelocatedSection == Obj.section_end())
738*9880d681SAndroid Build Coastguard Worker continue;
739*9880d681SAndroid Build Coastguard Worker
740*9880d681SAndroid Build Coastguard Worker StringRef RelSecName;
741*9880d681SAndroid Build Coastguard Worker StringRef RelSecData;
742*9880d681SAndroid Build Coastguard Worker RelocatedSection->getName(RelSecName);
743*9880d681SAndroid Build Coastguard Worker
744*9880d681SAndroid Build Coastguard Worker // If the section we're relocating was relocated already by the JIT,
745*9880d681SAndroid Build Coastguard Worker // then we used the relocated version above, so we do not need to process
746*9880d681SAndroid Build Coastguard Worker // relocations for it now.
747*9880d681SAndroid Build Coastguard Worker if (L && L->getLoadedSectionContents(*RelocatedSection,RelSecData))
748*9880d681SAndroid Build Coastguard Worker continue;
749*9880d681SAndroid Build Coastguard Worker
750*9880d681SAndroid Build Coastguard Worker // In Mach-o files, the relocations do not need to be applied if
751*9880d681SAndroid Build Coastguard Worker // there is no load offset to apply. The value read at the
752*9880d681SAndroid Build Coastguard Worker // relocation point already factors in the section address
753*9880d681SAndroid Build Coastguard Worker // (actually applying the relocations will produce wrong results
754*9880d681SAndroid Build Coastguard Worker // as the section address will be added twice).
755*9880d681SAndroid Build Coastguard Worker if (!L && isa<MachOObjectFile>(&Obj))
756*9880d681SAndroid Build Coastguard Worker continue;
757*9880d681SAndroid Build Coastguard Worker
758*9880d681SAndroid Build Coastguard Worker RelSecName = RelSecName.substr(
759*9880d681SAndroid Build Coastguard Worker RelSecName.find_first_not_of("._")); // Skip . and _ prefixes.
760*9880d681SAndroid Build Coastguard Worker
761*9880d681SAndroid Build Coastguard Worker // TODO: Add support for relocations in other sections as needed.
762*9880d681SAndroid Build Coastguard Worker // Record relocations for the debug_info and debug_line sections.
763*9880d681SAndroid Build Coastguard Worker RelocAddrMap *Map = StringSwitch<RelocAddrMap*>(RelSecName)
764*9880d681SAndroid Build Coastguard Worker .Case("debug_info", &InfoSection.Relocs)
765*9880d681SAndroid Build Coastguard Worker .Case("debug_loc", &LocSection.Relocs)
766*9880d681SAndroid Build Coastguard Worker .Case("debug_info.dwo", &InfoDWOSection.Relocs)
767*9880d681SAndroid Build Coastguard Worker .Case("debug_line", &LineSection.Relocs)
768*9880d681SAndroid Build Coastguard Worker .Case("apple_names", &AppleNamesSection.Relocs)
769*9880d681SAndroid Build Coastguard Worker .Case("apple_types", &AppleTypesSection.Relocs)
770*9880d681SAndroid Build Coastguard Worker .Case("apple_namespaces", &AppleNamespacesSection.Relocs)
771*9880d681SAndroid Build Coastguard Worker .Case("apple_namespac", &AppleNamespacesSection.Relocs)
772*9880d681SAndroid Build Coastguard Worker .Case("apple_objc", &AppleObjCSection.Relocs)
773*9880d681SAndroid Build Coastguard Worker .Default(nullptr);
774*9880d681SAndroid Build Coastguard Worker if (!Map) {
775*9880d681SAndroid Build Coastguard Worker // Find debug_types relocs by section rather than name as there are
776*9880d681SAndroid Build Coastguard Worker // multiple, comdat grouped, debug_types sections.
777*9880d681SAndroid Build Coastguard Worker if (RelSecName == "debug_types")
778*9880d681SAndroid Build Coastguard Worker Map = &TypesSections[*RelocatedSection].Relocs;
779*9880d681SAndroid Build Coastguard Worker else if (RelSecName == "debug_types.dwo")
780*9880d681SAndroid Build Coastguard Worker Map = &TypesDWOSections[*RelocatedSection].Relocs;
781*9880d681SAndroid Build Coastguard Worker else
782*9880d681SAndroid Build Coastguard Worker continue;
783*9880d681SAndroid Build Coastguard Worker }
784*9880d681SAndroid Build Coastguard Worker
785*9880d681SAndroid Build Coastguard Worker if (Section.relocation_begin() != Section.relocation_end()) {
786*9880d681SAndroid Build Coastguard Worker uint64_t SectionSize = RelocatedSection->getSize();
787*9880d681SAndroid Build Coastguard Worker for (const RelocationRef &Reloc : Section.relocations()) {
788*9880d681SAndroid Build Coastguard Worker uint64_t Address = Reloc.getOffset();
789*9880d681SAndroid Build Coastguard Worker uint64_t Type = Reloc.getType();
790*9880d681SAndroid Build Coastguard Worker uint64_t SymAddr = 0;
791*9880d681SAndroid Build Coastguard Worker uint64_t SectionLoadAddress = 0;
792*9880d681SAndroid Build Coastguard Worker object::symbol_iterator Sym = Reloc.getSymbol();
793*9880d681SAndroid Build Coastguard Worker object::section_iterator RSec = Obj.section_end();
794*9880d681SAndroid Build Coastguard Worker
795*9880d681SAndroid Build Coastguard Worker // First calculate the address of the symbol or section as it appears
796*9880d681SAndroid Build Coastguard Worker // in the objct file
797*9880d681SAndroid Build Coastguard Worker if (Sym != Obj.symbol_end()) {
798*9880d681SAndroid Build Coastguard Worker Expected<uint64_t> SymAddrOrErr = Sym->getAddress();
799*9880d681SAndroid Build Coastguard Worker if (!SymAddrOrErr) {
800*9880d681SAndroid Build Coastguard Worker std::string Buf;
801*9880d681SAndroid Build Coastguard Worker raw_string_ostream OS(Buf);
802*9880d681SAndroid Build Coastguard Worker logAllUnhandledErrors(SymAddrOrErr.takeError(), OS, "");
803*9880d681SAndroid Build Coastguard Worker OS.flush();
804*9880d681SAndroid Build Coastguard Worker errs() << "error: failed to compute symbol address: "
805*9880d681SAndroid Build Coastguard Worker << Buf << '\n';
806*9880d681SAndroid Build Coastguard Worker continue;
807*9880d681SAndroid Build Coastguard Worker }
808*9880d681SAndroid Build Coastguard Worker SymAddr = *SymAddrOrErr;
809*9880d681SAndroid Build Coastguard Worker // Also remember what section this symbol is in for later
810*9880d681SAndroid Build Coastguard Worker auto SectOrErr = Sym->getSection();
811*9880d681SAndroid Build Coastguard Worker if (!SectOrErr) {
812*9880d681SAndroid Build Coastguard Worker std::string Buf;
813*9880d681SAndroid Build Coastguard Worker raw_string_ostream OS(Buf);
814*9880d681SAndroid Build Coastguard Worker logAllUnhandledErrors(SectOrErr.takeError(), OS, "");
815*9880d681SAndroid Build Coastguard Worker OS.flush();
816*9880d681SAndroid Build Coastguard Worker errs() << "error: failed to get symbol section: "
817*9880d681SAndroid Build Coastguard Worker << Buf << '\n';
818*9880d681SAndroid Build Coastguard Worker continue;
819*9880d681SAndroid Build Coastguard Worker }
820*9880d681SAndroid Build Coastguard Worker RSec = *SectOrErr;
821*9880d681SAndroid Build Coastguard Worker } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
822*9880d681SAndroid Build Coastguard Worker // MachO also has relocations that point to sections and
823*9880d681SAndroid Build Coastguard Worker // scattered relocations.
824*9880d681SAndroid Build Coastguard Worker auto RelocInfo = MObj->getRelocation(Reloc.getRawDataRefImpl());
825*9880d681SAndroid Build Coastguard Worker if (MObj->isRelocationScattered(RelocInfo)) {
826*9880d681SAndroid Build Coastguard Worker // FIXME: it's not clear how to correctly handle scattered
827*9880d681SAndroid Build Coastguard Worker // relocations.
828*9880d681SAndroid Build Coastguard Worker continue;
829*9880d681SAndroid Build Coastguard Worker } else {
830*9880d681SAndroid Build Coastguard Worker RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
831*9880d681SAndroid Build Coastguard Worker SymAddr = RSec->getAddress();
832*9880d681SAndroid Build Coastguard Worker }
833*9880d681SAndroid Build Coastguard Worker }
834*9880d681SAndroid Build Coastguard Worker
835*9880d681SAndroid Build Coastguard Worker // If we are given load addresses for the sections, we need to adjust:
836*9880d681SAndroid Build Coastguard Worker // SymAddr = (Address of Symbol Or Section in File) -
837*9880d681SAndroid Build Coastguard Worker // (Address of Section in File) +
838*9880d681SAndroid Build Coastguard Worker // (Load Address of Section)
839*9880d681SAndroid Build Coastguard Worker if (L != nullptr && RSec != Obj.section_end()) {
840*9880d681SAndroid Build Coastguard Worker // RSec is now either the section being targeted or the section
841*9880d681SAndroid Build Coastguard Worker // containing the symbol being targeted. In either case,
842*9880d681SAndroid Build Coastguard Worker // we need to perform the same computation.
843*9880d681SAndroid Build Coastguard Worker StringRef SecName;
844*9880d681SAndroid Build Coastguard Worker RSec->getName(SecName);
845*9880d681SAndroid Build Coastguard Worker // llvm::dbgs() << "Name: '" << SecName
846*9880d681SAndroid Build Coastguard Worker // << "', RSec: " << RSec->getRawDataRefImpl()
847*9880d681SAndroid Build Coastguard Worker // << ", Section: " << Section.getRawDataRefImpl() << "\n";
848*9880d681SAndroid Build Coastguard Worker SectionLoadAddress = L->getSectionLoadAddress(*RSec);
849*9880d681SAndroid Build Coastguard Worker if (SectionLoadAddress != 0)
850*9880d681SAndroid Build Coastguard Worker SymAddr += SectionLoadAddress - RSec->getAddress();
851*9880d681SAndroid Build Coastguard Worker }
852*9880d681SAndroid Build Coastguard Worker
853*9880d681SAndroid Build Coastguard Worker object::RelocVisitor V(Obj);
854*9880d681SAndroid Build Coastguard Worker object::RelocToApply R(V.visit(Type, Reloc, SymAddr));
855*9880d681SAndroid Build Coastguard Worker if (V.error()) {
856*9880d681SAndroid Build Coastguard Worker SmallString<32> Name;
857*9880d681SAndroid Build Coastguard Worker Reloc.getTypeName(Name);
858*9880d681SAndroid Build Coastguard Worker errs() << "error: failed to compute relocation: "
859*9880d681SAndroid Build Coastguard Worker << Name << "\n";
860*9880d681SAndroid Build Coastguard Worker continue;
861*9880d681SAndroid Build Coastguard Worker }
862*9880d681SAndroid Build Coastguard Worker
863*9880d681SAndroid Build Coastguard Worker if (Address + R.Width > SectionSize) {
864*9880d681SAndroid Build Coastguard Worker errs() << "error: " << R.Width << "-byte relocation starting "
865*9880d681SAndroid Build Coastguard Worker << Address << " bytes into section " << name << " which is "
866*9880d681SAndroid Build Coastguard Worker << SectionSize << " bytes long.\n";
867*9880d681SAndroid Build Coastguard Worker continue;
868*9880d681SAndroid Build Coastguard Worker }
869*9880d681SAndroid Build Coastguard Worker if (R.Width > 8) {
870*9880d681SAndroid Build Coastguard Worker errs() << "error: can't handle a relocation of more than 8 bytes at "
871*9880d681SAndroid Build Coastguard Worker "a time.\n";
872*9880d681SAndroid Build Coastguard Worker continue;
873*9880d681SAndroid Build Coastguard Worker }
874*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Writing " << format("%p", R.Value)
875*9880d681SAndroid Build Coastguard Worker << " at " << format("%p", Address)
876*9880d681SAndroid Build Coastguard Worker << " with width " << format("%d", R.Width)
877*9880d681SAndroid Build Coastguard Worker << "\n");
878*9880d681SAndroid Build Coastguard Worker Map->insert(std::make_pair(Address, std::make_pair(R.Width, R.Value)));
879*9880d681SAndroid Build Coastguard Worker }
880*9880d681SAndroid Build Coastguard Worker }
881*9880d681SAndroid Build Coastguard Worker }
882*9880d681SAndroid Build Coastguard Worker }
883*9880d681SAndroid Build Coastguard Worker
anchor()884*9880d681SAndroid Build Coastguard Worker void DWARFContextInMemory::anchor() { }
885