]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
Merge ^/head r318964 through r319164.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / DebugInfo / DWARF / 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 "llvm/DebugInfo/DWARF/DWARFContext.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
17 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
18 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
19 #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
20 #include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
21 #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
22 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
23 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
24 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
25 #include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
26 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
27 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
28 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
29 #include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
30 #include "llvm/DebugInfo/DWARF/DWARFSection.h"
31 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
32 #include "llvm/DebugInfo/DWARF/DWARFVerifier.h"
33 #include "llvm/Object/Decompressor.h"
34 #include "llvm/Object/MachO.h"
35 #include "llvm/Object/ObjectFile.h"
36 #include "llvm/Object/RelocVisitor.h"
37 #include "llvm/Support/Casting.h"
38 #include "llvm/Support/DataExtractor.h"
39 #include "llvm/Support/Debug.h"
40 #include "llvm/Support/Error.h"
41 #include "llvm/Support/Format.h"
42 #include "llvm/Support/MemoryBuffer.h"
43 #include "llvm/Support/raw_ostream.h"
44 #include <algorithm>
45 #include <cstdint>
46 #include <map>
47 #include <set>
48 #include <string>
49 #include <utility>
50 #include <vector>
51
52 using namespace llvm;
53 using namespace dwarf;
54 using namespace object;
55
56 #define DEBUG_TYPE "dwarf"
57
58 typedef DWARFDebugLine::LineTable DWARFLineTable;
59 typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
60 typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
61
62 uint64_t llvm::getRelocatedValue(const DataExtractor &Data, uint32_t Size,
63                                  uint32_t *Off, const RelocAddrMap *Relocs,
64                                  uint64_t *SectionIndex) {
65   if (!Relocs)
66     return Data.getUnsigned(Off, Size);
67   RelocAddrMap::const_iterator AI = Relocs->find(*Off);
68   if (AI == Relocs->end())
69     return Data.getUnsigned(Off, Size);
70   if (SectionIndex)
71     *SectionIndex = AI->second.SectionIndex;
72   return Data.getUnsigned(Off, Size) + AI->second.Value;
73 }
74
75 static void dumpAccelSection(raw_ostream &OS, StringRef Name,
76                              const DWARFSection& Section, StringRef StringSection,
77                              bool LittleEndian) {
78   DataExtractor AccelSection(Section.Data, LittleEndian, 0);
79   DataExtractor StrData(StringSection, LittleEndian, 0);
80   OS << "\n." << Name << " contents:\n";
81   DWARFAcceleratorTable Accel(AccelSection, StrData, Section.Relocs);
82   if (!Accel.extract())
83     return;
84   Accel.dump(OS);
85 }
86
87 void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType, bool DumpEH,
88                         bool SummarizeTypes) {
89   if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) {
90     OS << ".debug_abbrev contents:\n";
91     getDebugAbbrev()->dump(OS);
92   }
93
94   if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo)
95     if (const DWARFDebugAbbrev *D = getDebugAbbrevDWO()) {
96       OS << "\n.debug_abbrev.dwo contents:\n";
97       D->dump(OS);
98     }
99
100   if (DumpType == DIDT_All || DumpType == DIDT_Info) {
101     OS << "\n.debug_info contents:\n";
102     for (const auto &CU : compile_units())
103       CU->dump(OS);
104   }
105
106   if ((DumpType == DIDT_All || DumpType == DIDT_InfoDwo) &&
107       getNumDWOCompileUnits()) {
108     OS << "\n.debug_info.dwo contents:\n";
109     for (const auto &DWOCU : dwo_compile_units())
110       DWOCU->dump(OS);
111   }
112
113   if ((DumpType == DIDT_All || DumpType == DIDT_Types) && getNumTypeUnits()) {
114     OS << "\n.debug_types contents:\n";
115     for (const auto &TUS : type_unit_sections())
116       for (const auto &TU : TUS)
117         TU->dump(OS, SummarizeTypes);
118   }
119
120   if ((DumpType == DIDT_All || DumpType == DIDT_TypesDwo) &&
121       getNumDWOTypeUnits()) {
122     OS << "\n.debug_types.dwo contents:\n";
123     for (const auto &DWOTUS : dwo_type_unit_sections())
124       for (const auto &DWOTU : DWOTUS)
125         DWOTU->dump(OS, SummarizeTypes);
126   }
127
128   if (DumpType == DIDT_All || DumpType == DIDT_Loc) {
129     OS << "\n.debug_loc contents:\n";
130     getDebugLoc()->dump(OS);
131   }
132
133   if (DumpType == DIDT_All || DumpType == DIDT_LocDwo) {
134     OS << "\n.debug_loc.dwo contents:\n";
135     getDebugLocDWO()->dump(OS);
136   }
137
138   if (DumpType == DIDT_All || DumpType == DIDT_Frames) {
139     OS << "\n.debug_frame contents:\n";
140     getDebugFrame()->dump(OS);
141     if (DumpEH) {
142       OS << "\n.eh_frame contents:\n";
143       getEHFrame()->dump(OS);
144     }
145   }
146
147   if (DumpType == DIDT_All || DumpType == DIDT_Macro) {
148     OS << "\n.debug_macinfo contents:\n";
149     getDebugMacro()->dump(OS);
150   }
151
152   uint32_t offset = 0;
153   if (DumpType == DIDT_All || DumpType == DIDT_Aranges) {
154     OS << "\n.debug_aranges contents:\n";
155     DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
156     DWARFDebugArangeSet set;
157     while (set.extract(arangesData, &offset))
158       set.dump(OS);
159   }
160
161   uint8_t savedAddressByteSize = 0;
162   if (DumpType == DIDT_All || DumpType == DIDT_Line) {
163     OS << "\n.debug_line contents:\n";
164     for (const auto &CU : compile_units()) {
165       savedAddressByteSize = CU->getAddressByteSize();
166       auto CUDIE = CU->getUnitDIE();
167       if (!CUDIE)
168         continue;
169       if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list))) {
170         DataExtractor lineData(getLineSection().Data, isLittleEndian(),
171                                savedAddressByteSize);
172         DWARFDebugLine::LineTable LineTable;
173         uint32_t Offset = *StmtOffset;
174         LineTable.parse(lineData, &getLineSection().Relocs, &Offset);
175         LineTable.dump(OS);
176       }
177     }
178   }
179
180   if (DumpType == DIDT_All || DumpType == DIDT_CUIndex) {
181     OS << "\n.debug_cu_index contents:\n";
182     getCUIndex().dump(OS);
183   }
184
185   if (DumpType == DIDT_All || DumpType == DIDT_TUIndex) {
186     OS << "\n.debug_tu_index contents:\n";
187     getTUIndex().dump(OS);
188   }
189
190   if (DumpType == DIDT_All || DumpType == DIDT_LineDwo) {
191     OS << "\n.debug_line.dwo contents:\n";
192     unsigned stmtOffset = 0;
193     DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(),
194                            savedAddressByteSize);
195     DWARFDebugLine::LineTable LineTable;
196     while (LineTable.Prologue.parse(lineData, &stmtOffset)) {
197       LineTable.dump(OS);
198       LineTable.clear();
199     }
200   }
201
202   if (DumpType == DIDT_All || DumpType == DIDT_Str) {
203     OS << "\n.debug_str contents:\n";
204     DataExtractor strData(getStringSection(), isLittleEndian(), 0);
205     offset = 0;
206     uint32_t strOffset = 0;
207     while (const char *s = strData.getCStr(&offset)) {
208       OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
209       strOffset = offset;
210     }
211   }
212
213   if ((DumpType == DIDT_All || DumpType == DIDT_StrDwo) &&
214       !getStringDWOSection().empty()) {
215     OS << "\n.debug_str.dwo contents:\n";
216     DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
217     offset = 0;
218     uint32_t strDWOOffset = 0;
219     while (const char *s = strDWOData.getCStr(&offset)) {
220       OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
221       strDWOOffset = offset;
222     }
223   }
224
225   if (DumpType == DIDT_All || DumpType == DIDT_Ranges) {
226     OS << "\n.debug_ranges contents:\n";
227     // In fact, different compile units may have different address byte
228     // sizes, but for simplicity we just use the address byte size of the last
229     // compile unit (there is no easy and fast way to associate address range
230     // list and the compile unit it describes).
231     DataExtractor rangesData(getRangeSection().Data, isLittleEndian(),
232                              savedAddressByteSize);
233     offset = 0;
234     DWARFDebugRangeList rangeList;
235     while (rangeList.extract(rangesData, &offset, getRangeSection().Relocs))
236       rangeList.dump(OS);
237   }
238
239   if (DumpType == DIDT_All || DumpType == DIDT_Pubnames)
240     DWARFDebugPubTable(getPubNamesSection(), isLittleEndian(), false)
241         .dump("debug_pubnames", OS);
242
243   if (DumpType == DIDT_All || DumpType == DIDT_Pubtypes)
244     DWARFDebugPubTable(getPubTypesSection(), isLittleEndian(), false)
245         .dump("debug_pubtypes", OS);
246
247   if (DumpType == DIDT_All || DumpType == DIDT_GnuPubnames)
248     DWARFDebugPubTable(getGnuPubNamesSection(), isLittleEndian(),
249                        true /* GnuStyle */)
250         .dump("debug_gnu_pubnames", OS);
251
252   if (DumpType == DIDT_All || DumpType == DIDT_GnuPubtypes)
253     DWARFDebugPubTable(getGnuPubTypesSection(), isLittleEndian(),
254                        true /* GnuStyle */)
255         .dump("debug_gnu_pubtypes", OS);
256
257   if ((DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) &&
258       !getStringOffsetDWOSection().empty()) {
259     OS << "\n.debug_str_offsets.dwo contents:\n";
260     DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(),
261                                0);
262     offset = 0;
263     uint64_t size = getStringOffsetDWOSection().size();
264     while (offset < size) {
265       OS << format("0x%8.8x: ", offset);
266       OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
267     }
268   }
269
270   if ((DumpType == DIDT_All || DumpType == DIDT_GdbIndex) &&
271       !getGdbIndexSection().empty()) {
272     OS << "\n.gnu_index contents:\n";
273     getGdbIndex().dump(OS);
274   }
275
276   if (DumpType == DIDT_All || DumpType == DIDT_AppleNames)
277     dumpAccelSection(OS, "apple_names", getAppleNamesSection(),
278                      getStringSection(), isLittleEndian());
279
280   if (DumpType == DIDT_All || DumpType == DIDT_AppleTypes)
281     dumpAccelSection(OS, "apple_types", getAppleTypesSection(),
282                      getStringSection(), isLittleEndian());
283
284   if (DumpType == DIDT_All || DumpType == DIDT_AppleNamespaces)
285     dumpAccelSection(OS, "apple_namespaces", getAppleNamespacesSection(),
286                      getStringSection(), isLittleEndian());
287
288   if (DumpType == DIDT_All || DumpType == DIDT_AppleObjC)
289     dumpAccelSection(OS, "apple_objc", getAppleObjCSection(),
290                      getStringSection(), isLittleEndian());
291 }
292
293 DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
294   // FIXME: Improve this for the case where this DWO file is really a DWP file
295   // with an index - use the index for lookup instead of a linear search.
296   for (const auto &DWOCU : dwo_compile_units())
297     if (DWOCU->getDWOId() == Hash)
298       return DWOCU.get();
299   return nullptr;
300 }
301
302 DWARFDie DWARFContext::getDIEForOffset(uint32_t Offset) {
303   parseCompileUnits();
304   if (auto *CU = CUs.getUnitForOffset(Offset))
305     return CU->getDIEForOffset(Offset);
306   return DWARFDie();
307 }
308
309 namespace {
310   
311 class Verifier {
312   raw_ostream &OS;
313   DWARFContext &DCtx;
314 public:
315   Verifier(raw_ostream &S, DWARFContext &D) : OS(S), DCtx(D) {}
316   
317   bool HandleDebugInfo() {
318     bool Success = true;
319     // A map that tracks all references (converted absolute references) so we
320     // can verify each reference points to a valid DIE and not an offset that
321     // lies between to valid DIEs.
322     std::map<uint64_t, std::set<uint32_t>> ReferenceToDIEOffsets;
323
324     OS << "Verifying .debug_info...\n";
325     for (const auto &CU : DCtx.compile_units()) {
326       unsigned NumDies = CU->getNumDIEs();
327       for (unsigned I = 0; I < NumDies; ++I) {
328         auto Die = CU->getDIEAtIndex(I);
329         const auto Tag = Die.getTag();
330         if (Tag == DW_TAG_null)
331           continue;
332         for (auto AttrValue : Die.attributes()) {
333           const auto Attr = AttrValue.Attr;
334           const auto Form = AttrValue.Value.getForm();
335           switch (Attr) {
336             case DW_AT_ranges:
337               // Make sure the offset in the DW_AT_ranges attribute is valid.
338               if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
339                 if (*SectionOffset >= DCtx.getRangeSection().Data.size()) {
340                   Success = false;
341                   OS << "error: DW_AT_ranges offset is beyond .debug_ranges "
342                   "bounds:\n";
343                   Die.dump(OS, 0);
344                   OS << "\n";
345                 }
346               } else {
347                 Success = false;
348                 OS << "error: DIE has invalid DW_AT_ranges encoding:\n";
349                 Die.dump(OS, 0);
350                 OS << "\n";
351               }
352               break;
353             case DW_AT_stmt_list:
354               // Make sure the offset in the DW_AT_stmt_list attribute is valid.
355               if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
356                 if (*SectionOffset >= DCtx.getLineSection().Data.size()) {
357                   Success = false;
358                   OS << "error: DW_AT_stmt_list offset is beyond .debug_line "
359                   "bounds: "
360                   << format("0x%08" PRIx32, *SectionOffset) << "\n";
361                   CU->getUnitDIE().dump(OS, 0);
362                   OS << "\n";
363                 }
364               } else {
365                 Success = false;
366                 OS << "error: DIE has invalid DW_AT_stmt_list encoding:\n";
367                 Die.dump(OS, 0);
368                 OS << "\n";
369               }
370               break;
371               
372             default:
373               break;
374           }
375           switch (Form) {
376             case DW_FORM_ref1:
377             case DW_FORM_ref2:
378             case DW_FORM_ref4:
379             case DW_FORM_ref8:
380             case DW_FORM_ref_udata: {
381               // Verify all CU relative references are valid CU offsets.
382               Optional<uint64_t> RefVal = AttrValue.Value.getAsReference();
383               assert(RefVal);
384               if (RefVal) {
385                 auto DieCU = Die.getDwarfUnit();
386                 auto CUSize = DieCU->getNextUnitOffset() - DieCU->getOffset();
387                 auto CUOffset = AttrValue.Value.getRawUValue();
388                 if (CUOffset >= CUSize) {
389                   Success = false;
390                   OS << "error: " << FormEncodingString(Form) << " CU offset "
391                   << format("0x%08" PRIx32, CUOffset)
392                   << " is invalid (must be less than CU size of "
393                   << format("0x%08" PRIx32, CUSize) << "):\n";
394                   Die.dump(OS, 0);
395                   OS << "\n";
396                 } else {
397                   // Valid reference, but we will verify it points to an actual
398                   // DIE later.
399                   ReferenceToDIEOffsets[*RefVal].insert(Die.getOffset());
400                 }
401               }
402               break;
403             }
404             case DW_FORM_ref_addr: {
405               // Verify all absolute DIE references have valid offsets in the
406               // .debug_info section.
407               Optional<uint64_t> RefVal = AttrValue.Value.getAsReference();
408               assert(RefVal);
409               if (RefVal) {
410                 if(*RefVal >= DCtx.getInfoSection().Data.size()) {
411                   Success = false;
412                   OS << "error: DW_FORM_ref_addr offset beyond .debug_info "
413                         "bounds:\n";
414                   Die.dump(OS, 0);
415                   OS << "\n";
416                 } else {
417                   // Valid reference, but we will verify it points to an actual
418                   // DIE later.
419                   ReferenceToDIEOffsets[*RefVal].insert(Die.getOffset());
420                 }
421               }
422               break;
423             }
424             case DW_FORM_strp: {
425               auto SecOffset = AttrValue.Value.getAsSectionOffset();
426               assert(SecOffset); // DW_FORM_strp is a section offset.
427               if (SecOffset && *SecOffset >= DCtx.getStringSection().size()) {
428                 Success = false;
429                 OS << "error: DW_FORM_strp offset beyond .debug_str bounds:\n";
430                 Die.dump(OS, 0);
431                 OS << "\n";
432               }
433               break;
434             }
435             default:
436               break;
437           }
438         }
439       }
440     }
441
442     // Take all references and make sure they point to an actual DIE by
443     // getting the DIE by offset and emitting an error
444     OS << "Verifying .debug_info references...\n";
445     for (auto Pair: ReferenceToDIEOffsets) {
446       auto Die = DCtx.getDIEForOffset(Pair.first);
447       if (Die)
448         continue;
449       Success = false;
450       OS << "error: invalid DIE reference " << format("0x%08" PRIx64, Pair.first)
451          << ". Offset is in between DIEs:\n";
452       for (auto Offset: Pair.second) {
453         auto ReferencingDie = DCtx.getDIEForOffset(Offset);
454         ReferencingDie.dump(OS, 0);
455         OS << "\n";
456       }
457       OS << "\n";
458     }
459     return Success;
460   }
461
462   bool HandleDebugLine() {
463     std::map<uint64_t, DWARFDie> StmtListToDie;
464     bool Success = true;
465     OS << "Verifying .debug_line...\n";
466     for (const auto &CU : DCtx.compile_units()) {
467       uint32_t LineTableOffset = 0;
468       auto CUDie = CU->getUnitDIE();
469       auto StmtFormValue = CUDie.find(DW_AT_stmt_list);
470       if (!StmtFormValue) {
471         // No line table for this compile unit.
472         continue;
473       }
474       // Get the attribute value as a section offset. No need to produce an
475       // error here if the encoding isn't correct because we validate this in
476       // the .debug_info verifier.
477       if (auto StmtSectionOffset = toSectionOffset(StmtFormValue)) {
478         LineTableOffset = *StmtSectionOffset;
479         if (LineTableOffset >= DCtx.getLineSection().Data.size()) {
480           // Make sure we don't get a valid line table back if the offset
481           // is wrong.
482           assert(DCtx.getLineTableForUnit(CU.get()) == nullptr);
483           // Skip this line table as it isn't valid. No need to create an error
484           // here because we validate this in the .debug_info verifier.
485           continue;
486         } else {
487           auto Iter = StmtListToDie.find(LineTableOffset);
488           if (Iter != StmtListToDie.end()) {
489             Success = false;
490             OS << "error: two compile unit DIEs, "
491                << format("0x%08" PRIx32, Iter->second.getOffset()) << " and "
492                << format("0x%08" PRIx32, CUDie.getOffset())
493                << ", have the same DW_AT_stmt_list section offset:\n";
494             Iter->second.dump(OS, 0);
495             CUDie.dump(OS, 0);
496             OS << '\n';
497             // Already verified this line table before, no need to do it again.
498             continue;
499           }
500           StmtListToDie[LineTableOffset] = CUDie;
501         }
502       }
503       auto LineTable = DCtx.getLineTableForUnit(CU.get());
504       if (!LineTable) {
505         Success = false;
506         OS << "error: .debug_line[" << format("0x%08" PRIx32, LineTableOffset)
507            << "] was not able to be parsed for CU:\n";
508         CUDie.dump(OS, 0);
509         OS << '\n';
510         continue;
511       }
512       uint32_t MaxFileIndex = LineTable->Prologue.FileNames.size();
513       uint64_t PrevAddress = 0;
514       uint32_t RowIndex = 0;
515       for (const auto &Row : LineTable->Rows) {
516         if (Row.Address < PrevAddress) {
517           Success = false;
518           OS << "error: .debug_line[" << format("0x%08" PRIx32, LineTableOffset)
519              << "] row[" << RowIndex
520              << "] decreases in address from previous row:\n";
521
522           DWARFDebugLine::Row::dumpTableHeader(OS);
523           if (RowIndex > 0)
524             LineTable->Rows[RowIndex - 1].dump(OS);
525           Row.dump(OS);
526           OS << '\n';
527         }
528
529         if (Row.File > MaxFileIndex) {
530           Success = false;
531           OS << "error: .debug_line[" << format("0x%08" PRIx32, LineTableOffset)
532              << "][" << RowIndex << "] has invalid file index " << Row.File
533              << " (valid values are [1," << MaxFileIndex << "]):\n";
534           DWARFDebugLine::Row::dumpTableHeader(OS);
535           Row.dump(OS);
536           OS << '\n';
537         }
538         if (Row.EndSequence)
539           PrevAddress = 0;
540         else
541           PrevAddress = Row.Address;
542         ++RowIndex;
543       }
544     }
545     return Success;
546   }
547 };
548   
549 } // anonymous namespace
550
551 bool DWARFContext::verify(raw_ostream &OS, DIDumpType DumpType) {
552   bool Success = true;
553   DWARFVerifier verifier(OS, *this);
554   if (DumpType == DIDT_All || DumpType == DIDT_Info) {
555     if (!verifier.handleDebugInfo())
556       Success = false;
557   }
558   if (DumpType == DIDT_All || DumpType == DIDT_Line) {
559     if (!verifier.handleDebugLine())
560       Success = false;
561   }
562   return Success;
563 }
564 const DWARFUnitIndex &DWARFContext::getCUIndex() {
565   if (CUIndex)
566     return *CUIndex;
567
568   DataExtractor CUIndexData(getCUIndexSection(), isLittleEndian(), 0);
569
570   CUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
571   CUIndex->parse(CUIndexData);
572   return *CUIndex;
573 }
574
575 const DWARFUnitIndex &DWARFContext::getTUIndex() {
576   if (TUIndex)
577     return *TUIndex;
578
579   DataExtractor TUIndexData(getTUIndexSection(), isLittleEndian(), 0);
580
581   TUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_TYPES);
582   TUIndex->parse(TUIndexData);
583   return *TUIndex;
584 }
585
586 DWARFGdbIndex &DWARFContext::getGdbIndex() {
587   if (GdbIndex)
588     return *GdbIndex;
589
590   DataExtractor GdbIndexData(getGdbIndexSection(), true /*LE*/, 0);
591   GdbIndex = llvm::make_unique<DWARFGdbIndex>();
592   GdbIndex->parse(GdbIndexData);
593   return *GdbIndex;
594 }
595
596 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
597   if (Abbrev)
598     return Abbrev.get();
599
600   DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0);
601
602   Abbrev.reset(new DWARFDebugAbbrev());
603   Abbrev->extract(abbrData);
604   return Abbrev.get();
605 }
606
607 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
608   if (AbbrevDWO)
609     return AbbrevDWO.get();
610
611   DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0);
612   AbbrevDWO.reset(new DWARFDebugAbbrev());
613   AbbrevDWO->extract(abbrData);
614   return AbbrevDWO.get();
615 }
616
617 const DWARFDebugLoc *DWARFContext::getDebugLoc() {
618   if (Loc)
619     return Loc.get();
620
621   DataExtractor LocData(getLocSection().Data, isLittleEndian(), 0);
622   Loc.reset(new DWARFDebugLoc(getLocSection().Relocs));
623   // assume all compile units have the same address byte size
624   if (getNumCompileUnits())
625     Loc->parse(LocData, getCompileUnitAtIndex(0)->getAddressByteSize());
626   return Loc.get();
627 }
628
629 const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() {
630   if (LocDWO)
631     return LocDWO.get();
632
633   DataExtractor LocData(getLocDWOSection().Data, isLittleEndian(), 0);
634   LocDWO.reset(new DWARFDebugLocDWO());
635   LocDWO->parse(LocData);
636   return LocDWO.get();
637 }
638
639 const DWARFDebugAranges *DWARFContext::getDebugAranges() {
640   if (Aranges)
641     return Aranges.get();
642
643   Aranges.reset(new DWARFDebugAranges());
644   Aranges->generate(this);
645   return Aranges.get();
646 }
647
648 const DWARFDebugFrame *DWARFContext::getDebugFrame() {
649   if (DebugFrame)
650     return DebugFrame.get();
651
652   // There's a "bug" in the DWARFv3 standard with respect to the target address
653   // size within debug frame sections. While DWARF is supposed to be independent
654   // of its container, FDEs have fields with size being "target address size",
655   // which isn't specified in DWARF in general. It's only specified for CUs, but
656   // .eh_frame can appear without a .debug_info section. Follow the example of
657   // other tools (libdwarf) and extract this from the container (ObjectFile
658   // provides this information). This problem is fixed in DWARFv4
659   // See this dwarf-discuss discussion for more details:
660   // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
661   DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(),
662                                getAddressSize());
663   DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */));
664   DebugFrame->parse(debugFrameData);
665   return DebugFrame.get();
666 }
667
668 const DWARFDebugFrame *DWARFContext::getEHFrame() {
669   if (EHFrame)
670     return EHFrame.get();
671
672   DataExtractor debugFrameData(getEHFrameSection(), isLittleEndian(),
673                                getAddressSize());
674   DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */));
675   DebugFrame->parse(debugFrameData);
676   return DebugFrame.get();
677 }
678
679 const DWARFDebugMacro *DWARFContext::getDebugMacro() {
680   if (Macro)
681     return Macro.get();
682
683   DataExtractor MacinfoData(getMacinfoSection(), isLittleEndian(), 0);
684   Macro.reset(new DWARFDebugMacro());
685   Macro->parse(MacinfoData);
686   return Macro.get();
687 }
688
689 const DWARFLineTable *
690 DWARFContext::getLineTableForUnit(DWARFUnit *U) {
691   if (!Line)
692     Line.reset(new DWARFDebugLine(&getLineSection().Relocs));
693
694   auto UnitDIE = U->getUnitDIE();
695   if (!UnitDIE)
696     return nullptr;
697
698   auto Offset = toSectionOffset(UnitDIE.find(DW_AT_stmt_list));
699   if (!Offset)
700     return nullptr; // No line table for this compile unit.
701
702   uint32_t stmtOffset = *Offset + U->getLineTableOffset();
703   // See if the line table is cached.
704   if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
705     return lt;
706
707   // Make sure the offset is good before we try to parse.
708   if (stmtOffset >= U->getLineSection().size())
709     return nullptr;  
710
711   // We have to parse it first.
712   DataExtractor lineData(U->getLineSection(), isLittleEndian(),
713                          U->getAddressByteSize());
714   return Line->getOrParseLineTable(lineData, stmtOffset);
715 }
716
717 void DWARFContext::parseCompileUnits() {
718   CUs.parse(*this, getInfoSection());
719 }
720
721 void DWARFContext::parseTypeUnits() {
722   if (!TUs.empty())
723     return;
724   for (const auto &I : getTypesSections()) {
725     TUs.emplace_back();
726     TUs.back().parse(*this, I.second);
727   }
728 }
729
730 void DWARFContext::parseDWOCompileUnits() {
731   DWOCUs.parseDWO(*this, getInfoDWOSection());
732 }
733
734 void DWARFContext::parseDWOTypeUnits() {
735   if (!DWOTUs.empty())
736     return;
737   for (const auto &I : getTypesDWOSections()) {
738     DWOTUs.emplace_back();
739     DWOTUs.back().parseDWO(*this, I.second);
740   }
741 }
742
743 DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
744   parseCompileUnits();
745   return CUs.getUnitForOffset(Offset);
746 }
747
748 DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
749   // First, get the offset of the compile unit.
750   uint32_t CUOffset = getDebugAranges()->findAddress(Address);
751   // Retrieve the compile unit.
752   return getCompileUnitForOffset(CUOffset);
753 }
754
755 static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU,
756                                                   uint64_t Address,
757                                                   FunctionNameKind Kind,
758                                                   std::string &FunctionName,
759                                                   uint32_t &StartLine) {
760   // The address may correspond to instruction in some inlined function,
761   // so we have to build the chain of inlined functions and take the
762   // name of the topmost function in it.
763   SmallVector<DWARFDie, 4> InlinedChain;
764   CU->getInlinedChainForAddress(Address, InlinedChain);
765   if (InlinedChain.empty())
766     return false;
767
768   const DWARFDie &DIE = InlinedChain[0];
769   bool FoundResult = false;
770   const char *Name = nullptr;
771   if (Kind != FunctionNameKind::None && (Name = DIE.getSubroutineName(Kind))) {
772     FunctionName = Name;
773     FoundResult = true;
774   }
775   if (auto DeclLineResult = DIE.getDeclLine()) {
776     StartLine = DeclLineResult;
777     FoundResult = true;
778   }
779
780   return FoundResult;
781 }
782
783 DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
784                                                DILineInfoSpecifier Spec) {
785   DILineInfo Result;
786
787   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
788   if (!CU)
789     return Result;
790   getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind,
791                                         Result.FunctionName,
792                                         Result.StartLine);
793   if (Spec.FLIKind != FileLineInfoKind::None) {
794     if (const DWARFLineTable *LineTable = getLineTableForUnit(CU))
795       LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
796                                            Spec.FLIKind, Result);
797   }
798   return Result;
799 }
800
801 DILineInfoTable
802 DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
803                                          DILineInfoSpecifier Spec) {
804   DILineInfoTable  Lines;
805   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
806   if (!CU)
807     return Lines;
808
809   std::string FunctionName = "<invalid>";
810   uint32_t StartLine = 0;
811   getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind, FunctionName,
812                                         StartLine);
813
814   // If the Specifier says we don't need FileLineInfo, just
815   // return the top-most function at the starting address.
816   if (Spec.FLIKind == FileLineInfoKind::None) {
817     DILineInfo Result;
818     Result.FunctionName = FunctionName;
819     Result.StartLine = StartLine;
820     Lines.push_back(std::make_pair(Address, Result));
821     return Lines;
822   }
823
824   const DWARFLineTable *LineTable = getLineTableForUnit(CU);
825
826   // Get the index of row we're looking for in the line table.
827   std::vector<uint32_t> RowVector;
828   if (!LineTable->lookupAddressRange(Address, Size, RowVector))
829     return Lines;
830
831   for (uint32_t RowIndex : RowVector) {
832     // Take file number and line/column from the row.
833     const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
834     DILineInfo Result;
835     LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(),
836                                   Spec.FLIKind, Result.FileName);
837     Result.FunctionName = FunctionName;
838     Result.Line = Row.Line;
839     Result.Column = Row.Column;
840     Result.StartLine = StartLine;
841     Lines.push_back(std::make_pair(Row.Address, Result));
842   }
843
844   return Lines;
845 }
846
847 DIInliningInfo
848 DWARFContext::getInliningInfoForAddress(uint64_t Address,
849                                         DILineInfoSpecifier Spec) {
850   DIInliningInfo InliningInfo;
851
852   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
853   if (!CU)
854     return InliningInfo;
855
856   const DWARFLineTable *LineTable = nullptr;
857   SmallVector<DWARFDie, 4> InlinedChain;
858   CU->getInlinedChainForAddress(Address, InlinedChain);
859   if (InlinedChain.size() == 0) {
860     // If there is no DIE for address (e.g. it is in unavailable .dwo file),
861     // try to at least get file/line info from symbol table.
862     if (Spec.FLIKind != FileLineInfoKind::None) {
863       DILineInfo Frame;
864       LineTable = getLineTableForUnit(CU);
865       if (LineTable &&
866           LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
867                                                Spec.FLIKind, Frame))
868         InliningInfo.addFrame(Frame);
869     }
870     return InliningInfo;
871   }
872
873   uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0;
874   for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) {
875     DWARFDie &FunctionDIE = InlinedChain[i];
876     DILineInfo Frame;
877     // Get function name if necessary.
878     if (const char *Name = FunctionDIE.getSubroutineName(Spec.FNKind))
879       Frame.FunctionName = Name;
880     if (auto DeclLineResult = FunctionDIE.getDeclLine())
881       Frame.StartLine = DeclLineResult;
882     if (Spec.FLIKind != FileLineInfoKind::None) {
883       if (i == 0) {
884         // For the topmost frame, initialize the line table of this
885         // compile unit and fetch file/line info from it.
886         LineTable = getLineTableForUnit(CU);
887         // For the topmost routine, get file/line info from line table.
888         if (LineTable)
889           LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
890                                                Spec.FLIKind, Frame);
891       } else {
892         // Otherwise, use call file, call line and call column from
893         // previous DIE in inlined chain.
894         if (LineTable)
895           LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(),
896                                         Spec.FLIKind, Frame.FileName);
897         Frame.Line = CallLine;
898         Frame.Column = CallColumn;
899         Frame.Discriminator = CallDiscriminator;
900       }
901       // Get call file/line/column of a current DIE.
902       if (i + 1 < n) {
903         FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn,
904                                    CallDiscriminator);
905       }
906     }
907     InliningInfo.addFrame(Frame);
908   }
909   return InliningInfo;
910 }
911
912 std::shared_ptr<DWARFContext>
913 DWARFContext::getDWOContext(StringRef AbsolutePath) {
914   if (auto S = DWP.lock()) {
915     DWARFContext *Ctxt = S->Context.get();
916     return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
917   }
918
919   std::weak_ptr<DWOFile> *Entry = &DWOFiles[AbsolutePath];
920
921   if (auto S = Entry->lock()) {
922     DWARFContext *Ctxt = S->Context.get();
923     return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
924   }
925
926   SmallString<128> DWPName;
927   Expected<OwningBinary<ObjectFile>> Obj = [&] {
928     if (!CheckedForDWP) {
929       (getFileName() + ".dwp").toVector(DWPName);
930       auto Obj = object::ObjectFile::createObjectFile(DWPName);
931       if (Obj) {
932         Entry = &DWP;
933         return Obj;
934       } else {
935         CheckedForDWP = true;
936         // TODO: Should this error be handled (maybe in a high verbosity mode)
937         // before falling back to .dwo files?
938         consumeError(Obj.takeError());
939       }
940     }
941
942     return object::ObjectFile::createObjectFile(AbsolutePath);
943   }();
944
945   if (!Obj) {
946     // TODO: Actually report errors helpfully.
947     consumeError(Obj.takeError());
948     return nullptr;
949   }
950
951   auto S = std::make_shared<DWOFile>();
952   S->File = std::move(Obj.get());
953   S->Context = llvm::make_unique<DWARFContextInMemory>(*S->File.getBinary());
954   *Entry = S;
955   auto *Ctxt = S->Context.get();
956   return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
957 }
958
959 static Error createError(const Twine &Reason, llvm::Error E) {
960   return make_error<StringError>(Reason + toString(std::move(E)),
961                                  inconvertibleErrorCode());
962 }
963
964 /// SymInfo contains information about symbol: it's address
965 /// and section index which is -1LL for absolute symbols.
966 struct SymInfo {
967   uint64_t Address;
968   uint64_t SectionIndex;
969 };
970
971 /// Returns the address of symbol relocation used against and a section index.
972 /// Used for futher relocations computation. Symbol's section load address is
973 static Expected<SymInfo> getSymbolInfo(const object::ObjectFile &Obj,
974                                        const RelocationRef &Reloc,
975                                        const LoadedObjectInfo *L,
976                                        std::map<SymbolRef, SymInfo> &Cache) {
977   SymInfo Ret = {0, (uint64_t)-1LL};
978   object::section_iterator RSec = Obj.section_end();
979   object::symbol_iterator Sym = Reloc.getSymbol();
980
981   std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end();
982   // First calculate the address of the symbol or section as it appears
983   // in the object file
984   if (Sym != Obj.symbol_end()) {
985     bool New;
986     std::tie(CacheIt, New) = Cache.insert({*Sym, {0, 0}});
987     if (!New)
988       return CacheIt->second;
989
990     Expected<uint64_t> SymAddrOrErr = Sym->getAddress();
991     if (!SymAddrOrErr)
992       return createError("error: failed to compute symbol address: ",
993                          SymAddrOrErr.takeError());
994
995     // Also remember what section this symbol is in for later
996     auto SectOrErr = Sym->getSection();
997     if (!SectOrErr)
998       return createError("error: failed to get symbol section: ",
999                          SectOrErr.takeError());
1000
1001     RSec = *SectOrErr;
1002     Ret.Address = *SymAddrOrErr;
1003   } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
1004     RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
1005     Ret.Address = RSec->getAddress();
1006   }
1007
1008   if (RSec != Obj.section_end())
1009     Ret.SectionIndex = RSec->getIndex();
1010
1011   // If we are given load addresses for the sections, we need to adjust:
1012   // SymAddr = (Address of Symbol Or Section in File) -
1013   //           (Address of Section in File) +
1014   //           (Load Address of Section)
1015   // RSec is now either the section being targeted or the section
1016   // containing the symbol being targeted. In either case,
1017   // we need to perform the same computation.
1018   if (L && RSec != Obj.section_end())
1019     if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec))
1020       Ret.Address += SectionLoadAddress - RSec->getAddress();
1021
1022   if (CacheIt != Cache.end())
1023     CacheIt->second = Ret;
1024
1025   return Ret;
1026 }
1027
1028 static bool isRelocScattered(const object::ObjectFile &Obj,
1029                              const RelocationRef &Reloc) {
1030   const MachOObjectFile *MachObj = dyn_cast<MachOObjectFile>(&Obj);
1031   if (!MachObj)
1032     return false;
1033   // MachO also has relocations that point to sections and
1034   // scattered relocations.
1035   auto RelocInfo = MachObj->getRelocation(Reloc.getRawDataRefImpl());
1036   return MachObj->isRelocationScattered(RelocInfo);
1037 }
1038
1039 Error DWARFContextInMemory::maybeDecompress(const SectionRef &Sec,
1040                                             StringRef Name, StringRef &Data) {
1041   if (!Decompressor::isCompressed(Sec))
1042     return Error::success();
1043
1044   Expected<Decompressor> Decompressor =
1045       Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8);
1046   if (!Decompressor)
1047     return Decompressor.takeError();
1048
1049   SmallString<32> Out;
1050   if (auto Err = Decompressor->resizeAndDecompress(Out))
1051     return Err;
1052
1053   UncompressedSections.emplace_back(std::move(Out));
1054   Data = UncompressedSections.back();
1055
1056   return Error::success();
1057 }
1058
1059 DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
1060                                            const LoadedObjectInfo *L)
1061     : FileName(Obj.getFileName()), IsLittleEndian(Obj.isLittleEndian()),
1062       AddressSize(Obj.getBytesInAddress()) {
1063   for (const SectionRef &Section : Obj.sections()) {
1064     StringRef name;
1065     Section.getName(name);
1066     // Skip BSS and Virtual sections, they aren't interesting.
1067     bool IsBSS = Section.isBSS();
1068     if (IsBSS)
1069       continue;
1070     bool IsVirtual = Section.isVirtual();
1071     if (IsVirtual)
1072       continue;
1073     StringRef data;
1074
1075     section_iterator RelocatedSection = Section.getRelocatedSection();
1076     // Try to obtain an already relocated version of this section.
1077     // Else use the unrelocated section from the object file. We'll have to
1078     // apply relocations ourselves later.
1079     if (!L || !L->getLoadedSectionContents(*RelocatedSection, data))
1080       Section.getContents(data);
1081
1082     if (auto Err = maybeDecompress(Section, name, data)) {
1083       errs() << "error: failed to decompress '" + name + "', " +
1084                     toString(std::move(Err))
1085              << '\n';
1086       continue;
1087     }
1088
1089     // Compressed sections names in GNU style starts from ".z",
1090     // at this point section is decompressed and we drop compression prefix.
1091     name = name.substr(
1092         name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes.
1093
1094     if (StringRef *SectionData = MapSectionToMember(name)) {
1095       *SectionData = data;
1096       if (name == "debug_ranges") {
1097         // FIXME: Use the other dwo range section when we emit it.
1098         RangeDWOSection.Data = data;
1099       }
1100     } else if (name == "debug_types") {
1101       // Find debug_types data by section rather than name as there are
1102       // multiple, comdat grouped, debug_types sections.
1103       TypesSections[Section].Data = data;
1104     } else if (name == "debug_types.dwo") {
1105       TypesDWOSections[Section].Data = data;
1106     }
1107
1108     if (RelocatedSection == Obj.section_end())
1109       continue;
1110
1111     StringRef RelSecName;
1112     StringRef RelSecData;
1113     RelocatedSection->getName(RelSecName);
1114
1115     // If the section we're relocating was relocated already by the JIT,
1116     // then we used the relocated version above, so we do not need to process
1117     // relocations for it now.
1118     if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))
1119       continue;
1120
1121     // In Mach-o files, the relocations do not need to be applied if
1122     // there is no load offset to apply. The value read at the
1123     // relocation point already factors in the section address
1124     // (actually applying the relocations will produce wrong results
1125     // as the section address will be added twice).
1126     if (!L && isa<MachOObjectFile>(&Obj))
1127       continue;
1128
1129     RelSecName = RelSecName.substr(
1130         RelSecName.find_first_not_of("._")); // Skip . and _ prefixes.
1131
1132     // TODO: Add support for relocations in other sections as needed.
1133     // Record relocations for the debug_info and debug_line sections.
1134     RelocAddrMap *Map =
1135         StringSwitch<RelocAddrMap *>(RelSecName)
1136             .Case("debug_info", &InfoSection.Relocs)
1137             .Case("debug_loc", &LocSection.Relocs)
1138             .Case("debug_info.dwo", &InfoDWOSection.Relocs)
1139             .Case("debug_line", &LineSection.Relocs)
1140             .Case("debug_ranges", &RangeSection.Relocs)
1141             .Case("debug_addr", &AddrSection.Relocs)
1142             .Case("apple_names", &AppleNamesSection.Relocs)
1143             .Case("apple_types", &AppleTypesSection.Relocs)
1144             .Case("apple_namespaces", &AppleNamespacesSection.Relocs)
1145             .Case("apple_namespac", &AppleNamespacesSection.Relocs)
1146             .Case("apple_objc", &AppleObjCSection.Relocs)
1147             .Default(nullptr);
1148     if (!Map) {
1149       // Find debug_types relocs by section rather than name as there are
1150       // multiple, comdat grouped, debug_types sections.
1151       if (RelSecName == "debug_types")
1152         Map = &TypesSections[*RelocatedSection].Relocs;
1153       else if (RelSecName == "debug_types.dwo")
1154         Map = &TypesDWOSections[*RelocatedSection].Relocs;
1155       else
1156         continue;
1157     }
1158
1159     if (Section.relocation_begin() == Section.relocation_end())
1160       continue;
1161
1162     // Symbol to [address, section index] cache mapping.
1163     std::map<SymbolRef, SymInfo> AddrCache;
1164     for (const RelocationRef &Reloc : Section.relocations()) {
1165       // FIXME: it's not clear how to correctly handle scattered
1166       // relocations.
1167       if (isRelocScattered(Obj, Reloc))
1168         continue;
1169
1170       Expected<SymInfo> SymInfoOrErr = getSymbolInfo(Obj, Reloc, L, AddrCache);
1171       if (!SymInfoOrErr) {
1172         errs() << toString(SymInfoOrErr.takeError()) << '\n';
1173         continue;
1174       }
1175
1176       object::RelocVisitor V(Obj);
1177       uint64_t Val = V.visit(Reloc.getType(), Reloc, SymInfoOrErr->Address);
1178       if (V.error()) {
1179         SmallString<32> Name;
1180         Reloc.getTypeName(Name);
1181         errs() << "error: failed to compute relocation: " << Name << "\n";
1182         continue;
1183       }
1184       llvm::RelocAddrEntry Rel = {SymInfoOrErr->SectionIndex, Val};
1185       Map->insert({Reloc.getOffset(), Rel});
1186     }
1187   }
1188 }
1189
1190 DWARFContextInMemory::DWARFContextInMemory(
1191     const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, uint8_t AddrSize,
1192     bool isLittleEndian)
1193     : IsLittleEndian(isLittleEndian), AddressSize(AddrSize) {
1194   for (const auto &SecIt : Sections) {
1195     if (StringRef *SectionData = MapSectionToMember(SecIt.first()))
1196       *SectionData = SecIt.second->getBuffer();
1197   }
1198 }
1199
1200 StringRef *DWARFContextInMemory::MapSectionToMember(StringRef Name) {
1201   return StringSwitch<StringRef *>(Name)
1202       .Case("debug_info", &InfoSection.Data)
1203       .Case("debug_abbrev", &AbbrevSection)
1204       .Case("debug_loc", &LocSection.Data)
1205       .Case("debug_line", &LineSection.Data)
1206       .Case("debug_aranges", &ARangeSection)
1207       .Case("debug_frame", &DebugFrameSection)
1208       .Case("eh_frame", &EHFrameSection)
1209       .Case("debug_str", &StringSection)
1210       .Case("debug_ranges", &RangeSection.Data)
1211       .Case("debug_macinfo", &MacinfoSection)
1212       .Case("debug_pubnames", &PubNamesSection)
1213       .Case("debug_pubtypes", &PubTypesSection)
1214       .Case("debug_gnu_pubnames", &GnuPubNamesSection)
1215       .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
1216       .Case("debug_info.dwo", &InfoDWOSection.Data)
1217       .Case("debug_abbrev.dwo", &AbbrevDWOSection)
1218       .Case("debug_loc.dwo", &LocDWOSection.Data)
1219       .Case("debug_line.dwo", &LineDWOSection.Data)
1220       .Case("debug_str.dwo", &StringDWOSection)
1221       .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
1222       .Case("debug_addr", &AddrSection.Data)
1223       .Case("apple_names", &AppleNamesSection.Data)
1224       .Case("apple_types", &AppleTypesSection.Data)
1225       .Case("apple_namespaces", &AppleNamespacesSection.Data)
1226       .Case("apple_namespac", &AppleNamespacesSection.Data)
1227       .Case("apple_objc", &AppleObjCSection.Data)
1228       .Case("debug_cu_index", &CUIndexSection)
1229       .Case("debug_tu_index", &TUIndexSection)
1230       .Case("gdb_index", &GdbIndexSection)
1231       // Any more debug info sections go here.
1232       .Default(nullptr);
1233 }
1234
1235 void DWARFContextInMemory::anchor() {}