LLDB  mainline
RegisterContextPOSIX_s390x.cpp
Go to the documentation of this file.
1 //===-- RegisterContextPOSIX_s390x.cpp --------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include <cstring>
10 #include <errno.h>
11 #include <stdint.h>
12 
13 #include "lldb/Target/Process.h"
14 #include "lldb/Target/Target.h"
15 #include "lldb/Target/Thread.h"
18 #include "lldb/Utility/Endian.h"
20 #include "lldb/Utility/Scalar.h"
21 #include "llvm/Support/Compiler.h"
22 
24 #include "RegisterContext_s390x.h"
25 
26 using namespace lldb_private;
27 using namespace lldb;
28 
29 // s390x 64-bit general purpose registers.
30 static const uint32_t g_gpr_regnums_s390x[] = {
40  LLDB_INVALID_REGNUM // register sets need to end with this flag
41 };
42 static_assert((sizeof(g_gpr_regnums_s390x) / sizeof(g_gpr_regnums_s390x[0])) -
43  1 ==
45  "g_gpr_regnums_s390x has wrong number of register infos");
46 
47 // s390x 64-bit floating point registers.
48 static const uint32_t g_fpu_regnums_s390x[] = {
54  LLDB_INVALID_REGNUM // register sets need to end with this flag
55 };
56 static_assert((sizeof(g_fpu_regnums_s390x) / sizeof(g_fpu_regnums_s390x[0])) -
57  1 ==
59  "g_fpu_regnums_s390x has wrong number of register infos");
60 
61 // Number of register sets provided by this context.
62 enum { k_num_register_sets = 2 };
63 
64 // Register sets for s390x 64-bit.
65 static const RegisterSet g_reg_sets_s390x[k_num_register_sets] = {
66  {"General Purpose Registers", "gpr", k_num_gpr_registers_s390x,
67  g_gpr_regnums_s390x},
68  {"Floating Point Registers", "fpr", k_num_fpr_registers_s390x,
69  g_fpu_regnums_s390x},
70 };
71 
73  return reg <= m_reg_info.last_gpr; // GPRs come first.
74 }
75 
77  return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
78 }
79 
81  Thread &thread, uint32_t concrete_frame_idx,
82  RegisterInfoInterface *register_info)
83  : RegisterContext(thread, concrete_frame_idx) {
84  m_register_info_up.reset(register_info);
85 
86  switch (register_info->m_target_arch.GetMachine()) {
87  case llvm::Triple::systemz:
94  break;
95  default:
96  assert(false && "Unhandled target architecture.");
97  break;
98  }
99 }
100 
102 
104 
106 
108  return m_register_info_up->GetRegisterInfo();
109 }
110 
111 const RegisterInfo *
113  if (reg < m_reg_info.num_registers)
114  return &GetRegisterInfo()[reg];
115  else
116  return NULL;
117 }
118 
120  return m_reg_info.num_registers;
121 }
122 
124  assert(reg < m_reg_info.num_registers && "Invalid register number.");
125  return GetRegisterInfo()[reg].byte_offset;
126 }
127 
129  assert(reg < m_reg_info.num_registers && "Invalid register number.");
130  return GetRegisterInfo()[reg].byte_size;
131 }
132 
134  assert(reg < m_reg_info.num_registers && "Invalid register offset.");
135  return GetRegisterInfo()[reg].name;
136 }
137 
139  return set_index < k_num_register_sets;
140 }
141 
143  size_t sets = 0;
144  for (size_t set = 0; set < k_num_register_sets; ++set) {
145  if (IsRegisterSetAvailable(set))
146  ++sets;
147  }
148 
149  return sets;
150 }
151 
152 const RegisterSet *RegisterContextPOSIX_s390x::GetRegisterSet(size_t set) {
153  if (IsRegisterSetAvailable(set)) {
154  switch (m_register_info_up->m_target_arch.GetMachine()) {
155  case llvm::Triple::systemz:
156  return &g_reg_sets_s390x[set];
157  default:
158  assert(false && "Unhandled target architecture.");
159  return NULL;
160  }
161  }
162  return NULL;
163 }
164 
166  // Get the target process whose privileged thread was used for the register
167  // read.
168  lldb::ByteOrder byte_order = eByteOrderInvalid;
169  Process *process = CalculateProcess().get();
170 
171  if (process)
172  byte_order = process->GetByteOrder();
173  return byte_order;
174 }
175 
176 // Used when parsing DWARF and EH frame information and any other object file
177 // sections that contain register numbers in them.
179  lldb::RegisterKind kind, uint32_t num) {
180  const uint32_t num_regs = GetRegisterCount();
181 
182  assert(kind < kNumRegisterKinds);
183  for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
184  const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
185 
186  if (reg_info->kinds[kind] == num)
187  return reg_idx;
188  }
189 
190  return LLDB_INVALID_REGNUM;
191 }
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
RegisterInfo interface to patch RegisterInfo structure for archs.
static const uint32_t g_gpr_regnums_s390x[]
RegisterContextPOSIX_s390x(lldb_private::Thread &thread, uint32_t concrete_frame_idx, lldb_private::RegisterInfoInterface *register_info)
lldb::ByteOrder GetByteOrder() const
Definition: Process.cpp:3366
uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override
Convert from a given register numbering scheme to the lldb register numbering scheme.
static const uint32_t g_fpu_regnums_s390x[]
static const RegisterSet g_reg_sets_s390x[k_num_register_sets]
const char * GetRegisterName(unsigned reg)
std::unique_ptr< lldb_private::RegisterInfoInterface > m_register_info_up
A plug-in interface definition class for debugging a process.
Definition: Process.h:353
virtual unsigned GetRegisterSize(unsigned reg)
virtual unsigned GetRegisterOffset(unsigned reg)
Definition: SBAddress.h:15
virtual const lldb_private::RegisterInfo * GetRegisterInfo()
const lldb_private::RegisterSet * GetRegisterSet(size_t set) override
lldb::ProcessSP CalculateProcess() override
virtual bool IsRegisterSetAvailable(size_t set_index)
const lldb_private::RegisterInfo * GetRegisterInfoAtIndex(size_t reg) override
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition: ArchSpec.cpp:726
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:90