brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.8 KiB · 6519df9 Raw
192 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "ScriptedFrame.h"10 11#include "lldb/Utility/DataBufferHeap.h"12 13using namespace lldb;14using namespace lldb_private;15 16void ScriptedFrame::CheckInterpreterAndScriptObject() const {17  lldbassert(m_script_object_sp && "Invalid Script Object.");18  lldbassert(GetInterface() && "Invalid Scripted Frame Interface.");19}20 21llvm::Expected<std::shared_ptr<ScriptedFrame>>22ScriptedFrame::Create(ScriptedThread &thread,23                      StructuredData::DictionarySP args_sp,24                      StructuredData::Generic *script_object) {25  if (!thread.IsValid())26    return llvm::createStringError("Invalid scripted thread.");27 28  thread.CheckInterpreterAndScriptObject();29 30  auto scripted_frame_interface =31      thread.GetInterface()->CreateScriptedFrameInterface();32  if (!scripted_frame_interface)33    return llvm::createStringError("failed to create scripted frame interface");34 35  llvm::StringRef frame_class_name;36  if (!script_object) {37    std::optional<std::string> class_name =38        thread.GetInterface()->GetScriptedFramePluginName();39    if (!class_name || class_name->empty())40      return llvm::createStringError(41          "failed to get scripted thread class name");42    frame_class_name = *class_name;43  }44 45  ExecutionContext exe_ctx(thread);46  auto obj_or_err = scripted_frame_interface->CreatePluginObject(47      frame_class_name, exe_ctx, args_sp, script_object);48 49  if (!obj_or_err)50    return llvm::createStringError(51        "failed to create script object: %s",52        llvm::toString(obj_or_err.takeError()).c_str());53 54  StructuredData::GenericSP owned_script_object_sp = *obj_or_err;55 56  if (!owned_script_object_sp->IsValid())57    return llvm::createStringError("created script object is invalid");58 59  lldb::user_id_t frame_id = scripted_frame_interface->GetID();60 61  lldb::addr_t pc = scripted_frame_interface->GetPC();62  SymbolContext sc;63  Address symbol_addr;64  if (pc != LLDB_INVALID_ADDRESS) {65    symbol_addr.SetLoadAddress(pc, &thread.GetProcess()->GetTarget());66    symbol_addr.CalculateSymbolContext(&sc);67  }68 69  std::optional<SymbolContext> maybe_sym_ctx =70      scripted_frame_interface->GetSymbolContext();71  if (maybe_sym_ctx) {72    sc = *maybe_sym_ctx;73  }74 75  StructuredData::DictionarySP reg_info =76      scripted_frame_interface->GetRegisterInfo();77 78  if (!reg_info)79    return llvm::createStringError(80        "failed to get scripted thread registers info");81 82  std::shared_ptr<DynamicRegisterInfo> register_info_sp =83      DynamicRegisterInfo::Create(84          *reg_info, thread.GetProcess()->GetTarget().GetArchitecture());85 86  lldb::RegisterContextSP reg_ctx_sp;87 88  std::optional<std::string> reg_data =89      scripted_frame_interface->GetRegisterContext();90  if (reg_data) {91    DataBufferSP data_sp(92        std::make_shared<DataBufferHeap>(reg_data->c_str(), reg_data->size()));93 94    if (!data_sp->GetByteSize())95      return llvm::createStringError("failed to copy raw registers data");96 97    std::shared_ptr<RegisterContextMemory> reg_ctx_memory =98        std::make_shared<RegisterContextMemory>(99            thread, frame_id, *register_info_sp, LLDB_INVALID_ADDRESS);100    if (!reg_ctx_memory)101      return llvm::createStringError("failed to create a register context.");102 103    reg_ctx_memory->SetAllRegisterData(data_sp);104    reg_ctx_sp = reg_ctx_memory;105  }106 107  return std::make_shared<ScriptedFrame>(108      thread, scripted_frame_interface, frame_id, pc, sc, reg_ctx_sp,109      register_info_sp, owned_script_object_sp);110}111 112ScriptedFrame::ScriptedFrame(ScriptedThread &thread,113                             ScriptedFrameInterfaceSP interface_sp,114                             lldb::user_id_t id, lldb::addr_t pc,115                             SymbolContext &sym_ctx,116                             lldb::RegisterContextSP reg_ctx_sp,117                             std::shared_ptr<DynamicRegisterInfo> reg_info_sp,118                             StructuredData::GenericSP script_object_sp)119    : StackFrame(thread.shared_from_this(), /*frame_idx=*/id,120                 /*concrete_frame_idx=*/id, /*reg_context_sp=*/reg_ctx_sp,121                 /*cfa=*/0, /*pc=*/pc,122                 /*behaves_like_zeroth_frame=*/!id, /*symbol_ctx=*/&sym_ctx),123      m_scripted_frame_interface_sp(interface_sp),124      m_script_object_sp(script_object_sp), m_register_info_sp(reg_info_sp) {}125 126ScriptedFrame::~ScriptedFrame() {}127 128const char *ScriptedFrame::GetFunctionName() {129  CheckInterpreterAndScriptObject();130  std::optional<std::string> function_name = GetInterface()->GetFunctionName();131  if (!function_name)132    return nullptr;133  return ConstString(function_name->c_str()).AsCString();134}135 136const char *ScriptedFrame::GetDisplayFunctionName() {137  CheckInterpreterAndScriptObject();138  std::optional<std::string> function_name =139      GetInterface()->GetDisplayFunctionName();140  if (!function_name)141    return nullptr;142  return ConstString(function_name->c_str()).AsCString();143}144 145bool ScriptedFrame::IsInlined() { return GetInterface()->IsInlined(); }146 147bool ScriptedFrame::IsArtificial() const {148  return GetInterface()->IsArtificial();149}150 151bool ScriptedFrame::IsHidden() { return GetInterface()->IsHidden(); }152 153lldb::ScriptedFrameInterfaceSP ScriptedFrame::GetInterface() const {154  return m_scripted_frame_interface_sp;155}156 157std::shared_ptr<DynamicRegisterInfo> ScriptedFrame::GetDynamicRegisterInfo() {158  CheckInterpreterAndScriptObject();159 160  if (!m_register_info_sp) {161    StructuredData::DictionarySP reg_info = GetInterface()->GetRegisterInfo();162 163    Status error;164    if (!reg_info)165      return ScriptedInterface::ErrorWithMessage<166          std::shared_ptr<DynamicRegisterInfo>>(167          LLVM_PRETTY_FUNCTION, "Failed to get scripted frame registers info.",168          error, LLDBLog::Thread);169 170    ThreadSP thread_sp = m_thread_wp.lock();171    if (!thread_sp || !thread_sp->IsValid())172      return ScriptedInterface::ErrorWithMessage<173          std::shared_ptr<DynamicRegisterInfo>>(174          LLVM_PRETTY_FUNCTION,175          "Failed to get scripted frame registers info: invalid thread.", error,176          LLDBLog::Thread);177 178    ProcessSP process_sp = thread_sp->GetProcess();179    if (!process_sp || !process_sp->IsValid())180      return ScriptedInterface::ErrorWithMessage<181          std::shared_ptr<DynamicRegisterInfo>>(182          LLVM_PRETTY_FUNCTION,183          "Failed to get scripted frame registers info: invalid process.",184          error, LLDBLog::Thread);185 186    m_register_info_sp = DynamicRegisterInfo::Create(187        *reg_info, process_sp->GetTarget().GetArchitecture());188  }189 190  return m_register_info_sp;191}192