1 //===-- ABISysV_s390x.cpp -------------------------------------------------===//
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"
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"
31 
32 using namespace lldb;
33 using namespace lldb_private;
34 
35 LLDB_PLUGIN_DEFINE_ADV(ABISysV_s390x, ABISystemZ)
36 
37 enum dwarf_regnums {
38   // General Purpose Registers
39   dwarf_r0_s390x = 0,
40   dwarf_r1_s390x,
41   dwarf_r2_s390x,
42   dwarf_r3_s390x,
43   dwarf_r4_s390x,
44   dwarf_r5_s390x,
45   dwarf_r6_s390x,
46   dwarf_r7_s390x,
47   dwarf_r8_s390x,
48   dwarf_r9_s390x,
49   dwarf_r10_s390x,
50   dwarf_r11_s390x,
51   dwarf_r12_s390x,
52   dwarf_r13_s390x,
53   dwarf_r14_s390x,
54   dwarf_r15_s390x,
55   // Floating Point Registers / Vector Registers 0-15
56   dwarf_f0_s390x = 16,
57   dwarf_f2_s390x,
58   dwarf_f4_s390x,
59   dwarf_f6_s390x,
60   dwarf_f1_s390x,
61   dwarf_f3_s390x,
62   dwarf_f5_s390x,
63   dwarf_f7_s390x,
64   dwarf_f8_s390x,
65   dwarf_f10_s390x,
66   dwarf_f12_s390x,
67   dwarf_f14_s390x,
68   dwarf_f9_s390x,
69   dwarf_f11_s390x,
70   dwarf_f13_s390x,
71   dwarf_f15_s390x,
72   // Access Registers
73   dwarf_acr0_s390x = 48,
74   dwarf_acr1_s390x,
75   dwarf_acr2_s390x,
76   dwarf_acr3_s390x,
77   dwarf_acr4_s390x,
78   dwarf_acr5_s390x,
79   dwarf_acr6_s390x,
80   dwarf_acr7_s390x,
81   dwarf_acr8_s390x,
82   dwarf_acr9_s390x,
83   dwarf_acr10_s390x,
84   dwarf_acr11_s390x,
85   dwarf_acr12_s390x,
86   dwarf_acr13_s390x,
87   dwarf_acr14_s390x,
88   dwarf_acr15_s390x,
89   // Program Status Word
90   dwarf_pswm_s390x = 64,
91   dwarf_pswa_s390x,
92   // Vector Registers 16-31
93   dwarf_v16_s390x = 68,
94   dwarf_v18_s390x,
95   dwarf_v20_s390x,
96   dwarf_v22_s390x,
97   dwarf_v17_s390x,
98   dwarf_v19_s390x,
99   dwarf_v21_s390x,
100   dwarf_v23_s390x,
101   dwarf_v24_s390x,
102   dwarf_v26_s390x,
103   dwarf_v28_s390x,
104   dwarf_v30_s390x,
105   dwarf_v25_s390x,
106   dwarf_v27_s390x,
107   dwarf_v29_s390x,
108   dwarf_v31_s390x,
109 };
110 
111 // RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB
112 
113 #define DEFINE_REG(name, size, alt, generic)                                   \
114   {                                                                            \
115     #name, alt, size, 0, eEncodingUint, eFormatHex,                            \
116         {dwarf_##name##_s390x, dwarf_##name##_s390x, generic,                  \
117          LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM },                           \
118          nullptr, nullptr, nullptr, 0                                          \
119   }
120 
121 static const RegisterInfo g_register_infos[] = {
122     DEFINE_REG(r0, 8, nullptr, LLDB_INVALID_REGNUM),
123     DEFINE_REG(r1, 8, nullptr, LLDB_INVALID_REGNUM),
124     DEFINE_REG(r2, 8, "arg1", LLDB_REGNUM_GENERIC_ARG1),
125     DEFINE_REG(r3, 8, "arg2", LLDB_REGNUM_GENERIC_ARG2),
126     DEFINE_REG(r4, 8, "arg3", LLDB_REGNUM_GENERIC_ARG3),
127     DEFINE_REG(r5, 8, "arg4", LLDB_REGNUM_GENERIC_ARG4),
128     DEFINE_REG(r6, 8, "arg5", LLDB_REGNUM_GENERIC_ARG5),
129     DEFINE_REG(r7, 8, nullptr, LLDB_INVALID_REGNUM),
130     DEFINE_REG(r8, 8, nullptr, LLDB_INVALID_REGNUM),
131     DEFINE_REG(r9, 8, nullptr, LLDB_INVALID_REGNUM),
132     DEFINE_REG(r10, 8, nullptr, LLDB_INVALID_REGNUM),
133     DEFINE_REG(r11, 8, "fp", LLDB_REGNUM_GENERIC_FP),
134     DEFINE_REG(r12, 8, nullptr, LLDB_INVALID_REGNUM),
135     DEFINE_REG(r13, 8, nullptr, LLDB_INVALID_REGNUM),
136     DEFINE_REG(r14, 8, nullptr, LLDB_INVALID_REGNUM),
137     DEFINE_REG(r15, 8, "sp", LLDB_REGNUM_GENERIC_SP),
138     DEFINE_REG(acr0, 4, nullptr, LLDB_INVALID_REGNUM),
139     DEFINE_REG(acr1, 4, nullptr, LLDB_INVALID_REGNUM),
140     DEFINE_REG(acr2, 4, nullptr, LLDB_INVALID_REGNUM),
141     DEFINE_REG(acr3, 4, nullptr, LLDB_INVALID_REGNUM),
142     DEFINE_REG(acr4, 4, nullptr, LLDB_INVALID_REGNUM),
143     DEFINE_REG(acr5, 4, nullptr, LLDB_INVALID_REGNUM),
144     DEFINE_REG(acr6, 4, nullptr, LLDB_INVALID_REGNUM),
145     DEFINE_REG(acr7, 4, nullptr, LLDB_INVALID_REGNUM),
146     DEFINE_REG(acr8, 4, nullptr, LLDB_INVALID_REGNUM),
147     DEFINE_REG(acr9, 4, nullptr, LLDB_INVALID_REGNUM),
148     DEFINE_REG(acr10, 4, nullptr, LLDB_INVALID_REGNUM),
149     DEFINE_REG(acr11, 4, nullptr, LLDB_INVALID_REGNUM),
150     DEFINE_REG(acr12, 4, nullptr, LLDB_INVALID_REGNUM),
151     DEFINE_REG(acr13, 4, nullptr, LLDB_INVALID_REGNUM),
152     DEFINE_REG(acr14, 4, nullptr, LLDB_INVALID_REGNUM),
153     DEFINE_REG(acr15, 4, nullptr, LLDB_INVALID_REGNUM),
154     DEFINE_REG(pswm, 8, "flags", LLDB_REGNUM_GENERIC_FLAGS),
155     DEFINE_REG(pswa, 8, "pc", LLDB_REGNUM_GENERIC_PC),
156     DEFINE_REG(f0, 8, nullptr, LLDB_INVALID_REGNUM),
157     DEFINE_REG(f1, 8, nullptr, LLDB_INVALID_REGNUM),
158     DEFINE_REG(f2, 8, nullptr, LLDB_INVALID_REGNUM),
159     DEFINE_REG(f3, 8, nullptr, LLDB_INVALID_REGNUM),
160     DEFINE_REG(f4, 8, nullptr, LLDB_INVALID_REGNUM),
161     DEFINE_REG(f5, 8, nullptr, LLDB_INVALID_REGNUM),
162     DEFINE_REG(f6, 8, nullptr, LLDB_INVALID_REGNUM),
163     DEFINE_REG(f7, 8, nullptr, LLDB_INVALID_REGNUM),
164     DEFINE_REG(f8, 8, nullptr, LLDB_INVALID_REGNUM),
165     DEFINE_REG(f9, 8, nullptr, LLDB_INVALID_REGNUM),
166     DEFINE_REG(f10, 8, nullptr, LLDB_INVALID_REGNUM),
167     DEFINE_REG(f11, 8, nullptr, LLDB_INVALID_REGNUM),
168     DEFINE_REG(f12, 8, nullptr, LLDB_INVALID_REGNUM),
169     DEFINE_REG(f13, 8, nullptr, LLDB_INVALID_REGNUM),
170     DEFINE_REG(f14, 8, nullptr, LLDB_INVALID_REGNUM),
171     DEFINE_REG(f15, 8, nullptr, LLDB_INVALID_REGNUM),
172 };
173 
174 static const uint32_t k_num_register_infos =
175     llvm::array_lengthof(g_register_infos);
176 
177 const lldb_private::RegisterInfo *
GetRegisterInfoArray(uint32_t & count)178 ABISysV_s390x::GetRegisterInfoArray(uint32_t &count) {
179   count = k_num_register_infos;
180   return g_register_infos;
181 }
182 
GetRedZoneSize() const183 size_t ABISysV_s390x::GetRedZoneSize() const { return 0; }
184 
185 // Static Functions
186 
187 ABISP
CreateInstance(lldb::ProcessSP process_sp,const ArchSpec & arch)188 ABISysV_s390x::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
189   if (arch.GetTriple().getArch() == llvm::Triple::systemz) {
190     return ABISP(new ABISysV_s390x(std::move(process_sp), MakeMCRegisterInfo(arch)));
191   }
192   return ABISP();
193 }
194 
PrepareTrivialCall(Thread & thread,addr_t sp,addr_t func_addr,addr_t return_addr,llvm::ArrayRef<addr_t> args) const195 bool ABISysV_s390x::PrepareTrivialCall(Thread &thread, addr_t sp,
196                                        addr_t func_addr, addr_t return_addr,
197                                        llvm::ArrayRef<addr_t> args) const {
198   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
199 
200   if (log) {
201     StreamString s;
202     s.Printf("ABISysV_s390x::PrepareTrivialCall (tid = 0x%" PRIx64
203              ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
204              ", return_addr = 0x%" PRIx64,
205              thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
206              (uint64_t)return_addr);
207 
208     for (size_t i = 0; i < args.size(); ++i)
209       s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1),
210                args[i]);
211     s.PutCString(")");
212     log->PutString(s.GetString());
213   }
214 
215   RegisterContext *reg_ctx = thread.GetRegisterContext().get();
216   if (!reg_ctx)
217     return false;
218 
219   const RegisterInfo *pc_reg_info =
220       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
221   const RegisterInfo *sp_reg_info =
222       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
223   const RegisterInfo *ra_reg_info = reg_ctx->GetRegisterInfoByName("r14", 0);
224   ProcessSP process_sp(thread.GetProcess());
225 
226   // Allocate a new stack frame and space for stack arguments if necessary
227 
228   addr_t arg_pos = 0;
229   if (args.size() > 5) {
230     sp -= 8 * (args.size() - 5);
231     arg_pos = sp;
232   }
233 
234   sp -= 160;
235 
236   // Process arguments
237 
238   for (size_t i = 0; i < args.size(); ++i) {
239     if (i < 5) {
240       const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
241           eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
242       LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
243                 static_cast<uint64_t>(i + 1), args[i], reg_info->name);
244       if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
245         return false;
246     } else {
247       Status error;
248       LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") onto stack",
249                 static_cast<uint64_t>(i + 1), args[i]);
250       if (!process_sp->WritePointerToMemory(arg_pos, args[i], error))
251         return false;
252       arg_pos += 8;
253     }
254   }
255 
256   // %r14 is set to the return address
257 
258   LLDB_LOGF(log, "Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
259 
260   if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr))
261     return false;
262 
263   // %r15 is set to the actual stack value.
264 
265   LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
266 
267   if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
268     return false;
269 
270   // %pc is set to the address of the called function.
271 
272   LLDB_LOGF(log, "Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
273 
274   if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
275     return false;
276 
277   return true;
278 }
279 
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)280 static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,
281                                 bool is_signed, Thread &thread,
282                                 uint32_t *argument_register_ids,
283                                 unsigned int &current_argument_register,
284                                 addr_t &current_stack_argument) {
285   if (bit_width > 64)
286     return false; // Scalar can't hold large integer arguments
287 
288   if (current_argument_register < 5) {
289     scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
290         argument_register_ids[current_argument_register], 0);
291     current_argument_register++;
292     if (is_signed)
293       scalar.SignExtend(bit_width);
294   } else {
295     uint32_t byte_size = (bit_width + (8 - 1)) / 8;
296     Status error;
297     if (thread.GetProcess()->ReadScalarIntegerFromMemory(
298             current_stack_argument + 8 - byte_size, byte_size, is_signed,
299             scalar, error)) {
300       current_stack_argument += 8;
301       return true;
302     }
303     return false;
304   }
305   return true;
306 }
307 
GetArgumentValues(Thread & thread,ValueList & values) const308 bool ABISysV_s390x::GetArgumentValues(Thread &thread, ValueList &values) const {
309   unsigned int num_values = values.GetSize();
310   unsigned int value_index;
311 
312   // Extract the register context so we can read arguments from registers
313 
314   RegisterContext *reg_ctx = thread.GetRegisterContext().get();
315 
316   if (!reg_ctx)
317     return false;
318 
319   // Get the pointer to the first stack argument so we have a place to start
320   // when reading data
321 
322   addr_t sp = reg_ctx->GetSP(0);
323 
324   if (!sp)
325     return false;
326 
327   addr_t current_stack_argument = sp + 160;
328 
329   uint32_t argument_register_ids[5];
330 
331   argument_register_ids[0] =
332       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)
333           ->kinds[eRegisterKindLLDB];
334   argument_register_ids[1] =
335       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)
336           ->kinds[eRegisterKindLLDB];
337   argument_register_ids[2] =
338       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)
339           ->kinds[eRegisterKindLLDB];
340   argument_register_ids[3] =
341       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)
342           ->kinds[eRegisterKindLLDB];
343   argument_register_ids[4] =
344       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5)
345           ->kinds[eRegisterKindLLDB];
346 
347   unsigned int current_argument_register = 0;
348 
349   for (value_index = 0; value_index < num_values; ++value_index) {
350     Value *value = values.GetValueAtIndex(value_index);
351 
352     if (!value)
353       return false;
354 
355     // We currently only support extracting values with Clang QualTypes. Do we
356     // care about others?
357     CompilerType compiler_type = value->GetCompilerType();
358     llvm::Optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread);
359     if (!bit_size)
360       return false;
361     bool is_signed;
362 
363     if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
364       ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread,
365                           argument_register_ids, current_argument_register,
366                           current_stack_argument);
367     } else if (compiler_type.IsPointerType()) {
368       ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread,
369                           argument_register_ids, current_argument_register,
370                           current_stack_argument);
371     }
372   }
373 
374   return true;
375 }
376 
SetReturnValueObject(lldb::StackFrameSP & frame_sp,lldb::ValueObjectSP & new_value_sp)377 Status ABISysV_s390x::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
378                                            lldb::ValueObjectSP &new_value_sp) {
379   Status error;
380   if (!new_value_sp) {
381     error.SetErrorString("Empty value object for return value.");
382     return error;
383   }
384 
385   CompilerType compiler_type = new_value_sp->GetCompilerType();
386   if (!compiler_type) {
387     error.SetErrorString("Null clang type for return value.");
388     return error;
389   }
390 
391   Thread *thread = frame_sp->GetThread().get();
392 
393   bool is_signed;
394   uint32_t count;
395   bool is_complex;
396 
397   RegisterContext *reg_ctx = thread->GetRegisterContext().get();
398 
399   bool set_it_simple = false;
400   if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
401       compiler_type.IsPointerType()) {
402     const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r2", 0);
403 
404     DataExtractor data;
405     Status data_error;
406     size_t num_bytes = new_value_sp->GetData(data, data_error);
407     if (data_error.Fail()) {
408       error.SetErrorStringWithFormat(
409           "Couldn't convert return value to raw data: %s",
410           data_error.AsCString());
411       return error;
412     }
413     lldb::offset_t offset = 0;
414     if (num_bytes <= 8) {
415       uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
416 
417       if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value))
418         set_it_simple = true;
419     } else {
420       error.SetErrorString("We don't support returning longer than 64 bit "
421                            "integer values at present.");
422     }
423   } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
424     if (is_complex)
425       error.SetErrorString(
426           "We don't support returning complex values at present");
427     else {
428       llvm::Optional<uint64_t> bit_width =
429           compiler_type.GetBitSize(frame_sp.get());
430       if (!bit_width) {
431         error.SetErrorString("can't get type size");
432         return error;
433       }
434       if (*bit_width <= 64) {
435         const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
436         RegisterValue f0_value;
437         DataExtractor data;
438         Status data_error;
439         size_t num_bytes = new_value_sp->GetData(data, data_error);
440         if (data_error.Fail()) {
441           error.SetErrorStringWithFormat(
442               "Couldn't convert return value to raw data: %s",
443               data_error.AsCString());
444           return error;
445         }
446 
447         unsigned char buffer[8];
448         ByteOrder byte_order = data.GetByteOrder();
449 
450         data.CopyByteOrderedData(0, num_bytes, buffer, 8, byte_order);
451         f0_value.SetBytes(buffer, 8, byte_order);
452         reg_ctx->WriteRegister(f0_info, f0_value);
453         set_it_simple = true;
454       } else {
455         // FIXME - don't know how to do long doubles yet.
456         error.SetErrorString(
457             "We don't support returning float values > 64 bits at present");
458       }
459     }
460   }
461 
462   if (!set_it_simple) {
463     // Okay we've got a structure or something that doesn't fit in a simple
464     // register. We should figure out where it really goes, but we don't
465     // support this yet.
466     error.SetErrorString("We only support setting simple integer and float "
467                          "return types at present.");
468   }
469 
470   return error;
471 }
472 
GetReturnValueObjectSimple(Thread & thread,CompilerType & return_compiler_type) const473 ValueObjectSP ABISysV_s390x::GetReturnValueObjectSimple(
474     Thread &thread, CompilerType &return_compiler_type) const {
475   ValueObjectSP return_valobj_sp;
476   Value value;
477 
478   if (!return_compiler_type)
479     return return_valobj_sp;
480 
481   // value.SetContext (Value::eContextTypeClangType, return_value_type);
482   value.SetCompilerType(return_compiler_type);
483 
484   RegisterContext *reg_ctx = thread.GetRegisterContext().get();
485   if (!reg_ctx)
486     return return_valobj_sp;
487 
488   const uint32_t type_flags = return_compiler_type.GetTypeInfo();
489   if (type_flags & eTypeIsScalar) {
490     value.SetValueType(Value::eValueTypeScalar);
491 
492     bool success = false;
493     if (type_flags & eTypeIsInteger) {
494       // Extract the register context so we can read arguments from registers.
495       llvm::Optional<uint64_t> byte_size =
496           return_compiler_type.GetByteSize(&thread);
497       if (!byte_size)
498         return return_valobj_sp;
499       uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
500           reg_ctx->GetRegisterInfoByName("r2", 0), 0);
501       const bool is_signed = (type_flags & eTypeIsSigned) != 0;
502       switch (*byte_size) {
503       default:
504         break;
505 
506       case sizeof(uint64_t):
507         if (is_signed)
508           value.GetScalar() = (int64_t)(raw_value);
509         else
510           value.GetScalar() = (uint64_t)(raw_value);
511         success = true;
512         break;
513 
514       case sizeof(uint32_t):
515         if (is_signed)
516           value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
517         else
518           value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
519         success = true;
520         break;
521 
522       case sizeof(uint16_t):
523         if (is_signed)
524           value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
525         else
526           value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
527         success = true;
528         break;
529 
530       case sizeof(uint8_t):
531         if (is_signed)
532           value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
533         else
534           value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
535         success = true;
536         break;
537       }
538     } else if (type_flags & eTypeIsFloat) {
539       if (type_flags & eTypeIsComplex) {
540         // Don't handle complex yet.
541       } else {
542         llvm::Optional<uint64_t> byte_size =
543             return_compiler_type.GetByteSize(&thread);
544         if (byte_size && *byte_size <= sizeof(long double)) {
545           const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
546           RegisterValue f0_value;
547           if (reg_ctx->ReadRegister(f0_info, f0_value)) {
548             DataExtractor data;
549             if (f0_value.GetData(data)) {
550               lldb::offset_t offset = 0;
551               if (*byte_size == sizeof(float)) {
552                 value.GetScalar() = (float)data.GetFloat(&offset);
553                 success = true;
554               } else if (*byte_size == sizeof(double)) {
555                 value.GetScalar() = (double)data.GetDouble(&offset);
556                 success = true;
557               } else if (*byte_size == sizeof(long double)) {
558                 // Don't handle long double yet.
559               }
560             }
561           }
562         }
563       }
564     }
565 
566     if (success)
567       return_valobj_sp = ValueObjectConstResult::Create(
568           thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
569   } else if (type_flags & eTypeIsPointer) {
570     unsigned r2_id =
571         reg_ctx->GetRegisterInfoByName("r2", 0)->kinds[eRegisterKindLLDB];
572     value.GetScalar() =
573         (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_id, 0);
574     value.SetValueType(Value::eValueTypeScalar);
575     return_valobj_sp = ValueObjectConstResult::Create(
576         thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
577   }
578 
579   return return_valobj_sp;
580 }
581 
GetReturnValueObjectImpl(Thread & thread,CompilerType & return_compiler_type) const582 ValueObjectSP ABISysV_s390x::GetReturnValueObjectImpl(
583     Thread &thread, CompilerType &return_compiler_type) const {
584   ValueObjectSP return_valobj_sp;
585 
586   if (!return_compiler_type)
587     return return_valobj_sp;
588 
589   ExecutionContext exe_ctx(thread.shared_from_this());
590   return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
591   if (return_valobj_sp)
592     return return_valobj_sp;
593 
594   RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
595   if (!reg_ctx_sp)
596     return return_valobj_sp;
597 
598   if (return_compiler_type.IsAggregateType()) {
599     // FIXME: This is just taking a guess, r2 may very well no longer hold the
600     // return storage location.
601     // If we are going to do this right, when we make a new frame we should
602     // check to see if it uses a memory return, and if we are at the first
603     // instruction and if so stash away the return location.  Then we would
604     // only return the memory return value if we know it is valid.
605 
606     unsigned r2_id =
607         reg_ctx_sp->GetRegisterInfoByName("r2", 0)->kinds[eRegisterKindLLDB];
608     lldb::addr_t storage_addr =
609         (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_id, 0);
610     return_valobj_sp = ValueObjectMemory::Create(
611         &thread, "", Address(storage_addr, nullptr), return_compiler_type);
612   }
613 
614   return return_valobj_sp;
615 }
616 
CreateFunctionEntryUnwindPlan(UnwindPlan & unwind_plan)617 bool ABISysV_s390x::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
618   unwind_plan.Clear();
619   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
620 
621   UnwindPlan::RowSP row(new UnwindPlan::Row);
622 
623   // Our Call Frame Address is the stack pointer value + 160
624   row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r15_s390x, 160);
625 
626   // The previous PC is in r14
627   row->SetRegisterLocationToRegister(dwarf_pswa_s390x, dwarf_r14_s390x, true);
628 
629   // All other registers are the same.
630   unwind_plan.AppendRow(row);
631   unwind_plan.SetSourceName("s390x at-func-entry default");
632   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
633   return true;
634 }
635 
CreateDefaultUnwindPlan(UnwindPlan & unwind_plan)636 bool ABISysV_s390x::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
637   // There's really no default way to unwind on s390x. Trust the .eh_frame CFI,
638   // which should always be good.
639   return false;
640 }
641 
GetFallbackRegisterLocation(const RegisterInfo * reg_info,UnwindPlan::Row::RegisterLocation & unwind_regloc)642 bool ABISysV_s390x::GetFallbackRegisterLocation(
643     const RegisterInfo *reg_info,
644     UnwindPlan::Row::RegisterLocation &unwind_regloc) {
645   // If a volatile register is being requested, we don't want to forward the
646   // next frame's register contents up the stack -- the register is not
647   // retrievable at this frame.
648   if (RegisterIsVolatile(reg_info)) {
649     unwind_regloc.SetUndefined();
650     return true;
651   }
652 
653   return false;
654 }
655 
RegisterIsVolatile(const RegisterInfo * reg_info)656 bool ABISysV_s390x::RegisterIsVolatile(const RegisterInfo *reg_info) {
657   return !RegisterIsCalleeSaved(reg_info);
658 }
659 
RegisterIsCalleeSaved(const RegisterInfo * reg_info)660 bool ABISysV_s390x::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
661   if (reg_info) {
662     // Preserved registers are :
663     //    r6-r13, r15
664     //    f8-f15
665 
666     const char *name = reg_info->name;
667     if (name[0] == 'r') {
668       switch (name[1]) {
669       case '6': // r6
670       case '7': // r7
671       case '8': // r8
672       case '9': // r9
673         return name[2] == '\0';
674 
675       case '1': // r10, r11, r12, r13, r15
676         if ((name[2] >= '0' && name[2] <= '3') || name[2] == '5')
677           return name[3] == '\0';
678         break;
679 
680       default:
681         break;
682       }
683     }
684     if (name[0] == 'f') {
685       switch (name[1]) {
686       case '8': // r8
687       case '9': // r9
688         return name[2] == '\0';
689 
690       case '1': // r10, r11, r12, r13, r14, r15
691         if (name[2] >= '0' && name[2] <= '5')
692           return name[3] == '\0';
693         break;
694 
695       default:
696         break;
697       }
698     }
699 
700     // Accept shorter-variant versions
701     if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
702       return true;
703     if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
704       return true;
705     if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
706       return true;
707   }
708   return false;
709 }
710 
Initialize()711 void ABISysV_s390x::Initialize() {
712   PluginManager::RegisterPlugin(
713       GetPluginNameStatic(), "System V ABI for s390x targets", CreateInstance);
714 }
715 
Terminate()716 void ABISysV_s390x::Terminate() {
717   PluginManager::UnregisterPlugin(CreateInstance);
718 }
719 
GetPluginNameStatic()720 lldb_private::ConstString ABISysV_s390x::GetPluginNameStatic() {
721   static ConstString g_name("sysv-s390x");
722   return g_name;
723 }
724 
725 // PluginInterface protocol
726 
GetPluginName()727 lldb_private::ConstString ABISysV_s390x::GetPluginName() {
728   return GetPluginNameStatic();
729 }
730 
GetPluginVersion()731 uint32_t ABISysV_s390x::GetPluginVersion() { return 1; }
732