]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / Process / Utility / RegisterContextPOSIX_s390x.cpp
1 //===-- RegisterContextPOSIX_s390x.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 <cstring>
11 #include <errno.h>
12 #include <stdint.h>
13
14 #include "lldb/Core/RegisterValue.h"
15 #include "lldb/Core/Scalar.h"
16 #include "lldb/Target/Process.h"
17 #include "lldb/Target/Target.h"
18 #include "lldb/Target/Thread.h"
19 #include "lldb/Utility/DataBufferHeap.h"
20 #include "lldb/Utility/DataExtractor.h"
21 #include "lldb/Utility/Endian.h"
22 #include "llvm/Support/Compiler.h"
23
24 #include "RegisterContextPOSIX_s390x.h"
25 #include "RegisterContext_s390x.h"
26
27 using namespace lldb_private;
28 using namespace lldb;
29
30 // s390x 64-bit general purpose registers.
31 static const uint32_t g_gpr_regnums_s390x[] = {
32     lldb_r0_s390x,      lldb_r1_s390x,    lldb_r2_s390x,    lldb_r3_s390x,
33     lldb_r4_s390x,      lldb_r5_s390x,    lldb_r6_s390x,    lldb_r7_s390x,
34     lldb_r8_s390x,      lldb_r9_s390x,    lldb_r10_s390x,   lldb_r11_s390x,
35     lldb_r12_s390x,     lldb_r13_s390x,   lldb_r14_s390x,   lldb_r15_s390x,
36     lldb_acr0_s390x,    lldb_acr1_s390x,  lldb_acr2_s390x,  lldb_acr3_s390x,
37     lldb_acr4_s390x,    lldb_acr5_s390x,  lldb_acr6_s390x,  lldb_acr7_s390x,
38     lldb_acr8_s390x,    lldb_acr9_s390x,  lldb_acr10_s390x, lldb_acr11_s390x,
39     lldb_acr12_s390x,   lldb_acr13_s390x, lldb_acr14_s390x, lldb_acr15_s390x,
40     lldb_pswm_s390x,    lldb_pswa_s390x,
41     LLDB_INVALID_REGNUM // register sets need to end with this flag
42 };
43 static_assert((sizeof(g_gpr_regnums_s390x) / sizeof(g_gpr_regnums_s390x[0])) -
44                       1 ==
45                   k_num_gpr_registers_s390x,
46               "g_gpr_regnums_s390x has wrong number of register infos");
47
48 // s390x 64-bit floating point registers.
49 static const uint32_t g_fpu_regnums_s390x[] = {
50     lldb_f0_s390x,      lldb_f1_s390x,  lldb_f2_s390x,  lldb_f3_s390x,
51     lldb_f4_s390x,      lldb_f5_s390x,  lldb_f6_s390x,  lldb_f7_s390x,
52     lldb_f8_s390x,      lldb_f9_s390x,  lldb_f10_s390x, lldb_f11_s390x,
53     lldb_f12_s390x,     lldb_f13_s390x, lldb_f14_s390x, lldb_f15_s390x,
54     lldb_fpc_s390x,
55     LLDB_INVALID_REGNUM // register sets need to end with this flag
56 };
57 static_assert((sizeof(g_fpu_regnums_s390x) / sizeof(g_fpu_regnums_s390x[0])) -
58                       1 ==
59                   k_num_fpr_registers_s390x,
60               "g_fpu_regnums_s390x has wrong number of register infos");
61
62 // Number of register sets provided by this context.
63 enum { k_num_register_sets = 2 };
64
65 // Register sets for s390x 64-bit.
66 static const RegisterSet g_reg_sets_s390x[k_num_register_sets] = {
67     {"General Purpose Registers", "gpr", k_num_gpr_registers_s390x,
68      g_gpr_regnums_s390x},
69     {"Floating Point Registers", "fpr", k_num_fpr_registers_s390x,
70      g_fpu_regnums_s390x},
71 };
72
73 bool RegisterContextPOSIX_s390x::IsGPR(unsigned reg) {
74   return reg <= m_reg_info.last_gpr; // GPRs come first.
75 }
76
77 bool RegisterContextPOSIX_s390x::IsFPR(unsigned reg) {
78   return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
79 }
80
81 RegisterContextPOSIX_s390x::RegisterContextPOSIX_s390x(
82     Thread &thread, uint32_t concrete_frame_idx,
83     RegisterInfoInterface *register_info)
84     : RegisterContext(thread, concrete_frame_idx) {
85   m_register_info_ap.reset(register_info);
86
87   switch (register_info->m_target_arch.GetMachine()) {
88   case llvm::Triple::systemz:
89     m_reg_info.num_registers = k_num_registers_s390x;
90     m_reg_info.num_gpr_registers = k_num_gpr_registers_s390x;
91     m_reg_info.num_fpr_registers = k_num_fpr_registers_s390x;
92     m_reg_info.last_gpr = k_last_gpr_s390x;
93     m_reg_info.first_fpr = k_first_fpr_s390x;
94     m_reg_info.last_fpr = k_last_fpr_s390x;
95     break;
96   default:
97     assert(false && "Unhandled target architecture.");
98     break;
99   }
100 }
101
102 RegisterContextPOSIX_s390x::~RegisterContextPOSIX_s390x() {}
103
104 void RegisterContextPOSIX_s390x::Invalidate() {}
105
106 void RegisterContextPOSIX_s390x::InvalidateAllRegisters() {}
107
108 const RegisterInfo *RegisterContextPOSIX_s390x::GetRegisterInfo() {
109   return m_register_info_ap->GetRegisterInfo();
110 }
111
112 const RegisterInfo *
113 RegisterContextPOSIX_s390x::GetRegisterInfoAtIndex(size_t reg) {
114   if (reg < m_reg_info.num_registers)
115     return &GetRegisterInfo()[reg];
116   else
117     return NULL;
118 }
119
120 size_t RegisterContextPOSIX_s390x::GetRegisterCount() {
121   return m_reg_info.num_registers;
122 }
123
124 unsigned RegisterContextPOSIX_s390x::GetRegisterOffset(unsigned reg) {
125   assert(reg < m_reg_info.num_registers && "Invalid register number.");
126   return GetRegisterInfo()[reg].byte_offset;
127 }
128
129 unsigned RegisterContextPOSIX_s390x::GetRegisterSize(unsigned reg) {
130   assert(reg < m_reg_info.num_registers && "Invalid register number.");
131   return GetRegisterInfo()[reg].byte_size;
132 }
133
134 const char *RegisterContextPOSIX_s390x::GetRegisterName(unsigned reg) {
135   assert(reg < m_reg_info.num_registers && "Invalid register offset.");
136   return GetRegisterInfo()[reg].name;
137 }
138
139 bool RegisterContextPOSIX_s390x::IsRegisterSetAvailable(size_t set_index) {
140   return set_index < k_num_register_sets;
141 }
142
143 size_t RegisterContextPOSIX_s390x::GetRegisterSetCount() {
144   size_t sets = 0;
145   for (size_t set = 0; set < k_num_register_sets; ++set) {
146     if (IsRegisterSetAvailable(set))
147       ++sets;
148   }
149
150   return sets;
151 }
152
153 const RegisterSet *RegisterContextPOSIX_s390x::GetRegisterSet(size_t set) {
154   if (IsRegisterSetAvailable(set)) {
155     switch (m_register_info_ap->m_target_arch.GetMachine()) {
156     case llvm::Triple::systemz:
157       return &g_reg_sets_s390x[set];
158     default:
159       assert(false && "Unhandled target architecture.");
160       return NULL;
161     }
162   }
163   return NULL;
164 }
165
166 lldb::ByteOrder RegisterContextPOSIX_s390x::GetByteOrder() {
167   // Get the target process whose privileged thread was used for the register
168   // read.
169   lldb::ByteOrder byte_order = eByteOrderInvalid;
170   Process *process = CalculateProcess().get();
171
172   if (process)
173     byte_order = process->GetByteOrder();
174   return byte_order;
175 }
176
177 // Used when parsing DWARF and EH frame information and any other object file
178 // sections that contain register numbers in them.
179 uint32_t RegisterContextPOSIX_s390x::ConvertRegisterKindToRegisterNumber(
180     lldb::RegisterKind kind, uint32_t num) {
181   const uint32_t num_regs = GetRegisterCount();
182
183   assert(kind < kNumRegisterKinds);
184   for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
185     const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
186
187     if (reg_info->kinds[kind] == num)
188       return reg_idx;
189   }
190
191   return LLDB_INVALID_REGNUM;
192 }