]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
Vendor import of lldb trunk r351319 (just before the release_80 branch
[FreeBSD/FreeBSD.git] / source / Plugins / Process / Utility / RegisterContextMacOSXFrameBackchain.cpp
1 //===-- RegisterContextMacOSXFrameBackchain.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 "RegisterContextMacOSXFrameBackchain.h"
11
12 #include "lldb/Target/Thread.h"
13 #include "lldb/Utility/DataBufferHeap.h"
14 #include "lldb/Utility/DataExtractor.h"
15 #include "lldb/Utility/RegisterValue.h"
16 #include "lldb/Utility/Scalar.h"
17 #include "lldb/Utility/StreamString.h"
18 #include "lldb/Utility/StringExtractorGDBRemote.h"
19
20 using namespace lldb;
21 using namespace lldb_private;
22
23 //----------------------------------------------------------------------
24 // RegisterContextMacOSXFrameBackchain constructor
25 //----------------------------------------------------------------------
26 RegisterContextMacOSXFrameBackchain::RegisterContextMacOSXFrameBackchain(
27     Thread &thread, uint32_t concrete_frame_idx,
28     const UnwindMacOSXFrameBackchain::Cursor &cursor)
29     : RegisterContext(thread, concrete_frame_idx), m_cursor(cursor),
30       m_cursor_is_valid(true) {}
31
32 //----------------------------------------------------------------------
33 // Destructor
34 //----------------------------------------------------------------------
35 RegisterContextMacOSXFrameBackchain::~RegisterContextMacOSXFrameBackchain() {}
36
37 void RegisterContextMacOSXFrameBackchain::InvalidateAllRegisters() {
38   m_cursor_is_valid = false;
39 }
40
41 size_t RegisterContextMacOSXFrameBackchain::GetRegisterCount() {
42   return m_thread.GetRegisterContext()->GetRegisterCount();
43 }
44
45 const RegisterInfo *
46 RegisterContextMacOSXFrameBackchain::GetRegisterInfoAtIndex(size_t reg) {
47   return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
48 }
49
50 size_t RegisterContextMacOSXFrameBackchain::GetRegisterSetCount() {
51   return m_thread.GetRegisterContext()->GetRegisterSetCount();
52 }
53
54 const RegisterSet *
55 RegisterContextMacOSXFrameBackchain::GetRegisterSet(size_t reg_set) {
56   return m_thread.GetRegisterContext()->GetRegisterSet(reg_set);
57 }
58
59 bool RegisterContextMacOSXFrameBackchain::ReadRegister(
60     const RegisterInfo *reg_info, RegisterValue &value) {
61   if (!m_cursor_is_valid)
62     return false;
63
64   uint64_t reg_value = LLDB_INVALID_ADDRESS;
65
66   switch (reg_info->kinds[eRegisterKindGeneric]) {
67   case LLDB_REGNUM_GENERIC_PC:
68     if (m_cursor.pc == LLDB_INVALID_ADDRESS)
69       return false;
70     reg_value = m_cursor.pc;
71     break;
72
73   case LLDB_REGNUM_GENERIC_FP:
74     if (m_cursor.fp == LLDB_INVALID_ADDRESS)
75       return false;
76     reg_value = m_cursor.fp;
77     break;
78
79   default:
80     return false;
81   }
82
83   switch (reg_info->encoding) {
84   case eEncodingInvalid:
85   case eEncodingVector:
86     break;
87
88   case eEncodingUint:
89   case eEncodingSint:
90     value.SetUInt(reg_value, reg_info->byte_size);
91     return true;
92
93   case eEncodingIEEE754:
94     switch (reg_info->byte_size) {
95     case sizeof(float):
96       if (sizeof(float) == sizeof(uint32_t)) {
97         value.SetUInt32(reg_value, RegisterValue::eTypeFloat);
98         return true;
99       } else if (sizeof(float) == sizeof(uint64_t)) {
100         value.SetUInt64(reg_value, RegisterValue::eTypeFloat);
101         return true;
102       }
103       break;
104
105     case sizeof(double):
106       if (sizeof(double) == sizeof(uint32_t)) {
107         value.SetUInt32(reg_value, RegisterValue::eTypeDouble);
108         return true;
109       } else if (sizeof(double) == sizeof(uint64_t)) {
110         value.SetUInt64(reg_value, RegisterValue::eTypeDouble);
111         return true;
112       }
113       break;
114
115 // TOOD: need a better way to detect when "long double" types are
116 // the same bytes size as "double"
117 #if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) &&       \
118     !defined(_MSC_VER) && !defined(__mips__) && !defined(__powerpc__) &&       \
119     !defined(__ANDROID__)
120     case sizeof(long double):
121       if (sizeof(long double) == sizeof(uint32_t)) {
122         value.SetUInt32(reg_value, RegisterValue::eTypeLongDouble);
123         return true;
124       } else if (sizeof(long double) == sizeof(uint64_t)) {
125         value.SetUInt64(reg_value, RegisterValue::eTypeLongDouble);
126         return true;
127       }
128       break;
129 #endif
130     }
131     break;
132   }
133   return false;
134 }
135
136 bool RegisterContextMacOSXFrameBackchain::WriteRegister(
137     const RegisterInfo *reg_info, const RegisterValue &value) {
138   // Not supported yet. We could easily add support for this by remembering the
139   // address of each entry (it would need to be part of the cursor)
140   return false;
141 }
142
143 bool RegisterContextMacOSXFrameBackchain::ReadAllRegisterValues(
144     lldb::DataBufferSP &data_sp) {
145   // libunwind frames can't handle this it doesn't always have all register
146   // values. This call should only be called on frame zero anyway so there
147   // shouldn't be any problem
148   return false;
149 }
150
151 bool RegisterContextMacOSXFrameBackchain::WriteAllRegisterValues(
152     const lldb::DataBufferSP &data_sp) {
153   // Since this class doesn't respond to "ReadAllRegisterValues()", it must not
154   // have been the one that saved all the register values. So we just let the
155   // thread's register context (the register context for frame zero) do the
156   // writing.
157   return m_thread.GetRegisterContext()->WriteAllRegisterValues(data_sp);
158 }
159
160 uint32_t
161 RegisterContextMacOSXFrameBackchain::ConvertRegisterKindToRegisterNumber(
162     lldb::RegisterKind kind, uint32_t num) {
163   return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
164       kind, num);
165 }