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