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/ADT/StringSwitch.h"
13#include "llvm/ADT/STLExtras.h"
14#include "llvm/Support/Compression.h"
15#include "llvm/Support/Dwarf.h"
16#include "llvm/Support/Format.h"
17#include "llvm/Support/Path.h"
18#include "llvm/Support/raw_ostream.h"
19#include <algorithm>
20using namespace llvm;
21using namespace dwarf;
22using namespace object;
23
24typedef DWARFDebugLine::LineTable DWARFLineTable;
25
26void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
27  if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) {
28    OS << ".debug_abbrev contents:\n";
29    getDebugAbbrev()->dump(OS);
30  }
31
32  if (DumpType == DIDT_All || DumpType == DIDT_Info) {
33    OS << "\n.debug_info contents:\n";
34    for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i)
35      getCompileUnitAtIndex(i)->dump(OS);
36  }
37
38  if (DumpType == DIDT_All || DumpType == DIDT_Loc) {
39    OS << ".debug_loc contents:\n";
40    getDebugLoc()->dump(OS);
41  }
42
43  if (DumpType == DIDT_All || DumpType == DIDT_Frames) {
44    OS << "\n.debug_frame contents:\n";
45    getDebugFrame()->dump(OS);
46  }
47
48  uint32_t offset = 0;
49  if (DumpType == DIDT_All || DumpType == DIDT_Aranges) {
50    OS << "\n.debug_aranges contents:\n";
51    DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
52    DWARFDebugArangeSet set;
53    while (set.extract(arangesData, &offset))
54      set.dump(OS);
55  }
56
57  uint8_t savedAddressByteSize = 0;
58  if (DumpType == DIDT_All || DumpType == DIDT_Line) {
59    OS << "\n.debug_line contents:\n";
60    for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i) {
61      DWARFCompileUnit *cu = getCompileUnitAtIndex(i);
62      savedAddressByteSize = cu->getAddressByteSize();
63      unsigned stmtOffset =
64        cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(cu, DW_AT_stmt_list,
65                                                             -1U);
66      if (stmtOffset != -1U) {
67        DataExtractor lineData(getLineSection(), isLittleEndian(),
68                               savedAddressByteSize);
69        DWARFDebugLine::DumpingState state(OS);
70        DWARFDebugLine::parseStatementTable(lineData, &lineRelocMap(), &stmtOffset, state);
71      }
72    }
73  }
74
75  if (DumpType == DIDT_All || DumpType == DIDT_Str) {
76    OS << "\n.debug_str contents:\n";
77    DataExtractor strData(getStringSection(), isLittleEndian(), 0);
78    offset = 0;
79    uint32_t strOffset = 0;
80    while (const char *s = strData.getCStr(&offset)) {
81      OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
82      strOffset = offset;
83    }
84  }
85
86  if (DumpType == DIDT_All || DumpType == DIDT_Ranges) {
87    OS << "\n.debug_ranges contents:\n";
88    // In fact, different compile units may have different address byte
89    // sizes, but for simplicity we just use the address byte size of the last
90    // compile unit (there is no easy and fast way to associate address range
91    // list and the compile unit it describes).
92    DataExtractor rangesData(getRangeSection(), isLittleEndian(),
93                             savedAddressByteSize);
94    offset = 0;
95    DWARFDebugRangeList rangeList;
96    while (rangeList.extract(rangesData, &offset))
97      rangeList.dump(OS);
98  }
99
100  if (DumpType == DIDT_All || DumpType == DIDT_Pubnames) {
101    OS << "\n.debug_pubnames contents:\n";
102    DataExtractor pubNames(getPubNamesSection(), isLittleEndian(), 0);
103    offset = 0;
104    OS << "Length:                " << pubNames.getU32(&offset) << "\n";
105    OS << "Version:               " << pubNames.getU16(&offset) << "\n";
106    OS << "Offset in .debug_info: " << pubNames.getU32(&offset) << "\n";
107    OS << "Size:                  " << pubNames.getU32(&offset) << "\n";
108    OS << "\n  Offset    Name\n";
109    while (offset < getPubNamesSection().size()) {
110      uint32_t n = pubNames.getU32(&offset);
111      if (n == 0)
112        break;
113      OS << format("%8x    ", n);
114      OS << pubNames.getCStr(&offset) << "\n";
115    }
116  }
117
118  if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo) {
119    const DWARFDebugAbbrev *D = getDebugAbbrevDWO();
120    if (D) {
121      OS << "\n.debug_abbrev.dwo contents:\n";
122      getDebugAbbrevDWO()->dump(OS);
123    }
124  }
125
126  if (DumpType == DIDT_All || DumpType == DIDT_InfoDwo)
127    if (getNumDWOCompileUnits()) {
128      OS << "\n.debug_info.dwo contents:\n";
129      for (unsigned i = 0, e = getNumDWOCompileUnits(); i != e; ++i)
130        getDWOCompileUnitAtIndex(i)->dump(OS);
131    }
132
133  if (DumpType == DIDT_All || DumpType == DIDT_StrDwo)
134    if (!getStringDWOSection().empty()) {
135      OS << "\n.debug_str.dwo contents:\n";
136      DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
137      offset = 0;
138      uint32_t strDWOOffset = 0;
139      while (const char *s = strDWOData.getCStr(&offset)) {
140        OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
141        strDWOOffset = offset;
142      }
143    }
144
145  if (DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo)
146    if (!getStringOffsetDWOSection().empty()) {
147      OS << "\n.debug_str_offsets.dwo contents:\n";
148      DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(), 0);
149      offset = 0;
150      uint64_t size = getStringOffsetDWOSection().size();
151      while (offset < size) {
152        OS << format("0x%8.8x: ", offset);
153        OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
154      }
155    }
156}
157
158const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
159  if (Abbrev)
160    return Abbrev.get();
161
162  DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0);
163
164  Abbrev.reset(new DWARFDebugAbbrev());
165  Abbrev->parse(abbrData);
166  return Abbrev.get();
167}
168
169const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
170  if (AbbrevDWO)
171    return AbbrevDWO.get();
172
173  DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0);
174  AbbrevDWO.reset(new DWARFDebugAbbrev());
175  AbbrevDWO->parse(abbrData);
176  return AbbrevDWO.get();
177}
178
179const DWARFDebugLoc *DWARFContext::getDebugLoc() {
180  if (Loc)
181    return Loc.get();
182
183  DataExtractor LocData(getLocSection(), isLittleEndian(), 0);
184  Loc.reset(new DWARFDebugLoc(locRelocMap()));
185  // assume all compile units have the same address byte size
186  if (getNumCompileUnits())
187    Loc->parse(LocData, getCompileUnitAtIndex(0)->getAddressByteSize());
188  return Loc.get();
189}
190
191const DWARFDebugAranges *DWARFContext::getDebugAranges() {
192  if (Aranges)
193    return Aranges.get();
194
195  DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
196
197  Aranges.reset(new DWARFDebugAranges());
198  Aranges->extract(arangesData);
199  // Generate aranges from DIEs: even if .debug_aranges section is present,
200  // it may describe only a small subset of compilation units, so we need to
201  // manually build aranges for the rest of them.
202  Aranges->generate(this);
203  return Aranges.get();
204}
205
206const DWARFDebugFrame *DWARFContext::getDebugFrame() {
207  if (DebugFrame)
208    return DebugFrame.get();
209
210  // There's a "bug" in the DWARFv3 standard with respect to the target address
211  // size within debug frame sections. While DWARF is supposed to be independent
212  // of its container, FDEs have fields with size being "target address size",
213  // which isn't specified in DWARF in general. It's only specified for CUs, but
214  // .eh_frame can appear without a .debug_info section. Follow the example of
215  // other tools (libdwarf) and extract this from the container (ObjectFile
216  // provides this information). This problem is fixed in DWARFv4
217  // See this dwarf-discuss discussion for more details:
218  // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
219  DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(),
220                               getAddressSize());
221  DebugFrame.reset(new DWARFDebugFrame());
222  DebugFrame->parse(debugFrameData);
223  return DebugFrame.get();
224}
225
226const DWARFLineTable *
227DWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) {
228  if (!Line)
229    Line.reset(new DWARFDebugLine(&lineRelocMap()));
230
231  unsigned stmtOffset =
232    cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(cu, DW_AT_stmt_list,
233                                                         -1U);
234  if (stmtOffset == -1U)
235    return 0; // No line table for this compile unit.
236
237  // See if the line table is cached.
238  if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
239    return lt;
240
241  // We have to parse it first.
242  DataExtractor lineData(getLineSection(), isLittleEndian(),
243                         cu->getAddressByteSize());
244  return Line->getOrParseLineTable(lineData, stmtOffset);
245}
246
247void DWARFContext::parseCompileUnits() {
248  uint32_t offset = 0;
249  const DataExtractor &DIData = DataExtractor(getInfoSection(),
250                                              isLittleEndian(), 0);
251  while (DIData.isValidOffset(offset)) {
252    CUs.push_back(DWARFCompileUnit(getDebugAbbrev(), getInfoSection(),
253                                   getAbbrevSection(), getRangeSection(),
254                                   getStringSection(), StringRef(),
255                                   getAddrSection(),
256                                   &infoRelocMap(),
257                                   isLittleEndian()));
258    if (!CUs.back().extract(DIData, &offset)) {
259      CUs.pop_back();
260      break;
261    }
262
263    offset = CUs.back().getNextCompileUnitOffset();
264  }
265}
266
267void DWARFContext::parseDWOCompileUnits() {
268  uint32_t offset = 0;
269  const DataExtractor &DIData = DataExtractor(getInfoDWOSection(),
270                                              isLittleEndian(), 0);
271  while (DIData.isValidOffset(offset)) {
272    DWOCUs.push_back(DWARFCompileUnit(getDebugAbbrevDWO(), getInfoDWOSection(),
273                                      getAbbrevDWOSection(),
274                                      getRangeDWOSection(),
275                                      getStringDWOSection(),
276                                      getStringOffsetDWOSection(),
277                                      getAddrSection(),
278                                      &infoDWORelocMap(),
279                                      isLittleEndian()));
280    if (!DWOCUs.back().extract(DIData, &offset)) {
281      DWOCUs.pop_back();
282      break;
283    }
284
285    offset = DWOCUs.back().getNextCompileUnitOffset();
286  }
287}
288
289namespace {
290  struct OffsetComparator {
291    bool operator()(const DWARFCompileUnit &LHS,
292                    const DWARFCompileUnit &RHS) const {
293      return LHS.getOffset() < RHS.getOffset();
294    }
295    bool operator()(const DWARFCompileUnit &LHS, uint32_t RHS) const {
296      return LHS.getOffset() < RHS;
297    }
298    bool operator()(uint32_t LHS, const DWARFCompileUnit &RHS) const {
299      return LHS < RHS.getOffset();
300    }
301  };
302}
303
304DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
305  if (CUs.empty())
306    parseCompileUnits();
307
308  DWARFCompileUnit *CU = std::lower_bound(CUs.begin(), CUs.end(), Offset,
309                                          OffsetComparator());
310  if (CU != CUs.end())
311    return &*CU;
312  return 0;
313}
314
315DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
316  // First, get the offset of the compile unit.
317  uint32_t CUOffset = getDebugAranges()->findAddress(Address);
318  // Retrieve the compile unit.
319  return getCompileUnitForOffset(CUOffset);
320}
321
322static bool getFileNameForCompileUnit(DWARFCompileUnit *CU,
323                                      const DWARFLineTable *LineTable,
324                                      uint64_t FileIndex,
325                                      bool NeedsAbsoluteFilePath,
326                                      std::string &FileName) {
327  if (CU == 0 ||
328      LineTable == 0 ||
329      !LineTable->getFileNameByIndex(FileIndex, NeedsAbsoluteFilePath,
330                                     FileName))
331    return false;
332  if (NeedsAbsoluteFilePath && sys::path::is_relative(FileName)) {
333    // We may still need to append compilation directory of compile unit.
334    SmallString<16> AbsolutePath;
335    if (const char *CompilationDir = CU->getCompilationDir()) {
336      sys::path::append(AbsolutePath, CompilationDir);
337    }
338    sys::path::append(AbsolutePath, FileName);
339    FileName = AbsolutePath.str();
340  }
341  return true;
342}
343
344static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU,
345                                          const DWARFLineTable *LineTable,
346                                          uint64_t Address,
347                                          bool NeedsAbsoluteFilePath,
348                                          std::string &FileName,
349                                          uint32_t &Line, uint32_t &Column) {
350  if (CU == 0 || LineTable == 0)
351    return false;
352  // Get the index of row we're looking for in the line table.
353  uint32_t RowIndex = LineTable->lookupAddress(Address);
354  if (RowIndex == -1U)
355    return false;
356  // Take file number and line/column from the row.
357  const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
358  if (!getFileNameForCompileUnit(CU, LineTable, Row.File,
359                                 NeedsAbsoluteFilePath, FileName))
360    return false;
361  Line = Row.Line;
362  Column = Row.Column;
363  return true;
364}
365
366DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
367    DILineInfoSpecifier Specifier) {
368  DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
369  if (!CU)
370    return DILineInfo();
371  std::string FileName = "<invalid>";
372  std::string FunctionName = "<invalid>";
373  uint32_t Line = 0;
374  uint32_t Column = 0;
375  if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
376    // The address may correspond to instruction in some inlined function,
377    // so we have to build the chain of inlined functions and take the
378    // name of the topmost function in it.
379    const DWARFDebugInfoEntryInlinedChain &InlinedChain =
380        CU->getInlinedChainForAddress(Address);
381    if (InlinedChain.DIEs.size() > 0) {
382      const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
383      if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.CU))
384        FunctionName = Name;
385    }
386  }
387  if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
388    const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
389    const bool NeedsAbsoluteFilePath =
390        Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
391    getFileLineInfoForCompileUnit(CU, LineTable, Address,
392                                  NeedsAbsoluteFilePath,
393                                  FileName, Line, Column);
394  }
395  return DILineInfo(StringRef(FileName), StringRef(FunctionName),
396                    Line, Column);
397}
398
399DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address,
400    uint64_t Size,
401    DILineInfoSpecifier Specifier) {
402  DILineInfoTable  Lines;
403  DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
404  if (!CU)
405    return Lines;
406
407  std::string FunctionName = "<invalid>";
408  if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
409    // The address may correspond to instruction in some inlined function,
410    // so we have to build the chain of inlined functions and take the
411    // name of the topmost function in it.
412    const DWARFDebugInfoEntryInlinedChain &InlinedChain =
413        CU->getInlinedChainForAddress(Address);
414    if (InlinedChain.DIEs.size() > 0) {
415      const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
416      if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.CU))
417        FunctionName = Name;
418    }
419  }
420
421  StringRef  FuncNameRef = StringRef(FunctionName);
422
423  // If the Specifier says we don't need FileLineInfo, just
424  // return the top-most function at the starting address.
425  if (!Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
426    Lines.push_back(std::make_pair(Address,
427                                   DILineInfo(StringRef("<invalid>"),
428                                              FuncNameRef, 0, 0)));
429    return Lines;
430  }
431
432  const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
433  const bool NeedsAbsoluteFilePath =
434      Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
435
436  // Get the index of row we're looking for in the line table.
437  std::vector<uint32_t> RowVector;
438  if (!LineTable->lookupAddressRange(Address, Size, RowVector))
439    return Lines;
440
441  uint32_t NumRows = RowVector.size();
442  for (uint32_t i = 0; i < NumRows; ++i) {
443    uint32_t RowIndex = RowVector[i];
444    // Take file number and line/column from the row.
445    const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
446    std::string FileName = "<invalid>";
447    getFileNameForCompileUnit(CU, LineTable, Row.File,
448                              NeedsAbsoluteFilePath, FileName);
449    Lines.push_back(std::make_pair(Row.Address,
450                                   DILineInfo(StringRef(FileName),
451                                         FuncNameRef, Row.Line, Row.Column)));
452  }
453
454  return Lines;
455}
456
457DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address,
458    DILineInfoSpecifier Specifier) {
459  DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
460  if (!CU)
461    return DIInliningInfo();
462
463  const DWARFDebugInfoEntryInlinedChain &InlinedChain =
464      CU->getInlinedChainForAddress(Address);
465  if (InlinedChain.DIEs.size() == 0)
466    return DIInliningInfo();
467
468  DIInliningInfo InliningInfo;
469  uint32_t CallFile = 0, CallLine = 0, CallColumn = 0;
470  const DWARFLineTable *LineTable = 0;
471  for (uint32_t i = 0, n = InlinedChain.DIEs.size(); i != n; i++) {
472    const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i];
473    std::string FileName = "<invalid>";
474    std::string FunctionName = "<invalid>";
475    uint32_t Line = 0;
476    uint32_t Column = 0;
477    // Get function name if necessary.
478    if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
479      if (const char *Name = FunctionDIE.getSubroutineName(InlinedChain.CU))
480        FunctionName = Name;
481    }
482    if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
483      const bool NeedsAbsoluteFilePath =
484          Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
485      if (i == 0) {
486        // For the topmost frame, initialize the line table of this
487        // compile unit and fetch file/line info from it.
488        LineTable = getLineTableForCompileUnit(CU);
489        // For the topmost routine, get file/line info from line table.
490        getFileLineInfoForCompileUnit(CU, LineTable, Address,
491                                      NeedsAbsoluteFilePath,
492                                      FileName, Line, Column);
493      } else {
494        // Otherwise, use call file, call line and call column from
495        // previous DIE in inlined chain.
496        getFileNameForCompileUnit(CU, LineTable, CallFile,
497                                  NeedsAbsoluteFilePath, FileName);
498        Line = CallLine;
499        Column = CallColumn;
500      }
501      // Get call file/line/column of a current DIE.
502      if (i + 1 < n) {
503        FunctionDIE.getCallerFrame(InlinedChain.CU, CallFile, CallLine,
504                                   CallColumn);
505      }
506    }
507    DILineInfo Frame(StringRef(FileName), StringRef(FunctionName),
508                     Line, Column);
509    InliningInfo.addFrame(Frame);
510  }
511  return InliningInfo;
512}
513
514static bool consumeCompressedDebugSectionHeader(StringRef &data,
515                                                uint64_t &OriginalSize) {
516  // Consume "ZLIB" prefix.
517  if (!data.startswith("ZLIB"))
518    return false;
519  data = data.substr(4);
520  // Consume uncompressed section size (big-endian 8 bytes).
521  DataExtractor extractor(data, false, 8);
522  uint32_t Offset = 0;
523  OriginalSize = extractor.getU64(&Offset);
524  if (Offset == 0)
525    return false;
526  data = data.substr(Offset);
527  return true;
528}
529
530DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
531  IsLittleEndian(Obj->isLittleEndian()),
532  AddressSize(Obj->getBytesInAddress()) {
533  error_code ec;
534  for (object::section_iterator i = Obj->begin_sections(),
535         e = Obj->end_sections();
536       i != e; i.increment(ec)) {
537    StringRef name;
538    i->getName(name);
539    StringRef data;
540    i->getContents(data);
541
542    name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes.
543
544    // Check if debug info section is compressed with zlib.
545    if (name.startswith("zdebug_")) {
546      uint64_t OriginalSize;
547      if (!zlib::isAvailable() ||
548          !consumeCompressedDebugSectionHeader(data, OriginalSize))
549        continue;
550      OwningPtr<MemoryBuffer> UncompressedSection;
551      if (zlib::uncompress(data, UncompressedSection, OriginalSize) !=
552          zlib::StatusOK)
553        continue;
554      // Make data point to uncompressed section contents and save its contents.
555      name = name.substr(1);
556      data = UncompressedSection->getBuffer();
557      UncompressedSections.push_back(UncompressedSection.take());
558    }
559
560    StringRef *Section = StringSwitch<StringRef*>(name)
561        .Case("debug_info", &InfoSection)
562        .Case("debug_abbrev", &AbbrevSection)
563        .Case("debug_loc", &LocSection)
564        .Case("debug_line", &LineSection)
565        .Case("debug_aranges", &ARangeSection)
566        .Case("debug_frame", &DebugFrameSection)
567        .Case("debug_str", &StringSection)
568        .Case("debug_ranges", &RangeSection)
569        .Case("debug_pubnames", &PubNamesSection)
570        .Case("debug_info.dwo", &InfoDWOSection)
571        .Case("debug_abbrev.dwo", &AbbrevDWOSection)
572        .Case("debug_str.dwo", &StringDWOSection)
573        .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
574        .Case("debug_addr", &AddrSection)
575        // Any more debug info sections go here.
576        .Default(0);
577    if (Section) {
578      *Section = data;
579      if (name == "debug_ranges") {
580        // FIXME: Use the other dwo range section when we emit it.
581        RangeDWOSection = data;
582      }
583    }
584
585    section_iterator RelocatedSection = i->getRelocatedSection();
586    if (RelocatedSection == Obj->end_sections())
587      continue;
588
589    StringRef RelSecName;
590    RelocatedSection->getName(RelSecName);
591    RelSecName = RelSecName.substr(
592        RelSecName.find_first_not_of("._")); // Skip . and _ prefixes.
593
594    // TODO: Add support for relocations in other sections as needed.
595    // Record relocations for the debug_info and debug_line sections.
596    RelocAddrMap *Map = StringSwitch<RelocAddrMap*>(RelSecName)
597        .Case("debug_info", &InfoRelocMap)
598        .Case("debug_loc", &LocRelocMap)
599        .Case("debug_info.dwo", &InfoDWORelocMap)
600        .Case("debug_line", &LineRelocMap)
601        .Default(0);
602    if (!Map)
603      continue;
604
605    if (i->begin_relocations() != i->end_relocations()) {
606      uint64_t SectionSize;
607      RelocatedSection->getSize(SectionSize);
608      for (object::relocation_iterator reloc_i = i->begin_relocations(),
609             reloc_e = i->end_relocations();
610           reloc_i != reloc_e; reloc_i.increment(ec)) {
611        uint64_t Address;
612        reloc_i->getOffset(Address);
613        uint64_t Type;
614        reloc_i->getType(Type);
615        uint64_t SymAddr = 0;
616        // ELF relocations may need the symbol address
617        if (Obj->isELF()) {
618          object::symbol_iterator Sym = reloc_i->getSymbol();
619          Sym->getAddress(SymAddr);
620        }
621
622        object::RelocVisitor V(Obj->getFileFormatName());
623        // The section address is always 0 for debug sections.
624        object::RelocToApply R(V.visit(Type, *reloc_i, 0, SymAddr));
625        if (V.error()) {
626          SmallString<32> Name;
627          error_code ec(reloc_i->getTypeName(Name));
628          if (ec) {
629            errs() << "Aaaaaa! Nameless relocation! Aaaaaa!\n";
630          }
631          errs() << "error: failed to compute relocation: "
632                 << Name << "\n";
633          continue;
634        }
635
636        if (Address + R.Width > SectionSize) {
637          errs() << "error: " << R.Width << "-byte relocation starting "
638                 << Address << " bytes into section " << name << " which is "
639                 << SectionSize << " bytes long.\n";
640          continue;
641        }
642        if (R.Width > 8) {
643          errs() << "error: can't handle a relocation of more than 8 bytes at "
644                    "a time.\n";
645          continue;
646        }
647        DEBUG(dbgs() << "Writing " << format("%p", R.Value)
648                     << " at " << format("%p", Address)
649                     << " with width " << format("%d", R.Width)
650                     << "\n");
651        Map->insert(std::make_pair(Address, std::make_pair(R.Width, R.Value)));
652      }
653    }
654  }
655}
656
657DWARFContextInMemory::~DWARFContextInMemory() {
658  DeleteContainerPointers(UncompressedSections);
659}
660
661void DWARFContextInMemory::anchor() { }
662