brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.3 KiB · d9dbed8 Raw
193 lines · cpp
1//===-- StackFrameRecognizer.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/StackFrameRecognizer.h"10#include "lldb/Core/Module.h"11#include "lldb/Interpreter/ScriptInterpreter.h"12#include "lldb/Symbol/Symbol.h"13#include "lldb/Target/StackFrame.h"14#include "lldb/Utility/RegularExpression.h"15 16using namespace lldb;17using namespace lldb_private;18 19class ScriptedRecognizedStackFrame : public RecognizedStackFrame {20  bool m_hidden;21 22public:23  ScriptedRecognizedStackFrame(ValueObjectListSP args, bool hidden)24      : m_hidden(hidden) {25    m_arguments = std::move(args);26  }27  bool ShouldHide() override { return m_hidden; }28};29 30ScriptedStackFrameRecognizer::ScriptedStackFrameRecognizer(31    ScriptInterpreter *interpreter, const char *pclass)32    : m_interpreter(interpreter), m_python_class(pclass) {33  m_python_object_sp =34      m_interpreter->CreateFrameRecognizer(m_python_class.c_str());35}36 37RecognizedStackFrameSP38ScriptedStackFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame) {39  if (!m_python_object_sp || !m_interpreter)40    return RecognizedStackFrameSP();41 42  ValueObjectListSP args =43      m_interpreter->GetRecognizedArguments(m_python_object_sp, frame);44  auto args_synthesized = std::make_shared<ValueObjectList>();45  if (args) {46    for (const auto &o : args->GetObjects())47      args_synthesized->Append(ValueObjectRecognizerSynthesizedValue::Create(48          *o, eValueTypeVariableArgument));49  }50 51  bool hidden = m_interpreter->ShouldHide(m_python_object_sp, frame);52 53  return RecognizedStackFrameSP(54      new ScriptedRecognizedStackFrame(args_synthesized, hidden));55}56 57void StackFrameRecognizerManager::BumpGeneration() {58  uint32_t n = m_generation;59  n = (n + 1) & ((1 << 16) - 1);60  m_generation = n;61}62 63void StackFrameRecognizerManager::AddRecognizer(64    StackFrameRecognizerSP recognizer, ConstString module,65    llvm::ArrayRef<ConstString> symbols,66    Mangled::NamePreference symbol_mangling, bool first_instruction_only) {67  m_recognizers.push_front({(uint32_t)m_recognizers.size(), recognizer, false,68                            module, RegularExpressionSP(), symbols,69                            RegularExpressionSP(), symbol_mangling,70                            first_instruction_only, true});71  BumpGeneration();72}73 74void StackFrameRecognizerManager::AddRecognizer(75    StackFrameRecognizerSP recognizer, RegularExpressionSP module,76    RegularExpressionSP symbol, Mangled::NamePreference symbol_mangling,77    bool first_instruction_only) {78  m_recognizers.push_front({(uint32_t)m_recognizers.size(), recognizer, true,79                            ConstString(), module, std::vector<ConstString>(),80                            symbol, symbol_mangling, first_instruction_only,81                            true});82  BumpGeneration();83}84 85void StackFrameRecognizerManager::ForEach(86    const std::function<void(87        uint32_t, bool, std::string, std::string, llvm::ArrayRef<ConstString>,88        Mangled::NamePreference name_preference, bool)> &callback) {89  for (auto entry : m_recognizers) {90    if (entry.is_regexp) {91      std::string module_name;92      std::string symbol_name;93 94      if (entry.module_regexp)95        module_name = entry.module_regexp->GetText().str();96      if (entry.symbol_regexp)97        symbol_name = entry.symbol_regexp->GetText().str();98 99      callback(entry.recognizer_id, entry.enabled, entry.recognizer->GetName(),100               module_name, llvm::ArrayRef(ConstString(symbol_name)),101               entry.symbol_mangling, true);102    } else {103      callback(entry.recognizer_id, entry.enabled, entry.recognizer->GetName(),104               entry.module.GetCString(), entry.symbols, entry.symbol_mangling,105               false);106    }107  }108}109 110bool StackFrameRecognizerManager::SetEnabledForID(uint32_t recognizer_id,111                                                  bool enabled) {112  auto found =113      llvm::find_if(m_recognizers, [recognizer_id](const RegisteredEntry &e) {114        return e.recognizer_id == recognizer_id;115      });116  if (found == m_recognizers.end())117    return false;118  found->enabled = enabled;119  BumpGeneration();120  return true;121}122 123bool StackFrameRecognizerManager::RemoveRecognizerWithID(124    uint32_t recognizer_id) {125  auto found =126      llvm::find_if(m_recognizers, [recognizer_id](const RegisteredEntry &e) {127        return e.recognizer_id == recognizer_id;128      });129  if (found == m_recognizers.end())130    return false;131  m_recognizers.erase(found);132  BumpGeneration();133  return true;134}135 136void StackFrameRecognizerManager::RemoveAllRecognizers() {137  BumpGeneration();138  m_recognizers.clear();139}140 141StackFrameRecognizerSP142StackFrameRecognizerManager::GetRecognizerForFrame(StackFrameSP frame) {143  const SymbolContext &symctx = frame->GetSymbolContext(144      eSymbolContextModule | eSymbolContextFunction | eSymbolContextSymbol);145  ModuleSP module_sp = symctx.module_sp;146  if (!module_sp)147    return StackFrameRecognizerSP();148  ConstString module_name = module_sp->GetFileSpec().GetFilename();149  Symbol *symbol = symctx.symbol;150  if (!symbol)151    return StackFrameRecognizerSP();152  Address start_addr = symbol->GetAddress();153  Address current_addr = frame->GetFrameCodeAddress();154 155  for (const auto &entry : m_recognizers) {156    if (!entry.enabled)157      continue;158 159    if (entry.module)160      if (entry.module != module_name)161        continue;162 163    if (entry.module_regexp)164      if (!entry.module_regexp->Execute(module_name.GetStringRef()))165        continue;166 167    ConstString function_name = symctx.GetFunctionName(entry.symbol_mangling);168 169    if (!entry.symbols.empty())170      if (!llvm::is_contained(entry.symbols, function_name))171        continue;172 173    if (entry.symbol_regexp)174      if (!entry.symbol_regexp->Execute(function_name.GetStringRef()))175        continue;176 177    if (entry.first_instruction_only)178      if (start_addr != current_addr)179        continue;180 181    return entry.recognizer;182  }183  return StackFrameRecognizerSP();184}185 186RecognizedStackFrameSP187StackFrameRecognizerManager::RecognizeFrame(StackFrameSP frame) {188  auto recognizer = GetRecognizerForFrame(frame);189  if (!recognizer)190    return RecognizedStackFrameSP();191  return recognizer->RecognizeFrame(frame);192}193