LLDB  mainline
ABISysV_s390x.cpp
Go to the documentation of this file.
1 //===-- ABISysV_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 "ABISysV_s390x.h"
10 
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/Triple.h"
13 
14 #include "lldb/Core/Module.h"
16 #include "lldb/Core/Value.h"
20 #include "lldb/Symbol/UnwindPlan.h"
21 #include "lldb/Target/Process.h"
23 #include "lldb/Target/StackFrame.h"
24 #include "lldb/Target/Target.h"
25 #include "lldb/Target/Thread.h"
28 #include "lldb/Utility/Log.h"
30 #include "lldb/Utility/Status.h"
31 
32 using namespace lldb;
33 using namespace lldb_private;
34 
36  // General Purpose Registers
53  // Floating Point Registers / Vector Registers 0-15
70  // Access Registers
87  // Program Status Word
90  // Vector Registers 16-31
107 };
108 
109 // RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB
110 
111 #define DEFINE_REG(name, size, alt, generic) \
112  { \
113  #name, alt, size, 0, eEncodingUint, eFormatHex, \
114  {dwarf_##name##_s390x, dwarf_##name##_s390x, generic, \
115  LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, \
116  nullptr, nullptr, nullptr, 0 \
117  }
118 
119 static RegisterInfo g_register_infos[] = {
120  DEFINE_REG(r0, 8, nullptr, LLDB_INVALID_REGNUM),
121  DEFINE_REG(r1, 8, nullptr, LLDB_INVALID_REGNUM),
127  DEFINE_REG(r7, 8, nullptr, LLDB_INVALID_REGNUM),
128  DEFINE_REG(r8, 8, nullptr, LLDB_INVALID_REGNUM),
129  DEFINE_REG(r9, 8, nullptr, LLDB_INVALID_REGNUM),
130  DEFINE_REG(r10, 8, nullptr, LLDB_INVALID_REGNUM),
132  DEFINE_REG(r12, 8, nullptr, LLDB_INVALID_REGNUM),
133  DEFINE_REG(r13, 8, nullptr, LLDB_INVALID_REGNUM),
134  DEFINE_REG(r14, 8, nullptr, LLDB_INVALID_REGNUM),
136  DEFINE_REG(acr0, 4, nullptr, LLDB_INVALID_REGNUM),
137  DEFINE_REG(acr1, 4, nullptr, LLDB_INVALID_REGNUM),
138  DEFINE_REG(acr2, 4, nullptr, LLDB_INVALID_REGNUM),
139  DEFINE_REG(acr3, 4, nullptr, LLDB_INVALID_REGNUM),
140  DEFINE_REG(acr4, 4, nullptr, LLDB_INVALID_REGNUM),
141  DEFINE_REG(acr5, 4, nullptr, LLDB_INVALID_REGNUM),
142  DEFINE_REG(acr6, 4, nullptr, LLDB_INVALID_REGNUM),
143  DEFINE_REG(acr7, 4, nullptr, LLDB_INVALID_REGNUM),
144  DEFINE_REG(acr8, 4, nullptr, LLDB_INVALID_REGNUM),
145  DEFINE_REG(acr9, 4, nullptr, LLDB_INVALID_REGNUM),
146  DEFINE_REG(acr10, 4, nullptr, LLDB_INVALID_REGNUM),
147  DEFINE_REG(acr11, 4, nullptr, LLDB_INVALID_REGNUM),
148  DEFINE_REG(acr12, 4, nullptr, LLDB_INVALID_REGNUM),
149  DEFINE_REG(acr13, 4, nullptr, LLDB_INVALID_REGNUM),
150  DEFINE_REG(acr14, 4, nullptr, LLDB_INVALID_REGNUM),
151  DEFINE_REG(acr15, 4, nullptr, LLDB_INVALID_REGNUM),
152  DEFINE_REG(pswm, 8, "flags", LLDB_REGNUM_GENERIC_FLAGS),
153  DEFINE_REG(pswa, 8, "pc", LLDB_REGNUM_GENERIC_PC),
154  DEFINE_REG(f0, 8, nullptr, LLDB_INVALID_REGNUM),
155  DEFINE_REG(f1, 8, nullptr, LLDB_INVALID_REGNUM),
156  DEFINE_REG(f2, 8, nullptr, LLDB_INVALID_REGNUM),
157  DEFINE_REG(f3, 8, nullptr, LLDB_INVALID_REGNUM),
158  DEFINE_REG(f4, 8, nullptr, LLDB_INVALID_REGNUM),
159  DEFINE_REG(f5, 8, nullptr, LLDB_INVALID_REGNUM),
160  DEFINE_REG(f6, 8, nullptr, LLDB_INVALID_REGNUM),
161  DEFINE_REG(f7, 8, nullptr, LLDB_INVALID_REGNUM),
162  DEFINE_REG(f8, 8, nullptr, LLDB_INVALID_REGNUM),
163  DEFINE_REG(f9, 8, nullptr, LLDB_INVALID_REGNUM),
164  DEFINE_REG(f10, 8, nullptr, LLDB_INVALID_REGNUM),
165  DEFINE_REG(f11, 8, nullptr, LLDB_INVALID_REGNUM),
166  DEFINE_REG(f12, 8, nullptr, LLDB_INVALID_REGNUM),
167  DEFINE_REG(f13, 8, nullptr, LLDB_INVALID_REGNUM),
168  DEFINE_REG(f14, 8, nullptr, LLDB_INVALID_REGNUM),
169  DEFINE_REG(f15, 8, nullptr, LLDB_INVALID_REGNUM),
170 };
171 
173  llvm::array_lengthof(g_register_infos);
175 
176 const lldb_private::RegisterInfo *
178  // Make the C-string names and alt_names for the register infos into const
179  // C-string values by having the ConstString unique the names in the global
180  // constant C-string pool.
183  for (uint32_t i = 0; i < k_num_register_infos; ++i) {
184  if (g_register_infos[i].name)
185  g_register_infos[i].name =
187  if (g_register_infos[i].alt_name)
188  g_register_infos[i].alt_name =
189  ConstString(g_register_infos[i].alt_name).GetCString();
190  }
191  }
192  count = k_num_register_infos;
193  return g_register_infos;
194 }
195 
196 size_t ABISysV_s390x::GetRedZoneSize() const { return 0; }
197 
198 // Static Functions
199 
200 ABISP
201 ABISysV_s390x::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
202  if (arch.GetTriple().getArch() == llvm::Triple::systemz) {
203  return ABISP(new ABISysV_s390x(process_sp));
204  }
205  return ABISP();
206 }
207 
209  addr_t func_addr, addr_t return_addr,
210  llvm::ArrayRef<addr_t> args) const {
212 
213  if (log) {
214  StreamString s;
215  s.Printf("ABISysV_s390x::PrepareTrivialCall (tid = 0x%" PRIx64
216  ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
217  ", return_addr = 0x%" PRIx64,
218  thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
219  (uint64_t)return_addr);
220 
221  for (size_t i = 0; i < args.size(); ++i)
222  s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1),
223  args[i]);
224  s.PutCString(")");
225  log->PutString(s.GetString());
226  }
227 
228  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
229  if (!reg_ctx)
230  return false;
231 
232  const RegisterInfo *pc_reg_info =
234  const RegisterInfo *sp_reg_info =
236  const RegisterInfo *ra_reg_info = reg_ctx->GetRegisterInfoByName("r14", 0);
237  ProcessSP process_sp(thread.GetProcess());
238 
239  // Allocate a new stack frame and space for stack arguments if necessary
240 
241  addr_t arg_pos = 0;
242  if (args.size() > 5) {
243  sp -= 8 * (args.size() - 5);
244  arg_pos = sp;
245  }
246 
247  sp -= 160;
248 
249  // Process arguments
250 
251  for (size_t i = 0; i < args.size(); ++i) {
252  if (i < 5) {
253  const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
255  if (log)
256  log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
257  static_cast<uint64_t>(i + 1), args[i], reg_info->name);
258  if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
259  return false;
260  } else {
261  Status error;
262  if (log)
263  log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") onto stack",
264  static_cast<uint64_t>(i + 1), args[i]);
265  if (!process_sp->WritePointerToMemory(arg_pos, args[i], error))
266  return false;
267  arg_pos += 8;
268  }
269  }
270 
271  // %r14 is set to the return address
272 
273  if (log)
274  log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
275 
276  if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr))
277  return false;
278 
279  // %r15 is set to the actual stack value.
280 
281  if (log)
282  log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
283 
284  if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
285  return false;
286 
287  // %pc is set to the address of the called function.
288 
289  if (log)
290  log->Printf("Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
291 
292  if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
293  return false;
294 
295  return true;
296 }
297 
298 static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,
299  bool is_signed, Thread &thread,
300  uint32_t *argument_register_ids,
301  unsigned int &current_argument_register,
302  addr_t &current_stack_argument) {
303  if (bit_width > 64)
304  return false; // Scalar can't hold large integer arguments
305 
306  if (current_argument_register < 5) {
307  scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
308  argument_register_ids[current_argument_register], 0);
309  current_argument_register++;
310  if (is_signed)
311  scalar.SignExtend(bit_width);
312  } else {
313  uint32_t byte_size = (bit_width + (8 - 1)) / 8;
314  Status error;
315  if (thread.GetProcess()->ReadScalarIntegerFromMemory(
316  current_stack_argument + 8 - byte_size, byte_size, is_signed,
317  scalar, error)) {
318  current_stack_argument += 8;
319  return true;
320  }
321  return false;
322  }
323  return true;
324 }
325 
326 bool ABISysV_s390x::GetArgumentValues(Thread &thread, ValueList &values) const {
327  unsigned int num_values = values.GetSize();
328  unsigned int value_index;
329 
330  // Extract the register context so we can read arguments from registers
331 
332  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
333 
334  if (!reg_ctx)
335  return false;
336 
337  // Get the pointer to the first stack argument so we have a place to start
338  // when reading data
339 
340  addr_t sp = reg_ctx->GetSP(0);
341 
342  if (!sp)
343  return false;
344 
345  addr_t current_stack_argument = sp + 160;
346 
347  uint32_t argument_register_ids[5];
348 
349  argument_register_ids[0] =
351  ->kinds[eRegisterKindLLDB];
352  argument_register_ids[1] =
354  ->kinds[eRegisterKindLLDB];
355  argument_register_ids[2] =
357  ->kinds[eRegisterKindLLDB];
358  argument_register_ids[3] =
360  ->kinds[eRegisterKindLLDB];
361  argument_register_ids[4] =
363  ->kinds[eRegisterKindLLDB];
364 
365  unsigned int current_argument_register = 0;
366 
367  for (value_index = 0; value_index < num_values; ++value_index) {
368  Value *value = values.GetValueAtIndex(value_index);
369 
370  if (!value)
371  return false;
372 
373  // We currently only support extracting values with Clang QualTypes. Do we
374  // care about others?
375  CompilerType compiler_type = value->GetCompilerType();
376  llvm::Optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread);
377  if (!bit_size)
378  return false;
379  bool is_signed;
380 
381  if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
382  ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread,
383  argument_register_ids, current_argument_register,
384  current_stack_argument);
385  } else if (compiler_type.IsPointerType()) {
386  ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread,
387  argument_register_ids, current_argument_register,
388  current_stack_argument);
389  }
390  }
391 
392  return true;
393 }
394 
395 Status ABISysV_s390x::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
396  lldb::ValueObjectSP &new_value_sp) {
397  Status error;
398  if (!new_value_sp) {
399  error.SetErrorString("Empty value object for return value.");
400  return error;
401  }
402 
403  CompilerType compiler_type = new_value_sp->GetCompilerType();
404  if (!compiler_type) {
405  error.SetErrorString("Null clang type for return value.");
406  return error;
407  }
408 
409  Thread *thread = frame_sp->GetThread().get();
410 
411  bool is_signed;
412  uint32_t count;
413  bool is_complex;
414 
415  RegisterContext *reg_ctx = thread->GetRegisterContext().get();
416 
417  bool set_it_simple = false;
418  if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
419  compiler_type.IsPointerType()) {
420  const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r2", 0);
421 
422  DataExtractor data;
423  Status data_error;
424  size_t num_bytes = new_value_sp->GetData(data, data_error);
425  if (data_error.Fail()) {
427  "Couldn't convert return value to raw data: %s",
428  data_error.AsCString());
429  return error;
430  }
431  lldb::offset_t offset = 0;
432  if (num_bytes <= 8) {
433  uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
434 
435  if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value))
436  set_it_simple = true;
437  } else {
438  error.SetErrorString("We don't support returning longer than 64 bit "
439  "integer values at present.");
440  }
441  } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
442  if (is_complex)
443  error.SetErrorString(
444  "We don't support returning complex values at present");
445  else {
446  llvm::Optional<uint64_t> bit_width =
447  compiler_type.GetBitSize(frame_sp.get());
448  if (!bit_width) {
449  error.SetErrorString("can't get type size");
450  return error;
451  }
452  if (*bit_width <= 64) {
453  const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
454  RegisterValue f0_value;
455  DataExtractor data;
456  Status data_error;
457  size_t num_bytes = new_value_sp->GetData(data, data_error);
458  if (data_error.Fail()) {
460  "Couldn't convert return value to raw data: %s",
461  data_error.AsCString());
462  return error;
463  }
464 
465  unsigned char buffer[8];
466  ByteOrder byte_order = data.GetByteOrder();
467 
468  data.CopyByteOrderedData(0, num_bytes, buffer, 8, byte_order);
469  f0_value.SetBytes(buffer, 8, byte_order);
470  reg_ctx->WriteRegister(f0_info, f0_value);
471  set_it_simple = true;
472  } else {
473  // FIXME - don't know how to do long doubles yet.
474  error.SetErrorString(
475  "We don't support returning float values > 64 bits at present");
476  }
477  }
478  }
479 
480  if (!set_it_simple) {
481  // Okay we've got a structure or something that doesn't fit in a simple
482  // register. We should figure out where it really goes, but we don't
483  // support this yet.
484  error.SetErrorString("We only support setting simple integer and float "
485  "return types at present.");
486  }
487 
488  return error;
489 }
490 
492  Thread &thread, CompilerType &return_compiler_type) const {
493  ValueObjectSP return_valobj_sp;
494  Value value;
495 
496  if (!return_compiler_type)
497  return return_valobj_sp;
498 
499  // value.SetContext (Value::eContextTypeClangType, return_value_type);
500  value.SetCompilerType(return_compiler_type);
501 
502  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
503  if (!reg_ctx)
504  return return_valobj_sp;
505 
506  const uint32_t type_flags = return_compiler_type.GetTypeInfo();
507  if (type_flags & eTypeIsScalar) {
508  value.SetValueType(Value::eValueTypeScalar);
509 
510  bool success = false;
511  if (type_flags & eTypeIsInteger) {
512  // Extract the register context so we can read arguments from registers.
513  llvm::Optional<uint64_t> byte_size =
514  return_compiler_type.GetByteSize(nullptr);
515  if (!byte_size)
516  return return_valobj_sp;
517  uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
518  reg_ctx->GetRegisterInfoByName("r2", 0), 0);
519  const bool is_signed = (type_flags & eTypeIsSigned) != 0;
520  switch (*byte_size) {
521  default:
522  break;
523 
524  case sizeof(uint64_t):
525  if (is_signed)
526  value.GetScalar() = (int64_t)(raw_value);
527  else
528  value.GetScalar() = (uint64_t)(raw_value);
529  success = true;
530  break;
531 
532  case sizeof(uint32_t):
533  if (is_signed)
534  value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
535  else
536  value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
537  success = true;
538  break;
539 
540  case sizeof(uint16_t):
541  if (is_signed)
542  value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
543  else
544  value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
545  success = true;
546  break;
547 
548  case sizeof(uint8_t):
549  if (is_signed)
550  value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
551  else
552  value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
553  success = true;
554  break;
555  }
556  } else if (type_flags & eTypeIsFloat) {
557  if (type_flags & eTypeIsComplex) {
558  // Don't handle complex yet.
559  } else {
560  llvm::Optional<uint64_t> byte_size =
561  return_compiler_type.GetByteSize(nullptr);
562  if (byte_size && *byte_size <= sizeof(long double)) {
563  const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
564  RegisterValue f0_value;
565  if (reg_ctx->ReadRegister(f0_info, f0_value)) {
566  DataExtractor data;
567  if (f0_value.GetData(data)) {
568  lldb::offset_t offset = 0;
569  if (*byte_size == sizeof(float)) {
570  value.GetScalar() = (float)data.GetFloat(&offset);
571  success = true;
572  } else if (*byte_size == sizeof(double)) {
573  value.GetScalar() = (double)data.GetDouble(&offset);
574  success = true;
575  } else if (*byte_size == sizeof(long double)) {
576  // Don't handle long double yet.
577  }
578  }
579  }
580  }
581  }
582  }
583 
584  if (success)
585  return_valobj_sp = ValueObjectConstResult::Create(
586  thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
587  } else if (type_flags & eTypeIsPointer) {
588  unsigned r2_id =
589  reg_ctx->GetRegisterInfoByName("r2", 0)->kinds[eRegisterKindLLDB];
590  value.GetScalar() =
591  (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_id, 0);
592  value.SetValueType(Value::eValueTypeScalar);
593  return_valobj_sp = ValueObjectConstResult::Create(
594  thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
595  }
596 
597  return return_valobj_sp;
598 }
599 
601  Thread &thread, CompilerType &return_compiler_type) const {
602  ValueObjectSP return_valobj_sp;
603 
604  if (!return_compiler_type)
605  return return_valobj_sp;
606 
607  ExecutionContext exe_ctx(thread.shared_from_this());
608  return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
609  if (return_valobj_sp)
610  return return_valobj_sp;
611 
612  RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
613  if (!reg_ctx_sp)
614  return return_valobj_sp;
615 
616  if (return_compiler_type.IsAggregateType()) {
617  // FIXME: This is just taking a guess, r2 may very well no longer hold the
618  // return storage location.
619  // If we are going to do this right, when we make a new frame we should
620  // check to see if it uses a memory return, and if we are at the first
621  // instruction and if so stash away the return location. Then we would
622  // only return the memory return value if we know it is valid.
623 
624  unsigned r2_id =
625  reg_ctx_sp->GetRegisterInfoByName("r2", 0)->kinds[eRegisterKindLLDB];
626  lldb::addr_t storage_addr =
627  (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_id, 0);
628  return_valobj_sp = ValueObjectMemory::Create(
629  &thread, "", Address(storage_addr, nullptr), return_compiler_type);
630  }
631 
632  return return_valobj_sp;
633 }
634 
636  unwind_plan.Clear();
637  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
638 
640 
641  // Our Call Frame Address is the stack pointer value + 160
642  row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r15_s390x, 160);
643 
644  // The previous PC is in r14
645  row->SetRegisterLocationToRegister(dwarf_pswa_s390x, dwarf_r14_s390x, true);
646 
647  // All other registers are the same.
648  unwind_plan.AppendRow(row);
649  unwind_plan.SetSourceName("s390x at-func-entry default");
650  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
651  return true;
652 }
653 
655  // There's really no default way to unwind on s390x. Trust the .eh_frame CFI,
656  // which should always be good.
657  return false;
658 }
659 
661  const RegisterInfo *reg_info,
662  UnwindPlan::Row::RegisterLocation &unwind_regloc) {
663  // If a volatile register is being requested, we don't want to forward the
664  // next frame's register contents up the stack -- the register is not
665  // retrievable at this frame.
666  if (RegisterIsVolatile(reg_info)) {
667  unwind_regloc.SetUndefined();
668  return true;
669  }
670 
671  return false;
672 }
673 
674 bool ABISysV_s390x::RegisterIsVolatile(const RegisterInfo *reg_info) {
675  return !RegisterIsCalleeSaved(reg_info);
676 }
677 
678 bool ABISysV_s390x::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
679  if (reg_info) {
680  // Preserved registers are :
681  // r6-r13, r15
682  // f8-f15
683 
684  const char *name = reg_info->name;
685  if (name[0] == 'r') {
686  switch (name[1]) {
687  case '6': // r6
688  case '7': // r7
689  case '8': // r8
690  case '9': // r9
691  return name[2] == '\0';
692 
693  case '1': // r10, r11, r12, r13, r15
694  if ((name[2] >= '0' && name[2] <= '3') || name[2] == '5')
695  return name[3] == '\0';
696  break;
697 
698  default:
699  break;
700  }
701  }
702  if (name[0] == 'f') {
703  switch (name[1]) {
704  case '8': // r8
705  case '9': // r9
706  return name[2] == '\0';
707 
708  case '1': // r10, r11, r12, r13, r14, r15
709  if (name[2] >= '0' && name[2] <= '5')
710  return name[3] == '\0';
711  break;
712 
713  default:
714  break;
715  }
716  }
717 
718  // Accept shorter-variant versions
719  if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
720  return true;
721  if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
722  return true;
723  if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
724  return true;
725  }
726  return false;
727 }
728 
730  PluginManager::RegisterPlugin(
731  GetPluginNameStatic(), "System V ABI for s390x targets", CreateInstance);
732 }
733 
735  PluginManager::UnregisterPlugin(CreateInstance);
736 }
737 
739  static ConstString g_name("sysv-s390x");
740  return g_name;
741 }
742 
743 // PluginInterface protocol
744 
746  return GetPluginNameStatic();
747 }
748 
lldb::ValueObjectSP GetReturnValueObjectSimple(lldb_private::Thread &thread, lldb_private::CompilerType &ast_type) const
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:61
static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch)
#define LLDB_REGNUM_GENERIC_PC
Definition: lldb-defines.h:63
An data extractor class.
Definition: DataExtractor.h:47
void SetSourceName(const char *)
Definition: UnwindPlan.cpp:542
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
static RegisterInfo g_register_infos[]
#define LLDB_REGNUM_GENERIC_ARG4
Definition: lldb-defines.h:74
bool IsIntegerOrEnumerationType(bool &is_signed) const
uint64_t GetSP(uint64_t fail_value=LLDB_INVALID_ADDRESS)
void PutString(llvm::StringRef str)
Definition: Log.cpp:110
lldb_private::ConstString GetPluginName() override
lldb::user_id_t GetID() const
Get accessor for the user ID.
Definition: UserID.h:49
An architecture specification class.
Definition: ArchSpec.h:32
#define LLDB_REGNUM_GENERIC_ARG2
Definition: lldb-defines.h:70
virtual bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value)=0
uint32_t GetTypeInfo(CompilerType *pointee_or_element_compiler_type=nullptr) const
Value * GetValueAtIndex(size_t idx)
Definition: Value.cpp:701
void SetValueType(ValueType value_type)
Definition: Value.h:154
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
const lldb_private::RegisterInfo * GetRegisterInfoArray(uint32_t &count) override
#define LLDB_REGNUM_GENERIC_SP
Definition: lldb-defines.h:64
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info)
llvm::Optional< uint64_t > GetByteSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bytes.
#define LLDB_REGNUM_GENERIC_ARG5
Definition: lldb-defines.h:76
bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
float GetFloat(lldb::offset_t *offset_ptr) const
Extract a float from *offset_ptr.
bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, lldb::addr_t functionAddress, lldb::addr_t returnAddress, llvm::ArrayRef< lldb::addr_t > args) const override
#define LLDB_REGNUM_GENERIC_ARG1
Definition: lldb-defines.h:68
static bool g_register_info_names_constified
bool IsPointerType(CompilerType *pointee_type=nullptr) const
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:431
lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &type) const override
bool SignExtend(uint32_t bit_pos)
Definition: Scalar.cpp:2609
#define LLDB_REGNUM_GENERIC_FP
Definition: lldb-defines.h:65
#define UINT32_MAX
Definition: lldb-defines.h:31
bool IsFloatingPointType(uint32_t &count, bool &is_complex) const
uint32_t GetPluginVersion() override
uint64_t offset_t
Definition: lldb-types.h:87
Log * GetLogIfAllCategoriesSet(uint32_t mask)
Definition: Logging.cpp:57
static void Initialize()
std::shared_ptr< Row > RowSP
Definition: UnwindPlan.h:366
void AppendRow(const RowSP &row_sp)
Definition: UnwindPlan.cpp:355
lldb::ByteOrder GetByteOrder() const
Get the current byte order value.
#define DEFINE_REG(name, size, alt, generic)
lldb_private::Status SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override
llvm::StringRef GetString() const
virtual lldb::RegisterContextSP GetRegisterContext()=0
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
Definition: Status.cpp:241
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)=0
double GetDouble(lldb::offset_t *offset_ptr) const
#define LLDB_REGNUM_GENERIC_FLAGS
Definition: lldb-defines.h:67
const RegisterInfo * GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx=0)
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
static const uint32_t k_num_register_infos
const CompilerType & GetCompilerType()
Definition: Value.cpp:239
void SetRegisterKind(lldb::RegisterKind kind)
Definition: UnwindPlan.h:408
static lldb_private::ConstString GetPluginNameStatic()
A section + offset based address class.
Definition: Address.h:80
bool WriteRegisterFromUnsigned(uint32_t reg, uint64_t uval)
lldb::ProcessSP GetProcess() const
Definition: Thread.h:154
dwarf_regnums
uint64_t GetMaxU64(lldb::offset_t *offset_ptr, size_t byte_size) const
Extract an unsigned integer of size byte_size from *offset_ptr.
bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override
bool GetFallbackRegisterLocation(const lldb_private::RegisterInfo *reg_info, lldb_private::UnwindPlan::Row::RegisterLocation &unwind_regloc) override
const RegisterInfo * GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num)
lldb::offset_t CopyByteOrderedData(lldb::offset_t src_offset, lldb::offset_t src_len, void *dst, lldb::offset_t dst_len, lldb::ByteOrder dst_byte_order) const
Copy dst_len bytes from *offset_ptr and ensure the copied data is treated as a value that can be swap...
bool GetArgumentValues(lldb_private::Thread &thread, lldb_private::ValueList &values) const override
uint64_t addr_t
Definition: lldb-types.h:83
size_t GetRedZoneSize() const override
bool GetData(DataExtractor &data) const
A uniqued constant string class.
Definition: ConstString.h:38
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:247
llvm::Optional< uint64_t > GetBitSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bits.
#define LLDB_REGNUM_GENERIC_ARG3
Definition: lldb-defines.h:72
Definition: SBAddress.h:15
void SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order)
static void Terminate()
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
Definition: Status.cpp:255
void SetCompilerType(const CompilerType &compiler_type)
Definition: Value.cpp:268
#define LIBLLDB_LOG_EXPRESSIONS
Definition: Logging.h:22
const Scalar & GetScalar() const
Definition: Value.h:178
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition: Status.cpp:130
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
Definition: Thread.h:395
static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width, bool is_signed, Thread &thread, uint32_t *argument_register_ids, unsigned int &current_argument_register, addr_t &current_stack_argument)
void Printf(const char *format,...) __attribute__((format(printf
Definition: Log.cpp:113
void SetSourcedFromCompiler(lldb_private::LazyBool from_compiler)
Definition: UnwindPlan.h:449
bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
An error handling class.
Definition: Status.h:44
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:90