1 //===-- SymbolVendorWasm.cpp ----------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "SymbolVendorWasm.h" 10 11 #include <cstring> 12 #include <optional> 13 14 #include "Plugins/ObjectFile/wasm/ObjectFileWasm.h" 15 #include "lldb/Core/Module.h" 16 #include "lldb/Core/ModuleSpec.h" 17 #include "lldb/Core/PluginManager.h" 18 #include "lldb/Core/Section.h" 19 #include "lldb/Host/Host.h" 20 #include "lldb/Symbol/LocateSymbolFile.h" 21 #include "lldb/Symbol/ObjectFile.h" 22 #include "lldb/Target/Target.h" 23 #include "lldb/Utility/StreamString.h" 24 #include "lldb/Utility/Timer.h" 25 26 using namespace lldb; 27 using namespace lldb_private; 28 using namespace lldb_private::wasm; 29 30 LLDB_PLUGIN_DEFINE(SymbolVendorWasm) 31 32 // SymbolVendorWasm constructor 33 SymbolVendorWasm::SymbolVendorWasm(const lldb::ModuleSP &module_sp) 34 : SymbolVendor(module_sp) {} 35 36 void SymbolVendorWasm::Initialize() { 37 PluginManager::RegisterPlugin(GetPluginNameStatic(), 38 GetPluginDescriptionStatic(), CreateInstance); 39 } 40 41 void SymbolVendorWasm::Terminate() { 42 PluginManager::UnregisterPlugin(CreateInstance); 43 } 44 45 llvm::StringRef SymbolVendorWasm::GetPluginDescriptionStatic() { 46 return "Symbol vendor for WASM that looks for dwo files that match " 47 "executables."; 48 } 49 50 // CreateInstance 51 // 52 // Platforms can register a callback to use when creating symbol vendors to 53 // allow for complex debug information file setups, and to also allow for 54 // finding separate debug information files. 55 SymbolVendor * 56 SymbolVendorWasm::CreateInstance(const lldb::ModuleSP &module_sp, 57 lldb_private::Stream *feedback_strm) { 58 if (!module_sp) 59 return nullptr; 60 61 ObjectFileWasm *obj_file = 62 llvm::dyn_cast_or_null<ObjectFileWasm>(module_sp->GetObjectFile()); 63 if (!obj_file) 64 return nullptr; 65 66 // If the main object file already contains debug info, then we are done. 67 if (obj_file->GetSectionList()->FindSectionByType( 68 lldb::eSectionTypeDWARFDebugInfo, true)) 69 return nullptr; 70 71 LLDB_SCOPED_TIMERF("SymbolVendorWasm::CreateInstance (module = %s)", 72 module_sp->GetFileSpec().GetPath().c_str()); 73 74 ModuleSpec module_spec; 75 module_spec.GetFileSpec() = obj_file->GetFileSpec(); 76 FileSystem::Instance().Resolve(module_spec.GetFileSpec()); 77 module_spec.GetUUID() = obj_file->GetUUID(); 78 79 // A Wasm module may have a custom section named "external_debug_info" whose 80 // content is the absolute or relative path of the Wasm module that contains 81 // debug symbols for this module. 82 std::optional<FileSpec> symbol_file_spec = 83 obj_file->GetExternalDebugInfoFileSpec(); 84 if (!symbol_file_spec) 85 return nullptr; 86 module_spec.GetSymbolFileSpec() = *symbol_file_spec; 87 88 FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths(); 89 FileSpec sym_fspec = 90 Symbols::LocateExecutableSymbolFile(module_spec, search_paths); 91 if (!sym_fspec) 92 return nullptr; 93 94 DataBufferSP sym_file_data_sp; 95 lldb::offset_t sym_file_data_offset = 0; 96 ObjectFileSP sym_objfile_sp = ObjectFile::FindPlugin( 97 module_sp, &sym_fspec, 0, FileSystem::Instance().GetByteSize(sym_fspec), 98 sym_file_data_sp, sym_file_data_offset); 99 if (!sym_objfile_sp) 100 return nullptr; 101 102 // This objfile is for debugging purposes. 103 sym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo); 104 105 SymbolVendorWasm *symbol_vendor = new SymbolVendorWasm(module_sp); 106 107 // Get the module unified section list and add our debug sections to 108 // that. 109 SectionList *module_section_list = module_sp->GetSectionList(); 110 SectionList *objfile_section_list = sym_objfile_sp->GetSectionList(); 111 112 if (!module_section_list || !objfile_section_list) 113 return nullptr; 114 115 static const SectionType g_sections[] = { 116 eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr, 117 eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugCuIndex, 118 eSectionTypeDWARFDebugFrame, eSectionTypeDWARFDebugInfo, 119 eSectionTypeDWARFDebugLine, eSectionTypeDWARFDebugLineStr, 120 eSectionTypeDWARFDebugLoc, eSectionTypeDWARFDebugLocLists, 121 eSectionTypeDWARFDebugMacInfo, eSectionTypeDWARFDebugMacro, 122 eSectionTypeDWARFDebugPubNames, eSectionTypeDWARFDebugPubTypes, 123 eSectionTypeDWARFDebugRanges, eSectionTypeDWARFDebugRngLists, 124 eSectionTypeDWARFDebugStr, eSectionTypeDWARFDebugStrOffsets, 125 eSectionTypeDWARFDebugTypes}; 126 for (SectionType section_type : g_sections) { 127 if (SectionSP section_sp = 128 objfile_section_list->FindSectionByType(section_type, true)) { 129 if (SectionSP module_section_sp = 130 module_section_list->FindSectionByType(section_type, true)) 131 module_section_list->ReplaceSection(module_section_sp->GetID(), 132 section_sp); 133 else 134 module_section_list->AddSection(section_sp); 135 } 136 } 137 138 symbol_vendor->AddSymbolFileRepresentation(sym_objfile_sp); 139 return symbol_vendor; 140 } 141