1 //===-- DWARFContext.cpp --------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "DWARFContext.h"
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/StringSwitch.h"
13 #include "llvm/Support/Dwarf.h"
14 #include "llvm/Support/Format.h"
15 #include "llvm/Support/Path.h"
16 #include "llvm/Support/raw_ostream.h"
19 using namespace dwarf;
21 typedef DWARFDebugLine::LineTable DWARFLineTable;
23 void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
24 if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) {
25 OS << ".debug_abbrev contents:\n";
26 getDebugAbbrev()->dump(OS);
29 if (DumpType == DIDT_All || DumpType == DIDT_Info) {
30 OS << "\n.debug_info contents:\n";
31 for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i)
32 getCompileUnitAtIndex(i)->dump(OS);
35 if (DumpType == DIDT_All || DumpType == DIDT_Frames) {
36 OS << "\n.debug_frame contents:\n";
37 getDebugFrame()->dump(OS);
41 if (DumpType == DIDT_All || DumpType == DIDT_Aranges) {
42 OS << "\n.debug_aranges contents:\n";
43 DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
44 DWARFDebugArangeSet set;
45 while (set.extract(arangesData, &offset))
49 uint8_t savedAddressByteSize = 0;
50 if (DumpType == DIDT_All || DumpType == DIDT_Line) {
51 OS << "\n.debug_line contents:\n";
52 for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i) {
53 DWARFCompileUnit *cu = getCompileUnitAtIndex(i);
54 savedAddressByteSize = cu->getAddressByteSize();
56 cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(cu, DW_AT_stmt_list,
58 if (stmtOffset != -1U) {
59 DataExtractor lineData(getLineSection(), isLittleEndian(),
60 savedAddressByteSize);
61 DWARFDebugLine::DumpingState state(OS);
62 DWARFDebugLine::parseStatementTable(lineData, &lineRelocMap(), &stmtOffset, state);
67 if (DumpType == DIDT_All || DumpType == DIDT_Str) {
68 OS << "\n.debug_str contents:\n";
69 DataExtractor strData(getStringSection(), isLittleEndian(), 0);
71 uint32_t strOffset = 0;
72 while (const char *s = strData.getCStr(&offset)) {
73 OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
78 if (DumpType == DIDT_All || DumpType == DIDT_Ranges) {
79 OS << "\n.debug_ranges contents:\n";
80 // In fact, different compile units may have different address byte
81 // sizes, but for simplicity we just use the address byte size of the last
82 // compile unit (there is no easy and fast way to associate address range
83 // list and the compile unit it describes).
84 DataExtractor rangesData(getRangeSection(), isLittleEndian(),
85 savedAddressByteSize);
87 DWARFDebugRangeList rangeList;
88 while (rangeList.extract(rangesData, &offset))
92 if (DumpType == DIDT_All || DumpType == DIDT_Pubnames) {
93 OS << "\n.debug_pubnames contents:\n";
94 DataExtractor pubNames(getPubNamesSection(), isLittleEndian(), 0);
96 OS << "Length: " << pubNames.getU32(&offset) << "\n";
97 OS << "Version: " << pubNames.getU16(&offset) << "\n";
98 OS << "Offset in .debug_info: " << pubNames.getU32(&offset) << "\n";
99 OS << "Size: " << pubNames.getU32(&offset) << "\n";
100 OS << "\n Offset Name\n";
101 while (offset < getPubNamesSection().size()) {
102 uint32_t n = pubNames.getU32(&offset);
105 OS << format("%8x ", n);
106 OS << pubNames.getCStr(&offset) << "\n";
110 if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo) {
111 OS << "\n.debug_abbrev.dwo contents:\n";
112 getDebugAbbrevDWO()->dump(OS);
115 if (DumpType == DIDT_All || DumpType == DIDT_InfoDwo) {
116 OS << "\n.debug_info.dwo contents:\n";
117 for (unsigned i = 0, e = getNumDWOCompileUnits(); i != e; ++i)
118 getDWOCompileUnitAtIndex(i)->dump(OS);
121 if (DumpType == DIDT_All || DumpType == DIDT_StrDwo) {
122 OS << "\n.debug_str.dwo contents:\n";
123 DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
125 uint32_t strDWOOffset = 0;
126 while (const char *s = strDWOData.getCStr(&offset)) {
127 OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
128 strDWOOffset = offset;
132 if (DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) {
133 OS << "\n.debug_str_offsets.dwo contents:\n";
134 DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(), 0);
136 while (offset < getStringOffsetDWOSection().size()) {
137 OS << format("0x%8.8x: ", offset);
138 OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
143 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
147 DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0);
149 Abbrev.reset(new DWARFDebugAbbrev());
150 Abbrev->parse(abbrData);
154 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
156 return AbbrevDWO.get();
158 DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0);
159 AbbrevDWO.reset(new DWARFDebugAbbrev());
160 AbbrevDWO->parse(abbrData);
161 return AbbrevDWO.get();
164 const DWARFDebugAranges *DWARFContext::getDebugAranges() {
166 return Aranges.get();
168 DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
170 Aranges.reset(new DWARFDebugAranges());
171 Aranges->extract(arangesData);
172 // Generate aranges from DIEs: even if .debug_aranges section is present,
173 // it may describe only a small subset of compilation units, so we need to
174 // manually build aranges for the rest of them.
175 Aranges->generate(this);
176 return Aranges.get();
179 const DWARFDebugFrame *DWARFContext::getDebugFrame() {
181 return DebugFrame.get();
183 // There's a "bug" in the DWARFv3 standard with respect to the target address
184 // size within debug frame sections. While DWARF is supposed to be independent
185 // of its container, FDEs have fields with size being "target address size",
186 // which isn't specified in DWARF in general. It's only specified for CUs, but
187 // .eh_frame can appear without a .debug_info section. Follow the example of
188 // other tools (libdwarf) and extract this from the container (ObjectFile
189 // provides this information). This problem is fixed in DWARFv4
190 // See this dwarf-discuss discussion for more details:
191 // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
192 DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(),
194 DebugFrame.reset(new DWARFDebugFrame());
195 DebugFrame->parse(debugFrameData);
196 return DebugFrame.get();
199 const DWARFLineTable *
200 DWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) {
202 Line.reset(new DWARFDebugLine(&lineRelocMap()));
204 unsigned stmtOffset =
205 cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(cu, DW_AT_stmt_list,
207 if (stmtOffset == -1U)
208 return 0; // No line table for this compile unit.
210 // See if the line table is cached.
211 if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
214 // We have to parse it first.
215 DataExtractor lineData(getLineSection(), isLittleEndian(),
216 cu->getAddressByteSize());
217 return Line->getOrParseLineTable(lineData, stmtOffset);
220 void DWARFContext::parseCompileUnits() {
222 const DataExtractor &DIData = DataExtractor(getInfoSection(),
223 isLittleEndian(), 0);
224 while (DIData.isValidOffset(offset)) {
225 CUs.push_back(DWARFCompileUnit(getDebugAbbrev(), getInfoSection(),
226 getAbbrevSection(), getRangeSection(),
227 getStringSection(), StringRef(),
231 if (!CUs.back().extract(DIData, &offset)) {
236 offset = CUs.back().getNextCompileUnitOffset();
240 void DWARFContext::parseDWOCompileUnits() {
242 const DataExtractor &DIData = DataExtractor(getInfoDWOSection(),
243 isLittleEndian(), 0);
244 while (DIData.isValidOffset(offset)) {
245 DWOCUs.push_back(DWARFCompileUnit(getDebugAbbrevDWO(), getInfoDWOSection(),
246 getAbbrevDWOSection(),
247 getRangeDWOSection(),
248 getStringDWOSection(),
249 getStringOffsetDWOSection(),
253 if (!DWOCUs.back().extract(DIData, &offset)) {
258 offset = DWOCUs.back().getNextCompileUnitOffset();
263 struct OffsetComparator {
264 bool operator()(const DWARFCompileUnit &LHS,
265 const DWARFCompileUnit &RHS) const {
266 return LHS.getOffset() < RHS.getOffset();
268 bool operator()(const DWARFCompileUnit &LHS, uint32_t RHS) const {
269 return LHS.getOffset() < RHS;
271 bool operator()(uint32_t LHS, const DWARFCompileUnit &RHS) const {
272 return LHS < RHS.getOffset();
277 DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
281 DWARFCompileUnit *CU = std::lower_bound(CUs.begin(), CUs.end(), Offset,
288 DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
289 // First, get the offset of the compile unit.
290 uint32_t CUOffset = getDebugAranges()->findAddress(Address);
291 // Retrieve the compile unit.
292 return getCompileUnitForOffset(CUOffset);
295 static bool getFileNameForCompileUnit(DWARFCompileUnit *CU,
296 const DWARFLineTable *LineTable,
298 bool NeedsAbsoluteFilePath,
299 std::string &FileName) {
302 !LineTable->getFileNameByIndex(FileIndex, NeedsAbsoluteFilePath,
305 if (NeedsAbsoluteFilePath && sys::path::is_relative(FileName)) {
306 // We may still need to append compilation directory of compile unit.
307 SmallString<16> AbsolutePath;
308 if (const char *CompilationDir = CU->getCompilationDir()) {
309 sys::path::append(AbsolutePath, CompilationDir);
311 sys::path::append(AbsolutePath, FileName);
312 FileName = AbsolutePath.str();
317 static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU,
318 const DWARFLineTable *LineTable,
320 bool NeedsAbsoluteFilePath,
321 std::string &FileName,
322 uint32_t &Line, uint32_t &Column) {
323 if (CU == 0 || LineTable == 0)
325 // Get the index of row we're looking for in the line table.
326 uint32_t RowIndex = LineTable->lookupAddress(Address);
329 // Take file number and line/column from the row.
330 const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
331 if (!getFileNameForCompileUnit(CU, LineTable, Row.File,
332 NeedsAbsoluteFilePath, FileName))
339 DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
340 DILineInfoSpecifier Specifier) {
341 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
344 std::string FileName = "<invalid>";
345 std::string FunctionName = "<invalid>";
348 if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
349 // The address may correspond to instruction in some inlined function,
350 // so we have to build the chain of inlined functions and take the
351 // name of the topmost function in it.
352 const DWARFDebugInfoEntryMinimal::InlinedChain &InlinedChain =
353 CU->getInlinedChainForAddress(Address);
354 if (InlinedChain.size() > 0) {
355 const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain[0];
356 if (const char *Name = TopFunctionDIE.getSubroutineName(CU))
360 if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
361 const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
362 const bool NeedsAbsoluteFilePath =
363 Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
364 getFileLineInfoForCompileUnit(CU, LineTable, Address,
365 NeedsAbsoluteFilePath,
366 FileName, Line, Column);
368 return DILineInfo(StringRef(FileName), StringRef(FunctionName),
372 DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address,
374 DILineInfoSpecifier Specifier) {
375 DILineInfoTable Lines;
376 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
380 std::string FunctionName = "<invalid>";
381 if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
382 // The address may correspond to instruction in some inlined function,
383 // so we have to build the chain of inlined functions and take the
384 // name of the topmost function in it.
385 const DWARFDebugInfoEntryMinimal::InlinedChain &InlinedChain =
386 CU->getInlinedChainForAddress(Address);
387 if (InlinedChain.size() > 0) {
388 const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain[0];
389 if (const char *Name = TopFunctionDIE.getSubroutineName(CU))
394 StringRef FuncNameRef = StringRef(FunctionName);
396 // If the Specifier says we don't need FileLineInfo, just
397 // return the top-most function at the starting address.
398 if (!Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
399 Lines.push_back(std::make_pair(Address,
400 DILineInfo(StringRef("<invalid>"),
401 FuncNameRef, 0, 0)));
405 const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
406 const bool NeedsAbsoluteFilePath =
407 Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
409 // Get the index of row we're looking for in the line table.
410 std::vector<uint32_t> RowVector;
411 if (!LineTable->lookupAddressRange(Address, Size, RowVector))
414 uint32_t NumRows = RowVector.size();
415 for (uint32_t i = 0; i < NumRows; ++i) {
416 uint32_t RowIndex = RowVector[i];
417 // Take file number and line/column from the row.
418 const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
419 std::string FileName = "<invalid>";
420 getFileNameForCompileUnit(CU, LineTable, Row.File,
421 NeedsAbsoluteFilePath, FileName);
422 Lines.push_back(std::make_pair(Row.Address,
423 DILineInfo(StringRef(FileName),
424 FuncNameRef, Row.Line, Row.Column)));
430 DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address,
431 DILineInfoSpecifier Specifier) {
432 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
434 return DIInliningInfo();
436 const DWARFDebugInfoEntryMinimal::InlinedChain &InlinedChain =
437 CU->getInlinedChainForAddress(Address);
438 if (InlinedChain.size() == 0)
439 return DIInliningInfo();
441 DIInliningInfo InliningInfo;
442 uint32_t CallFile = 0, CallLine = 0, CallColumn = 0;
443 const DWARFLineTable *LineTable = 0;
444 for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) {
445 const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain[i];
446 std::string FileName = "<invalid>";
447 std::string FunctionName = "<invalid>";
450 // Get function name if necessary.
451 if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
452 if (const char *Name = FunctionDIE.getSubroutineName(CU))
455 if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
456 const bool NeedsAbsoluteFilePath =
457 Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
459 // For the topmost frame, initialize the line table of this
460 // compile unit and fetch file/line info from it.
461 LineTable = getLineTableForCompileUnit(CU);
462 // For the topmost routine, get file/line info from line table.
463 getFileLineInfoForCompileUnit(CU, LineTable, Address,
464 NeedsAbsoluteFilePath,
465 FileName, Line, Column);
467 // Otherwise, use call file, call line and call column from
468 // previous DIE in inlined chain.
469 getFileNameForCompileUnit(CU, LineTable, CallFile,
470 NeedsAbsoluteFilePath, FileName);
474 // Get call file/line/column of a current DIE.
476 FunctionDIE.getCallerFrame(CU, CallFile, CallLine, CallColumn);
479 DILineInfo Frame(StringRef(FileName), StringRef(FunctionName),
481 InliningInfo.addFrame(Frame);
486 DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
487 IsLittleEndian(Obj->isLittleEndian()),
488 AddressSize(Obj->getBytesInAddress()) {
490 for (object::section_iterator i = Obj->begin_sections(),
491 e = Obj->end_sections();
492 i != e; i.increment(ec)) {
496 i->getContents(data);
498 name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes.
500 StringRef *Section = StringSwitch<StringRef*>(name)
501 .Case("debug_info", &InfoSection)
502 .Case("debug_abbrev", &AbbrevSection)
503 .Case("debug_line", &LineSection)
504 .Case("debug_aranges", &ARangeSection)
505 .Case("debug_frame", &DebugFrameSection)
506 .Case("debug_str", &StringSection)
507 .Case("debug_ranges", &RangeSection)
508 .Case("debug_pubnames", &PubNamesSection)
509 .Case("debug_info.dwo", &InfoDWOSection)
510 .Case("debug_abbrev.dwo", &AbbrevDWOSection)
511 .Case("debug_str.dwo", &StringDWOSection)
512 .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
513 .Case("debug_addr", &AddrSection)
514 // Any more debug info sections go here.
519 if (name == "debug_ranges") {
520 // FIXME: Use the other dwo range section when we emit it.
521 RangeDWOSection = data;
524 // TODO: Add support for relocations in other sections as needed.
525 // Record relocations for the debug_info and debug_line sections.
526 RelocAddrMap *Map = StringSwitch<RelocAddrMap*>(name)
527 .Case("debug_info", &InfoRelocMap)
528 .Case("debug_info.dwo", &InfoDWORelocMap)
529 .Case("debug_line", &LineRelocMap)
534 if (i->begin_relocations() != i->end_relocations()) {
535 uint64_t SectionSize;
536 i->getSize(SectionSize);
537 for (object::relocation_iterator reloc_i = i->begin_relocations(),
538 reloc_e = i->end_relocations();
539 reloc_i != reloc_e; reloc_i.increment(ec)) {
541 reloc_i->getAddress(Address);
543 reloc_i->getType(Type);
544 uint64_t SymAddr = 0;
545 // ELF relocations may need the symbol address
547 object::SymbolRef Sym;
548 reloc_i->getSymbol(Sym);
549 Sym.getAddress(SymAddr);
552 object::RelocVisitor V(Obj->getFileFormatName());
553 // The section address is always 0 for debug sections.
554 object::RelocToApply R(V.visit(Type, *reloc_i, 0, SymAddr));
556 SmallString<32> Name;
557 error_code ec(reloc_i->getTypeName(Name));
559 errs() << "Aaaaaa! Nameless relocation! Aaaaaa!\n";
561 errs() << "error: failed to compute relocation: "
566 if (Address + R.Width > SectionSize) {
567 errs() << "error: " << R.Width << "-byte relocation starting "
568 << Address << " bytes into section " << name << " which is "
569 << SectionSize << " bytes long.\n";
573 errs() << "error: can't handle a relocation of more than 8 bytes at "
577 DEBUG(dbgs() << "Writing " << format("%p", R.Value)
578 << " at " << format("%p", Address)
579 << " with width " << format("%d", R.Width)
581 Map->insert(std::make_pair(Address, std::make_pair(R.Width, R.Value)));
587 void DWARFContextInMemory::anchor() { }