247ee5b3575b59e68e72f861d6a849d287143474
[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 strOffset = 0;
57   while (const char *s = strData.getCStr(&offset)) {
58     OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
59     strOffset = 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   OS << "\n.debug_abbrev.dwo contents:\n";
75   getDebugAbbrevDWO()->dump(OS);
76
77   OS << "\n.debug_info.dwo contents:\n";
78   for (unsigned i = 0, e = getNumDWOCompileUnits(); i != e; ++i)
79     getDWOCompileUnitAtIndex(i)->dump(OS);
80
81   OS << "\n.debug_str.dwo contents:\n";
82   DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
83   offset = 0;
84   uint32_t strDWOOffset = 0;
85   while (const char *s = strDWOData.getCStr(&offset)) {
86     OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
87     strDWOOffset = offset;
88   }
89 }
90
91 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
92   if (Abbrev)
93     return Abbrev.get();
94
95   DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0);
96
97   Abbrev.reset(new DWARFDebugAbbrev());
98   Abbrev->parse(abbrData);
99   return Abbrev.get();
100 }
101
102 const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
103   if (AbbrevDWO)
104     return AbbrevDWO.get();
105
106   DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0);
107   AbbrevDWO.reset(new DWARFDebugAbbrev());
108   AbbrevDWO->parse(abbrData);
109   return AbbrevDWO.get();
110 }
111
112 const DWARFDebugAranges *DWARFContext::getDebugAranges() {
113   if (Aranges)
114     return Aranges.get();
115
116   DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
117
118   Aranges.reset(new DWARFDebugAranges());
119   Aranges->extract(arangesData);
120   // Generate aranges from DIEs: even if .debug_aranges section is present,
121   // it may describe only a small subset of compilation units, so we need to
122   // manually build aranges for the rest of them.
123   Aranges->generate(this);
124   return Aranges.get();
125 }
126
127 const DWARFLineTable *
128 DWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) {
129   if (!Line)
130     Line.reset(new DWARFDebugLine());
131
132   unsigned stmtOffset =
133     cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(cu, DW_AT_stmt_list,
134                                                          -1U);
135   if (stmtOffset == -1U)
136     return 0; // No line table for this compile unit.
137
138   // See if the line table is cached.
139   if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
140     return lt;
141
142   // We have to parse it first.
143   DataExtractor lineData(getLineSection(), isLittleEndian(),
144                          cu->getAddressByteSize());
145   return Line->getOrParseLineTable(lineData, stmtOffset);
146 }
147
148 void DWARFContext::parseCompileUnits() {
149   uint32_t offset = 0;
150   const DataExtractor &DIData = DataExtractor(getInfoSection(),
151                                               isLittleEndian(), 0);
152   while (DIData.isValidOffset(offset)) {
153     CUs.push_back(DWARFCompileUnit(getDebugAbbrev(), getInfoSection(),
154                                    getAbbrevSection(), getRangeSection(),
155                                    getStringSection(), "",
156                                    &infoRelocMap(),
157                                    isLittleEndian()));
158     if (!CUs.back().extract(DIData, &offset)) {
159       CUs.pop_back();
160       break;
161     }
162
163     offset = CUs.back().getNextCompileUnitOffset();
164   }
165 }
166
167 void DWARFContext::parseDWOCompileUnits() {
168   uint32_t offset = 0;
169   const DataExtractor &DIData = DataExtractor(getInfoDWOSection(),
170                                               isLittleEndian(), 0);
171   while (DIData.isValidOffset(offset)) {
172     DWOCUs.push_back(DWARFCompileUnit(getDebugAbbrevDWO(), getInfoDWOSection(),
173                                       getAbbrevDWOSection(),
174                                       getRangeDWOSection(),
175                                       getStringDWOSection(),
176                                       getStringOffsetDWOSection(),
177                                       &infoDWORelocMap(),
178                                       isLittleEndian()));
179     if (!DWOCUs.back().extract(DIData, &offset)) {
180       DWOCUs.pop_back();
181       break;
182     }
183
184     offset = DWOCUs.back().getNextCompileUnitOffset();
185   }
186 }
187
188 namespace {
189   struct OffsetComparator {
190     bool operator()(const DWARFCompileUnit &LHS,
191                     const DWARFCompileUnit &RHS) const {
192       return LHS.getOffset() < RHS.getOffset();
193     }
194     bool operator()(const DWARFCompileUnit &LHS, uint32_t RHS) const {
195       return LHS.getOffset() < RHS;
196     }
197     bool operator()(uint32_t LHS, const DWARFCompileUnit &RHS) const {
198       return LHS < RHS.getOffset();
199     }
200   };
201 }
202
203 DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
204   if (CUs.empty())
205     parseCompileUnits();
206
207   DWARFCompileUnit *CU = std::lower_bound(CUs.begin(), CUs.end(), Offset,
208                                           OffsetComparator());
209   if (CU != CUs.end())
210     return &*CU;
211   return 0;
212 }
213
214 DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
215   // First, get the offset of the compile unit.
216   uint32_t CUOffset = getDebugAranges()->findAddress(Address);
217   // Retrieve the compile unit.
218   return getCompileUnitForOffset(CUOffset);
219 }
220
221 static bool getFileNameForCompileUnit(DWARFCompileUnit *CU,
222                                       const DWARFLineTable *LineTable,
223                                       uint64_t FileIndex,
224                                       bool NeedsAbsoluteFilePath,
225                                       std::string &FileName) {
226   if (CU == 0 ||
227       LineTable == 0 ||
228       !LineTable->getFileNameByIndex(FileIndex, NeedsAbsoluteFilePath,
229                                      FileName))
230     return false;
231   if (NeedsAbsoluteFilePath && sys::path::is_relative(FileName)) {
232     // We may still need to append compilation directory of compile unit.
233     SmallString<16> AbsolutePath;
234     if (const char *CompilationDir = CU->getCompilationDir()) {
235       sys::path::append(AbsolutePath, CompilationDir);
236     }
237     sys::path::append(AbsolutePath, FileName);
238     FileName = AbsolutePath.str();
239   }
240   return true;
241 }
242
243 static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU,
244                                           const DWARFLineTable *LineTable,
245                                           uint64_t Address,
246                                           bool NeedsAbsoluteFilePath,
247                                           std::string &FileName,
248                                           uint32_t &Line, uint32_t &Column) {
249   if (CU == 0 || LineTable == 0)
250     return false;
251   // Get the index of row we're looking for in the line table.
252   uint32_t RowIndex = LineTable->lookupAddress(Address);
253   if (RowIndex == -1U)
254     return false;
255   // Take file number and line/column from the row.
256   const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
257   if (!getFileNameForCompileUnit(CU, LineTable, Row.File,
258                                  NeedsAbsoluteFilePath, FileName))
259     return false;
260   Line = Row.Line;
261   Column = Row.Column;
262   return true;
263 }
264
265 DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
266     DILineInfoSpecifier Specifier) {
267   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
268   if (!CU)
269     return DILineInfo();
270   std::string FileName = "<invalid>";
271   std::string FunctionName = "<invalid>";
272   uint32_t Line = 0;
273   uint32_t Column = 0;
274   if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
275     // The address may correspond to instruction in some inlined function,
276     // so we have to build the chain of inlined functions and take the
277     // name of the topmost function in it.
278     const DWARFDebugInfoEntryMinimal::InlinedChain &InlinedChain =
279         CU->getInlinedChainForAddress(Address);
280     if (InlinedChain.size() > 0) {
281       const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain[0];
282       if (const char *Name = TopFunctionDIE.getSubroutineName(CU))
283         FunctionName = Name;
284     }
285   }
286   if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
287     const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
288     const bool NeedsAbsoluteFilePath =
289         Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
290     getFileLineInfoForCompileUnit(CU, LineTable, Address,
291                                   NeedsAbsoluteFilePath,
292                                   FileName, Line, Column);
293   }
294   return DILineInfo(StringRef(FileName), StringRef(FunctionName),
295                     Line, Column);
296 }
297
298 DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address,
299     DILineInfoSpecifier Specifier) {
300   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
301   if (!CU)
302     return DIInliningInfo();
303
304   const DWARFDebugInfoEntryMinimal::InlinedChain &InlinedChain =
305       CU->getInlinedChainForAddress(Address);
306   if (InlinedChain.size() == 0)
307     return DIInliningInfo();
308
309   DIInliningInfo InliningInfo;
310   uint32_t CallFile = 0, CallLine = 0, CallColumn = 0;
311   const DWARFLineTable *LineTable = 0;
312   for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) {
313     const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain[i];
314     std::string FileName = "<invalid>";
315     std::string FunctionName = "<invalid>";
316     uint32_t Line = 0;
317     uint32_t Column = 0;
318     // Get function name if necessary.
319     if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
320       if (const char *Name = FunctionDIE.getSubroutineName(CU))
321         FunctionName = Name;
322     }
323     if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
324       const bool NeedsAbsoluteFilePath =
325           Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
326       if (i == 0) {
327         // For the topmost frame, initialize the line table of this
328         // compile unit and fetch file/line info from it.
329         LineTable = getLineTableForCompileUnit(CU);
330         // For the topmost routine, get file/line info from line table.
331         getFileLineInfoForCompileUnit(CU, LineTable, Address,
332                                       NeedsAbsoluteFilePath,
333                                       FileName, Line, Column);
334       } else {
335         // Otherwise, use call file, call line and call column from
336         // previous DIE in inlined chain.
337         getFileNameForCompileUnit(CU, LineTable, CallFile,
338                                   NeedsAbsoluteFilePath, FileName);
339         Line = CallLine;
340         Column = CallColumn;
341       }
342       // Get call file/line/column of a current DIE.
343       if (i + 1 < n) {
344         FunctionDIE.getCallerFrame(CU, CallFile, CallLine, CallColumn);
345       }
346     }
347     DILineInfo Frame(StringRef(FileName), StringRef(FunctionName),
348                      Line, Column);
349     InliningInfo.addFrame(Frame);
350   }
351   return InliningInfo;
352 }
353
354 DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
355   IsLittleEndian(Obj->isLittleEndian()) {
356   error_code ec;
357   for (object::section_iterator i = Obj->begin_sections(),
358          e = Obj->end_sections();
359        i != e; i.increment(ec)) {
360     StringRef name;
361     i->getName(name);
362     StringRef data;
363     i->getContents(data);
364
365     name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes.
366     if (name == "debug_info")
367       InfoSection = data;
368     else if (name == "debug_abbrev")
369       AbbrevSection = data;
370     else if (name == "debug_line")
371       LineSection = data;
372     else if (name == "debug_aranges")
373       ARangeSection = data;
374     else if (name == "debug_str")
375       StringSection = data;
376     else if (name == "debug_ranges") {
377       // FIXME: Use the other dwo range section when we emit it.
378       RangeDWOSection = data;
379       RangeSection = data;
380     }
381     else if (name == "debug_info.dwo")
382       InfoDWOSection = data;
383     else if (name == "debug_abbrev.dwo")
384       AbbrevDWOSection = data;
385     else if (name == "debug_str.dwo")
386       StringDWOSection = data;
387     else if (name == "debug_str_offsets.dwo")
388       StringOffsetDWOSection = data;
389     // Any more debug info sections go here.
390     else
391       continue;
392
393     // TODO: For now only handle relocations for the debug_info section.
394     RelocAddrMap *Map;
395     if (name == "debug_info")
396       Map = &InfoRelocMap;
397     else if (name == "debug_info.dwo")
398       Map = &InfoDWORelocMap;
399     else
400       continue;
401
402     if (i->begin_relocations() != i->end_relocations()) {
403       uint64_t SectionSize;
404       i->getSize(SectionSize);
405       for (object::relocation_iterator reloc_i = i->begin_relocations(),
406              reloc_e = i->end_relocations();
407            reloc_i != reloc_e; reloc_i.increment(ec)) {
408         uint64_t Address;
409         reloc_i->getAddress(Address);
410         uint64_t Type;
411         reloc_i->getType(Type);
412
413         object::RelocVisitor V(Obj->getFileFormatName());
414         // The section address is always 0 for debug sections.
415         object::RelocToApply R(V.visit(Type, *reloc_i));
416         if (V.error()) {
417           SmallString<32> Name;
418           error_code ec(reloc_i->getTypeName(Name));
419           if (ec) {
420             errs() << "Aaaaaa! Nameless relocation! Aaaaaa!\n";
421           }
422           errs() << "error: failed to compute relocation: "
423                  << Name << "\n";
424           continue;
425         }
426
427         if (Address + R.Width > SectionSize) {
428           errs() << "error: " << R.Width << "-byte relocation starting "
429                  << Address << " bytes into section " << name << " which is "
430                  << SectionSize << " bytes long.\n";
431           continue;
432         }
433         if (R.Width > 8) {
434           errs() << "error: can't handle a relocation of more than 8 bytes at "
435                     "a time.\n";
436           continue;
437         }
438         DEBUG(dbgs() << "Writing " << format("%p", R.Value)
439                      << " at " << format("%p", Address)
440                      << " with width " << format("%d", R.Width)
441                      << "\n");
442         Map->insert(std::make_pair(Address, std::make_pair(R.Width, R.Value)));
443       }
444     }
445   }
446 }
447
448 void DWARFContextInMemory::anchor() { }