184a8b595c596bb11c3805a3d1b6b03e5b0e0897
[oota-llvm.git] / lib / DebugInfo / DWARFContext.cpp
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/Support/Dwarf.h"
12 #include "llvm/Support/Format.h"
13 #include "llvm/Support/raw_ostream.h"
14 using namespace llvm;
15 using namespace dwarf;
16
17 void DWARFContext::dump(raw_ostream &OS) {
18   OS << ".debug_abbrev contents:\n";
19   getDebugAbbrev()->dump(OS);
20
21   OS << "\n.debug_info contents:\n";
22   for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i)
23     getCompileUnitAtIndex(i)->dump(OS);
24
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);
31
32   OS << "\n.debug_lines contents:\n";
33   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   }
45
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   }
54 }
55
56 const 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
67 const 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);
75   if (Aranges->isEmpty()) // No aranges in file, generate them from the DIEs.
76     Aranges->generate(this);
77   return Aranges.get();
78 }
79
80 const 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
91 void 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 }