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