DWARFContext.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//===-- DWARFContext.cpp --------------------------------------------------===//
272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//                     The LLVM Compiler Infrastructure
472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// This file is distributed under the University of Illinois Open Source
672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer// License. See LICENSE.TXT for details.
772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//
872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer//===----------------------------------------------------------------------===//
972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
1072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer#include "DWARFContext.h"
1171d94f805514f28730bf39143ee227648d521d09Alexey Samsonov#include "llvm/ADT/SmallString.h"
12784baa6f4440beac54881673ecc7baa88f8b94ddAlexey Samsonov#include "llvm/ADT/StringSwitch.h"
13005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov#include "llvm/Support/Compression.h"
14fe80f1da404d25f93e4a2492b127554a882bd5bbBenjamin Kramer#include "llvm/Support/Dwarf.h"
1534f864fd382156331c61fbb6b7ae4828108b9d69Benjamin Kramer#include "llvm/Support/Format.h"
1671d94f805514f28730bf39143ee227648d521d09Alexey Samsonov#include "llvm/Support/Path.h"
17358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer#include "llvm/Support/raw_ostream.h"
18101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer#include <algorithm>
1972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerusing namespace llvm;
20fe80f1da404d25f93e4a2492b127554a882bd5bbBenjamin Kramerusing namespace dwarf;
217486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindolausing namespace object;
2272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
23e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christophertypedef DWARFDebugLine::LineTable DWARFLineTable;
24e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopher
259ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikiestatic void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data,
26c839df0e4cbc3329ae9f03ca4db5893ea9b2c7bdEric Christopher                           bool LittleEndian, bool GnuStyle) {
279ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikie  OS << "\n." << Name << " contents:\n";
289ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikie  DataExtractor pubNames(Data, LittleEndian, 0);
299ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikie  uint32_t offset = 0;
3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  while (pubNames.isValidOffset(offset)) {
3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << "length = " << format("0x%08x", pubNames.getU32(&offset));
3236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << " version = " << format("0x%04x", pubNames.getU16(&offset));
3336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << " unit_offset = " << format("0x%08x", pubNames.getU32(&offset));
3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << " unit_size = " << format("0x%08x", pubNames.getU32(&offset)) << '\n';
3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (GnuStyle)
3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << "Offset     Linkage  Kind     Name\n";
3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << "Offset     Name\n";
3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    while (offset < Data.size()) {
4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      uint32_t dieRef = pubNames.getU32(&offset);
4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (dieRef == 0)
4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        break;
4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << format("0x%8.8x ", dieRef);
4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (GnuStyle) {
4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        PubIndexEntryDescriptor desc(pubNames.getU8(&offset));
4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        OS << format("%-8s", dwarf::GDBIndexEntryLinkageString(desc.Linkage))
4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           << ' ' << format("%-8s", dwarf::GDBIndexEntryKindString(desc.Kind))
4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           << ' ';
5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << '\"' << pubNames.getCStr(&offset) << "\"\n";
52c839df0e4cbc3329ae9f03ca4db5893ea9b2c7bdEric Christopher    }
539ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikie  }
549ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikie}
559ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikie
56939a4e8b693820d161f362317f7dba9057e66cc7Eli Benderskyvoid DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
57939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) {
58939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    OS << ".debug_abbrev contents:\n";
59939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    getDebugAbbrev()->dump(OS);
60939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  }
61358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer
6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo)
6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (const DWARFDebugAbbrev *D = getDebugAbbrevDWO()) {
6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << "\n.debug_abbrev.dwo contents:\n";
6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      D->dump(OS);
6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
68939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  if (DumpType == DIDT_All || DumpType == DIDT_Info) {
69939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    OS << "\n.debug_info contents:\n";
7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (const auto &CU : compile_units())
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      CU->dump(OS);
7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if ((DumpType == DIDT_All || DumpType == DIDT_InfoDwo) &&
7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      getNumDWOCompileUnits()) {
7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << "\n.debug_info.dwo contents:\n";
7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (const auto &DWOCU : dwo_compile_units())
7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DWOCU->dump(OS);
79939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  }
80358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer
8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if ((DumpType == DIDT_All || DumpType == DIDT_Types) && getNumTypeUnits()) {
82438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie    OS << "\n.debug_types contents:\n";
8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (const auto &TU : type_units())
8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      TU->dump(OS);
8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if ((DumpType == DIDT_All || DumpType == DIDT_TypesDwo) &&
8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      getNumDWOTypeUnits()) {
8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << "\n.debug_types.dwo contents:\n";
9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (const auto &DWOTU : dwo_type_units())
9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DWOTU->dump(OS);
92438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie  }
93438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie
943df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie  if (DumpType == DIDT_All || DumpType == DIDT_Loc) {
95438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie    OS << "\n.debug_loc contents:\n";
963df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie    getDebugLoc()->dump(OS);
973df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie  }
983df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie
9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (DumpType == DIDT_All || DumpType == DIDT_LocDwo) {
10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << "\n.debug_loc.dwo contents:\n";
10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    getDebugLocDWO()->dump(OS);
10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
10460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  if (DumpType == DIDT_All || DumpType == DIDT_Frames) {
10560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky    OS << "\n.debug_frame contents:\n";
10660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky    getDebugFrame()->dump(OS);
10760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  }
10860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky
109358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer  uint32_t offset = 0;
110939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  if (DumpType == DIDT_All || DumpType == DIDT_Aranges) {
111939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    OS << "\n.debug_aranges contents:\n";
112939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
113939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    DWARFDebugArangeSet set;
114939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    while (set.extract(arangesData, &offset))
115939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky      set.dump(OS);
116939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  }
117b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
118eceb5b99777ba944a0ae3748a0371e9a3aa94d56Alexey Samsonov  uint8_t savedAddressByteSize = 0;
119939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  if (DumpType == DIDT_All || DumpType == DIDT_Line) {
120939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    OS << "\n.debug_line contents:\n";
12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (const auto &CU : compile_units()) {
12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      savedAddressByteSize = CU->getAddressByteSize();
123939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky      unsigned stmtOffset =
12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          CU->getCompileUnitDIE()->getAttributeValueAsSectionOffset(
12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines              CU.get(), DW_AT_stmt_list, -1U);
126939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky      if (stmtOffset != -1U) {
1279528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie        DataExtractor lineData(getLineSection().Data, isLittleEndian(),
128939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky                               savedAddressByteSize);
129939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky        DWARFDebugLine::DumpingState state(OS);
1309528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie        DWARFDebugLine::parseStatementTable(lineData, &getLineSection().Relocs, &stmtOffset, state);
131939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky      }
132fe80f1da404d25f93e4a2492b127554a882bd5bbBenjamin Kramer    }
133fe80f1da404d25f93e4a2492b127554a882bd5bbBenjamin Kramer  }
13434f864fd382156331c61fbb6b7ae4828108b9d69Benjamin Kramer
13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (DumpType == DIDT_All || DumpType == DIDT_LineDwo) {
13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << "\n.debug_line.dwo contents:\n";
13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned stmtOffset = 0;
13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(),
13936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                           savedAddressByteSize);
14036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DWARFDebugLine::DumpingState state(OS);
14136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    while (DWARFDebugLine::parsePrologue(lineData, &stmtOffset, &state.Prologue))
14236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      state.finalize();
14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
145939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  if (DumpType == DIDT_All || DumpType == DIDT_Str) {
146939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    OS << "\n.debug_str contents:\n";
147939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    DataExtractor strData(getStringSection(), isLittleEndian(), 0);
148939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    offset = 0;
149939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    uint32_t strOffset = 0;
150939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    while (const char *s = strData.getCStr(&offset)) {
151939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky      OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
152939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky      strOffset = offset;
153939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    }
15434f864fd382156331c61fbb6b7ae4828108b9d69Benjamin Kramer  }
155eceb5b99777ba944a0ae3748a0371e9a3aa94d56Alexey Samsonov
15636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if ((DumpType == DIDT_All || DumpType == DIDT_StrDwo) &&
15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      !getStringDWOSection().empty()) {
15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << "\n.debug_str.dwo contents:\n";
15936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
16036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    offset = 0;
16136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint32_t strDWOOffset = 0;
16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    while (const char *s = strDWOData.getCStr(&offset)) {
16336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
16436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      strDWOOffset = offset;
16536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
16636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
168939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  if (DumpType == DIDT_All || DumpType == DIDT_Ranges) {
169939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    OS << "\n.debug_ranges contents:\n";
170939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    // In fact, different compile units may have different address byte
171939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    // sizes, but for simplicity we just use the address byte size of the last
172939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    // compile unit (there is no easy and fast way to associate address range
173939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    // list and the compile unit it describes).
174939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    DataExtractor rangesData(getRangeSection(), isLittleEndian(),
175939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky                             savedAddressByteSize);
176939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    offset = 0;
177939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    DWARFDebugRangeList rangeList;
178939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    while (rangeList.extract(rangesData, &offset))
179939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky      rangeList.dump(OS);
18082de10a34c9432029040ced17129079a7d80904eEric Christopher  }
18172f7bfbf0e02bb11d3e7cca1f9598c5f9d9fa2caEric Christopher
182c839df0e4cbc3329ae9f03ca4db5893ea9b2c7bdEric Christopher  if (DumpType == DIDT_All || DumpType == DIDT_Pubnames)
183c839df0e4cbc3329ae9f03ca4db5893ea9b2c7bdEric Christopher    dumpPubSection(OS, "debug_pubnames", getPubNamesSection(),
184c839df0e4cbc3329ae9f03ca4db5893ea9b2c7bdEric Christopher                   isLittleEndian(), false);
185e38825f490b898644089d5cd9cb90cec681bded8Krzysztof Parzyszek
1867357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher  if (DumpType == DIDT_All || DumpType == DIDT_Pubtypes)
1877357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher    dumpPubSection(OS, "debug_pubtypes", getPubTypesSection(),
1887357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher                   isLittleEndian(), false);
1897357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher
1909ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikie  if (DumpType == DIDT_All || DumpType == DIDT_GnuPubnames)
1919ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikie    dumpPubSection(OS, "debug_gnu_pubnames", getGnuPubNamesSection(),
192c839df0e4cbc3329ae9f03ca4db5893ea9b2c7bdEric Christopher                   isLittleEndian(), true /* GnuStyle */);
1939ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikie
1949ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikie  if (DumpType == DIDT_All || DumpType == DIDT_GnuPubtypes)
1959ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikie    dumpPubSection(OS, "debug_gnu_pubtypes", getGnuPubTypesSection(),
196c839df0e4cbc3329ae9f03ca4db5893ea9b2c7bdEric Christopher                   isLittleEndian(), true /* GnuStyle */);
197994c37fcb001bc5a53bf2c676009b327b882d765David Blaikie
19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if ((DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) &&
19936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      !getStringOffsetDWOSection().empty()) {
20036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << "\n.debug_str_offsets.dwo contents:\n";
20136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(),
20236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                               0);
20336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    offset = 0;
20436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint64_t size = getStringOffsetDWOSection().size();
20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    while (offset < size) {
20636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << format("0x%8.8x: ", offset);
20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
20893f3fed999e039988deca64d19cbf122d46cdd59Eric Christopher    }
209939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  }
21072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
21172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
21272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerconst DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
21372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (Abbrev)
21472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return Abbrev.get();
21572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
21672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0);
21772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
21872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  Abbrev.reset(new DWARFDebugAbbrev());
21972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  Abbrev->parse(abbrData);
22072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return Abbrev.get();
22172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
22272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
22382de10a34c9432029040ced17129079a7d80904eEric Christopherconst DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
22482de10a34c9432029040ced17129079a7d80904eEric Christopher  if (AbbrevDWO)
22582de10a34c9432029040ced17129079a7d80904eEric Christopher    return AbbrevDWO.get();
22682de10a34c9432029040ced17129079a7d80904eEric Christopher
22782de10a34c9432029040ced17129079a7d80904eEric Christopher  DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0);
22882de10a34c9432029040ced17129079a7d80904eEric Christopher  AbbrevDWO.reset(new DWARFDebugAbbrev());
22982de10a34c9432029040ced17129079a7d80904eEric Christopher  AbbrevDWO->parse(abbrData);
23082de10a34c9432029040ced17129079a7d80904eEric Christopher  return AbbrevDWO.get();
23182de10a34c9432029040ced17129079a7d80904eEric Christopher}
23282de10a34c9432029040ced17129079a7d80904eEric Christopher
2333df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikieconst DWARFDebugLoc *DWARFContext::getDebugLoc() {
2343df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie  if (Loc)
2353df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie    return Loc.get();
2363df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie
2379528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie  DataExtractor LocData(getLocSection().Data, isLittleEndian(), 0);
2389528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie  Loc.reset(new DWARFDebugLoc(getLocSection().Relocs));
2393df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie  // assume all compile units have the same address byte size
2403df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie  if (getNumCompileUnits())
2413df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie    Loc->parse(LocData, getCompileUnitAtIndex(0)->getAddressByteSize());
2423df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie  return Loc.get();
2433df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie}
2443df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie
24536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesconst DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() {
24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (LocDWO)
24736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return LocDWO.get();
24836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
24936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DataExtractor LocData(getLocDWOSection().Data, isLittleEndian(), 0);
25036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  LocDWO.reset(new DWARFDebugLocDWO());
25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  LocDWO->parse(LocData);
25236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return LocDWO.get();
25336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
25436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
255358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramerconst DWARFDebugAranges *DWARFContext::getDebugAranges() {
256358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer  if (Aranges)
257358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer    return Aranges.get();
258358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer
259358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer  Aranges.reset(new DWARFDebugAranges());
26063a450a313a9b0a08622e97b53f5dd83f9266143Alexey Samsonov  Aranges->generate(this);
261358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer  return Aranges.get();
262358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer}
263358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer
26460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskyconst DWARFDebugFrame *DWARFContext::getDebugFrame() {
26560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  if (DebugFrame)
26660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky    return DebugFrame.get();
26760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky
26860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  // There's a "bug" in the DWARFv3 standard with respect to the target address
26960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  // size within debug frame sections. While DWARF is supposed to be independent
27060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  // of its container, FDEs have fields with size being "target address size",
27160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  // which isn't specified in DWARF in general. It's only specified for CUs, but
27260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  // .eh_frame can appear without a .debug_info section. Follow the example of
27360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  // other tools (libdwarf) and extract this from the container (ObjectFile
27460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  // provides this information). This problem is fixed in DWARFv4
27560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  // See this dwarf-discuss discussion for more details:
27660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
27760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(),
27860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky                               getAddressSize());
27960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  DebugFrame.reset(new DWARFDebugFrame());
28060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  DebugFrame->parse(debugFrameData);
28160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  return DebugFrame.get();
28260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky}
28360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky
284e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopherconst DWARFLineTable *
285c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin KramerDWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) {
286c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer  if (!Line)
2879528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie    Line.reset(new DWARFDebugLine(&getLineSection().Relocs));
288c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer
289c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer  unsigned stmtOffset =
290c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov      cu->getCompileUnitDIE()->getAttributeValueAsSectionOffset(
291c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov          cu, DW_AT_stmt_list, -1U);
292c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer  if (stmtOffset == -1U)
293c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer    return 0; // No line table for this compile unit.
294c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer
295c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer  // See if the line table is cached.
296e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopher  if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
297c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer    return lt;
298c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer
299c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer  // We have to parse it first.
3009528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie  DataExtractor lineData(getLineSection().Data, isLittleEndian(),
301c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer                         cu->getAddressByteSize());
302c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer  return Line->getOrParseLineTable(lineData, stmtOffset);
303b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer}
304b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
30572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramervoid DWARFContext::parseCompileUnits() {
30636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!CUs.empty())
30736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
30872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint32_t offset = 0;
3099528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie  const DataExtractor &DIData = DataExtractor(getInfoSection().Data,
310b69b55f54a66d4df9549927a3cce307855d6de49Eric Christopher                                              isLittleEndian(), 0);
311b69b55f54a66d4df9549927a3cce307855d6de49Eric Christopher  while (DIData.isValidOffset(offset)) {
31236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    std::unique_ptr<DWARFCompileUnit> CU(new DWARFCompileUnit(
3139528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie        getDebugAbbrev(), getInfoSection().Data, getAbbrevSection(),
314eb0c179b5688177c1ab5f52a8c0338459e97606eAlexey Samsonov        getRangeSection(), getStringSection(), StringRef(), getAddrSection(),
3159528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie        &getInfoSection().Relocs, isLittleEndian()));
316eb0c179b5688177c1ab5f52a8c0338459e97606eAlexey Samsonov    if (!CU->extract(DIData, &offset)) {
31772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      break;
31872c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
31936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    CUs.push_back(std::move(CU));
320cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    offset = CUs.back()->getNextUnitOffset();
32172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
32272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
323101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer
324438f5391b2d502a132a4a20469e9e56305b221a4David Blaikievoid DWARFContext::parseTypeUnits() {
32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!TUs.empty())
32636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
32736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (const auto &I : getTypesSections()) {
328438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie    uint32_t offset = 0;
329438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie    const DataExtractor &DIData =
33036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        DataExtractor(I.second.Data, isLittleEndian(), 0);
331438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie    while (DIData.isValidOffset(offset)) {
33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      std::unique_ptr<DWARFTypeUnit> TU(new DWARFTypeUnit(
33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          getDebugAbbrev(), I.second.Data, getAbbrevSection(),
334438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie          getRangeSection(), getStringSection(), StringRef(), getAddrSection(),
33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          &I.second.Relocs, isLittleEndian()));
336438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie      if (!TU->extract(DIData, &offset))
337438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie        break;
33836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      TUs.push_back(std::move(TU));
339438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie      offset = TUs.back()->getNextUnitOffset();
340438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie    }
341438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie  }
342438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie}
343438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie
34482de10a34c9432029040ced17129079a7d80904eEric Christophervoid DWARFContext::parseDWOCompileUnits() {
34536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!DWOCUs.empty())
34636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
34782de10a34c9432029040ced17129079a7d80904eEric Christopher  uint32_t offset = 0;
3489528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie  const DataExtractor &DIData =
3499528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie      DataExtractor(getInfoDWOSection().Data, isLittleEndian(), 0);
35082de10a34c9432029040ced17129079a7d80904eEric Christopher  while (DIData.isValidOffset(offset)) {
35136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    std::unique_ptr<DWARFCompileUnit> DWOCU(new DWARFCompileUnit(
3529528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie        getDebugAbbrevDWO(), getInfoDWOSection().Data, getAbbrevDWOSection(),
353eb0c179b5688177c1ab5f52a8c0338459e97606eAlexey Samsonov        getRangeDWOSection(), getStringDWOSection(),
3549528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie        getStringOffsetDWOSection(), getAddrSection(),
3559528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie        &getInfoDWOSection().Relocs, isLittleEndian()));
356eb0c179b5688177c1ab5f52a8c0338459e97606eAlexey Samsonov    if (!DWOCU->extract(DIData, &offset)) {
35782de10a34c9432029040ced17129079a7d80904eEric Christopher      break;
35882de10a34c9432029040ced17129079a7d80904eEric Christopher    }
35936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DWOCUs.push_back(std::move(DWOCU));
360cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    offset = DWOCUs.back()->getNextUnitOffset();
36182de10a34c9432029040ced17129079a7d80904eEric Christopher  }
36282de10a34c9432029040ced17129079a7d80904eEric Christopher}
36382de10a34c9432029040ced17129079a7d80904eEric Christopher
36436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid DWARFContext::parseDWOTypeUnits() {
36536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!DWOTUs.empty())
36636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
36736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (const auto &I : getTypesDWOSections()) {
36836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint32_t offset = 0;
36936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const DataExtractor &DIData =
37036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        DataExtractor(I.second.Data, isLittleEndian(), 0);
37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    while (DIData.isValidOffset(offset)) {
37236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      std::unique_ptr<DWARFTypeUnit> TU(new DWARFTypeUnit(
37336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          getDebugAbbrevDWO(), I.second.Data, getAbbrevDWOSection(),
37436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          getRangeDWOSection(), getStringDWOSection(),
37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          getStringOffsetDWOSection(), getAddrSection(), &I.second.Relocs,
37636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          isLittleEndian()));
37736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (!TU->extract(DIData, &offset))
37836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        break;
37936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DWOTUs.push_back(std::move(TU));
38036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      offset = DWOTUs.back()->getNextUnitOffset();
38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
38236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
38336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
38436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
385101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramernamespace {
386101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer  struct OffsetComparator {
38736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
38836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool operator()(const std::unique_ptr<DWARFCompileUnit> &LHS,
38936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                    const std::unique_ptr<DWARFCompileUnit> &RHS) const {
390eb0c179b5688177c1ab5f52a8c0338459e97606eAlexey Samsonov      return LHS->getOffset() < RHS->getOffset();
391101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer    }
39236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool operator()(const std::unique_ptr<DWARFCompileUnit> &LHS,
39336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                    uint32_t RHS) const {
394eb0c179b5688177c1ab5f52a8c0338459e97606eAlexey Samsonov      return LHS->getOffset() < RHS;
395101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer    }
39636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool operator()(uint32_t LHS,
39736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                    const std::unique_ptr<DWARFCompileUnit> &RHS) const {
398eb0c179b5688177c1ab5f52a8c0338459e97606eAlexey Samsonov      return LHS < RHS->getOffset();
399101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer    }
400101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer  };
401101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer}
402101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer
40338a6381c0a58e013577b1957199128af9573fc20Alexey SamsonovDWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
40436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  parseCompileUnits();
405101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer
40636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<DWARFCompileUnit> *CU =
407eb0c179b5688177c1ab5f52a8c0338459e97606eAlexey Samsonov      std::lower_bound(CUs.begin(), CUs.end(), Offset, OffsetComparator());
408eb0c179b5688177c1ab5f52a8c0338459e97606eAlexey Samsonov  if (CU != CUs.end()) {
40936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return CU->get();
410eb0c179b5688177c1ab5f52a8c0338459e97606eAlexey Samsonov  }
411101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer  return 0;
412101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer}
413101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer
41438a6381c0a58e013577b1957199128af9573fc20Alexey SamsonovDWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
4159013db3399d2847899ba32daf58844bba1aef6ddBenjamin Kramer  // First, get the offset of the compile unit.
41638a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  uint32_t CUOffset = getDebugAranges()->findAddress(Address);
417101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer  // Retrieve the compile unit.
41838a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  return getCompileUnitForOffset(CUOffset);
41938a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov}
42038a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov
421e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopherstatic bool getFileNameForCompileUnit(DWARFCompileUnit *CU,
422e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopher                                      const DWARFLineTable *LineTable,
423e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopher                                      uint64_t FileIndex,
424e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopher                                      bool NeedsAbsoluteFilePath,
425e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopher                                      std::string &FileName) {
42638a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  if (CU == 0 ||
42738a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov      LineTable == 0 ||
42838a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov      !LineTable->getFileNameByIndex(FileIndex, NeedsAbsoluteFilePath,
42938a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov                                     FileName))
43038a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    return false;
43138a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  if (NeedsAbsoluteFilePath && sys::path::is_relative(FileName)) {
43238a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    // We may still need to append compilation directory of compile unit.
43338a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    SmallString<16> AbsolutePath;
43438a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    if (const char *CompilationDir = CU->getCompilationDir()) {
43538a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov      sys::path::append(AbsolutePath, CompilationDir);
4369d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov    }
43738a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    sys::path::append(AbsolutePath, FileName);
43838a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    FileName = AbsolutePath.str();
4393e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  }
44038a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  return true;
44138a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov}
44238a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov
443e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopherstatic bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU,
444e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopher                                          const DWARFLineTable *LineTable,
445e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopher                                          uint64_t Address,
446e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopher                                          bool NeedsAbsoluteFilePath,
447e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopher                                          std::string &FileName,
448e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopher                                          uint32_t &Line, uint32_t &Column) {
4495eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  if (CU == 0 || LineTable == 0)
45038a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    return false;
45138a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  // Get the index of row we're looking for in the line table.
45238a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  uint32_t RowIndex = LineTable->lookupAddress(Address);
45338a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  if (RowIndex == -1U)
45438a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    return false;
45538a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  // Take file number and line/column from the row.
45638a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
45738a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  if (!getFileNameForCompileUnit(CU, LineTable, Row.File,
45838a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov                                 NeedsAbsoluteFilePath, FileName))
45938a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    return false;
46038a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  Line = Row.Line;
46138a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  Column = Row.Column;
46238a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  return true;
46338a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov}
46438a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov
46538a6381c0a58e013577b1957199128af9573fc20Alexey SamsonovDILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
46638a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    DILineInfoSpecifier Specifier) {
46738a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
46838a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  if (!CU)
46938a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    return DILineInfo();
47038a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  std::string FileName = "<invalid>";
47138a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  std::string FunctionName = "<invalid>";
47238a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  uint32_t Line = 0;
47338a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  uint32_t Column = 0;
47438a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
4755eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    // The address may correspond to instruction in some inlined function,
4765eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    // so we have to build the chain of inlined functions and take the
4775eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    // name of the topmost function in it.
478e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov    const DWARFDebugInfoEntryInlinedChain &InlinedChain =
4795eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        CU->getInlinedChainForAddress(Address);
480e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov    if (InlinedChain.DIEs.size() > 0) {
481e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov      const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
482cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie      if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U))
48338a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov        FunctionName = Name;
4843e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov    }
4853e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  }
48638a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
487e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopher    const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
48838a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    const bool NeedsAbsoluteFilePath =
48938a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov        Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
4905eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    getFileLineInfoForCompileUnit(CU, LineTable, Address,
4915eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov                                  NeedsAbsoluteFilePath,
49238a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov                                  FileName, Line, Column);
49338a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  }
49438a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  return DILineInfo(StringRef(FileName), StringRef(FunctionName),
49538a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov                    Line, Column);
496101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer}
4972d24e2a396a1d211baaeedf32148a3b657240170David Blaikie
498e27a787760ea7c2899da3287002fe8ba316df0d0Andrew KaylorDILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address,
499e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    uint64_t Size,
500e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    DILineInfoSpecifier Specifier) {
501e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  DILineInfoTable  Lines;
502e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
503e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  if (!CU)
504e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    return Lines;
505e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor
506e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  std::string FunctionName = "<invalid>";
507e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
508e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    // The address may correspond to instruction in some inlined function,
509e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    // so we have to build the chain of inlined functions and take the
510e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    // name of the topmost function in it.
511e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov    const DWARFDebugInfoEntryInlinedChain &InlinedChain =
512e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor        CU->getInlinedChainForAddress(Address);
513e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov    if (InlinedChain.DIEs.size() > 0) {
514e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov      const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
515cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie      if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U))
516e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor        FunctionName = Name;
517e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    }
518e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  }
519e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor
520e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  // If the Specifier says we don't need FileLineInfo, just
521e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  // return the top-most function at the starting address.
522e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  if (!Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
523eaad5cdc2a3ac1f8813e9ee72c58428fd5e8bc33David Blaikie    Lines.push_back(
524eaad5cdc2a3ac1f8813e9ee72c58428fd5e8bc33David Blaikie        std::make_pair(Address, DILineInfo("<invalid>", FunctionName, 0, 0)));
525e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    return Lines;
526e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  }
527e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor
528e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
529e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  const bool NeedsAbsoluteFilePath =
530e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor      Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
531e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor
532e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  // Get the index of row we're looking for in the line table.
533e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  std::vector<uint32_t> RowVector;
534e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  if (!LineTable->lookupAddressRange(Address, Size, RowVector))
535e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    return Lines;
536e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor
53736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (uint32_t RowIndex : RowVector) {
538e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    // Take file number and line/column from the row.
539e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
540e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    std::string FileName = "<invalid>";
541e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    getFileNameForCompileUnit(CU, LineTable, Row.File,
542e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor                              NeedsAbsoluteFilePath, FileName);
543eaad5cdc2a3ac1f8813e9ee72c58428fd5e8bc33David Blaikie    Lines.push_back(std::make_pair(
544eaad5cdc2a3ac1f8813e9ee72c58428fd5e8bc33David Blaikie        Row.Address, DILineInfo(FileName, FunctionName, Row.Line, Row.Column)));
545e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  }
546e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor
547e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  return Lines;
548e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor}
549e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor
5505eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey SamsonovDIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address,
5515eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    DILineInfoSpecifier Specifier) {
5525eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
5535eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  if (!CU)
5545eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    return DIInliningInfo();
5555eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
556e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov  const DWARFDebugInfoEntryInlinedChain &InlinedChain =
5575eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      CU->getInlinedChainForAddress(Address);
558e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov  if (InlinedChain.DIEs.size() == 0)
5595eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    return DIInliningInfo();
5605eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
5615eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  DIInliningInfo InliningInfo;
5625eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  uint32_t CallFile = 0, CallLine = 0, CallColumn = 0;
563e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopher  const DWARFLineTable *LineTable = 0;
564e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov  for (uint32_t i = 0, n = InlinedChain.DIEs.size(); i != n; i++) {
565e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov    const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i];
5665eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    std::string FileName = "<invalid>";
5675eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    std::string FunctionName = "<invalid>";
5685eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    uint32_t Line = 0;
5695eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    uint32_t Column = 0;
5705eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    // Get function name if necessary.
5715eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
572cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie      if (const char *Name = FunctionDIE.getSubroutineName(InlinedChain.U))
5735eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        FunctionName = Name;
5745eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    }
5755eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
5765eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      const bool NeedsAbsoluteFilePath =
5775eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov          Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
5785eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      if (i == 0) {
5795eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        // For the topmost frame, initialize the line table of this
5805eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        // compile unit and fetch file/line info from it.
5815eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        LineTable = getLineTableForCompileUnit(CU);
5825eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        // For the topmost routine, get file/line info from line table.
5835eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        getFileLineInfoForCompileUnit(CU, LineTable, Address,
5845eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov                                      NeedsAbsoluteFilePath,
5855eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov                                      FileName, Line, Column);
5865eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      } else {
5875eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        // Otherwise, use call file, call line and call column from
5885eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        // previous DIE in inlined chain.
5895eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        getFileNameForCompileUnit(CU, LineTable, CallFile,
5905eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov                                  NeedsAbsoluteFilePath, FileName);
5915eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        Line = CallLine;
5925eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        Column = CallColumn;
5935eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      }
5945eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      // Get call file/line/column of a current DIE.
5955eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      if (i + 1 < n) {
596cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie        FunctionDIE.getCallerFrame(InlinedChain.U, CallFile, CallLine,
597e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov                                   CallColumn);
5985eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      }
5995eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    }
6005eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    DILineInfo Frame(StringRef(FileName), StringRef(FunctionName),
6015eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov                     Line, Column);
6025eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    InliningInfo.addFrame(Frame);
6035eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  }
6045eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  return InliningInfo;
6055eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov}
6065eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
607005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonovstatic bool consumeCompressedDebugSectionHeader(StringRef &data,
608005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov                                                uint64_t &OriginalSize) {
609005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov  // Consume "ZLIB" prefix.
610005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov  if (!data.startswith("ZLIB"))
611005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov    return false;
612005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov  data = data.substr(4);
613005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov  // Consume uncompressed section size (big-endian 8 bytes).
614005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov  DataExtractor extractor(data, false, 8);
615005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov  uint32_t Offset = 0;
616005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov  OriginalSize = extractor.getU64(&Offset);
617005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov  if (Offset == 0)
618005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov    return false;
619005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov  data = data.substr(Offset);
620005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov  return true;
621005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov}
622005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov
62336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesDWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj)
62436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    : IsLittleEndian(Obj->isLittleEndian()),
62536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      AddressSize(Obj->getBytesInAddress()) {
62636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (const SectionRef &Section : Obj->sections()) {
627d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher    StringRef name;
62836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Section.getName(name);
629d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher    StringRef data;
63036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Section.getContents(data);
631d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher
632d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher    name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes.
633784baa6f4440beac54881673ecc7baa88f8b94ddAlexey Samsonov
634005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov    // Check if debug info section is compressed with zlib.
635005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov    if (name.startswith("zdebug_")) {
636005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov      uint64_t OriginalSize;
637005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov      if (!zlib::isAvailable() ||
638005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov          !consumeCompressedDebugSectionHeader(data, OriginalSize))
639005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov        continue;
64036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      std::unique_ptr<MemoryBuffer> UncompressedSection;
641005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov      if (zlib::uncompress(data, UncompressedSection, OriginalSize) !=
642005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov          zlib::StatusOK)
643005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov        continue;
644005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov      // Make data point to uncompressed section contents and save its contents.
645005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov      name = name.substr(1);
646005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov      data = UncompressedSection->getBuffer();
64736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      UncompressedSections.push_back(std::move(UncompressedSection));
648005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov    }
649005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov
65036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    StringRef *SectionData =
6517357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher        StringSwitch<StringRef *>(name)
6527357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_info", &InfoSection.Data)
6537357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_abbrev", &AbbrevSection)
6547357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_loc", &LocSection.Data)
6557357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_line", &LineSection.Data)
6567357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_aranges", &ARangeSection)
6577357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_frame", &DebugFrameSection)
6587357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_str", &StringSection)
6597357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_ranges", &RangeSection)
6607357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_pubnames", &PubNamesSection)
6617357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_pubtypes", &PubTypesSection)
6627357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_gnu_pubnames", &GnuPubNamesSection)
6637357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
6647357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_info.dwo", &InfoDWOSection.Data)
6657357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_abbrev.dwo", &AbbrevDWOSection)
66636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            .Case("debug_loc.dwo", &LocDWOSection.Data)
66736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            .Case("debug_line.dwo", &LineDWOSection.Data)
6687357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_str.dwo", &StringDWOSection)
6697357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
6707357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_addr", &AddrSection)
6717357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            // Any more debug info sections go here.
6727357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Default(0);
67336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (SectionData) {
67436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      *SectionData = data;
6757486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola      if (name == "debug_ranges") {
6767486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola        // FIXME: Use the other dwo range section when we emit it.
6777486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola        RangeDWOSection = data;
6787486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola      }
679438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie    } else if (name == "debug_types") {
68075331656124ddfdc7829b4dd430083e140bd8549David Blaikie      // Find debug_types data by section rather than name as there are
68175331656124ddfdc7829b4dd430083e140bd8549David Blaikie      // multiple, comdat grouped, debug_types sections.
68236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      TypesSections[Section].Data = data;
68336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    } else if (name == "debug_types.dwo") {
68436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      TypesDWOSections[Section].Data = data;
68582de10a34c9432029040ced17129079a7d80904eEric Christopher    }
686d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher
68736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    section_iterator RelocatedSection = Section.getRelocatedSection();
68836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (RelocatedSection == Obj->section_end())
6897486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola      continue;
6907486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola
6917486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola    StringRef RelSecName;
6927486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola    RelocatedSection->getName(RelSecName);
6937486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola    RelSecName = RelSecName.substr(
6947486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola        RelSecName.find_first_not_of("._")); // Skip . and _ prefixes.
6957486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola
696ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor    // TODO: Add support for relocations in other sections as needed.
697ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor    // Record relocations for the debug_info and debug_line sections.
6987486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola    RelocAddrMap *Map = StringSwitch<RelocAddrMap*>(RelSecName)
6999528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie        .Case("debug_info", &InfoSection.Relocs)
7009528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie        .Case("debug_loc", &LocSection.Relocs)
7019528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie        .Case("debug_info.dwo", &InfoDWOSection.Relocs)
7029528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie        .Case("debug_line", &LineSection.Relocs)
703784baa6f4440beac54881673ecc7baa88f8b94ddAlexey Samsonov        .Default(0);
704438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie    if (!Map) {
70575331656124ddfdc7829b4dd430083e140bd8549David Blaikie      // Find debug_types relocs by section rather than name as there are
70675331656124ddfdc7829b4dd430083e140bd8549David Blaikie      // multiple, comdat grouped, debug_types sections.
70736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (RelSecName == "debug_types")
70836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Map = &TypesSections[*RelocatedSection].Relocs;
70936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      else if (RelSecName == "debug_types.dwo")
71036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Map = &TypesDWOSections[*RelocatedSection].Relocs;
71136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      else
71236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        continue;
713438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie    }
714d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher
71536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Section.relocation_begin() != Section.relocation_end()) {
716d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher      uint64_t SectionSize;
7177486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola      RelocatedSection->getSize(SectionSize);
71836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      for (const RelocationRef &Reloc : Section.relocations()) {
719d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        uint64_t Address;
72036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Reloc.getOffset(Address);
721d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        uint64_t Type;
72236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Reloc.getType(Type);
723ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor        uint64_t SymAddr = 0;
724ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor        // ELF relocations may need the symbol address
725ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor        if (Obj->isELF()) {
72636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          object::symbol_iterator Sym = Reloc.getSymbol();
7276c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindola          Sym->getAddress(SymAddr);
728ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor        }
729d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher
730d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        object::RelocVisitor V(Obj->getFileFormatName());
731d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        // The section address is always 0 for debug sections.
73236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        object::RelocToApply R(V.visit(Type, Reloc, 0, SymAddr));
733d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        if (V.error()) {
734d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher          SmallString<32> Name;
73536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          error_code ec(Reloc.getTypeName(Name));
736d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher          if (ec) {
737d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher            errs() << "Aaaaaa! Nameless relocation! Aaaaaa!\n";
738d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher          }
739d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher          errs() << "error: failed to compute relocation: "
740d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher                 << Name << "\n";
741d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher          continue;
742d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        }
743d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher
744d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        if (Address + R.Width > SectionSize) {
745d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher          errs() << "error: " << R.Width << "-byte relocation starting "
746d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher                 << Address << " bytes into section " << name << " which is "
747d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher                 << SectionSize << " bytes long.\n";
748d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher          continue;
749d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        }
750d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        if (R.Width > 8) {
751d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher          errs() << "error: can't handle a relocation of more than 8 bytes at "
752d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher                    "a time.\n";
753d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher          continue;
754d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        }
755d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        DEBUG(dbgs() << "Writing " << format("%p", R.Value)
756d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher                     << " at " << format("%p", Address)
757d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher                     << " with width " << format("%d", R.Width)
758d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher                     << "\n");
75982de10a34c9432029040ced17129079a7d80904eEric Christopher        Map->insert(std::make_pair(Address, std::make_pair(R.Width, R.Value)));
760d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher      }
761d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher    }
762d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher  }
763d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher}
764d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher
7652d24e2a396a1d211baaeedf32148a3b657240170David Blaikievoid DWARFContextInMemory::anchor() { }
766