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