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