blob: 184a8b595c596bb11c3805a3d1b6b03e5b0e0897 [file] [log] [blame]
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +00001//===-- 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"
Benjamin Kramerfe80f1d2011-09-15 18:02:20 +000011#include "llvm/Support/Dwarf.h"
Benjamin Kramer34f864f2011-09-15 16:57:13 +000012#include "llvm/Support/Format.h"
Benjamin Kramer358f4fd2011-09-14 01:09:52 +000013#include "llvm/Support/raw_ostream.h"
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000014using namespace llvm;
Benjamin Kramerfe80f1d2011-09-15 18:02:20 +000015using namespace dwarf;
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000016
17void DWARFContext::dump(raw_ostream &OS) {
Benjamin Kramer358f4fd2011-09-14 01:09:52 +000018 OS << ".debug_abbrev contents:\n";
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000019 getDebugAbbrev()->dump(OS);
Benjamin Kramer358f4fd2011-09-14 01:09:52 +000020
21 OS << "\n.debug_info contents:\n";
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000022 for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i)
23 getCompileUnitAtIndex(i)->dump(OS);
Benjamin Kramer358f4fd2011-09-14 01:09:52 +000024
25 OS << "\n.debug_aranges contents:\n";
26 DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
27 uint32_t offset = 0;
28 DWARFDebugArangeSet set;
29 while (set.extract(arangesData, &offset))
30 set.dump(OS);
Benjamin Kramerb848e972011-09-15 02:12:05 +000031
32 OS << "\n.debug_lines contents:\n";
Benjamin Kramerfe80f1d2011-09-15 18:02:20 +000033 for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i) {
34 DWARFCompileUnit *cu = getCompileUnitAtIndex(i);
35 unsigned stmtOffset =
36 cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(cu, DW_AT_stmt_list,
37 -1U);
38 if (stmtOffset != -1U) {
39 DataExtractor lineData(getLineSection(), isLittleEndian(),
40 cu->getAddressByteSize());
41 DWARFDebugLine::DumpingState state(OS);
42 DWARFDebugLine::parseStatementTable(lineData, &stmtOffset, state);
43 }
44 }
Benjamin Kramer34f864f2011-09-15 16:57:13 +000045
46 OS << "\n.debug_str contents:\n";
47 DataExtractor strData(getStringSection(), isLittleEndian(), 0);
48 offset = 0;
49 uint32_t lastOffset = 0;
50 while (const char *s = strData.getCStr(&offset)) {
51 OS << format("0x%8.8x: \"%s\"\n", lastOffset, s);
52 lastOffset = offset;
53 }
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000054}
55
56const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
57 if (Abbrev)
58 return Abbrev.get();
59
60 DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0);
61
62 Abbrev.reset(new DWARFDebugAbbrev());
63 Abbrev->parse(abbrData);
64 return Abbrev.get();
65}
66
Benjamin Kramer358f4fd2011-09-14 01:09:52 +000067const DWARFDebugAranges *DWARFContext::getDebugAranges() {
68 if (Aranges)
69 return Aranges.get();
70
71 DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
72
73 Aranges.reset(new DWARFDebugAranges());
74 Aranges->extract(arangesData);
Benjamin Kramer10df8062011-09-14 20:52:27 +000075 if (Aranges->isEmpty()) // No aranges in file, generate them from the DIEs.
76 Aranges->generate(this);
Benjamin Kramer358f4fd2011-09-14 01:09:52 +000077 return Aranges.get();
78}
79
Benjamin Kramerb848e972011-09-15 02:12:05 +000080const DWARFDebugLine *DWARFContext::getDebugLine() {
81 if (Line)
82 return Line.get();
83
84 DataExtractor lineData(getLineSection(), isLittleEndian(), 0);
85
86 Line.reset(new DWARFDebugLine());
87 Line->parse(lineData);
88 return Line.get();
89}
90
Benjamin Kramer72c0d7f2011-09-13 19:42:23 +000091void DWARFContext::parseCompileUnits() {
92 uint32_t offset = 0;
93 const DataExtractor &debug_info_data = DataExtractor(getInfoSection(),
94 isLittleEndian(), 0);
95 while (debug_info_data.isValidOffset(offset)) {
96 CUs.push_back(DWARFCompileUnit(*this));
97 if (!CUs.back().extract(debug_info_data, &offset)) {
98 CUs.pop_back();
99 break;
100 }
101
102 offset = CUs.back().getNextCompileUnitOffset();
103 }
104}