Don't skip __DWARF,
[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/ADT/SmallString.h"
12 #include "llvm/Support/Dwarf.h"
13 #include "llvm/Support/Format.h"
14 #include "llvm/Support/Path.h"
15 #include "llvm/Support/raw_ostream.h"
16 #include <algorithm>
17 using namespace llvm;
18 using namespace dwarf;
19
20 typedef DWARFDebugLine::LineTable DWARFLineTable;
21
22 void DWARFContext::dump(raw_ostream &OS) {
23   OS << ".debug_abbrev contents:\n";
24   getDebugAbbrev()->dump(OS);
25
26   OS << "\n.debug_info contents:\n";
27   for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i)
28     getCompileUnitAtIndex(i)->dump(OS);
29
30   OS << "\n.debug_aranges contents:\n";
31   DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
32   uint32_t offset = 0;
33   DWARFDebugArangeSet set;
34   while (set.extract(arangesData, &offset))
35     set.dump(OS);
36
37   uint8_t savedAddressByteSize = 0;
38   OS << "\n.debug_line contents:\n";
39   for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i) {
40     DWARFCompileUnit *cu = getCompileUnitAtIndex(i);
41     savedAddressByteSize = cu->getAddressByteSize();
42     unsigned stmtOffset =
43       cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(cu, DW_AT_stmt_list,
44                                                            -1U);
45     if (stmtOffset != -1U) {
46       DataExtractor lineData(getLineSection(), isLittleEndian(),
47                              savedAddressByteSize);
48       DWARFDebugLine::DumpingState state(OS);
49       DWARFDebugLine::parseStatementTable(lineData, &stmtOffset, state);
50     }
51   }
52
53   OS << "\n.debug_str contents:\n";
54   DataExtractor strData(getStringSection(), isLittleEndian(), 0);
55   offset = 0;
56   uint32_t lastOffset = 0;
57   while (const char *s = strData.getCStr(&offset)) {
58     OS << format("0x%8.8x: \"%s\"\n", lastOffset, s);
59     lastOffset = offset;
60   }
61
62   OS << "\n.debug_ranges contents:\n";
63   // In fact, different compile units may have different address byte
64   // sizes, but for simplicity we just use the address byte size of the last
65   // compile unit (there is no easy and fast way to associate address range
66   // list and the compile unit it describes).
67   DataExtractor rangesData(getRangeSection(), isLittleEndian(),
68                            savedAddressByteSize);
69   offset = 0;
70   DWARFDebugRangeList rangeList;
71   while (rangeList.extract(rangesData, &offset))
72     rangeList.dump(OS);
73 }
74
75 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
76   if (Abbrev)
77     return Abbrev.get();
78
79   DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0);
80
81   Abbrev.reset(new DWARFDebugAbbrev());
82   Abbrev->parse(abbrData);
83   return Abbrev.get();
84 }
85
86 const DWARFDebugAranges *DWARFContext::getDebugAranges() {
87   if (Aranges)
88     return Aranges.get();
89
90   DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
91
92   Aranges.reset(new DWARFDebugAranges());
93   Aranges->extract(arangesData);
94   // Generate aranges from DIEs: even if .debug_aranges section is present,
95   // it may describe only a small subset of compilation units, so we need to
96   // manually build aranges for the rest of them.
97   Aranges->generate(this);
98   return Aranges.get();
99 }
100
101 const DWARFLineTable *
102 DWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) {
103   if (!Line)
104     Line.reset(new DWARFDebugLine());
105
106   unsigned stmtOffset =
107     cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(cu, DW_AT_stmt_list,
108                                                          -1U);
109   if (stmtOffset == -1U)
110     return 0; // No line table for this compile unit.
111
112   // See if the line table is cached.
113   if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
114     return lt;
115
116   // We have to parse it first.
117   DataExtractor lineData(getLineSection(), isLittleEndian(),
118                          cu->getAddressByteSize());
119   return Line->getOrParseLineTable(lineData, stmtOffset);
120 }
121
122 void DWARFContext::parseCompileUnits() {
123   uint32_t offset = 0;
124   const DataExtractor &DIData = DataExtractor(getInfoSection(),
125                                               isLittleEndian(), 0);
126   while (DIData.isValidOffset(offset)) {
127     CUs.push_back(DWARFCompileUnit(*this));
128     if (!CUs.back().extract(DIData, &offset)) {
129       CUs.pop_back();
130       break;
131     }
132
133     offset = CUs.back().getNextCompileUnitOffset();
134   }
135 }
136
137 namespace {
138   struct OffsetComparator {
139     bool operator()(const DWARFCompileUnit &LHS,
140                     const DWARFCompileUnit &RHS) const {
141       return LHS.getOffset() < RHS.getOffset();
142     }
143     bool operator()(const DWARFCompileUnit &LHS, uint32_t RHS) const {
144       return LHS.getOffset() < RHS;
145     }
146     bool operator()(uint32_t LHS, const DWARFCompileUnit &RHS) const {
147       return LHS < RHS.getOffset();
148     }
149   };
150 }
151
152 DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
153   if (CUs.empty())
154     parseCompileUnits();
155
156   DWARFCompileUnit *CU = std::lower_bound(CUs.begin(), CUs.end(), Offset,
157                                           OffsetComparator());
158   if (CU != CUs.end())
159     return &*CU;
160   return 0;
161 }
162
163 DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
164   // First, get the offset of the compile unit.
165   uint32_t CUOffset = getDebugAranges()->findAddress(Address);
166   // Retrieve the compile unit.
167   return getCompileUnitForOffset(CUOffset);
168 }
169
170 static bool getFileNameForCompileUnit(DWARFCompileUnit *CU,
171                                       const DWARFLineTable *LineTable,
172                                       uint64_t FileIndex,
173                                       bool NeedsAbsoluteFilePath,
174                                       std::string &FileName) {
175   if (CU == 0 ||
176       LineTable == 0 ||
177       !LineTable->getFileNameByIndex(FileIndex, NeedsAbsoluteFilePath,
178                                      FileName))
179     return false;
180   if (NeedsAbsoluteFilePath && sys::path::is_relative(FileName)) {
181     // We may still need to append compilation directory of compile unit.
182     SmallString<16> AbsolutePath;
183     if (const char *CompilationDir = CU->getCompilationDir()) {
184       sys::path::append(AbsolutePath, CompilationDir);
185     }
186     sys::path::append(AbsolutePath, FileName);
187     FileName = AbsolutePath.str();
188   }
189   return true;
190 }
191
192 static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU,
193                                           const DWARFLineTable *LineTable,
194                                           uint64_t Address,
195                                           bool NeedsAbsoluteFilePath,
196                                           std::string &FileName,
197                                           uint32_t &Line, uint32_t &Column) {
198   if (CU == 0 || LineTable == 0)
199     return false;
200   // Get the index of row we're looking for in the line table.
201   uint32_t RowIndex = LineTable->lookupAddress(Address);
202   if (RowIndex == -1U)
203     return false;
204   // Take file number and line/column from the row.
205   const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
206   if (!getFileNameForCompileUnit(CU, LineTable, Row.File,
207                                  NeedsAbsoluteFilePath, FileName))
208     return false;
209   Line = Row.Line;
210   Column = Row.Column;
211   return true;
212 }
213
214 DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
215     DILineInfoSpecifier Specifier) {
216   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
217   if (!CU)
218     return DILineInfo();
219   std::string FileName = "<invalid>";
220   std::string FunctionName = "<invalid>";
221   uint32_t Line = 0;
222   uint32_t Column = 0;
223   if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
224     // The address may correspond to instruction in some inlined function,
225     // so we have to build the chain of inlined functions and take the
226     // name of the topmost function in it.
227     const DWARFDebugInfoEntryMinimal::InlinedChain &InlinedChain =
228         CU->getInlinedChainForAddress(Address);
229     if (InlinedChain.size() > 0) {
230       const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain[0];
231       if (const char *Name = TopFunctionDIE.getSubroutineName(CU))
232         FunctionName = Name;
233     }
234   }
235   if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
236     const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
237     const bool NeedsAbsoluteFilePath =
238         Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
239     getFileLineInfoForCompileUnit(CU, LineTable, Address,
240                                   NeedsAbsoluteFilePath,
241                                   FileName, Line, Column);
242   }
243   return DILineInfo(StringRef(FileName), StringRef(FunctionName),
244                     Line, Column);
245 }
246
247 DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address,
248     DILineInfoSpecifier Specifier) {
249   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
250   if (!CU)
251     return DIInliningInfo();
252
253   const DWARFDebugInfoEntryMinimal::InlinedChain &InlinedChain =
254       CU->getInlinedChainForAddress(Address);
255   if (InlinedChain.size() == 0)
256     return DIInliningInfo();
257
258   DIInliningInfo InliningInfo;
259   uint32_t CallFile = 0, CallLine = 0, CallColumn = 0;
260   const DWARFLineTable *LineTable = 0;
261   for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) {
262     const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain[i];
263     std::string FileName = "<invalid>";
264     std::string FunctionName = "<invalid>";
265     uint32_t Line = 0;
266     uint32_t Column = 0;
267     // Get function name if necessary.
268     if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
269       if (const char *Name = FunctionDIE.getSubroutineName(CU))
270         FunctionName = Name;
271     }
272     if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
273       const bool NeedsAbsoluteFilePath =
274           Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
275       if (i == 0) {
276         // For the topmost frame, initialize the line table of this
277         // compile unit and fetch file/line info from it.
278         LineTable = getLineTableForCompileUnit(CU);
279         // For the topmost routine, get file/line info from line table.
280         getFileLineInfoForCompileUnit(CU, LineTable, Address,
281                                       NeedsAbsoluteFilePath,
282                                       FileName, Line, Column);
283       } else {
284         // Otherwise, use call file, call line and call column from
285         // previous DIE in inlined chain.
286         getFileNameForCompileUnit(CU, LineTable, CallFile,
287                                   NeedsAbsoluteFilePath, FileName);
288         Line = CallLine;
289         Column = CallColumn;
290       }
291       // Get call file/line/column of a current DIE.
292       if (i + 1 < n) {
293         FunctionDIE.getCallerFrame(CU, CallFile, CallLine, CallColumn);
294       }
295     }
296     DILineInfo Frame(StringRef(FileName), StringRef(FunctionName),
297                      Line, Column);
298     InliningInfo.addFrame(Frame);
299   }
300   return InliningInfo;
301 }
302
303 DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
304   IsLittleEndian(true /* FIXME */) {
305   error_code ec;
306   for (object::section_iterator i = Obj->begin_sections(),
307          e = Obj->end_sections();
308        i != e; i.increment(ec)) {
309     StringRef name;
310     i->getName(name);
311     StringRef data;
312     i->getContents(data);
313
314     name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes.
315     if (name == "debug_info")
316       InfoSection = data;
317     else if (name == "debug_abbrev")
318       AbbrevSection = data;
319     else if (name == "debug_line")
320       LineSection = data;
321     else if (name == "debug_aranges")
322       ARangeSection = data;
323     else if (name == "debug_str")
324       StringSection = data;
325     else if (name == "debug_ranges")
326       RangeSection = data;
327     // Any more debug info sections go here.
328     else
329       continue;
330
331     // TODO: For now only handle relocations for the debug_info section.
332     if (name != "debug_info")
333       continue;
334
335     if (i->begin_relocations() != i->end_relocations()) {
336       uint64_t SectionSize;
337       i->getSize(SectionSize);
338       for (object::relocation_iterator reloc_i = i->begin_relocations(),
339              reloc_e = i->end_relocations();
340            reloc_i != reloc_e; reloc_i.increment(ec)) {
341         uint64_t Address;
342         reloc_i->getAddress(Address);
343         uint64_t Type;
344         reloc_i->getType(Type);
345
346         object::RelocVisitor V(Obj->getFileFormatName());
347         // The section address is always 0 for debug sections.
348         object::RelocToApply R(V.visit(Type, *reloc_i));
349         if (V.error()) {
350           SmallString<32> Name;
351           error_code ec(reloc_i->getTypeName(Name));
352           if (ec) {
353             errs() << "Aaaaaa! Nameless relocation! Aaaaaa!\n";
354           }
355           errs() << "error: failed to compute relocation: "
356                  << Name << "\n";
357           continue;
358         }
359
360         if (Address + R.Width > SectionSize) {
361           errs() << "error: " << R.Width << "-byte relocation starting "
362                  << Address << " bytes into section " << name << " which is "
363                  << SectionSize << " bytes long.\n";
364           continue;
365         }
366         if (R.Width > 8) {
367           errs() << "error: can't handle a relocation of more than 8 bytes at "
368                     "a time.\n";
369           continue;
370         }
371         DEBUG(dbgs() << "Writing " << format("%p", R.Value)
372                      << " at " << format("%p", Address)
373                      << " with width " << format("%d", R.Width)
374                      << "\n");
375         RelocMap[Address] = std::make_pair(R.Width, R.Value);
376       }
377     }
378   }
379 }
380
381 void DWARFContextInMemory::anchor() { }