brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.3 KiB · 269d1e0 Raw
313 lines · cpp
1//===-- LanguageRuntime.cpp -----------------------------------------------===//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 "lldb/Target/LanguageRuntime.h"10#include "lldb/Core/PluginManager.h"11#include "lldb/Core/SearchFilter.h"12#include "lldb/Interpreter/CommandInterpreter.h"13#include "lldb/Target/Language.h"14#include "lldb/Target/Target.h"15 16using namespace lldb;17using namespace lldb_private;18 19char LanguageRuntime::ID = 0;20 21ExceptionSearchFilter::ExceptionSearchFilter(const lldb::TargetSP &target_sp,22                                             lldb::LanguageType language,23                                             bool update_module_list)24    : SearchFilter(target_sp, FilterTy::Exception), m_language(language),25      m_language_runtime(nullptr), m_filter_sp() {26  if (update_module_list)27    UpdateModuleListIfNeeded();28}29 30bool ExceptionSearchFilter::ModulePasses(const lldb::ModuleSP &module_sp) {31  UpdateModuleListIfNeeded();32  if (m_filter_sp)33    return m_filter_sp->ModulePasses(module_sp);34  return false;35}36 37bool ExceptionSearchFilter::ModulePasses(const FileSpec &spec) {38  UpdateModuleListIfNeeded();39  if (m_filter_sp)40    return m_filter_sp->ModulePasses(spec);41  return false;42}43 44void ExceptionSearchFilter::Search(Searcher &searcher) {45  UpdateModuleListIfNeeded();46  if (m_filter_sp)47    m_filter_sp->Search(searcher);48}49 50void ExceptionSearchFilter::GetDescription(Stream *s) {51  UpdateModuleListIfNeeded();52  if (m_filter_sp)53    m_filter_sp->GetDescription(s);54}55 56void ExceptionSearchFilter::UpdateModuleListIfNeeded() {57  ProcessSP process_sp(m_target_sp->GetProcessSP());58  if (process_sp) {59    bool refreash_filter = !m_filter_sp;60    if (m_language_runtime == nullptr) {61      m_language_runtime = process_sp->GetLanguageRuntime(m_language);62      refreash_filter = true;63    } else {64      LanguageRuntime *language_runtime =65          process_sp->GetLanguageRuntime(m_language);66      if (m_language_runtime != language_runtime) {67        m_language_runtime = language_runtime;68        refreash_filter = true;69      }70    }71 72    if (refreash_filter && m_language_runtime) {73      m_filter_sp = m_language_runtime->CreateExceptionSearchFilter();74    }75  } else {76    m_filter_sp.reset();77    m_language_runtime = nullptr;78  }79}80 81SearchFilterSP ExceptionSearchFilter::DoCreateCopy() {82  return SearchFilterSP(83      new ExceptionSearchFilter(TargetSP(), m_language, false));84}85 86SearchFilter *ExceptionSearchFilter::CreateFromStructuredData(87    Target &target, const StructuredData::Dictionary &data_dict,88    Status &error) {89  SearchFilter *result = nullptr;90  return result;91}92 93StructuredData::ObjectSP ExceptionSearchFilter::SerializeToStructuredData() {94  StructuredData::ObjectSP result_sp;95 96  return result_sp;97}98 99// The Target is the one that knows how to create breakpoints, so this function100// is meant to be used either by the target or internally in101// Set/ClearExceptionBreakpoints.102class ExceptionBreakpointResolver : public BreakpointResolver {103public:104  ExceptionBreakpointResolver(lldb::LanguageType language, bool catch_bp,105                              bool throw_bp)106      : BreakpointResolver(nullptr, BreakpointResolver::ExceptionResolver),107        m_language(language), m_catch_bp(catch_bp), m_throw_bp(throw_bp) {}108 109  ~ExceptionBreakpointResolver() override = default;110 111  Searcher::CallbackReturn SearchCallback(SearchFilter &filter,112                                          SymbolContext &context,113                                          Address *addr) override {114 115    if (SetActualResolver())116      return m_actual_resolver_sp->SearchCallback(filter, context, addr);117    else118      return eCallbackReturnStop;119  }120 121  lldb::SearchDepth GetDepth() override {122    if (SetActualResolver())123      return m_actual_resolver_sp->GetDepth();124    else125      return lldb::eSearchDepthTarget;126  }127 128  void GetDescription(Stream *s) override {129    Language *language_plugin = Language::FindPlugin(m_language);130    if (language_plugin)131      language_plugin->GetExceptionResolverDescription(m_catch_bp, m_throw_bp,132                                                       *s);133    else134      Language::GetDefaultExceptionResolverDescription(m_catch_bp, m_throw_bp,135                                                       *s);136 137    SetActualResolver();138    if (m_actual_resolver_sp) {139      s->Printf(" using: ");140      m_actual_resolver_sp->GetDescription(s);141    } else142      s->Printf(" the correct runtime exception handler will be determined "143                "when you run");144  }145 146  void Dump(Stream *s) const override {}147 148  /// Methods for support type inquiry through isa, cast, and dyn_cast:149  static inline bool classof(const BreakpointResolverName *) { return true; }150  static inline bool classof(const BreakpointResolver *V) {151    return V->getResolverID() == BreakpointResolver::ExceptionResolver;152  }153 154protected:155  BreakpointResolverSP CopyForBreakpoint(BreakpointSP &breakpoint) override {156    BreakpointResolverSP ret_sp(157        new ExceptionBreakpointResolver(m_language, m_catch_bp, m_throw_bp));158    ret_sp->SetBreakpoint(breakpoint);159    return ret_sp;160  }161 162  bool SetActualResolver() {163    BreakpointSP breakpoint_sp = GetBreakpoint();164    if (breakpoint_sp) {165      ProcessSP process_sp = breakpoint_sp->GetTarget().GetProcessSP();166      if (process_sp) {167        bool refreash_resolver = !m_actual_resolver_sp;168        if (m_language_runtime == nullptr) {169          m_language_runtime = process_sp->GetLanguageRuntime(m_language);170          refreash_resolver = true;171        } else {172          LanguageRuntime *language_runtime =173              process_sp->GetLanguageRuntime(m_language);174          if (m_language_runtime != language_runtime) {175            m_language_runtime = language_runtime;176            refreash_resolver = true;177          }178        }179 180        if (refreash_resolver && m_language_runtime) {181          m_actual_resolver_sp = m_language_runtime->CreateExceptionResolver(182              breakpoint_sp, m_catch_bp, m_throw_bp);183        }184      } else {185        m_actual_resolver_sp.reset();186        m_language_runtime = nullptr;187      }188    } else {189      m_actual_resolver_sp.reset();190      m_language_runtime = nullptr;191    }192    return (bool)m_actual_resolver_sp;193  }194 195  lldb::BreakpointResolverSP m_actual_resolver_sp;196  lldb::LanguageType m_language;197  LanguageRuntime *m_language_runtime = nullptr;198  bool m_catch_bp;199  bool m_throw_bp;200};201 202LanguageRuntime *LanguageRuntime::FindPlugin(Process *process,203                                             lldb::LanguageType language) {204  LanguageRuntimeCreateInstance create_callback;205  for (uint32_t idx = 0;206       (create_callback =207            PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) !=208       nullptr;209       ++idx) {210    if (LanguageRuntime *runtime = create_callback(process, language))211      return runtime;212  }213  return nullptr;214}215 216LanguageRuntime::LanguageRuntime(Process *process) : Runtime(process) {}217 218BreakpointPreconditionSP219LanguageRuntime::GetExceptionPrecondition(LanguageType language,220                                          bool throw_bp) {221  LanguageRuntimeCreateInstance create_callback;222  for (uint32_t idx = 0;223       (create_callback =224            PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) !=225       nullptr;226       idx++) {227    if (auto precondition_callback =228            PluginManager::GetLanguageRuntimeGetExceptionPreconditionAtIndex(229                idx)) {230      if (BreakpointPreconditionSP precond =231              precondition_callback(language, throw_bp))232        return precond;233    }234  }235  return BreakpointPreconditionSP();236}237 238BreakpointSP LanguageRuntime::CreateExceptionBreakpoint(239    Target &target, lldb::LanguageType language, bool catch_bp, bool throw_bp,240    bool is_internal) {241  BreakpointResolverSP resolver_sp(242      new ExceptionBreakpointResolver(language, catch_bp, throw_bp));243  SearchFilterSP filter_sp(244      new ExceptionSearchFilter(target.shared_from_this(), language));245  bool hardware = false;246  bool resolve_indirect_functions = false;247  BreakpointSP exc_breakpt_sp(248      target.CreateBreakpoint(filter_sp, resolver_sp, is_internal, hardware,249                              resolve_indirect_functions));250  if (exc_breakpt_sp) {251    if (auto precond = GetExceptionPrecondition(language, throw_bp))252      exc_breakpt_sp->SetPrecondition(precond);253 254    if (is_internal)255      exc_breakpt_sp->SetBreakpointKind("exception");256  }257 258  return exc_breakpt_sp;259}260 261UnwindPlanSP262LanguageRuntime::GetRuntimeUnwindPlan(Thread &thread, RegisterContext *regctx,263                                      bool &behaves_like_zeroth_frame) {264  ProcessSP process_sp = thread.GetProcess();265  if (!process_sp.get())266    return UnwindPlanSP();267  if (process_sp->GetDisableLangRuntimeUnwindPlans() == true)268    return UnwindPlanSP();269  for (const lldb::LanguageType lang_type : Language::GetSupportedLanguages()) {270    if (LanguageRuntime *runtime = process_sp->GetLanguageRuntime(lang_type)) {271      UnwindPlanSP plan_sp = runtime->GetRuntimeUnwindPlan(272          process_sp, regctx, behaves_like_zeroth_frame);273      if (plan_sp.get())274        return plan_sp;275    }276  }277  return UnwindPlanSP();278}279 280StructuredData::ObjectSP281LanguageRuntime::GetLanguageSpecificData(SymbolContext sc) {282  return {};283}284 285void LanguageRuntime::InitializeCommands(CommandObject *parent) {286  if (!parent)287    return;288 289  if (!parent->IsMultiwordObject())290    return;291 292  LanguageRuntimeCreateInstance create_callback;293 294  for (uint32_t idx = 0;295       (create_callback =296            PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) !=297       nullptr;298       ++idx) {299    if (LanguageRuntimeGetCommandObject command_callback =300            PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(idx)) {301      CommandObjectSP command =302          command_callback(parent->GetCommandInterpreter());303      if (command) {304        // the CommandObject vended by a Language plugin cannot be created once305        // and cached because we may create multiple debuggers and need one306        // instance of the command each - the implementing function is meant to307        // create a new instance of the command each time it is invoked.308        parent->LoadSubCommand(command->GetCommandName().str().c_str(), command);309      }310    }311  }312}313