36c6d98ac6dcb3f4367de7846e0e830880ccac08
[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::LineTable *
81 DWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) {
82   if (!Line)
83     Line.reset(new DWARFDebugLine());
84
85   unsigned stmtOffset =
86     cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(cu, DW_AT_stmt_list,
87                                                          -1U);
88   if (stmtOffset == -1U)
89     return 0; // No line table for this compile unit.
90
91   // See if the line table is cached.
92   if (const DWARFDebugLine::LineTable *lt = Line->getLineTable(stmtOffset))
93     return lt;
94
95   // We have to parse it first.
96   DataExtractor lineData(getLineSection(), isLittleEndian(),
97                          cu->getAddressByteSize());
98   return Line->getOrParseLineTable(lineData, stmtOffset);
99 }
100
101 void DWARFContext::parseCompileUnits() {
102   uint32_t offset = 0;
103   const DataExtractor &debug_info_data = DataExtractor(getInfoSection(),
104                                                        isLittleEndian(), 0);
105   while (debug_info_data.isValidOffset(offset)) {
106     CUs.push_back(DWARFCompileUnit(*this));
107     if (!CUs.back().extract(debug_info_data, &offset)) {
108       CUs.pop_back();
109       break;
110     }
111
112     offset = CUs.back().getNextCompileUnitOffset();
113   }
114 }