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