]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Target/StackFrameRecognizer.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Target / StackFrameRecognizer.cpp
1 //===-- StackFrameRecognizer.cpp --------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include <vector>
11 #include "lldb/Core/Module.h"
12 #include "lldb/Interpreter/ScriptInterpreter.h"
13 #include "lldb/Symbol/Symbol.h"
14 #include "lldb/Target/StackFrame.h"
15 #include "lldb/Target/StackFrameRecognizer.h"
16 #include "lldb/Utility/RegularExpression.h"
17
18 using namespace lldb;
19 using namespace lldb_private;
20
21 #ifndef LLDB_DISABLE_PYTHON
22
23 class ScriptedRecognizedStackFrame : public RecognizedStackFrame {
24 public:
25   ScriptedRecognizedStackFrame(ValueObjectListSP args) {
26     m_arguments = args;
27   }
28 };
29
30 ScriptedStackFrameRecognizer::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
37 RecognizedStackFrameSP
38 ScriptedStackFrameRecognizer::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
45   return RecognizedStackFrameSP(new ScriptedRecognizedStackFrame(args));
46 }
47
48 #endif
49
50 class StackFrameRecognizerManagerImpl {
51 public:
52   void AddRecognizer(StackFrameRecognizerSP recognizer,
53                      const ConstString &module, const ConstString &symbol,
54                      bool first_instruction_only) {
55     m_recognizers.push_front({(uint32_t)m_recognizers.size(), false, recognizer, false, module, RegularExpressionSP(),
56                               symbol, RegularExpressionSP(),
57                               first_instruction_only});
58   }
59
60   void AddRecognizer(StackFrameRecognizerSP recognizer,
61                      RegularExpressionSP module, RegularExpressionSP symbol,
62                      bool first_instruction_only) {
63     m_recognizers.push_front({(uint32_t)m_recognizers.size(), false, recognizer, true, ConstString(), module,
64                               ConstString(), symbol, first_instruction_only});
65   }
66
67   void ForEach(
68       std::function<void(uint32_t recognized_id, std::string recognizer_name, std::string module,
69                          std::string symbol, bool regexp)> const &callback) {
70     for (auto entry : m_recognizers) {
71       if (entry.is_regexp) {
72         callback(entry.recognizer_id, entry.recognizer->GetName(), entry.module_regexp->GetText(),
73                  entry.symbol_regexp->GetText(), true);
74       } else {
75         callback(entry.recognizer_id, entry.recognizer->GetName(), entry.module.GetCString(),
76                  entry.symbol.GetCString(), false);
77       }
78     }
79   }
80
81   bool RemoveRecognizerWithID(uint32_t recognizer_id) {
82     if (recognizer_id >= m_recognizers.size()) return false;
83     if (m_recognizers[recognizer_id].deleted) return false;
84     m_recognizers[recognizer_id].deleted = true;
85     return true;
86   }
87
88   void RemoveAllRecognizers() {
89     m_recognizers.clear();
90   }
91
92   StackFrameRecognizerSP GetRecognizerForFrame(StackFrameSP frame) {
93     const SymbolContext &symctx =
94         frame->GetSymbolContext(eSymbolContextModule | eSymbolContextFunction);
95     ConstString function_name = symctx.GetFunctionName();
96     ModuleSP module_sp = symctx.module_sp;
97     if (!module_sp) return StackFrameRecognizerSP();
98     ConstString module_name = module_sp->GetFileSpec().GetFilename();
99     Symbol *symbol = symctx.symbol;
100     if (!symbol) return StackFrameRecognizerSP();
101     Address start_addr = symbol->GetAddress();
102     Address current_addr = frame->GetFrameCodeAddress();
103
104     for (auto entry : m_recognizers) {
105       if (entry.deleted) continue;
106       if (entry.module)
107         if (entry.module != module_name) continue;
108
109       if (entry.module_regexp)
110         if (!entry.module_regexp->Execute(module_name.GetStringRef())) continue;
111
112       if (entry.symbol)
113         if (entry.symbol != function_name) continue;
114
115       if (entry.symbol_regexp)
116         if (!entry.symbol_regexp->Execute(function_name.GetStringRef()))
117           continue;
118
119       if (entry.first_instruction_only)
120         if (start_addr != current_addr) continue;
121
122       return entry.recognizer;
123     }
124     return StackFrameRecognizerSP();
125   }
126
127   RecognizedStackFrameSP RecognizeFrame(StackFrameSP frame) {
128     auto recognizer = GetRecognizerForFrame(frame);
129     if (!recognizer) return RecognizedStackFrameSP();
130     return recognizer->RecognizeFrame(frame);
131   }
132
133  private:
134   struct RegisteredEntry {
135     uint32_t recognizer_id;
136     bool deleted;
137     StackFrameRecognizerSP recognizer;
138     bool is_regexp;
139     ConstString module;
140     RegularExpressionSP module_regexp;
141     ConstString symbol;
142     RegularExpressionSP symbol_regexp;
143     bool first_instruction_only;
144   };
145
146   std::deque<RegisteredEntry> m_recognizers;
147 };
148
149 StackFrameRecognizerManagerImpl &GetStackFrameRecognizerManagerImpl() {
150   static StackFrameRecognizerManagerImpl instance =
151       StackFrameRecognizerManagerImpl();
152   return instance;
153 }
154
155 void StackFrameRecognizerManager::AddRecognizer(
156     StackFrameRecognizerSP recognizer, const ConstString &module,
157     const ConstString &symbol, bool first_instruction_only) {
158   GetStackFrameRecognizerManagerImpl().AddRecognizer(recognizer, module, symbol,
159                                                      first_instruction_only);
160 }
161
162 void StackFrameRecognizerManager::AddRecognizer(
163     StackFrameRecognizerSP recognizer, RegularExpressionSP module,
164     RegularExpressionSP symbol, bool first_instruction_only) {
165   GetStackFrameRecognizerManagerImpl().AddRecognizer(recognizer, module, symbol,
166                                                      first_instruction_only);
167 }
168
169 void StackFrameRecognizerManager::ForEach(
170     std::function<void(uint32_t recognized_id, std::string recognizer_name, std::string module,
171                        std::string symbol, bool regexp)> const &callback) {
172   GetStackFrameRecognizerManagerImpl().ForEach(callback);
173 }
174
175 void StackFrameRecognizerManager::RemoveAllRecognizers() {
176   GetStackFrameRecognizerManagerImpl().RemoveAllRecognizers();
177 }
178
179 bool StackFrameRecognizerManager::RemoveRecognizerWithID(uint32_t recognizer_id) {
180   return GetStackFrameRecognizerManagerImpl().RemoveRecognizerWithID(recognizer_id);
181 }
182
183 RecognizedStackFrameSP StackFrameRecognizerManager::RecognizeFrame(
184     StackFrameSP frame) {
185   return GetStackFrameRecognizerManagerImpl().RecognizeFrame(frame);
186 }
187
188 StackFrameRecognizerSP StackFrameRecognizerManager::GetRecognizerForFrame(
189     lldb::StackFrameSP frame) {
190   return GetStackFrameRecognizerManagerImpl().GetRecognizerForFrame(frame);
191 }