LLVM  3.7.0
DWARFContext.cpp
Go to the documentation of this file.
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 
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/Support/Dwarf.h"
17 #include "llvm/Support/Format.h"
18 #include "llvm/Support/Path.h"
20 #include <algorithm>
21 using namespace llvm;
22 using namespace dwarf;
23 using namespace object;
24 
25 #define DEBUG_TYPE "dwarf"
26 
30 
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 
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 
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);
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 
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 
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 
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 
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 
297  if (Aranges)
298  return Aranges.get();
299 
300  Aranges.reset(new DWARFDebugAranges());
301  Aranges->generate(this);
302  return Aranges.get();
303 }
304 
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 
325 const DWARFLineTable *
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 =
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 
347 void DWARFContext::parseCompileUnits() {
348  CUs.parse(*this, getInfoSection());
349 }
350 
351 void 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 
360 void DWARFContext::parseDWOCompileUnits() {
361  DWOCUs.parseDWO(*this, getInfoDWOSection());
362 }
363 
364 void 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 
373 DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
374  parseCompileUnits();
375  return CUs.getUnitForOffset(Offset);
376 }
377 
378 DWARFCompileUnit *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 
385 static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address,
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 
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 
423 DWARFContext::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 
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 
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 
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 =
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();
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()) {
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 
743 void DWARFContextInMemory::anchor() { }
RelocToApply visit(uint32_t RelocType, RelocationRef R, uint64_t Value=0)
Definition: RelocVisitor.h:52
void push_back(const T &Elt)
Definition: SmallVector.h:222
std::error_code getError() const
Definition: ErrorOr.h:178
Represents either an error or a value T.
Definition: ErrorOr.h:82
const DWARFDebugFrame * getDebugFrame()
Get a pointer to the parsed frame information object.
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
std::string FileName
Definition: DIContext.h:32
A parsed .debug_frame section.
size_t size() const
size - Get the string size.
Definition: StringRef.h:113
const DWARFDebugLocDWO * getDebugLocDWO()
Get a pointer to the parsed DebugLoc object.
const DWARFDebugLoc * getDebugLoc()
Get a pointer to the parsed DebugLoc object.
const char * getSubroutineName(const DWARFUnit *U, DINameKind Kind) const
If a DIE represents a subprogram (or inlined subroutine), returns its mangled name (or short name...
virtual bool getLoadedSectionContents(StringRef Name, StringRef &Data) const
If conveniently available, return the content of the given Section.
Definition: DIContext.h:165
RelocAddrMap Relocs
Definition: DWARFSection.h:20
static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address, FunctionNameKind Kind, std::string &FunctionName)
bool getFileNameByIndex(uint64_t FileIndex, const char *CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, std::string &Result) const
StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:405
This class is the base class for all object file types.
Definition: ObjectFile.h:176
void addFrame(const DILineInfo &Frame)
Definition: DIContext.h:63
const DWARFDebugAbbrev * getDebugAbbrevDWO()
Get a pointer to the parsed dwo abbreviations object.
DINameKind
A DINameKind is passed to name search methods to specify a preference regarding the type of name reso...
Definition: DIContext.h:70
void generate(DWARFContext *CTX)
bool isValidOffset(uint32_t offset) const
Test the validity of offset.
StringSwitch & Case(const char(&S)[N], const T &Value)
Definition: StringSwitch.h:55
virtual uint64_t getSectionLoadAddress(StringRef Name) const =0
Obtain the Load Address of a section by Name.
static void dumpAccelSection(raw_ostream &OS, StringRef Name, const DWARFSection &Section, StringRef StringSection, bool LittleEndian)
DILineInfo - a format-neutral container for source line information.
Definition: DIContext.h:31
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:169
const char * GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage)
Definition: Dwarf.cpp:554
uint32_t getU32(uint32_t *offset_ptr) const
Extract a uint32_t value from *offset_ptr.
void dump(raw_ostream &OS, DIDumpType DumpType=DIDT_All) override
const char * getCompilationDir()
Definition: DWARFUnit.cpp:123
FunctionNameKind FNKind
Definition: DIContext.h:79
FileLineInfoKind FLIKind
Definition: DIContext.h:78
This is a value type class that represents a single relocation in the list of relocations in the obje...
Definition: ObjectFile.h:40
Decsribes an entry of the various gnu_pub* debug sections.
Definition: Dwarf.h:622
const DWARFDebugAranges * getDebugAranges()
Get a pointer to the parsed DebugAranges object.
DWARFDebugInfoEntryInlinedChain getInlinedChainForAddress(uint64_t Address)
getInlinedChainForAddress - fetches inlined chain for a given address.
Definition: DWARFUnit.cpp:355
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:25
const DWARFDebugAbbrev * getDebugAbbrev()
Get a pointer to the parsed DebugAbbrev object.
bool extract(DataExtractor data, uint32_t *offset_ptr)
SmallVector< DWARFDebugInfoEntryMinimal, 4 > DIEs
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:111
bool isAvailable()
Definition: Compression.cpp:48
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:42
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
uint32_t Column
Definition: DIContext.h:35
void dump(raw_ostream &OS) const
const char * getCStr(uint32_t *offset_ptr) const
Extract a C string from *offset_ptr.
DWARFDebugInfoEntryMinimal - A DIE with only the minimum required data.
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
DILineInfoSpecifier - controls which fields of DILineInfo container should be filled with data...
Definition: DIContext.h:74
uint8_t getU8(uint32_t *offset_ptr) const
Extract a uint8_t value from *offset_ptr.
DIInliningInfo - a format-neutral container for inlined code description.
Definition: DIContext.h:52
DIDumpType
Selects which debug sections get dumped.
Definition: DIContext.h:87
DILineInfo getLineInfoForAddress(uint64_t Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
static void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data, bool LittleEndian, bool GnuStyle)
bool parse(DataExtractor debug_line_data, uint32_t *offset_ptr)
void dump(raw_ostream &OS) const
bool parse(DataExtractor debug_line_data, const RelocAddrMap *RMap, uint32_t *offset_ptr)
Parse prologue and all rows.
section_iterator_range sections() const
Definition: ObjectFile.h:253
bool lookupAddressRange(uint64_t address, uint64_t size, std::vector< uint32_t > &result) const
size_t find_first_not_of(char C, size_t From=0) const
Find the first character in the string that is not C or npos if not found.
Definition: StringRef.cpp:212
void dump(raw_ostream &OS) const
uint64_t getU64(uint32_t *offset_ptr) const
Extract a uint64_t value from *offset_ptr.
basic_symbol_iterator symbol_end() const
Definition: SymbolicFile.h:139
DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:215
uint32_t Line
Definition: DIContext.h:34
static bool consumeCompressedDebugSectionHeader(StringRef &data, uint64_t &OriginalSize)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
DIInliningInfo getInliningInfoForAddress(uint64_t Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
std::string FunctionName
Definition: DIContext.h:33
bool extract(DataExtractor data, uint32_t *offset_ptr)
uint16_t getU16(uint32_t *offset_ptr) const
Extract a uint16_t value from *offset_ptr.
uint64_t getAttributeValueAsSectionOffset(const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const
R Default(const T &Value) const
Definition: StringSwitch.h:111
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:123
An inferface for inquiring the load address of a loaded object file to be used by the DIContext imple...
Definition: DIContext.h:142
void getCallerFrame(const DWARFUnit *U, uint32_t &CallFile, uint32_t &CallLine, uint32_t &CallColumn) const
Retrieves values of DW_AT_call_file, DW_AT_call_line and DW_AT_call_column from DIE (or zeroes if the...
DWARFDebugLine::LineTable DWARFLineTable
DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
DILineInfoSpecifier::FunctionNameKind FunctionNameKind
const char * GDBIndexEntryKindString(GDBIndexEntryKind Kind)
Definition: Dwarf.cpp:532
Status uncompress(StringRef InputBuffer, SmallVectorImpl< char > &UncompressedBuffer, size_t UncompressedSize)
Definition: Compression.cpp:65
virtual section_iterator section_end() const =0
void dump(raw_ostream &OS) const
#define I(x, y, z)
Definition: MD5.cpp:54
DWARFContextInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L=nullptr)
void size_t size
bool getFileLineInfoForAddress(uint64_t Address, const char *CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, DILineInfo &Result) const
uint8_t getAddressByteSize() const
Definition: DWARFUnit.h:191
const ARM::ArchExtKind Kind
static const char * name
const DWARFDebugLine::LineTable * getLineTableForUnit(DWARFUnit *cu)
Get a pointer to a parsed line table corresponding to a compile unit.
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:38
#define DEBUG(X)
Definition: Debug.h:92
const DWARFDebugInfoEntryMinimal * getUnitDIE(bool ExtractUnitDIEOnly=true)
Definition: DWARFUnit.h:198
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
ErrorOr< uint64_t > getAddress() const
Returns the symbol virtual address (i.e.
Definition: ObjectFile.h:310
std::error_code getSection(section_iterator &Result) const
Get section this symbol is defined in reference to.
Definition: ObjectFile.h:326
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:69
Base class for object file relocation visitors.
Definition: RelocVisitor.h:44
DWARFDebugInfoEntryInlinedChain - represents a chain of inlined_subroutine DIEs, (possibly ending wit...