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