blob: 6b587b19aa6f2d5ee44c110282d3c645dc99fe5b [file]
//===-- SourceRequestHandler.cpp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "DAP.h"
#include "EventHelper.h"
#include "JSONUtils.h"
#include "LLDBUtils.h"
#include "RequestHandler.h"
#include "lldb/API/SBFrame.h"
#include "lldb/API/SBInstructionList.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBTarget.h"
#include "lldb/API/SBThread.h"
#include "llvm/Support/JSON.h"
namespace lldb_dap {
// "SourceRequest": {
// "allOf": [ { "$ref": "#/definitions/Request" }, {
// "type": "object",
// "description": "Source request; value of command field is 'source'. The
// request retrieves the source code for a given source reference.",
// "properties": {
// "command": {
// "type": "string",
// "enum": [ "source" ]
// },
// "arguments": {
// "$ref": "#/definitions/SourceArguments"
// }
// },
// "required": [ "command", "arguments" ]
// }]
// },
// "SourceArguments": {
// "type": "object",
// "description": "Arguments for 'source' request.",
// "properties": {
// "source": {
// "$ref": "#/definitions/Source",
// "description": "Specifies the source content to load. Either
// source.path or source.sourceReference must be specified."
// },
// "sourceReference": {
// "type": "integer",
// "description": "The reference to the source. This is the same as
// source.sourceReference. This is provided for backward compatibility
// since old backends do not understand the 'source' attribute."
// }
// },
// "required": [ "sourceReference" ]
// },
// "SourceResponse": {
// "allOf": [ { "$ref": "#/definitions/Response" }, {
// "type": "object",
// "description": "Response to 'source' request.",
// "properties": {
// "body": {
// "type": "object",
// "properties": {
// "content": {
// "type": "string",
// "description": "Content of the source reference."
// },
// "mimeType": {
// "type": "string",
// "description": "Optional content type (mime type) of the source."
// }
// },
// "required": [ "content" ]
// }
// },
// "required": [ "body" ]
// }]
// }
void SourceRequestHandler::operator()(const llvm::json::Object &request) const {
llvm::json::Object response;
FillResponse(request, response);
const auto *arguments = request.getObject("arguments");
const auto *source = arguments->getObject("source");
llvm::json::Object body;
int64_t source_ref = GetUnsigned(
source, "sourceReference", GetUnsigned(arguments, "sourceReference", 0));
if (source_ref) {
lldb::SBProcess process = dap.target.GetProcess();
// Upper 32 bits is the thread index ID
lldb::SBThread thread =
process.GetThreadByIndexID(GetLLDBThreadIndexID(source_ref));
// Lower 32 bits is the frame index
lldb::SBFrame frame = thread.GetFrameAtIndex(GetLLDBFrameID(source_ref));
if (!frame.IsValid()) {
response["success"] = false;
response["message"] = "source not found";
} else {
lldb::SBInstructionList insts =
frame.GetSymbol().GetInstructions(dap.target);
lldb::SBStream stream;
insts.GetDescription(stream);
body["content"] = stream.GetData();
body["mimeType"] = "text/x-lldb.disassembly";
response.try_emplace("body", std::move(body));
}
} else {
response["success"] = false;
response["message"] =
"invalid arguments, expected source.sourceReference to be set";
}
dap.SendJSON(llvm::json::Value(std::move(response)));
}
} // namespace lldb_dap