1 //===-- ABISysV_s390x.cpp ---------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "ABISysV_s390x.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/Triple.h"
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/PluginManager.h"
16 #include "lldb/Core/Value.h"
17 #include "lldb/Core/ValueObjectConstResult.h"
18 #include "lldb/Core/ValueObjectMemory.h"
19 #include "lldb/Core/ValueObjectRegister.h"
20 #include "lldb/Symbol/UnwindPlan.h"
21 #include "lldb/Target/Process.h"
22 #include "lldb/Target/RegisterContext.h"
23 #include "lldb/Target/StackFrame.h"
24 #include "lldb/Target/Target.h"
25 #include "lldb/Target/Thread.h"
26 #include "lldb/Utility/ConstString.h"
27 #include "lldb/Utility/DataExtractor.h"
28 #include "lldb/Utility/Log.h"
29 #include "lldb/Utility/RegisterValue.h"
30 #include "lldb/Utility/Status.h"
33 using namespace lldb_private;
36 // General Purpose Registers
53 // Floating Point Registers / Vector Registers 0-15
71 dwarf_acr0_s390x = 48,
87 // Program Status Word
88 dwarf_pswm_s390x = 64,
90 // Vector Registers 16-31
109 // RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB
111 #define DEFINE_REG(name, size, alt, generic) \
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 \
119 static RegisterInfo g_register_infos[] = {
120 DEFINE_REG(r0, 8, nullptr, LLDB_INVALID_REGNUM),
121 DEFINE_REG(r1, 8, nullptr, LLDB_INVALID_REGNUM),
122 DEFINE_REG(r2, 8, "arg1", LLDB_REGNUM_GENERIC_ARG1),
123 DEFINE_REG(r3, 8, "arg2", LLDB_REGNUM_GENERIC_ARG2),
124 DEFINE_REG(r4, 8, "arg3", LLDB_REGNUM_GENERIC_ARG3),
125 DEFINE_REG(r5, 8, "arg4", LLDB_REGNUM_GENERIC_ARG4),
126 DEFINE_REG(r6, 8, "arg5", LLDB_REGNUM_GENERIC_ARG5),
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),
131 DEFINE_REG(r11, 8, "fp", LLDB_REGNUM_GENERIC_FP),
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),
135 DEFINE_REG(r15, 8, "sp", LLDB_REGNUM_GENERIC_SP),
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),
172 static const uint32_t k_num_register_infos =
173 llvm::array_lengthof(g_register_infos);
174 static bool g_register_info_names_constified = false;
176 const lldb_private::RegisterInfo *
177 ABISysV_s390x::GetRegisterInfoArray(uint32_t &count) {
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.
181 if (!g_register_info_names_constified) {
182 g_register_info_names_constified = true;
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 =
186 ConstString(g_register_infos[i].name).GetCString();
187 if (g_register_infos[i].alt_name)
188 g_register_infos[i].alt_name =
189 ConstString(g_register_infos[i].alt_name).GetCString();
192 count = k_num_register_infos;
193 return g_register_infos;
196 size_t ABISysV_s390x::GetRedZoneSize() const { return 0; }
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));
208 bool ABISysV_s390x::PrepareTrivialCall(Thread &thread, addr_t sp,
209 addr_t func_addr, addr_t return_addr,
210 llvm::ArrayRef<addr_t> args) const {
211 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
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);
221 for (size_t i = 0; i < args.size(); ++i)
222 s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1),
225 log->PutString(s.GetString());
228 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
232 const RegisterInfo *pc_reg_info =
233 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
234 const RegisterInfo *sp_reg_info =
235 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
236 const RegisterInfo *ra_reg_info = reg_ctx->GetRegisterInfoByName("r14", 0);
237 ProcessSP process_sp(thread.GetProcess());
239 // Allocate a new stack frame and space for stack arguments if necessary
242 if (args.size() > 5) {
243 sp -= 8 * (args.size() - 5);
251 for (size_t i = 0; i < args.size(); ++i) {
253 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
254 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
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]))
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))
271 // %r14 is set to the return address
274 log->Printf("Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
276 if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr))
279 // %r15 is set to the actual stack value.
282 log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
284 if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
287 // %pc is set to the address of the called function.
290 log->Printf("Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
292 if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
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 ¤t_argument_register,
302 addr_t ¤t_stack_argument) {
304 return false; // Scalar can't hold large integer arguments
306 if (current_argument_register < 5) {
307 scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
308 argument_register_ids[current_argument_register], 0);
309 current_argument_register++;
311 scalar.SignExtend(bit_width);
313 uint32_t byte_size = (bit_width + (8 - 1)) / 8;
315 if (thread.GetProcess()->ReadScalarIntegerFromMemory(
316 current_stack_argument + 8 - byte_size, byte_size, is_signed,
318 current_stack_argument += 8;
326 bool ABISysV_s390x::GetArgumentValues(Thread &thread, ValueList &values) const {
327 unsigned int num_values = values.GetSize();
328 unsigned int value_index;
330 // Extract the register context so we can read arguments from registers
332 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
337 // Get the pointer to the first stack argument so we have a place to start
340 addr_t sp = reg_ctx->GetSP(0);
345 addr_t current_stack_argument = sp + 160;
347 uint32_t argument_register_ids[5];
349 argument_register_ids[0] =
350 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)
351 ->kinds[eRegisterKindLLDB];
352 argument_register_ids[1] =
353 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)
354 ->kinds[eRegisterKindLLDB];
355 argument_register_ids[2] =
356 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)
357 ->kinds[eRegisterKindLLDB];
358 argument_register_ids[3] =
359 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)
360 ->kinds[eRegisterKindLLDB];
361 argument_register_ids[4] =
362 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5)
363 ->kinds[eRegisterKindLLDB];
365 unsigned int current_argument_register = 0;
367 for (value_index = 0; value_index < num_values; ++value_index) {
368 Value *value = values.GetValueAtIndex(value_index);
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);
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);
395 Status ABISysV_s390x::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
396 lldb::ValueObjectSP &new_value_sp) {
399 error.SetErrorString("Empty value object for return value.");
403 CompilerType compiler_type = new_value_sp->GetCompilerType();
404 if (!compiler_type) {
405 error.SetErrorString("Null clang type for return value.");
409 Thread *thread = frame_sp->GetThread().get();
415 RegisterContext *reg_ctx = thread->GetRegisterContext().get();
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);
424 size_t num_bytes = new_value_sp->GetData(data, data_error);
425 if (data_error.Fail()) {
426 error.SetErrorStringWithFormat(
427 "Couldn't convert return value to raw data: %s",
428 data_error.AsCString());
431 lldb::offset_t offset = 0;
432 if (num_bytes <= 8) {
433 uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
435 if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value))
436 set_it_simple = true;
438 error.SetErrorString("We don't support returning longer than 64 bit "
439 "integer values at present.");
441 } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
443 error.SetErrorString(
444 "We don't support returning complex values at present");
446 llvm::Optional<uint64_t> bit_width =
447 compiler_type.GetBitSize(frame_sp.get());
449 error.SetErrorString("can't get type size");
452 if (*bit_width <= 64) {
453 const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
454 RegisterValue f0_value;
457 size_t num_bytes = new_value_sp->GetData(data, data_error);
458 if (data_error.Fail()) {
459 error.SetErrorStringWithFormat(
460 "Couldn't convert return value to raw data: %s",
461 data_error.AsCString());
465 unsigned char buffer[8];
466 ByteOrder byte_order = data.GetByteOrder();
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;
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");
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
484 error.SetErrorString("We only support setting simple integer and float "
485 "return types at present.");
491 ValueObjectSP ABISysV_s390x::GetReturnValueObjectSimple(
492 Thread &thread, CompilerType &return_compiler_type) const {
493 ValueObjectSP return_valobj_sp;
496 if (!return_compiler_type)
497 return return_valobj_sp;
499 // value.SetContext (Value::eContextTypeClangType, return_value_type);
500 value.SetCompilerType(return_compiler_type);
502 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
504 return return_valobj_sp;
506 const uint32_t type_flags = return_compiler_type.GetTypeInfo();
507 if (type_flags & eTypeIsScalar) {
508 value.SetValueType(Value::eValueTypeScalar);
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);
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) {
524 case sizeof(uint64_t):
526 value.GetScalar() = (int64_t)(raw_value);
528 value.GetScalar() = (uint64_t)(raw_value);
532 case sizeof(uint32_t):
534 value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
536 value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
540 case sizeof(uint16_t):
542 value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
544 value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
548 case sizeof(uint8_t):
550 value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
552 value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
556 } else if (type_flags & eTypeIsFloat) {
557 if (type_flags & eTypeIsComplex) {
558 // Don't handle complex yet.
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)) {
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);
572 } else if (*byte_size == sizeof(double)) {
573 value.GetScalar() = (double)data.GetDouble(&offset);
575 } else if (*byte_size == sizeof(long double)) {
576 // Don't handle long double yet.
585 return_valobj_sp = ValueObjectConstResult::Create(
586 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
587 } else if (type_flags & eTypeIsPointer) {
589 reg_ctx->GetRegisterInfoByName("r2", 0)->kinds[eRegisterKindLLDB];
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(""));
597 return return_valobj_sp;
600 ValueObjectSP ABISysV_s390x::GetReturnValueObjectImpl(
601 Thread &thread, CompilerType &return_compiler_type) const {
602 ValueObjectSP return_valobj_sp;
604 if (!return_compiler_type)
605 return return_valobj_sp;
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;
612 RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
614 return return_valobj_sp;
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.
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);
632 return return_valobj_sp;
635 bool ABISysV_s390x::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
637 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
639 UnwindPlan::RowSP row(new UnwindPlan::Row);
641 // Our Call Frame Address is the stack pointer value + 160
642 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r15_s390x, 160);
644 // The previous PC is in r14
645 row->SetRegisterLocationToRegister(dwarf_pswa_s390x, dwarf_r14_s390x, true);
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);
654 bool ABISysV_s390x::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
655 // There's really no default way to unwind on s390x. Trust the .eh_frame CFI,
656 // which should always be good.
660 bool ABISysV_s390x::GetFallbackRegisterLocation(
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();
674 bool ABISysV_s390x::RegisterIsVolatile(const RegisterInfo *reg_info) {
675 return !RegisterIsCalleeSaved(reg_info);
678 bool ABISysV_s390x::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
680 // Preserved registers are :
684 const char *name = reg_info->name;
685 if (name[0] == 'r') {
691 return name[2] == '\0';
693 case '1': // r10, r11, r12, r13, r15
694 if ((name[2] >= '0' && name[2] <= '3') || name[2] == '5')
695 return name[3] == '\0';
702 if (name[0] == 'f') {
706 return name[2] == '\0';
708 case '1': // r10, r11, r12, r13, r14, r15
709 if (name[2] >= '0' && name[2] <= '5')
710 return name[3] == '\0';
718 // Accept shorter-variant versions
719 if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
721 if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
723 if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
729 void ABISysV_s390x::Initialize() {
730 PluginManager::RegisterPlugin(
731 GetPluginNameStatic(), "System V ABI for s390x targets", CreateInstance);
734 void ABISysV_s390x::Terminate() {
735 PluginManager::UnregisterPlugin(CreateInstance);
738 lldb_private::ConstString ABISysV_s390x::GetPluginNameStatic() {
739 static ConstString g_name("sysv-s390x");
743 // PluginInterface protocol
745 lldb_private::ConstString ABISysV_s390x::GetPluginName() {
746 return GetPluginNameStatic();
749 uint32_t ABISysV_s390x::GetPluginVersion() { return 1; }