62e3b9ccf6410718290f71b042768ba29ef0e74b
[oota-llvm.git] / lib / DebugInfo / DWARFContext.cpp
1 //===-- 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
10 #include "DWARFContext.h"
11 #include "DWARFDebugArangeSet.h"
12
13 #include "llvm/ADT/SmallString.h"
14 #include "llvm/ADT/StringSwitch.h"
15 #include "llvm/Support/Compression.h"
16 #include "llvm/Support/Dwarf.h"
17 #include "llvm/Support/Format.h"
18 #include "llvm/Support/Path.h"
19 #include "llvm/Support/raw_ostream.h"
20 #include <algorithm>
21 using namespace llvm;
22 using namespace dwarf;
23 using namespace object;
24
25 #define DEBUG_TYPE "dwarf"
26
27 typedef DWARFDebugLine::LineTable DWARFLineTable;
28 typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
29 typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
30
31 static void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data,
32                            bool LittleEndian, bool GnuStyle) {
33   OS << "\n." << Name << " contents:\n";
34   DataExtractor pubNames(Data, LittleEndian, 0);
35   uint32_t offset = 0;
36   while (pubNames.isValidOffset(offset)) {
37     OS << "length = " << format("0x%08x", pubNames.getU32(&offset));
38     OS << " version = " << format("0x%04x", pubNames.getU16(&offset));
39     OS << " unit_offset = " << format("0x%08x", pubNames.getU32(&offset));
40     OS << " unit_size = " << format("0x%08x", pubNames.getU32(&offset)) << '\n';
41     if (GnuStyle)
42       OS << "Offset     Linkage  Kind     Name\n";
43     else
44       OS << "Offset     Name\n";
45
46     while (offset < Data.size()) {
47       uint32_t dieRef = pubNames.getU32(&offset);
48       if (dieRef == 0)
49         break;
50       OS << format("0x%8.8x ", dieRef);
51       if (GnuStyle) {
52         PubIndexEntryDescriptor desc(pubNames.getU8(&offset));
53         OS << format("%-8s", dwarf::GDBIndexEntryLinkageString(desc.Linkage))
54            << ' ' << format("%-8s", dwarf::GDBIndexEntryKindString(desc.Kind))
55            << ' ';
56       }
57       OS << '\"' << pubNames.getCStr(&offset) << "\"\n";
58     }
59   }
60 }
61
62 void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
63   if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) {
64     OS << ".debug_abbrev contents:\n";
65     getDebugAbbrev()->dump(OS);
66   }
67
68   if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo)
69     if (const DWARFDebugAbbrev *D = getDebugAbbrevDWO()) {
70       OS << "\n.debug_abbrev.dwo contents:\n";
71       D->dump(OS);
72     }
73
74   if (DumpType == DIDT_All || DumpType == DIDT_Info) {
75     OS << "\n.debug_info contents:\n";
76     for (const auto &CU : compile_units())
77       CU->dump(OS);
78   }
79
80   if ((DumpType == DIDT_All || DumpType == DIDT_InfoDwo) &&
81       getNumDWOCompileUnits()) {
82     OS << "\n.debug_info.dwo contents:\n";
83     for (const auto &DWOCU : dwo_compile_units())
84       DWOCU->dump(OS);
85   }
86
87   if ((DumpType == DIDT_All || DumpType == DIDT_Types) && getNumTypeUnits()) {
88     OS << "\n.debug_types contents:\n";
89     for (const auto &TU : type_units())
90       TU->dump(OS);
91   }
92
93   if ((DumpType == DIDT_All || DumpType == DIDT_TypesDwo) &&
94       getNumDWOTypeUnits()) {
95     OS << "\n.debug_types.dwo contents:\n";
96     for (const auto &DWOTU : dwo_type_units())
97       DWOTU->dump(OS);
98   }
99
100   if (DumpType == DIDT_All || DumpType == DIDT_Loc) {
101     OS << "\n.debug_loc contents:\n";
102     getDebugLoc()->dump(OS);
103   }
104
105   if (DumpType == DIDT_All || DumpType == DIDT_LocDwo) {
106     OS << "\n.debug_loc.dwo contents:\n";
107     getDebugLocDWO()->dump(OS);
108   }
109
110   if (DumpType == DIDT_All || DumpType == DIDT_Frames) {
111     OS << "\n.debug_frame contents:\n";
112     getDebugFrame()->dump(OS);
113   }
114
115   uint32_t offset = 0;
116   if (DumpType == DIDT_All || DumpType == DIDT_Aranges) {
117     OS << "\n.debug_aranges contents:\n";
118     DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
119     DWARFDebugArangeSet set;
120     while (set.extract(arangesData, &offset))
121       set.dump(OS);
122   }
123
124   uint8_t savedAddressByteSize = 0;
125   if (DumpType == DIDT_All || DumpType == DIDT_Line) {
126     OS << "\n.debug_line contents:\n";
127     for (const auto &CU : compile_units()) {
128       savedAddressByteSize = CU->getAddressByteSize();
129       unsigned stmtOffset =
130           CU->getCompileUnitDIE()->getAttributeValueAsSectionOffset(
131               CU.get(), DW_AT_stmt_list, -1U);
132       if (stmtOffset != -1U) {
133         DataExtractor lineData(getLineSection().Data, isLittleEndian(),
134                                savedAddressByteSize);
135         DWARFDebugLine::LineTable LineTable;
136         LineTable.parse(lineData, &getLineSection().Relocs, &stmtOffset);
137         LineTable.dump(OS);
138       }
139     }
140   }
141
142   if (DumpType == DIDT_All || DumpType == DIDT_LineDwo) {
143     OS << "\n.debug_line.dwo contents:\n";
144     unsigned stmtOffset = 0;
145     DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(),
146                            savedAddressByteSize);
147     DWARFDebugLine::LineTable LineTable;
148     while (LineTable.Prologue.parse(lineData, &stmtOffset)) {
149       LineTable.dump(OS);
150       LineTable.clear();
151     }
152   }
153
154   if (DumpType == DIDT_All || DumpType == DIDT_Str) {
155     OS << "\n.debug_str contents:\n";
156     DataExtractor strData(getStringSection(), isLittleEndian(), 0);
157     offset = 0;
158     uint32_t strOffset = 0;
159     while (const char *s = strData.getCStr(&offset)) {
160       OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
161       strOffset = offset;
162     }
163   }
164
165   if ((DumpType == DIDT_All || DumpType == DIDT_StrDwo) &&
166       !getStringDWOSection().empty()) {
167     OS << "\n.debug_str.dwo contents:\n";
168     DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
169     offset = 0;
170     uint32_t strDWOOffset = 0;
171     while (const char *s = strDWOData.getCStr(&offset)) {
172       OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
173       strDWOOffset = offset;
174     }
175   }
176
177   if (DumpType == DIDT_All || DumpType == DIDT_Ranges) {
178     OS << "\n.debug_ranges contents:\n";
179     // In fact, different compile units may have different address byte
180     // sizes, but for simplicity we just use the address byte size of the last
181     // compile unit (there is no easy and fast way to associate address range
182     // list and the compile unit it describes).
183     DataExtractor rangesData(getRangeSection(), isLittleEndian(),
184                              savedAddressByteSize);
185     offset = 0;
186     DWARFDebugRangeList rangeList;
187     while (rangeList.extract(rangesData, &offset))
188       rangeList.dump(OS);
189   }
190
191   if (DumpType == DIDT_All || DumpType == DIDT_Pubnames)
192     dumpPubSection(OS, "debug_pubnames", getPubNamesSection(),
193                    isLittleEndian(), false);
194
195   if (DumpType == DIDT_All || DumpType == DIDT_Pubtypes)
196     dumpPubSection(OS, "debug_pubtypes", getPubTypesSection(),
197                    isLittleEndian(), false);
198
199   if (DumpType == DIDT_All || DumpType == DIDT_GnuPubnames)
200     dumpPubSection(OS, "debug_gnu_pubnames", getGnuPubNamesSection(),
201                    isLittleEndian(), true /* GnuStyle */);
202
203   if (DumpType == DIDT_All || DumpType == DIDT_GnuPubtypes)
204     dumpPubSection(OS, "debug_gnu_pubtypes", getGnuPubTypesSection(),
205                    isLittleEndian(), true /* GnuStyle */);
206
207   if ((DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) &&
208       !getStringOffsetDWOSection().empty()) {
209     OS << "\n.debug_str_offsets.dwo contents:\n";
210     DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(),
211                                0);
212     offset = 0;
213     uint64_t size = getStringOffsetDWOSection().size();
214     while (offset < size) {
215       OS << format("0x%8.8x: ", offset);
216       OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
217     }
218   }
219 }
220
221 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
222   if (Abbrev)
223     return Abbrev.get();
224
225   DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0);
226
227   Abbrev.reset(new DWARFDebugAbbrev());
228   Abbrev->extract(abbrData);
229   return Abbrev.get();
230 }
231
232 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
233   if (AbbrevDWO)
234     return AbbrevDWO.get();
235
236   DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0);
237   AbbrevDWO.reset(new DWARFDebugAbbrev());
238   AbbrevDWO->extract(abbrData);
239   return AbbrevDWO.get();
240 }
241
242 const DWARFDebugLoc *DWARFContext::getDebugLoc() {
243   if (Loc)
244     return Loc.get();
245
246   DataExtractor LocData(getLocSection().Data, isLittleEndian(), 0);
247   Loc.reset(new DWARFDebugLoc(getLocSection().Relocs));
248   // assume all compile units have the same address byte size
249   if (getNumCompileUnits())
250     Loc->parse(LocData, getCompileUnitAtIndex(0)->getAddressByteSize());
251   return Loc.get();
252 }
253
254 const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() {
255   if (LocDWO)
256     return LocDWO.get();
257
258   DataExtractor LocData(getLocDWOSection().Data, isLittleEndian(), 0);
259   LocDWO.reset(new DWARFDebugLocDWO());
260   LocDWO->parse(LocData);
261   return LocDWO.get();
262 }
263
264 const DWARFDebugAranges *DWARFContext::getDebugAranges() {
265   if (Aranges)
266     return Aranges.get();
267
268   Aranges.reset(new DWARFDebugAranges());
269   Aranges->generate(this);
270   return Aranges.get();
271 }
272
273 const DWARFDebugFrame *DWARFContext::getDebugFrame() {
274   if (DebugFrame)
275     return DebugFrame.get();
276
277   // There's a "bug" in the DWARFv3 standard with respect to the target address
278   // size within debug frame sections. While DWARF is supposed to be independent
279   // of its container, FDEs have fields with size being "target address size",
280   // which isn't specified in DWARF in general. It's only specified for CUs, but
281   // .eh_frame can appear without a .debug_info section. Follow the example of
282   // other tools (libdwarf) and extract this from the container (ObjectFile
283   // provides this information). This problem is fixed in DWARFv4
284   // See this dwarf-discuss discussion for more details:
285   // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
286   DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(),
287                                getAddressSize());
288   DebugFrame.reset(new DWARFDebugFrame());
289   DebugFrame->parse(debugFrameData);
290   return DebugFrame.get();
291 }
292
293 const DWARFLineTable *
294 DWARFContext::getLineTableForUnit(DWARFUnit *cu) {
295   if (!Line)
296     Line.reset(new DWARFDebugLine(&getLineSection().Relocs));
297
298   unsigned stmtOffset =
299       cu->getCompileUnitDIE()->getAttributeValueAsSectionOffset(
300           cu, DW_AT_stmt_list, -1U);
301   if (stmtOffset == -1U)
302     return nullptr; // No line table for this compile unit.
303
304   // See if the line table is cached.
305   if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
306     return lt;
307
308   // We have to parse it first.
309   DataExtractor lineData(getLineSection().Data, isLittleEndian(),
310                          cu->getAddressByteSize());
311   return Line->getOrParseLineTable(lineData, stmtOffset);
312 }
313
314 void DWARFContext::parseCompileUnits() {
315   if (!CUs.empty())
316     return;
317   uint32_t offset = 0;
318   const DataExtractor &DIData = DataExtractor(getInfoSection().Data,
319                                               isLittleEndian(), 0);
320   while (DIData.isValidOffset(offset)) {
321     std::unique_ptr<DWARFCompileUnit> CU(new DWARFCompileUnit(*this,
322         getDebugAbbrev(), getInfoSection().Data, getRangeSection(),
323         getStringSection(), StringRef(), getAddrSection(),
324         &getInfoSection().Relocs, isLittleEndian(), CUs));
325     if (!CU->extract(DIData, &offset)) {
326       break;
327     }
328     CUs.push_back(std::move(CU));
329     offset = CUs.back()->getNextUnitOffset();
330   }
331 }
332
333 void DWARFContext::parseTypeUnits() {
334   if (!TUs.empty())
335     return;
336   for (const auto &I : getTypesSections()) {
337     uint32_t offset = 0;
338     const DataExtractor &DIData =
339         DataExtractor(I.second.Data, isLittleEndian(), 0);
340     while (DIData.isValidOffset(offset)) {
341       std::unique_ptr<DWARFTypeUnit> TU(new DWARFTypeUnit(*this,
342            getDebugAbbrev(), I.second.Data, getRangeSection(),
343            getStringSection(), StringRef(), getAddrSection(),
344            &I.second.Relocs, isLittleEndian(), TUs));
345       if (!TU->extract(DIData, &offset))
346         break;
347       TUs.push_back(std::move(TU));
348       offset = TUs.back()->getNextUnitOffset();
349     }
350   }
351 }
352
353 void DWARFContext::parseDWOCompileUnits() {
354   if (!DWOCUs.empty())
355     return;
356   uint32_t offset = 0;
357   const DataExtractor &DIData =
358       DataExtractor(getInfoDWOSection().Data, isLittleEndian(), 0);
359   while (DIData.isValidOffset(offset)) {
360     std::unique_ptr<DWARFCompileUnit> DWOCU(new DWARFCompileUnit(*this,
361         getDebugAbbrevDWO(), getInfoDWOSection().Data, getRangeDWOSection(),
362         getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(),
363         &getInfoDWOSection().Relocs, isLittleEndian(), DWOCUs));
364     if (!DWOCU->extract(DIData, &offset)) {
365       break;
366     }
367     DWOCUs.push_back(std::move(DWOCU));
368     offset = DWOCUs.back()->getNextUnitOffset();
369   }
370 }
371
372 void DWARFContext::parseDWOTypeUnits() {
373   if (!DWOTUs.empty())
374     return;
375   for (const auto &I : getTypesDWOSections()) {
376     uint32_t offset = 0;
377     const DataExtractor &DIData =
378         DataExtractor(I.second.Data, isLittleEndian(), 0);
379     while (DIData.isValidOffset(offset)) {
380       std::unique_ptr<DWARFTypeUnit> TU(new DWARFTypeUnit(*this,
381           getDebugAbbrevDWO(), I.second.Data, getRangeDWOSection(),
382           getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(),
383           &I.second.Relocs, isLittleEndian(), DWOTUs));
384       if (!TU->extract(DIData, &offset))
385         break;
386       DWOTUs.push_back(std::move(TU));
387       offset = DWOTUs.back()->getNextUnitOffset();
388     }
389   }
390 }
391
392 DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
393   parseCompileUnits();
394   return CUs.getUnitForOffset(Offset);
395 }
396
397 DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
398   // First, get the offset of the compile unit.
399   uint32_t CUOffset = getDebugAranges()->findAddress(Address);
400   // Retrieve the compile unit.
401   return getCompileUnitForOffset(CUOffset);
402 }
403
404 static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address,
405                                       FunctionNameKind Kind,
406                                       std::string &FunctionName) {
407   if (Kind == FunctionNameKind::None)
408     return false;
409   // The address may correspond to instruction in some inlined function,
410   // so we have to build the chain of inlined functions and take the
411   // name of the topmost function in it.
412   const DWARFDebugInfoEntryInlinedChain &InlinedChain =
413       CU->getInlinedChainForAddress(Address);
414   if (InlinedChain.DIEs.size() == 0)
415     return false;
416   const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
417   if (const char *Name =
418           TopFunctionDIE.getSubroutineName(InlinedChain.U, Kind)) {
419     FunctionName = Name;
420     return true;
421   }
422   return false;
423 }
424
425 DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
426                                                DILineInfoSpecifier Spec) {
427   DILineInfo Result;
428
429   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
430   if (!CU)
431     return Result;
432   getFunctionNameForAddress(CU, Address, Spec.FNKind, Result.FunctionName);
433   if (Spec.FLIKind != FileLineInfoKind::None) {
434     if (const DWARFLineTable *LineTable = getLineTableForUnit(CU))
435       LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
436                                            Spec.FLIKind, Result);
437   }
438   return Result;
439 }
440
441 DILineInfoTable
442 DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
443                                          DILineInfoSpecifier Spec) {
444   DILineInfoTable  Lines;
445   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
446   if (!CU)
447     return Lines;
448
449   std::string FunctionName = "<invalid>";
450   getFunctionNameForAddress(CU, Address, Spec.FNKind, FunctionName);
451
452   // If the Specifier says we don't need FileLineInfo, just
453   // return the top-most function at the starting address.
454   if (Spec.FLIKind == FileLineInfoKind::None) {
455     DILineInfo Result;
456     Result.FunctionName = FunctionName;
457     Lines.push_back(std::make_pair(Address, Result));
458     return Lines;
459   }
460
461   const DWARFLineTable *LineTable = getLineTableForUnit(CU);
462
463   // Get the index of row we're looking for in the line table.
464   std::vector<uint32_t> RowVector;
465   if (!LineTable->lookupAddressRange(Address, Size, RowVector))
466     return Lines;
467
468   for (uint32_t RowIndex : RowVector) {
469     // Take file number and line/column from the row.
470     const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
471     DILineInfo Result;
472     LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(),
473                                   Spec.FLIKind, Result.FileName);
474     Result.FunctionName = FunctionName;
475     Result.Line = Row.Line;
476     Result.Column = Row.Column;
477     Lines.push_back(std::make_pair(Row.Address, Result));
478   }
479
480   return Lines;
481 }
482
483 DIInliningInfo
484 DWARFContext::getInliningInfoForAddress(uint64_t Address,
485                                         DILineInfoSpecifier Spec) {
486   DIInliningInfo InliningInfo;
487
488   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
489   if (!CU)
490     return InliningInfo;
491
492   const DWARFLineTable *LineTable = nullptr;
493   const DWARFDebugInfoEntryInlinedChain &InlinedChain =
494       CU->getInlinedChainForAddress(Address);
495   if (InlinedChain.DIEs.size() == 0) {
496     // If there is no DIE for address (e.g. it is in unavailable .dwo file),
497     // try to at least get file/line info from symbol table.
498     if (Spec.FLIKind != FileLineInfoKind::None) {
499       DILineInfo Frame;
500       LineTable = getLineTableForUnit(CU);
501       if (LineTable &&
502           LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
503                                                Spec.FLIKind, Frame))
504         InliningInfo.addFrame(Frame);
505     }
506     return InliningInfo;
507   }
508
509   uint32_t CallFile = 0, CallLine = 0, CallColumn = 0;
510   for (uint32_t i = 0, n = InlinedChain.DIEs.size(); i != n; i++) {
511     const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i];
512     DILineInfo Frame;
513     // Get function name if necessary.
514     if (const char *Name =
515             FunctionDIE.getSubroutineName(InlinedChain.U, Spec.FNKind))
516       Frame.FunctionName = Name;
517     if (Spec.FLIKind != FileLineInfoKind::None) {
518       if (i == 0) {
519         // For the topmost frame, initialize the line table of this
520         // compile unit and fetch file/line info from it.
521         LineTable = getLineTableForUnit(CU);
522         // For the topmost routine, get file/line info from line table.
523         if (LineTable)
524           LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
525                                                Spec.FLIKind, Frame);
526       } else {
527         // Otherwise, use call file, call line and call column from
528         // previous DIE in inlined chain.
529         if (LineTable)
530           LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(),
531                                         Spec.FLIKind, Frame.FileName);
532         Frame.Line = CallLine;
533         Frame.Column = CallColumn;
534       }
535       // Get call file/line/column of a current DIE.
536       if (i + 1 < n) {
537         FunctionDIE.getCallerFrame(InlinedChain.U, CallFile, CallLine,
538                                    CallColumn);
539       }
540     }
541     InliningInfo.addFrame(Frame);
542   }
543   return InliningInfo;
544 }
545
546 static bool consumeCompressedDebugSectionHeader(StringRef &data,
547                                                 uint64_t &OriginalSize) {
548   // Consume "ZLIB" prefix.
549   if (!data.startswith("ZLIB"))
550     return false;
551   data = data.substr(4);
552   // Consume uncompressed section size (big-endian 8 bytes).
553   DataExtractor extractor(data, false, 8);
554   uint32_t Offset = 0;
555   OriginalSize = extractor.getU64(&Offset);
556   if (Offset == 0)
557     return false;
558   data = data.substr(Offset);
559   return true;
560 }
561
562 DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile &Obj)
563     : IsLittleEndian(Obj.isLittleEndian()),
564       AddressSize(Obj.getBytesInAddress()) {
565   for (const SectionRef &Section : Obj.sections()) {
566     StringRef name;
567     Section.getName(name);
568     // Skip BSS and Virtual sections, they aren't interesting.
569     bool IsBSS;
570     Section.isBSS(IsBSS);
571     if (IsBSS)
572       continue;
573     bool IsVirtual;
574     Section.isVirtual(IsVirtual);
575     if (IsVirtual)
576       continue;
577     StringRef data;
578     Section.getContents(data);
579
580     name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes.
581
582     // Check if debug info section is compressed with zlib.
583     if (name.startswith("zdebug_")) {
584       uint64_t OriginalSize;
585       if (!zlib::isAvailable() ||
586           !consumeCompressedDebugSectionHeader(data, OriginalSize))
587         continue;
588       UncompressedSections.resize(UncompressedSections.size() + 1);
589       if (zlib::uncompress(data, UncompressedSections.back(), OriginalSize) !=
590           zlib::StatusOK) {
591         UncompressedSections.pop_back();
592         continue;
593       }
594       // Make data point to uncompressed section contents and save its contents.
595       name = name.substr(1);
596       data = UncompressedSections.back();
597     }
598
599     StringRef *SectionData =
600         StringSwitch<StringRef *>(name)
601             .Case("debug_info", &InfoSection.Data)
602             .Case("debug_abbrev", &AbbrevSection)
603             .Case("debug_loc", &LocSection.Data)
604             .Case("debug_line", &LineSection.Data)
605             .Case("debug_aranges", &ARangeSection)
606             .Case("debug_frame", &DebugFrameSection)
607             .Case("debug_str", &StringSection)
608             .Case("debug_ranges", &RangeSection)
609             .Case("debug_pubnames", &PubNamesSection)
610             .Case("debug_pubtypes", &PubTypesSection)
611             .Case("debug_gnu_pubnames", &GnuPubNamesSection)
612             .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
613             .Case("debug_info.dwo", &InfoDWOSection.Data)
614             .Case("debug_abbrev.dwo", &AbbrevDWOSection)
615             .Case("debug_loc.dwo", &LocDWOSection.Data)
616             .Case("debug_line.dwo", &LineDWOSection.Data)
617             .Case("debug_str.dwo", &StringDWOSection)
618             .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
619             .Case("debug_addr", &AddrSection)
620             // Any more debug info sections go here.
621             .Default(nullptr);
622     if (SectionData) {
623       *SectionData = data;
624       if (name == "debug_ranges") {
625         // FIXME: Use the other dwo range section when we emit it.
626         RangeDWOSection = data;
627       }
628     } else if (name == "debug_types") {
629       // Find debug_types data by section rather than name as there are
630       // multiple, comdat grouped, debug_types sections.
631       TypesSections[Section].Data = data;
632     } else if (name == "debug_types.dwo") {
633       TypesDWOSections[Section].Data = data;
634     }
635
636     section_iterator RelocatedSection = Section.getRelocatedSection();
637     if (RelocatedSection == Obj.section_end())
638       continue;
639
640     StringRef RelSecName;
641     RelocatedSection->getName(RelSecName);
642     RelSecName = RelSecName.substr(
643         RelSecName.find_first_not_of("._")); // Skip . and _ prefixes.
644
645     // TODO: Add support for relocations in other sections as needed.
646     // Record relocations for the debug_info and debug_line sections.
647     RelocAddrMap *Map = StringSwitch<RelocAddrMap*>(RelSecName)
648         .Case("debug_info", &InfoSection.Relocs)
649         .Case("debug_loc", &LocSection.Relocs)
650         .Case("debug_info.dwo", &InfoDWOSection.Relocs)
651         .Case("debug_line", &LineSection.Relocs)
652         .Default(nullptr);
653     if (!Map) {
654       // Find debug_types relocs by section rather than name as there are
655       // multiple, comdat grouped, debug_types sections.
656       if (RelSecName == "debug_types")
657         Map = &TypesSections[*RelocatedSection].Relocs;
658       else if (RelSecName == "debug_types.dwo")
659         Map = &TypesDWOSections[*RelocatedSection].Relocs;
660       else
661         continue;
662     }
663
664     if (Section.relocation_begin() != Section.relocation_end()) {
665       uint64_t SectionSize;
666       RelocatedSection->getSize(SectionSize);
667       for (const RelocationRef &Reloc : Section.relocations()) {
668         uint64_t Address;
669         Reloc.getOffset(Address);
670         uint64_t Type;
671         Reloc.getType(Type);
672         uint64_t SymAddr = 0;
673         // ELF relocations may need the symbol address
674         if (Obj.isELF()) {
675           object::symbol_iterator Sym = Reloc.getSymbol();
676           Sym->getAddress(SymAddr);
677         }
678
679         object::RelocVisitor V(Obj.getFileFormatName());
680         // The section address is always 0 for debug sections.
681         object::RelocToApply R(V.visit(Type, Reloc, 0, SymAddr));
682         if (V.error()) {
683           SmallString<32> Name;
684           std::error_code ec(Reloc.getTypeName(Name));
685           if (ec) {
686             errs() << "Aaaaaa! Nameless relocation! Aaaaaa!\n";
687           }
688           errs() << "error: failed to compute relocation: "
689                  << Name << "\n";
690           continue;
691         }
692
693         if (Address + R.Width > SectionSize) {
694           errs() << "error: " << R.Width << "-byte relocation starting "
695                  << Address << " bytes into section " << name << " which is "
696                  << SectionSize << " bytes long.\n";
697           continue;
698         }
699         if (R.Width > 8) {
700           errs() << "error: can't handle a relocation of more than 8 bytes at "
701                     "a time.\n";
702           continue;
703         }
704         DEBUG(dbgs() << "Writing " << format("%p", R.Value)
705                      << " at " << format("%p", Address)
706                      << " with width " << format("%d", R.Width)
707                      << "\n");
708         Map->insert(std::make_pair(Address, std::make_pair(R.Width, R.Value)));
709       }
710     }
711   }
712 }
713
714 void DWARFContextInMemory::anchor() { }