File indexing completed on 2026-05-10 08:42:54
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLDB_TARGET_REGISTERCONTEXTUNWIND_H
0010 #define LLDB_TARGET_REGISTERCONTEXTUNWIND_H
0011
0012 #include <vector>
0013
0014 #include "lldb/Symbol/SymbolContext.h"
0015 #include "lldb/Symbol/UnwindPlan.h"
0016 #include "lldb/Target/RegisterContext.h"
0017 #include "lldb/Target/RegisterNumber.h"
0018 #include "lldb/Target/UnwindLLDB.h"
0019 #include "lldb/lldb-private.h"
0020
0021 namespace lldb_private {
0022
0023 class UnwindLLDB;
0024
0025 class RegisterContextUnwind : public lldb_private::RegisterContext {
0026 public:
0027 typedef std::shared_ptr<RegisterContextUnwind> SharedPtr;
0028
0029 RegisterContextUnwind(lldb_private::Thread &thread,
0030 const SharedPtr &next_frame,
0031 lldb_private::SymbolContext &sym_ctx,
0032 uint32_t frame_number,
0033 lldb_private::UnwindLLDB &unwind_lldb);
0034
0035 ~RegisterContextUnwind() override = default;
0036
0037 void InvalidateAllRegisters() override;
0038
0039 size_t GetRegisterCount() override;
0040
0041 const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
0042
0043 size_t GetRegisterSetCount() override;
0044
0045 const lldb_private::RegisterSet *GetRegisterSet(size_t reg_set) override;
0046
0047 bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
0048 lldb_private::RegisterValue &value) override;
0049
0050 bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
0051 const lldb_private::RegisterValue &value) override;
0052
0053 bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override;
0054
0055 bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
0056
0057 uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
0058 uint32_t num) override;
0059
0060 bool IsValid() const;
0061
0062 bool IsTrapHandlerFrame() const;
0063
0064 bool GetCFA(lldb::addr_t &cfa);
0065
0066 bool GetStartPC(lldb::addr_t &start_pc);
0067
0068 bool ReadPC(lldb::addr_t &start_pc);
0069
0070
0071
0072
0073 bool BehavesLikeZerothFrame() const override;
0074
0075 private:
0076 enum FrameType {
0077 eNormalFrame,
0078 eTrapHandlerFrame,
0079 eDebuggerFrame,
0080
0081 eSkipFrame,
0082
0083 eNotAValidFrame
0084
0085 };
0086
0087
0088 friend class UnwindLLDB;
0089
0090
0091
0092 bool CheckIfLoopingStack();
0093
0094
0095
0096 bool IsFrameZero() const;
0097
0098 void InitializeZerothFrame();
0099
0100 void InitializeNonZerothFrame();
0101
0102 SharedPtr GetNextFrame() const;
0103
0104 SharedPtr GetPrevFrame() const;
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116 bool IsSkipFrame() const;
0117
0118
0119
0120
0121
0122
0123
0124
0125 bool IsTrapHandlerSymbol(lldb_private::Process *process,
0126 const lldb_private::SymbolContext &m_sym_ctx) const;
0127
0128
0129
0130 void PropagateTrapHandlerFlagFromUnwindPlan(lldb::UnwindPlanSP unwind_plan);
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149 lldb_private::UnwindLLDB::RegisterSearchResult SavedLocationForRegister(
0150 uint32_t lldb_regnum,
0151 lldb_private::UnwindLLDB::ConcreteRegisterLocation ®loc);
0152
0153 bool ReadRegisterValueFromRegisterLocation(
0154 lldb_private::UnwindLLDB::ConcreteRegisterLocation regloc,
0155 const lldb_private::RegisterInfo *reg_info,
0156 lldb_private::RegisterValue &value);
0157
0158 bool WriteRegisterValueToRegisterLocation(
0159 lldb_private::UnwindLLDB::ConcreteRegisterLocation regloc,
0160 const lldb_private::RegisterInfo *reg_info,
0161 const lldb_private::RegisterValue &value);
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173 bool TryFallbackUnwindPlan();
0174
0175
0176
0177
0178
0179
0180
0181
0182 bool ForceSwitchToFallbackUnwindPlan();
0183
0184
0185
0186
0187 bool ReadGPRValue(lldb::RegisterKind register_kind, uint32_t regnum,
0188 lldb::addr_t &value);
0189
0190 bool ReadGPRValue(const RegisterNumber ®_num, lldb::addr_t &value);
0191
0192
0193 bool ReadFrameAddress(lldb::RegisterKind register_kind,
0194 UnwindPlan::Row::FAValue &fa, lldb::addr_t &address);
0195
0196 lldb::UnwindPlanSP GetFastUnwindPlanForFrame();
0197
0198 lldb::UnwindPlanSP GetFullUnwindPlanForFrame();
0199
0200 void UnwindLogMsg(const char *fmt, ...) __attribute__((format(printf, 2, 3)));
0201
0202 void UnwindLogMsgVerbose(const char *fmt, ...)
0203 __attribute__((format(printf, 2, 3)));
0204
0205 bool IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp);
0206
0207 lldb::addr_t GetReturnAddressHint(int32_t plan_offset);
0208
0209 lldb_private::Thread &m_thread;
0210
0211
0212
0213
0214
0215
0216
0217 lldb::UnwindPlanSP m_fast_unwind_plan_sp;
0218 lldb::UnwindPlanSP m_full_unwind_plan_sp;
0219 lldb::UnwindPlanSP m_fallback_unwind_plan_sp;
0220
0221 bool m_all_registers_available;
0222
0223 int m_frame_type;
0224
0225 lldb::addr_t m_cfa;
0226 lldb::addr_t m_afa;
0227 lldb_private::Address m_start_pc;
0228 lldb_private::Address m_current_pc;
0229
0230 int m_current_offset;
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240 int m_current_offset_backed_up_one;
0241
0242
0243 bool m_behaves_like_zeroth_frame;
0244
0245 lldb_private::SymbolContext &m_sym_ctx;
0246 bool m_sym_ctx_valid;
0247
0248
0249 uint32_t m_frame_number;
0250
0251 std::map<uint32_t, lldb_private::UnwindLLDB::ConcreteRegisterLocation>
0252 m_registers;
0253
0254 lldb_private::UnwindLLDB &m_parent_unwind;
0255
0256
0257 RegisterContextUnwind(const RegisterContextUnwind &) = delete;
0258 const RegisterContextUnwind &
0259 operator=(const RegisterContextUnwind &) = delete;
0260 };
0261
0262 }
0263
0264 #endif