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