blob: cfd96cd08245489931c482fdf45ef71377107c19 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// clang-format off
#include <string>
#include <vector>
#include <emscripten.h>
#include <emscripten/bind.h>
#include "ApiContext.h"
#include "WasmVendorPlugins.h"
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
#include "Plugins/ObjectFile/wasm/ObjectFileWasm.h"
#include "Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
#include "Plugins/SymbolVendor/wasm/SymbolVendorWasm.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/linux/HostInfoLinux.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Base64.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/raw_ostream.h"
namespace {
struct DefaultPluginsContext
: symbols_backend::PluginRegistryContext<
lldb_private::HostInfoPosix,
symbols_backend::WasmPlatform,
lldb_private::ScriptInterpreterNone,
lldb_private::FileSystem,
lldb_private::CPlusPlusLanguage,
lldb_private::TypeSystemClang,
lldb_private::wasm::ObjectFileWasm,
lldb_private::wasm::SymbolVendorWasm,
symbols_backend::WasmProcess,
symbols_backend::SymbolFileWasmDWARF> {
DefaultPluginsContext() : PluginRegistryContext() {
lldb_private::Debugger::Initialize(nullptr);
}
~DefaultPluginsContext() { lldb_private::Debugger::Terminate(); }
};
DefaultPluginsContext& GetGlobalContext() {
static DefaultPluginsContext global_context;
return global_context;
}
template <typename T, typename ClassT>
std::function<void(ClassT&, emscripten::val)> OptionalSetter(
ClassT& (ClassT::*setter)(llvm::Optional<T>)) {
return [setter](ClassT& cls, emscripten::val value) {
if (value == emscripten::val::undefined() ||
value == emscripten::val::null()) {
(cls.*setter)(llvm::None);
} else {
(cls.*setter)(value.as<T>());
}
};
}
template <typename T, typename ClassT>
std::function<emscripten::val(const ClassT&)> OptionalGetter(
llvm::Optional<T> (ClassT::*getter)() const) {
return [getter](const ClassT& cls) {
if (auto value = (cls.*getter)()) {
return emscripten::val(std::move(*value));
}
return emscripten::val::undefined();
};
}
} // namespace
namespace symbols_backend {
class DWARFSymbolsPlugin : public api::ApiContext {
public:
DWARFSymbolsPlugin() : context_(GetGlobalContext()) {}
private:
DefaultPluginsContext& context_;
};
} // namespace symbols_backend
EMSCRIPTEN_BINDINGS(DWARFSymbolsPlugin) {
emscripten::enum_<symbols_backend::api::Error::Code>("ErrorCode")
.value("INTERNAL_ERROR", symbols_backend::api::Error::Code::kInternalError)
.value("PROTOCOL_ERROR", symbols_backend::api::Error::Code::kProtocolError)
.value("MODULE_NOT_FOUND_ERROR", symbols_backend::api::Error::Code::kModuleNotFoundError)
.value("EVAL_ERROR", symbols_backend::api::Error::Code::kEvalError)
;
emscripten::class_<symbols_backend::api::Error>("Error")
.constructor<>()
.property("code", &symbols_backend::api::Error::GetCode, &symbols_backend::api::Error::SetCode)
.property("message", &symbols_backend::api::Error::GetMessage, &symbols_backend::api::Error::SetMessage)
;
emscripten::class_<symbols_backend::api::RawLocationRange>("RawLocationRange")
.constructor<>()
.property("rawModuleId", &symbols_backend::api::RawLocationRange::GetRawModuleId, &symbols_backend::api::RawLocationRange::SetRawModuleId)
.property("startOffset", &symbols_backend::api::RawLocationRange::GetStartOffset, &symbols_backend::api::RawLocationRange::SetStartOffset)
.property("endOffset", &symbols_backend::api::RawLocationRange::GetEndOffset, &symbols_backend::api::RawLocationRange::SetEndOffset)
;
emscripten::class_<symbols_backend::api::RawLocation>("RawLocation")
.constructor<>()
.property("rawModuleId", &symbols_backend::api::RawLocation::GetRawModuleId, &symbols_backend::api::RawLocation::SetRawModuleId)
.property("codeOffset", &symbols_backend::api::RawLocation::GetCodeOffset, &symbols_backend::api::RawLocation::SetCodeOffset)
.property("inlineFrameIndex", &symbols_backend::api::RawLocation::GetInlineFrameIndex, &symbols_backend::api::RawLocation::SetInlineFrameIndex)
;
emscripten::class_<symbols_backend::api::SourceLocation>("SourceLocation")
.constructor<>()
.property("rawModuleId", &symbols_backend::api::SourceLocation::GetRawModuleId, &symbols_backend::api::SourceLocation::SetRawModuleId)
.property("sourceFile", &symbols_backend::api::SourceLocation::GetSourceFile, &symbols_backend::api::SourceLocation::SetSourceFile)
.property("lineNumber", &symbols_backend::api::SourceLocation::GetLineNumber, &symbols_backend::api::SourceLocation::SetLineNumber)
.property("columnNumber", &symbols_backend::api::SourceLocation::GetColumnNumber, &symbols_backend::api::SourceLocation::SetColumnNumber)
;
emscripten::enum_<symbols_backend::api::Variable::Scope>("VariableScope")
.value("LOCAL", symbols_backend::api::Variable::Scope::kLocal)
.value("PARAMETER", symbols_backend::api::Variable::Scope::kParameter)
.value("GLOBAL", symbols_backend::api::Variable::Scope::kGlobal)
;
emscripten::class_<symbols_backend::api::Variable>("Variable")
.constructor<>()
.property("scope", &symbols_backend::api::Variable::GetScope, &symbols_backend::api::Variable::SetScope)
.property("name", &symbols_backend::api::Variable::GetName, &symbols_backend::api::Variable::SetName)
.property("type", &symbols_backend::api::Variable::GetType, &symbols_backend::api::Variable::SetType)
.property("typedefs", &symbols_backend::api::Variable::GetTypedefs, &symbols_backend::api::Variable::SetTypedefs)
;
emscripten::class_<symbols_backend::api::FieldInfo>("FieldInfo")
.constructor<>()
.property("name", OptionalGetter(&symbols_backend::api::FieldInfo::GetName), OptionalSetter(&symbols_backend::api::FieldInfo::SetName))
.property("offset", &symbols_backend::api::FieldInfo::GetOffset, &symbols_backend::api::FieldInfo::SetOffset)
.property("typeId", &symbols_backend::api::FieldInfo::GetTypeId, &symbols_backend::api::FieldInfo::SetTypeId)
;
emscripten::class_<symbols_backend::api::Enumerator>("Enumerator")
.constructor<>()
.property("name", &symbols_backend::api::Enumerator::GetName, &symbols_backend::api::Enumerator::SetName)
.property("value", &symbols_backend::api::Enumerator::GetValue, &symbols_backend::api::Enumerator::SetValue)
.property("typeId", &symbols_backend::api::Enumerator::GetTypeId, &symbols_backend::api::Enumerator::SetTypeId)
;
emscripten::class_<symbols_backend::api::TypeInfo>("TypeInfo")
.constructor<>()
.property("typeNames", &symbols_backend::api::TypeInfo::GetTypeNames, &symbols_backend::api::TypeInfo::SetTypeNames)
.property("typeId", &symbols_backend::api::TypeInfo::GetTypeId, &symbols_backend::api::TypeInfo::SetTypeId)
.property("alignment", &symbols_backend::api::TypeInfo::GetAlignment, &symbols_backend::api::TypeInfo::SetAlignment)
.property("size", &symbols_backend::api::TypeInfo::GetSize, &symbols_backend::api::TypeInfo::SetSize)
.property("canExpand", &symbols_backend::api::TypeInfo::GetCanExpand, &symbols_backend::api::TypeInfo::SetCanExpand)
.property("hasValue", &symbols_backend::api::TypeInfo::GetHasValue, &symbols_backend::api::TypeInfo::SetHasValue)
.property("arraySize", OptionalGetter(&symbols_backend::api::TypeInfo::GetArraySize), OptionalSetter(&symbols_backend::api::TypeInfo::SetArraySize))
.property("isPointer", &symbols_backend::api::TypeInfo::GetIsPointer, &symbols_backend::api::TypeInfo::SetIsPointer)
.property("members", &symbols_backend::api::TypeInfo::GetMembers, &symbols_backend::api::TypeInfo::SetMembers)
.property("enumerators", &symbols_backend::api::TypeInfo::GetEnumerators, &symbols_backend::api::TypeInfo::SetEnumerators)
;
emscripten::class_<symbols_backend::api::AddRawModuleResponse>("AddRawModuleResponse")
.constructor<>()
.property("sources", &symbols_backend::api::AddRawModuleResponse::GetSources, &symbols_backend::api::AddRawModuleResponse::SetSources)
.property("dwos", &symbols_backend::api::AddRawModuleResponse::GetDwos, &symbols_backend::api::AddRawModuleResponse::SetDwos)
.property("error", OptionalGetter(&symbols_backend::api::AddRawModuleResponse::GetError), OptionalSetter(&symbols_backend::api::AddRawModuleResponse::SetError))
;
emscripten::class_<symbols_backend::api::SourceLocationToRawLocationResponse>("SourceLocationToRawLocationResponse")
.constructor<>()
.property("rawLocationRanges", &symbols_backend::api::SourceLocationToRawLocationResponse::GetRawLocationRanges, &symbols_backend::api::SourceLocationToRawLocationResponse::SetRawLocationRanges)
.property("error", OptionalGetter(&symbols_backend::api::SourceLocationToRawLocationResponse::GetError), OptionalSetter(&symbols_backend::api::SourceLocationToRawLocationResponse::SetError))
;
emscripten::class_<symbols_backend::api::RawLocationToSourceLocationResponse>("RawLocationToSourceLocationResponse")
.constructor<>()
.property("sourceLocation", &symbols_backend::api::RawLocationToSourceLocationResponse::GetSourceLocation, &symbols_backend::api::RawLocationToSourceLocationResponse::SetSourceLocation)
.property("error", OptionalGetter(&symbols_backend::api::RawLocationToSourceLocationResponse::GetError), OptionalSetter(&symbols_backend::api::RawLocationToSourceLocationResponse::SetError))
;
emscripten::class_<symbols_backend::api::ListVariablesInScopeResponse>("ListVariablesInScopeResponse")
.constructor<>()
.property("variable", &symbols_backend::api::ListVariablesInScopeResponse::GetVariable, &symbols_backend::api::ListVariablesInScopeResponse::SetVariable)
.property("error", OptionalGetter(&symbols_backend::api::ListVariablesInScopeResponse::GetError), OptionalSetter(&symbols_backend::api::ListVariablesInScopeResponse::SetError))
;
emscripten::class_<symbols_backend::api::GetFunctionInfoResponse>("GetFunctionInfoResponse")
.constructor<>()
.property("functionNames", &symbols_backend::api::GetFunctionInfoResponse::GetFunctionNames, &symbols_backend::api::GetFunctionInfoResponse::SetFunctionNames)
.property("missingSymbolFiles", &symbols_backend::api::GetFunctionInfoResponse::GetMissingSymbolFiles, &symbols_backend::api::GetFunctionInfoResponse::SetMissingSymbolFiles)
.property("error", OptionalGetter(&symbols_backend::api::GetFunctionInfoResponse::GetError), OptionalSetter(&symbols_backend::api::GetFunctionInfoResponse::SetError))
;
emscripten::class_<symbols_backend::api::GetInlinedFunctionRangesResponse>("GetInlinedFunctionRangesResponse")
.constructor<>()
.property("rawLocationRanges", &symbols_backend::api::GetInlinedFunctionRangesResponse::GetRawLocationRanges, &symbols_backend::api::GetInlinedFunctionRangesResponse::SetRawLocationRanges)
.property("error", OptionalGetter(&symbols_backend::api::GetInlinedFunctionRangesResponse::GetError), OptionalSetter(&symbols_backend::api::GetInlinedFunctionRangesResponse::SetError))
;
emscripten::class_<symbols_backend::api::GetInlinedCalleesRangesResponse>("GetInlinedCalleesRangesResponse")
.constructor<>()
.property("rawLocationRanges", &symbols_backend::api::GetInlinedCalleesRangesResponse::GetRawLocationRanges, &symbols_backend::api::GetInlinedCalleesRangesResponse::SetRawLocationRanges)
.property("error", OptionalGetter(&symbols_backend::api::GetInlinedCalleesRangesResponse::GetError), OptionalSetter(&symbols_backend::api::GetInlinedCalleesRangesResponse::SetError))
;
emscripten::class_<symbols_backend::api::GetMappedLinesResponse>("GetMappedLinesResponse")
.constructor<>()
.property("MappedLines", &symbols_backend::api::GetMappedLinesResponse::GetMappedLines, &symbols_backend::api::GetMappedLinesResponse::SetMappedLines)
.property("error", OptionalGetter(&symbols_backend::api::GetMappedLinesResponse::GetError), OptionalSetter(&symbols_backend::api::GetMappedLinesResponse::SetError))
;
emscripten::class_<symbols_backend::api::EvaluateExpressionResponse>("EvaluateExpressionResponse")
.constructor<>()
.property("typeInfos", &symbols_backend::api::EvaluateExpressionResponse::GetTypeInfos, &symbols_backend::api::EvaluateExpressionResponse::SetTypeInfos)
.property("root", &symbols_backend::api::EvaluateExpressionResponse::GetRoot, &symbols_backend::api::EvaluateExpressionResponse::SetRoot)
.property("displayValue", OptionalGetter(&symbols_backend::api::EvaluateExpressionResponse::GetDisplayValue), OptionalSetter(&symbols_backend::api::EvaluateExpressionResponse::SetDisplayValue))
.property("location", OptionalGetter(&symbols_backend::api::EvaluateExpressionResponse::GetLocation), OptionalSetter(&symbols_backend::api::EvaluateExpressionResponse::SetLocation))
.property("memoryAddress", OptionalGetter(&symbols_backend::api::EvaluateExpressionResponse::GetMemoryAddress), OptionalSetter(&symbols_backend::api::EvaluateExpressionResponse::SetMemoryAddress))
.property("data", OptionalGetter(&symbols_backend::api::EvaluateExpressionResponse::GetData), OptionalSetter(&symbols_backend::api::EvaluateExpressionResponse::SetData))
.property("error", OptionalGetter(&symbols_backend::api::EvaluateExpressionResponse::GetError), OptionalSetter(&symbols_backend::api::EvaluateExpressionResponse::SetError))
;
emscripten::register_vector<std::string>("StringArray");
emscripten::register_vector<symbols_backend::api::RawLocationRange>("RawLocationRangeArray");
emscripten::register_vector<symbols_backend::api::SourceLocation>("SourceLocationArray");
emscripten::register_vector<symbols_backend::api::Variable>("VariableArray");
emscripten::register_vector<int32_t>("Int32_TArray");
emscripten::register_vector<symbols_backend::api::TypeInfo>("TypeInfoArray");
emscripten::register_vector<symbols_backend::api::FieldInfo>("FieldInfoArray");
emscripten::register_vector<symbols_backend::api::Enumerator>("EnumeratorArray");
emscripten::register_vector<uint8_t>("ByteArray");
emscripten::class_<symbols_backend::api::ApiContext>("DWARFSymbolsPluginBase")
.constructor<>()
.function("AddRawModule",
&symbols_backend::DWARFSymbolsPlugin::AddRawModule)
.function("RemoveRawModule",
&symbols_backend::DWARFSymbolsPlugin::RemoveRawModule)
.function("SourceLocationToRawLocation",
&symbols_backend::DWARFSymbolsPlugin::SourceLocationToRawLocation)
.function("RawLocationToSourceLocation",
&symbols_backend::DWARFSymbolsPlugin::RawLocationToSourceLocation)
.function("ListVariablesInScope",
&symbols_backend::DWARFSymbolsPlugin::ListVariablesInScope)
.function("GetFunctionInfo",
&symbols_backend::DWARFSymbolsPlugin::GetFunctionInfo)
.function("GetInlinedFunctionRanges",
&symbols_backend::DWARFSymbolsPlugin::GetInlinedFunctionRanges)
.function("GetInlinedCalleesRanges",
&symbols_backend::DWARFSymbolsPlugin::GetInlinedCalleesRanges)
.function("GetMappedLines",
&symbols_backend::DWARFSymbolsPlugin::GetMappedLines)
.function("EvaluateExpression",
&symbols_backend::DWARFSymbolsPlugin::EvaluateExpression)
;
emscripten::class_<symbols_backend::DWARFSymbolsPlugin, emscripten::base<symbols_backend::api::ApiContext>>("DWARFSymbolsPlugin")
.constructor<>();
}