xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
15ffd83dbSDimitry Andric //===-- SymbolVendorWasm.cpp ----------------------------------------------===//
25ffd83dbSDimitry Andric //
35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65ffd83dbSDimitry Andric //
75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
85ffd83dbSDimitry Andric 
95ffd83dbSDimitry Andric #include "SymbolVendorWasm.h"
105ffd83dbSDimitry Andric 
11fe6060f1SDimitry Andric #include <cstring>
12bdd1243dSDimitry Andric #include <optional>
135ffd83dbSDimitry Andric 
145ffd83dbSDimitry Andric #include "Plugins/ObjectFile/wasm/ObjectFileWasm.h"
155ffd83dbSDimitry Andric #include "lldb/Core/Module.h"
165ffd83dbSDimitry Andric #include "lldb/Core/ModuleSpec.h"
175ffd83dbSDimitry Andric #include "lldb/Core/PluginManager.h"
185ffd83dbSDimitry Andric #include "lldb/Core/Section.h"
195ffd83dbSDimitry Andric #include "lldb/Host/Host.h"
205ffd83dbSDimitry Andric #include "lldb/Symbol/ObjectFile.h"
215ffd83dbSDimitry Andric #include "lldb/Target/Target.h"
225ffd83dbSDimitry Andric #include "lldb/Utility/StreamString.h"
235ffd83dbSDimitry Andric #include "lldb/Utility/Timer.h"
245ffd83dbSDimitry Andric 
255ffd83dbSDimitry Andric using namespace lldb;
265ffd83dbSDimitry Andric using namespace lldb_private;
275ffd83dbSDimitry Andric using namespace lldb_private::wasm;
285ffd83dbSDimitry Andric 
LLDB_PLUGIN_DEFINE(SymbolVendorWasm)295ffd83dbSDimitry Andric LLDB_PLUGIN_DEFINE(SymbolVendorWasm)
305ffd83dbSDimitry Andric 
315ffd83dbSDimitry Andric // SymbolVendorWasm constructor
325ffd83dbSDimitry Andric SymbolVendorWasm::SymbolVendorWasm(const lldb::ModuleSP &module_sp)
335ffd83dbSDimitry Andric     : SymbolVendor(module_sp) {}
345ffd83dbSDimitry Andric 
Initialize()355ffd83dbSDimitry Andric void SymbolVendorWasm::Initialize() {
365ffd83dbSDimitry Andric   PluginManager::RegisterPlugin(GetPluginNameStatic(),
375ffd83dbSDimitry Andric                                 GetPluginDescriptionStatic(), CreateInstance);
385ffd83dbSDimitry Andric }
395ffd83dbSDimitry Andric 
Terminate()405ffd83dbSDimitry Andric void SymbolVendorWasm::Terminate() {
415ffd83dbSDimitry Andric   PluginManager::UnregisterPlugin(CreateInstance);
425ffd83dbSDimitry Andric }
435ffd83dbSDimitry Andric 
GetPluginDescriptionStatic()44349cc55cSDimitry Andric llvm::StringRef SymbolVendorWasm::GetPluginDescriptionStatic() {
455ffd83dbSDimitry Andric   return "Symbol vendor for WASM that looks for dwo files that match "
465ffd83dbSDimitry Andric          "executables.";
475ffd83dbSDimitry Andric }
485ffd83dbSDimitry Andric 
495ffd83dbSDimitry Andric // CreateInstance
505ffd83dbSDimitry Andric //
515ffd83dbSDimitry Andric // Platforms can register a callback to use when creating symbol vendors to
525ffd83dbSDimitry Andric // allow for complex debug information file setups, and to also allow for
535ffd83dbSDimitry Andric // finding separate debug information files.
545ffd83dbSDimitry Andric SymbolVendor *
CreateInstance(const lldb::ModuleSP & module_sp,lldb_private::Stream * feedback_strm)555ffd83dbSDimitry Andric SymbolVendorWasm::CreateInstance(const lldb::ModuleSP &module_sp,
565ffd83dbSDimitry Andric                                  lldb_private::Stream *feedback_strm) {
575ffd83dbSDimitry Andric   if (!module_sp)
585ffd83dbSDimitry Andric     return nullptr;
595ffd83dbSDimitry Andric 
605ffd83dbSDimitry Andric   ObjectFileWasm *obj_file =
615ffd83dbSDimitry Andric       llvm::dyn_cast_or_null<ObjectFileWasm>(module_sp->GetObjectFile());
625ffd83dbSDimitry Andric   if (!obj_file)
635ffd83dbSDimitry Andric     return nullptr;
645ffd83dbSDimitry Andric 
655ffd83dbSDimitry Andric   // If the main object file already contains debug info, then we are done.
665ffd83dbSDimitry Andric   if (obj_file->GetSectionList()->FindSectionByType(
675ffd83dbSDimitry Andric           lldb::eSectionTypeDWARFDebugInfo, true))
685ffd83dbSDimitry Andric     return nullptr;
695ffd83dbSDimitry Andric 
70e8d8bef9SDimitry Andric   LLDB_SCOPED_TIMERF("SymbolVendorWasm::CreateInstance (module = %s)",
715ffd83dbSDimitry Andric                      module_sp->GetFileSpec().GetPath().c_str());
725ffd83dbSDimitry Andric 
735ffd83dbSDimitry Andric   ModuleSpec module_spec;
745ffd83dbSDimitry Andric   module_spec.GetFileSpec() = obj_file->GetFileSpec();
755ffd83dbSDimitry Andric   FileSystem::Instance().Resolve(module_spec.GetFileSpec());
765ffd83dbSDimitry Andric   module_spec.GetUUID() = obj_file->GetUUID();
775ffd83dbSDimitry Andric 
785ffd83dbSDimitry Andric   // A Wasm module may have a custom section named "external_debug_info" whose
795ffd83dbSDimitry Andric   // content is the absolute or relative path of the Wasm module that contains
805ffd83dbSDimitry Andric   // debug symbols for this module.
81bdd1243dSDimitry Andric   std::optional<FileSpec> symbol_file_spec =
825ffd83dbSDimitry Andric       obj_file->GetExternalDebugInfoFileSpec();
835ffd83dbSDimitry Andric   if (!symbol_file_spec)
845ffd83dbSDimitry Andric     return nullptr;
855ffd83dbSDimitry Andric   module_spec.GetSymbolFileSpec() = *symbol_file_spec;
865ffd83dbSDimitry Andric 
875ffd83dbSDimitry Andric   FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
885ffd83dbSDimitry Andric   FileSpec sym_fspec =
89*5f757f3fSDimitry Andric       PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
905ffd83dbSDimitry Andric   if (!sym_fspec)
915ffd83dbSDimitry Andric     return nullptr;
925ffd83dbSDimitry Andric 
935ffd83dbSDimitry Andric   DataBufferSP sym_file_data_sp;
945ffd83dbSDimitry Andric   lldb::offset_t sym_file_data_offset = 0;
955ffd83dbSDimitry Andric   ObjectFileSP sym_objfile_sp = ObjectFile::FindPlugin(
965ffd83dbSDimitry Andric       module_sp, &sym_fspec, 0, FileSystem::Instance().GetByteSize(sym_fspec),
975ffd83dbSDimitry Andric       sym_file_data_sp, sym_file_data_offset);
985ffd83dbSDimitry Andric   if (!sym_objfile_sp)
995ffd83dbSDimitry Andric     return nullptr;
1005ffd83dbSDimitry Andric 
1015ffd83dbSDimitry Andric   // This objfile is for debugging purposes.
1025ffd83dbSDimitry Andric   sym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo);
1035ffd83dbSDimitry Andric 
1045ffd83dbSDimitry Andric   SymbolVendorWasm *symbol_vendor = new SymbolVendorWasm(module_sp);
1055ffd83dbSDimitry Andric 
1065ffd83dbSDimitry Andric   // Get the module unified section list and add our debug sections to
1075ffd83dbSDimitry Andric   // that.
1085ffd83dbSDimitry Andric   SectionList *module_section_list = module_sp->GetSectionList();
1095ffd83dbSDimitry Andric   SectionList *objfile_section_list = sym_objfile_sp->GetSectionList();
1105ffd83dbSDimitry Andric 
11106c3fb27SDimitry Andric   if (!module_section_list || !objfile_section_list)
11206c3fb27SDimitry Andric     return nullptr;
11306c3fb27SDimitry Andric 
1145ffd83dbSDimitry Andric   static const SectionType g_sections[] = {
1155ffd83dbSDimitry Andric       eSectionTypeDWARFDebugAbbrev,   eSectionTypeDWARFDebugAddr,
1165ffd83dbSDimitry Andric       eSectionTypeDWARFDebugAranges,  eSectionTypeDWARFDebugCuIndex,
1175ffd83dbSDimitry Andric       eSectionTypeDWARFDebugFrame,    eSectionTypeDWARFDebugInfo,
1185ffd83dbSDimitry Andric       eSectionTypeDWARFDebugLine,     eSectionTypeDWARFDebugLineStr,
1195ffd83dbSDimitry Andric       eSectionTypeDWARFDebugLoc,      eSectionTypeDWARFDebugLocLists,
1205ffd83dbSDimitry Andric       eSectionTypeDWARFDebugMacInfo,  eSectionTypeDWARFDebugMacro,
1215ffd83dbSDimitry Andric       eSectionTypeDWARFDebugPubNames, eSectionTypeDWARFDebugPubTypes,
1225ffd83dbSDimitry Andric       eSectionTypeDWARFDebugRanges,   eSectionTypeDWARFDebugRngLists,
1235ffd83dbSDimitry Andric       eSectionTypeDWARFDebugStr,      eSectionTypeDWARFDebugStrOffsets,
1245ffd83dbSDimitry Andric       eSectionTypeDWARFDebugTypes};
1255ffd83dbSDimitry Andric   for (SectionType section_type : g_sections) {
1265ffd83dbSDimitry Andric     if (SectionSP section_sp =
1275ffd83dbSDimitry Andric             objfile_section_list->FindSectionByType(section_type, true)) {
1285ffd83dbSDimitry Andric       if (SectionSP module_section_sp =
1295ffd83dbSDimitry Andric               module_section_list->FindSectionByType(section_type, true))
1305ffd83dbSDimitry Andric         module_section_list->ReplaceSection(module_section_sp->GetID(),
1315ffd83dbSDimitry Andric                                             section_sp);
1325ffd83dbSDimitry Andric       else
1335ffd83dbSDimitry Andric         module_section_list->AddSection(section_sp);
1345ffd83dbSDimitry Andric     }
1355ffd83dbSDimitry Andric   }
1365ffd83dbSDimitry Andric 
1375ffd83dbSDimitry Andric   symbol_vendor->AddSymbolFileRepresentation(sym_objfile_sp);
1385ffd83dbSDimitry Andric   return symbol_vendor;
1395ffd83dbSDimitry Andric }
140