LLVM API Documentation

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