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