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"
11dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "DWARFDebugArangeSet.h"
12dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1371d94f805514f28730bf39143ee227648d521d09Alexey Samsonov#include "llvm/ADT/SmallString.h"
14784baa6f4440beac54881673ecc7baa88f8b94ddAlexey Samsonov#include "llvm/ADT/StringSwitch.h"
15005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov#include "llvm/Support/Compression.h"
16fe80f1da404d25f93e4a2492b127554a882bd5bbBenjamin Kramer#include "llvm/Support/Dwarf.h"
1734f864fd382156331c61fbb6b7ae4828108b9d69Benjamin Kramer#include "llvm/Support/Format.h"
1871d94f805514f28730bf39143ee227648d521d09Alexey Samsonov#include "llvm/Support/Path.h"
19358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer#include "llvm/Support/raw_ostream.h"
20101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer#include <algorithm>
2172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerusing namespace llvm;
22fe80f1da404d25f93e4a2492b127554a882bd5bbBenjamin Kramerusing namespace dwarf;
237486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindolausing namespace object;
2472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
25dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "dwarf"
26dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
27e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christophertypedef DWARFDebugLine::LineTable DWARFLineTable;
28dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinestypedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
29dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinestypedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
30e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopher
319ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikiestatic void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data,
32c839df0e4cbc3329ae9f03ca4db5893ea9b2c7bdEric Christopher                           bool LittleEndian, bool GnuStyle) {
339ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikie  OS << "\n." << Name << " contents:\n";
349ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikie  DataExtractor pubNames(Data, LittleEndian, 0);
359ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikie  uint32_t offset = 0;
3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  while (pubNames.isValidOffset(offset)) {
3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << "length = " << format("0x%08x", pubNames.getU32(&offset));
3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << " version = " << format("0x%04x", pubNames.getU16(&offset));
3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << " unit_offset = " << format("0x%08x", pubNames.getU32(&offset));
4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << " unit_size = " << format("0x%08x", pubNames.getU32(&offset)) << '\n';
4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (GnuStyle)
4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << "Offset     Linkage  Kind     Name\n";
4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << "Offset     Name\n";
4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    while (offset < Data.size()) {
4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      uint32_t dieRef = pubNames.getU32(&offset);
4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (dieRef == 0)
4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        break;
5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << format("0x%8.8x ", dieRef);
5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (GnuStyle) {
5236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        PubIndexEntryDescriptor desc(pubNames.getU8(&offset));
5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        OS << format("%-8s", dwarf::GDBIndexEntryLinkageString(desc.Linkage))
5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           << ' ' << format("%-8s", dwarf::GDBIndexEntryKindString(desc.Kind))
5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           << ' ';
5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << '\"' << pubNames.getCStr(&offset) << "\"\n";
58c839df0e4cbc3329ae9f03ca4db5893ea9b2c7bdEric Christopher    }
599ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikie  }
609ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikie}
619ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikie
62939a4e8b693820d161f362317f7dba9057e66cc7Eli Benderskyvoid DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
63939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) {
64939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    OS << ".debug_abbrev contents:\n";
65939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    getDebugAbbrev()->dump(OS);
66939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  }
67358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer
6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo)
6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (const DWARFDebugAbbrev *D = getDebugAbbrevDWO()) {
7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << "\n.debug_abbrev.dwo contents:\n";
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      D->dump(OS);
7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
74939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  if (DumpType == DIDT_All || DumpType == DIDT_Info) {
75939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    OS << "\n.debug_info contents:\n";
7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (const auto &CU : compile_units())
7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      CU->dump(OS);
7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if ((DumpType == DIDT_All || DumpType == DIDT_InfoDwo) &&
8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      getNumDWOCompileUnits()) {
8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << "\n.debug_info.dwo contents:\n";
8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (const auto &DWOCU : dwo_compile_units())
8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DWOCU->dump(OS);
85939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  }
86358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer
8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if ((DumpType == DIDT_All || DumpType == DIDT_Types) && getNumTypeUnits()) {
88438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie    OS << "\n.debug_types contents:\n";
8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (const auto &TU : type_units())
9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      TU->dump(OS);
9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if ((DumpType == DIDT_All || DumpType == DIDT_TypesDwo) &&
9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      getNumDWOTypeUnits()) {
9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << "\n.debug_types.dwo contents:\n";
9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (const auto &DWOTU : dwo_type_units())
9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DWOTU->dump(OS);
98438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie  }
99438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie
1003df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie  if (DumpType == DIDT_All || DumpType == DIDT_Loc) {
101438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie    OS << "\n.debug_loc contents:\n";
1023df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie    getDebugLoc()->dump(OS);
1033df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie  }
1043df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie
10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (DumpType == DIDT_All || DumpType == DIDT_LocDwo) {
10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << "\n.debug_loc.dwo contents:\n";
10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    getDebugLocDWO()->dump(OS);
10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
11060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  if (DumpType == DIDT_All || DumpType == DIDT_Frames) {
11160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky    OS << "\n.debug_frame contents:\n";
11260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky    getDebugFrame()->dump(OS);
11360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  }
11460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky
115358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer  uint32_t offset = 0;
116939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  if (DumpType == DIDT_All || DumpType == DIDT_Aranges) {
117939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    OS << "\n.debug_aranges contents:\n";
118939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
119939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    DWARFDebugArangeSet set;
120939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    while (set.extract(arangesData, &offset))
121939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky      set.dump(OS);
122939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  }
123b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
124eceb5b99777ba944a0ae3748a0371e9a3aa94d56Alexey Samsonov  uint8_t savedAddressByteSize = 0;
125939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  if (DumpType == DIDT_All || DumpType == DIDT_Line) {
126939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    OS << "\n.debug_line contents:\n";
12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (const auto &CU : compile_units()) {
12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      savedAddressByteSize = CU->getAddressByteSize();
129939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky      unsigned stmtOffset =
13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          CU->getCompileUnitDIE()->getAttributeValueAsSectionOffset(
13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines              CU.get(), DW_AT_stmt_list, -1U);
132939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky      if (stmtOffset != -1U) {
1339528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie        DataExtractor lineData(getLineSection().Data, isLittleEndian(),
134939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky                               savedAddressByteSize);
135dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        DWARFDebugLine::LineTable LineTable;
136dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        LineTable.parse(lineData, &getLineSection().Relocs, &stmtOffset);
137dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        LineTable.dump(OS);
138939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky      }
139fe80f1da404d25f93e4a2492b127554a882bd5bbBenjamin Kramer    }
140fe80f1da404d25f93e4a2492b127554a882bd5bbBenjamin Kramer  }
14134f864fd382156331c61fbb6b7ae4828108b9d69Benjamin Kramer
14236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (DumpType == DIDT_All || DumpType == DIDT_LineDwo) {
14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << "\n.debug_line.dwo contents:\n";
14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned stmtOffset = 0;
14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DataExtractor lineData(getLineDWOSection().Data, isLittleEndian(),
14636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                           savedAddressByteSize);
147dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    DWARFDebugLine::LineTable LineTable;
148dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    while (LineTable.Prologue.parse(lineData, &stmtOffset)) {
149dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      LineTable.dump(OS);
150dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      LineTable.clear();
151dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
15236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
15336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
154939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  if (DumpType == DIDT_All || DumpType == DIDT_Str) {
155939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    OS << "\n.debug_str contents:\n";
156939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    DataExtractor strData(getStringSection(), isLittleEndian(), 0);
157939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    offset = 0;
158939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    uint32_t strOffset = 0;
159939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    while (const char *s = strData.getCStr(&offset)) {
160939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky      OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
161939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky      strOffset = offset;
162939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    }
16334f864fd382156331c61fbb6b7ae4828108b9d69Benjamin Kramer  }
164eceb5b99777ba944a0ae3748a0371e9a3aa94d56Alexey Samsonov
16536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if ((DumpType == DIDT_All || DumpType == DIDT_StrDwo) &&
16636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      !getStringDWOSection().empty()) {
16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << "\n.debug_str.dwo contents:\n";
16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    offset = 0;
17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint32_t strDWOOffset = 0;
17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    while (const char *s = strDWOData.getCStr(&offset)) {
17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      strDWOOffset = offset;
17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
177939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  if (DumpType == DIDT_All || DumpType == DIDT_Ranges) {
178939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    OS << "\n.debug_ranges contents:\n";
179939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    // In fact, different compile units may have different address byte
180939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    // sizes, but for simplicity we just use the address byte size of the last
181939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    // compile unit (there is no easy and fast way to associate address range
182939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    // list and the compile unit it describes).
183939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    DataExtractor rangesData(getRangeSection(), isLittleEndian(),
184939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky                             savedAddressByteSize);
185939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    offset = 0;
186939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    DWARFDebugRangeList rangeList;
187939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky    while (rangeList.extract(rangesData, &offset))
188939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky      rangeList.dump(OS);
18982de10a34c9432029040ced17129079a7d80904eEric Christopher  }
19072f7bfbf0e02bb11d3e7cca1f9598c5f9d9fa2caEric Christopher
191c839df0e4cbc3329ae9f03ca4db5893ea9b2c7bdEric Christopher  if (DumpType == DIDT_All || DumpType == DIDT_Pubnames)
192c839df0e4cbc3329ae9f03ca4db5893ea9b2c7bdEric Christopher    dumpPubSection(OS, "debug_pubnames", getPubNamesSection(),
193c839df0e4cbc3329ae9f03ca4db5893ea9b2c7bdEric Christopher                   isLittleEndian(), false);
194e38825f490b898644089d5cd9cb90cec681bded8Krzysztof Parzyszek
1957357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher  if (DumpType == DIDT_All || DumpType == DIDT_Pubtypes)
1967357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher    dumpPubSection(OS, "debug_pubtypes", getPubTypesSection(),
1977357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher                   isLittleEndian(), false);
1987357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher
1999ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikie  if (DumpType == DIDT_All || DumpType == DIDT_GnuPubnames)
2009ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikie    dumpPubSection(OS, "debug_gnu_pubnames", getGnuPubNamesSection(),
201c839df0e4cbc3329ae9f03ca4db5893ea9b2c7bdEric Christopher                   isLittleEndian(), true /* GnuStyle */);
2029ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikie
2039ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikie  if (DumpType == DIDT_All || DumpType == DIDT_GnuPubtypes)
2049ddf28d501144276fb47ce2e5f48f2497d9898d5David Blaikie    dumpPubSection(OS, "debug_gnu_pubtypes", getGnuPubTypesSection(),
205c839df0e4cbc3329ae9f03ca4db5893ea9b2c7bdEric Christopher                   isLittleEndian(), true /* GnuStyle */);
206994c37fcb001bc5a53bf2c676009b327b882d765David Blaikie
20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if ((DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) &&
20836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      !getStringOffsetDWOSection().empty()) {
20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << "\n.debug_str_offsets.dwo contents:\n";
21036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(),
21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                               0);
21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    offset = 0;
21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint64_t size = getStringOffsetDWOSection().size();
21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    while (offset < size) {
21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << format("0x%8.8x: ", offset);
21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
21793f3fed999e039988deca64d19cbf122d46cdd59Eric Christopher    }
218939a4e8b693820d161f362317f7dba9057e66cc7Eli Bendersky  }
21972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
22072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
22172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramerconst DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
22272c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  if (Abbrev)
22372c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    return Abbrev.get();
22472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
22572c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0);
22672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
22772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  Abbrev.reset(new DWARFDebugAbbrev());
228dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Abbrev->extract(abbrData);
22972c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  return Abbrev.get();
23072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
23172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer
23282de10a34c9432029040ced17129079a7d80904eEric Christopherconst DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
23382de10a34c9432029040ced17129079a7d80904eEric Christopher  if (AbbrevDWO)
23482de10a34c9432029040ced17129079a7d80904eEric Christopher    return AbbrevDWO.get();
23582de10a34c9432029040ced17129079a7d80904eEric Christopher
23682de10a34c9432029040ced17129079a7d80904eEric Christopher  DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0);
23782de10a34c9432029040ced17129079a7d80904eEric Christopher  AbbrevDWO.reset(new DWARFDebugAbbrev());
238dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  AbbrevDWO->extract(abbrData);
23982de10a34c9432029040ced17129079a7d80904eEric Christopher  return AbbrevDWO.get();
24082de10a34c9432029040ced17129079a7d80904eEric Christopher}
24182de10a34c9432029040ced17129079a7d80904eEric Christopher
2423df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikieconst DWARFDebugLoc *DWARFContext::getDebugLoc() {
2433df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie  if (Loc)
2443df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie    return Loc.get();
2453df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie
2469528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie  DataExtractor LocData(getLocSection().Data, isLittleEndian(), 0);
2479528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie  Loc.reset(new DWARFDebugLoc(getLocSection().Relocs));
2483df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie  // assume all compile units have the same address byte size
2493df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie  if (getNumCompileUnits())
2503df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie    Loc->parse(LocData, getCompileUnitAtIndex(0)->getAddressByteSize());
2513df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie  return Loc.get();
2523df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie}
2533df7d2f70bb316ebeec8a8c862b3da5386fbb145David Blaikie
25436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesconst DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() {
25536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (LocDWO)
25636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return LocDWO.get();
25736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
25836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DataExtractor LocData(getLocDWOSection().Data, isLittleEndian(), 0);
25936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  LocDWO.reset(new DWARFDebugLocDWO());
26036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  LocDWO->parse(LocData);
26136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return LocDWO.get();
26236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
26336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
264358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramerconst DWARFDebugAranges *DWARFContext::getDebugAranges() {
265358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer  if (Aranges)
266358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer    return Aranges.get();
267358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer
268358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer  Aranges.reset(new DWARFDebugAranges());
26963a450a313a9b0a08622e97b53f5dd83f9266143Alexey Samsonov  Aranges->generate(this);
270358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer  return Aranges.get();
271358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer}
272358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer
27360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Benderskyconst DWARFDebugFrame *DWARFContext::getDebugFrame() {
27460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  if (DebugFrame)
27560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky    return DebugFrame.get();
27660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky
27760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  // There's a "bug" in the DWARFv3 standard with respect to the target address
27860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  // size within debug frame sections. While DWARF is supposed to be independent
27960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  // of its container, FDEs have fields with size being "target address size",
28060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  // which isn't specified in DWARF in general. It's only specified for CUs, but
28160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  // .eh_frame can appear without a .debug_info section. Follow the example of
28260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  // other tools (libdwarf) and extract this from the container (ObjectFile
28360bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  // provides this information). This problem is fixed in DWARFv4
28460bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  // See this dwarf-discuss discussion for more details:
28560bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
28660bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(),
28760bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky                               getAddressSize());
28860bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  DebugFrame.reset(new DWARFDebugFrame());
28960bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  DebugFrame->parse(debugFrameData);
29060bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky  return DebugFrame.get();
29160bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky}
29260bdc5b16e2fc17be184b515a00c2e2a2eb40b89Eli Bendersky
293e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopherconst DWARFLineTable *
294c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin KramerDWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) {
295c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer  if (!Line)
2969528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie    Line.reset(new DWARFDebugLine(&getLineSection().Relocs));
297c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer
298c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer  unsigned stmtOffset =
299c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov      cu->getCompileUnitDIE()->getAttributeValueAsSectionOffset(
300c5253237f8b3b4eb888f7f85f39acd7d4d0f57cfAlexey Samsonov          cu, DW_AT_stmt_list, -1U);
301c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer  if (stmtOffset == -1U)
302dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return nullptr; // No line table for this compile unit.
303c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer
304c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer  // See if the line table is cached.
305e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopher  if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
306c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer    return lt;
307c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer
308c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer  // We have to parse it first.
3099528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie  DataExtractor lineData(getLineSection().Data, isLittleEndian(),
310c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer                         cu->getAddressByteSize());
311c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer  return Line->getOrParseLineTable(lineData, stmtOffset);
312b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer}
313b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
31472c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramervoid DWARFContext::parseCompileUnits() {
31536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!CUs.empty())
31636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
31772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  uint32_t offset = 0;
3189528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie  const DataExtractor &DIData = DataExtractor(getInfoSection().Data,
319b69b55f54a66d4df9549927a3cce307855d6de49Eric Christopher                                              isLittleEndian(), 0);
320b69b55f54a66d4df9549927a3cce307855d6de49Eric Christopher  while (DIData.isValidOffset(offset)) {
32136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    std::unique_ptr<DWARFCompileUnit> CU(new DWARFCompileUnit(
322dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        getDebugAbbrev(), getInfoSection().Data, getRangeSection(),
323dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        getStringSection(), StringRef(), getAddrSection(),
3249528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie        &getInfoSection().Relocs, isLittleEndian()));
325eb0c179b5688177c1ab5f52a8c0338459e97606eAlexey Samsonov    if (!CU->extract(DIData, &offset)) {
32672c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer      break;
32772c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer    }
32836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    CUs.push_back(std::move(CU));
329cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    offset = CUs.back()->getNextUnitOffset();
33072c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer  }
33172c0d7fdd3d0930c7507060e96aec7d7429a8190Benjamin Kramer}
332101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer
333438f5391b2d502a132a4a20469e9e56305b221a4David Blaikievoid DWARFContext::parseTypeUnits() {
33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!TUs.empty())
33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
33636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (const auto &I : getTypesSections()) {
337438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie    uint32_t offset = 0;
338438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie    const DataExtractor &DIData =
33936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        DataExtractor(I.second.Data, isLittleEndian(), 0);
340438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie    while (DIData.isValidOffset(offset)) {
341dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      std::unique_ptr<DWARFTypeUnit> TU(
342dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          new DWARFTypeUnit(getDebugAbbrev(), I.second.Data, getRangeSection(),
343dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                            getStringSection(), StringRef(), getAddrSection(),
344dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                            &I.second.Relocs, isLittleEndian()));
345438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie      if (!TU->extract(DIData, &offset))
346438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie        break;
34736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      TUs.push_back(std::move(TU));
348438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie      offset = TUs.back()->getNextUnitOffset();
349438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie    }
350438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie  }
351438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie}
352438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie
35382de10a34c9432029040ced17129079a7d80904eEric Christophervoid DWARFContext::parseDWOCompileUnits() {
35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!DWOCUs.empty())
35536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
35682de10a34c9432029040ced17129079a7d80904eEric Christopher  uint32_t offset = 0;
3579528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie  const DataExtractor &DIData =
3589528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie      DataExtractor(getInfoDWOSection().Data, isLittleEndian(), 0);
35982de10a34c9432029040ced17129079a7d80904eEric Christopher  while (DIData.isValidOffset(offset)) {
36036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    std::unique_ptr<DWARFCompileUnit> DWOCU(new DWARFCompileUnit(
361dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        getDebugAbbrevDWO(), getInfoDWOSection().Data, getRangeDWOSection(),
362dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(),
3639528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie        &getInfoDWOSection().Relocs, isLittleEndian()));
364eb0c179b5688177c1ab5f52a8c0338459e97606eAlexey Samsonov    if (!DWOCU->extract(DIData, &offset)) {
36582de10a34c9432029040ced17129079a7d80904eEric Christopher      break;
36682de10a34c9432029040ced17129079a7d80904eEric Christopher    }
36736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DWOCUs.push_back(std::move(DWOCU));
368cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie    offset = DWOCUs.back()->getNextUnitOffset();
36982de10a34c9432029040ced17129079a7d80904eEric Christopher  }
37082de10a34c9432029040ced17129079a7d80904eEric Christopher}
37182de10a34c9432029040ced17129079a7d80904eEric Christopher
37236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid DWARFContext::parseDWOTypeUnits() {
37336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!DWOTUs.empty())
37436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (const auto &I : getTypesDWOSections()) {
37636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint32_t offset = 0;
37736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const DataExtractor &DIData =
37836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        DataExtractor(I.second.Data, isLittleEndian(), 0);
37936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    while (DIData.isValidOffset(offset)) {
38036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      std::unique_ptr<DWARFTypeUnit> TU(new DWARFTypeUnit(
381dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          getDebugAbbrevDWO(), I.second.Data, getRangeDWOSection(),
382dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(),
383dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          &I.second.Relocs, isLittleEndian()));
38436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (!TU->extract(DIData, &offset))
38536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        break;
38636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DWOTUs.push_back(std::move(TU));
38736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      offset = DWOTUs.back()->getNextUnitOffset();
38836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
38936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
39036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
39136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
392101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramernamespace {
393101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer  struct OffsetComparator {
39436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
39536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool operator()(const std::unique_ptr<DWARFCompileUnit> &LHS,
39636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                    const std::unique_ptr<DWARFCompileUnit> &RHS) const {
397eb0c179b5688177c1ab5f52a8c0338459e97606eAlexey Samsonov      return LHS->getOffset() < RHS->getOffset();
398101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer    }
39936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool operator()(const std::unique_ptr<DWARFCompileUnit> &LHS,
40036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                    uint32_t RHS) const {
401eb0c179b5688177c1ab5f52a8c0338459e97606eAlexey Samsonov      return LHS->getOffset() < RHS;
402101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer    }
40336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool operator()(uint32_t LHS,
40436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                    const std::unique_ptr<DWARFCompileUnit> &RHS) const {
405eb0c179b5688177c1ab5f52a8c0338459e97606eAlexey Samsonov      return LHS < RHS->getOffset();
406101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer    }
407101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer  };
408101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer}
409101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer
41038a6381c0a58e013577b1957199128af9573fc20Alexey SamsonovDWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
41136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  parseCompileUnits();
412101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer
41336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<DWARFCompileUnit> *CU =
414eb0c179b5688177c1ab5f52a8c0338459e97606eAlexey Samsonov      std::lower_bound(CUs.begin(), CUs.end(), Offset, OffsetComparator());
415eb0c179b5688177c1ab5f52a8c0338459e97606eAlexey Samsonov  if (CU != CUs.end()) {
41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return CU->get();
417eb0c179b5688177c1ab5f52a8c0338459e97606eAlexey Samsonov  }
418dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return nullptr;
419101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer}
420101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer
42138a6381c0a58e013577b1957199128af9573fc20Alexey SamsonovDWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
4229013db3399d2847899ba32daf58844bba1aef6ddBenjamin Kramer  // First, get the offset of the compile unit.
42338a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  uint32_t CUOffset = getDebugAranges()->findAddress(Address);
424101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer  // Retrieve the compile unit.
42538a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  return getCompileUnitForOffset(CUOffset);
42638a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov}
42738a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov
428e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopherstatic bool getFileNameForCompileUnit(DWARFCompileUnit *CU,
429e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopher                                      const DWARFLineTable *LineTable,
430dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      uint64_t FileIndex, FileLineInfoKind Kind,
431e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopher                                      std::string &FileName) {
432dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!CU || !LineTable || Kind == FileLineInfoKind::None ||
433dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      !LineTable->getFileNameByIndex(FileIndex, Kind, FileName))
43438a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    return false;
435dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Kind == FileLineInfoKind::AbsoluteFilePath &&
436dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      sys::path::is_relative(FileName)) {
43738a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    // We may still need to append compilation directory of compile unit.
43838a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    SmallString<16> AbsolutePath;
43938a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    if (const char *CompilationDir = CU->getCompilationDir()) {
44038a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov      sys::path::append(AbsolutePath, CompilationDir);
4419d26b0ba06479d9debadebce19344169f72407ddAlexey Samsonov    }
44238a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    sys::path::append(AbsolutePath, FileName);
44338a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    FileName = AbsolutePath.str();
4443e25c4a1e3e58bc1d00d894854a29dd2e4e7e88aAlexey Samsonov  }
44538a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  return true;
44638a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov}
44738a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov
448e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopherstatic bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU,
449e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopher                                          const DWARFLineTable *LineTable,
450e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopher                                          uint64_t Address,
451dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                          FileLineInfoKind Kind,
452dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                          DILineInfo &Result) {
453dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!CU || !LineTable)
45438a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    return false;
45538a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  // Get the index of row we're looking for in the line table.
45638a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  uint32_t RowIndex = LineTable->lookupAddress(Address);
45738a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  if (RowIndex == -1U)
45838a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    return false;
45938a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  // Take file number and line/column from the row.
46038a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
461dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!getFileNameForCompileUnit(CU, LineTable, Row.File, Kind,
462dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                 Result.FileName))
46338a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    return false;
464dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Result.Line = Row.Line;
465dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Result.Column = Row.Column;
46638a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  return true;
46738a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov}
46838a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov
469dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address,
470dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      FunctionNameKind Kind,
471dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      std::string &FunctionName) {
472dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Kind == FunctionNameKind::None)
473dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
474dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // The address may correspond to instruction in some inlined function,
475dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // so we have to build the chain of inlined functions and take the
476dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // name of the topmost function in it.
477dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const DWARFDebugInfoEntryInlinedChain &InlinedChain =
478dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CU->getInlinedChainForAddress(Address);
479dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (InlinedChain.DIEs.size() == 0)
480dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
481dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
482dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (const char *Name =
483dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          TopFunctionDIE.getSubroutineName(InlinedChain.U, Kind)) {
484dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    FunctionName = Name;
485dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return true;
486dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
487dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
488dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
489dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
49038a6381c0a58e013577b1957199128af9573fc20Alexey SamsonovDILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
491dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                               DILineInfoSpecifier Spec) {
492dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  DILineInfo Result;
493dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
49438a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
49538a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  if (!CU)
496dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return Result;
497dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  getFunctionNameForAddress(CU, Address, Spec.FNKind, Result.FunctionName);
498dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Spec.FLIKind != FileLineInfoKind::None) {
499e9403c1fd6647eda9f6c9d46a75ab9370b2354b6Eric Christopher    const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
500dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind, Result);
50138a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  }
502dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return Result;
503101b1c5ff16dffd45d03746d92c024740f72ecc6Benjamin Kramer}
5042d24e2a396a1d211baaeedf32148a3b657240170David Blaikie
505dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesDILineInfoTable
506dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesDWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
507dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                         DILineInfoSpecifier Spec) {
508e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  DILineInfoTable  Lines;
509e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
510e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  if (!CU)
511e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    return Lines;
512e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor
513e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  std::string FunctionName = "<invalid>";
514dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  getFunctionNameForAddress(CU, Address, Spec.FNKind, FunctionName);
515e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor
516e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  // If the Specifier says we don't need FileLineInfo, just
517e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  // return the top-most function at the starting address.
518dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Spec.FLIKind == FileLineInfoKind::None) {
519dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    DILineInfo Result;
520dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Result.FunctionName = FunctionName;
521dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Lines.push_back(std::make_pair(Address, Result));
522e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    return Lines;
523e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  }
524e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor
525e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
526e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor
527e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  // Get the index of row we're looking for in the line table.
528e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  std::vector<uint32_t> RowVector;
529e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  if (!LineTable->lookupAddressRange(Address, Size, RowVector))
530e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    return Lines;
531e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor
53236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (uint32_t RowIndex : RowVector) {
533e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    // Take file number and line/column from the row.
534e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
535dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    DILineInfo Result;
536dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    getFileNameForCompileUnit(CU, LineTable, Row.File, Spec.FLIKind,
537dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                              Result.FileName);
538dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Result.FunctionName = FunctionName;
539dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Result.Line = Row.Line;
540dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Result.Column = Row.Column;
541dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Lines.push_back(std::make_pair(Row.Address, Result));
542e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  }
543e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor
544e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  return Lines;
545e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor}
546e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor
547dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesDIInliningInfo
548dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesDWARFContext::getInliningInfoForAddress(uint64_t Address,
549dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                        DILineInfoSpecifier Spec) {
550dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  DIInliningInfo InliningInfo;
551dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
5525eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
5535eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  if (!CU)
554dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return InliningInfo;
5555eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
556dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const DWARFLineTable *LineTable = nullptr;
557e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov  const DWARFDebugInfoEntryInlinedChain &InlinedChain =
5585eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      CU->getInlinedChainForAddress(Address);
559dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (InlinedChain.DIEs.size() == 0) {
560dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // If there is no DIE for address (e.g. it is in unavailable .dwo file),
561dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // try to at least get file/line info from symbol table.
562dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Spec.FLIKind != FileLineInfoKind::None) {
563dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      DILineInfo Frame;
564dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      LineTable = getLineTableForCompileUnit(CU);
565dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind,
566dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                        Frame)) {
567dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        InliningInfo.addFrame(Frame);
568dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
569dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
570dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return InliningInfo;
571dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
5725eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
5735eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  uint32_t CallFile = 0, CallLine = 0, CallColumn = 0;
574e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov  for (uint32_t i = 0, n = InlinedChain.DIEs.size(); i != n; i++) {
575e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov    const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i];
576dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    DILineInfo Frame;
5775eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    // Get function name if necessary.
578dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (const char *Name =
579dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            FunctionDIE.getSubroutineName(InlinedChain.U, Spec.FNKind))
580dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Frame.FunctionName = Name;
581dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Spec.FLIKind != FileLineInfoKind::None) {
5825eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      if (i == 0) {
5835eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        // For the topmost frame, initialize the line table of this
5845eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        // compile unit and fetch file/line info from it.
5855eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        LineTable = getLineTableForCompileUnit(CU);
5865eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        // For the topmost routine, get file/line info from line table.
587dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind,
588dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      Frame);
5895eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      } else {
5905eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        // Otherwise, use call file, call line and call column from
5915eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov        // previous DIE in inlined chain.
592dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        getFileNameForCompileUnit(CU, LineTable, CallFile, Spec.FLIKind,
593dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                  Frame.FileName);
594dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Frame.Line = CallLine;
595dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Frame.Column = CallColumn;
5965eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      }
5975eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      // Get call file/line/column of a current DIE.
5985eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      if (i + 1 < n) {
599cd7c4980d4ee2d22d92a4907f2d029e67b52d732David Blaikie        FunctionDIE.getCallerFrame(InlinedChain.U, CallFile, CallLine,
600e664290ad6d988e0ae40f2461084f6adbababa47Alexey Samsonov                                   CallColumn);
6015eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov      }
6025eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    }
6035eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov    InliningInfo.addFrame(Frame);
6045eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  }
6055eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov  return InliningInfo;
6065eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov}
6075eae90d727c64ca5b4b43b110521b38dcd9f0de6Alexey Samsonov
608005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonovstatic bool consumeCompressedDebugSectionHeader(StringRef &data,
609005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov                                                uint64_t &OriginalSize) {
610005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov  // Consume "ZLIB" prefix.
611005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov  if (!data.startswith("ZLIB"))
612005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov    return false;
613005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov  data = data.substr(4);
614005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov  // Consume uncompressed section size (big-endian 8 bytes).
615005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov  DataExtractor extractor(data, false, 8);
616005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov  uint32_t Offset = 0;
617005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov  OriginalSize = extractor.getU64(&Offset);
618005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov  if (Offset == 0)
619005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov    return false;
620005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov  data = data.substr(Offset);
621005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov  return true;
622005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov}
623005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov
62436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesDWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj)
62536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    : IsLittleEndian(Obj->isLittleEndian()),
62636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      AddressSize(Obj->getBytesInAddress()) {
62736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (const SectionRef &Section : Obj->sections()) {
628d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher    StringRef name;
62936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Section.getName(name);
630d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher    StringRef data;
63136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Section.getContents(data);
632d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher
633d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher    name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes.
634784baa6f4440beac54881673ecc7baa88f8b94ddAlexey Samsonov
635005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov    // Check if debug info section is compressed with zlib.
636005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov    if (name.startswith("zdebug_")) {
637005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov      uint64_t OriginalSize;
638005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov      if (!zlib::isAvailable() ||
639005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov          !consumeCompressedDebugSectionHeader(data, OriginalSize))
640005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov        continue;
641dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      UncompressedSections.resize(UncompressedSections.size() + 1);
642dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (zlib::uncompress(data, UncompressedSections.back(), OriginalSize) !=
643dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          zlib::StatusOK) {
644dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        UncompressedSections.pop_back();
645005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov        continue;
646dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
647005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov      // Make data point to uncompressed section contents and save its contents.
648005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov      name = name.substr(1);
649dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      data = UncompressedSections.back();
650005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov    }
651005159e92420a102516ee6e29ef2178c818da5d0Alexey Samsonov
65236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    StringRef *SectionData =
6537357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher        StringSwitch<StringRef *>(name)
6547357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_info", &InfoSection.Data)
6557357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_abbrev", &AbbrevSection)
6567357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_loc", &LocSection.Data)
6577357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_line", &LineSection.Data)
6587357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_aranges", &ARangeSection)
6597357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_frame", &DebugFrameSection)
6607357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_str", &StringSection)
6617357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_ranges", &RangeSection)
6627357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_pubnames", &PubNamesSection)
6637357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_pubtypes", &PubTypesSection)
6647357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_gnu_pubnames", &GnuPubNamesSection)
6657357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
6667357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_info.dwo", &InfoDWOSection.Data)
6677357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_abbrev.dwo", &AbbrevDWOSection)
66836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            .Case("debug_loc.dwo", &LocDWOSection.Data)
66936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            .Case("debug_line.dwo", &LineDWOSection.Data)
6707357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_str.dwo", &StringDWOSection)
6717357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
6727357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            .Case("debug_addr", &AddrSection)
6737357f03e888e7d95066ca1bbb26994c278eb465cEric Christopher            // Any more debug info sections go here.
674dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            .Default(nullptr);
67536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (SectionData) {
67636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      *SectionData = data;
6777486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola      if (name == "debug_ranges") {
6787486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola        // FIXME: Use the other dwo range section when we emit it.
6797486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola        RangeDWOSection = data;
6807486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola      }
681438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie    } else if (name == "debug_types") {
68275331656124ddfdc7829b4dd430083e140bd8549David Blaikie      // Find debug_types data by section rather than name as there are
68375331656124ddfdc7829b4dd430083e140bd8549David Blaikie      // multiple, comdat grouped, debug_types sections.
68436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      TypesSections[Section].Data = data;
68536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    } else if (name == "debug_types.dwo") {
68636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      TypesDWOSections[Section].Data = data;
68782de10a34c9432029040ced17129079a7d80904eEric Christopher    }
688d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher
68936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    section_iterator RelocatedSection = Section.getRelocatedSection();
69036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (RelocatedSection == Obj->section_end())
6917486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola      continue;
6927486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola
6937486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola    StringRef RelSecName;
6947486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola    RelocatedSection->getName(RelSecName);
6957486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola    RelSecName = RelSecName.substr(
6967486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola        RelSecName.find_first_not_of("._")); // Skip . and _ prefixes.
6977486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola
698ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor    // TODO: Add support for relocations in other sections as needed.
699ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor    // Record relocations for the debug_info and debug_line sections.
7007486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola    RelocAddrMap *Map = StringSwitch<RelocAddrMap*>(RelSecName)
7019528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie        .Case("debug_info", &InfoSection.Relocs)
7029528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie        .Case("debug_loc", &LocSection.Relocs)
7039528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie        .Case("debug_info.dwo", &InfoDWOSection.Relocs)
7049528b0e466ace36268abe9d011fffc67d831088cDavid Blaikie        .Case("debug_line", &LineSection.Relocs)
705dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        .Default(nullptr);
706438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie    if (!Map) {
70775331656124ddfdc7829b4dd430083e140bd8549David Blaikie      // Find debug_types relocs by section rather than name as there are
70875331656124ddfdc7829b4dd430083e140bd8549David Blaikie      // multiple, comdat grouped, debug_types sections.
70936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (RelSecName == "debug_types")
71036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Map = &TypesSections[*RelocatedSection].Relocs;
71136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      else if (RelSecName == "debug_types.dwo")
71236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Map = &TypesDWOSections[*RelocatedSection].Relocs;
71336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      else
71436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        continue;
715438f5391b2d502a132a4a20469e9e56305b221a4David Blaikie    }
716d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher
71736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Section.relocation_begin() != Section.relocation_end()) {
718d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher      uint64_t SectionSize;
7197486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola      RelocatedSection->getSize(SectionSize);
72036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      for (const RelocationRef &Reloc : Section.relocations()) {
721d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        uint64_t Address;
72236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Reloc.getOffset(Address);
723d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        uint64_t Type;
72436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Reloc.getType(Type);
725ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor        uint64_t SymAddr = 0;
726ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor        // ELF relocations may need the symbol address
727ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor        if (Obj->isELF()) {
72836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          object::symbol_iterator Sym = Reloc.getSymbol();
7296c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindola          Sym->getAddress(SymAddr);
730ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor        }
731d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher
732d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        object::RelocVisitor V(Obj->getFileFormatName());
733d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        // The section address is always 0 for debug sections.
73436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        object::RelocToApply R(V.visit(Type, Reloc, 0, SymAddr));
735d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        if (V.error()) {
736d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher          SmallString<32> Name;
737cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines          std::error_code ec(Reloc.getTypeName(Name));
738d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher          if (ec) {
739d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher            errs() << "Aaaaaa! Nameless relocation! Aaaaaa!\n";
740d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher          }
741d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher          errs() << "error: failed to compute relocation: "
742d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher                 << Name << "\n";
743d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher          continue;
744d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        }
745d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher
746d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        if (Address + R.Width > SectionSize) {
747d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher          errs() << "error: " << R.Width << "-byte relocation starting "
748d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher                 << Address << " bytes into section " << name << " which is "
749d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher                 << SectionSize << " bytes long.\n";
750d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher          continue;
751d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        }
752d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        if (R.Width > 8) {
753d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher          errs() << "error: can't handle a relocation of more than 8 bytes at "
754d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher                    "a time.\n";
755d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher          continue;
756d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        }
757d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher        DEBUG(dbgs() << "Writing " << format("%p", R.Value)
758d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher                     << " at " << format("%p", Address)
759d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher                     << " with width " << format("%d", R.Width)
760d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher                     << "\n");
76182de10a34c9432029040ced17129079a7d80904eEric Christopher        Map->insert(std::make_pair(Address, std::make_pair(R.Width, R.Value)));
762d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher      }
763d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher    }
764d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher  }
765d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher}
766d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher
7672d24e2a396a1d211baaeedf32148a3b657240170David Blaikievoid DWARFContextInMemory::anchor() { }
768