1 //===-- ABIWindows_x86_64.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 "ABIWindows_x86_64.h"
10
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/StringSwitch.h"
13 #include "llvm/ADT/Triple.h"
14
15 #include "lldb/Core/Module.h"
16 #include "lldb/Core/PluginManager.h"
17 #include "lldb/Core/Value.h"
18 #include "lldb/Core/ValueObjectConstResult.h"
19 #include "lldb/Core/ValueObjectMemory.h"
20 #include "lldb/Core/ValueObjectRegister.h"
21 #include "lldb/Symbol/UnwindPlan.h"
22 #include "lldb/Target/Process.h"
23 #include "lldb/Target/RegisterContext.h"
24 #include "lldb/Target/StackFrame.h"
25 #include "lldb/Target/Target.h"
26 #include "lldb/Target/Thread.h"
27 #include "lldb/Utility/ConstString.h"
28 #include "lldb/Utility/DataExtractor.h"
29 #include "lldb/Utility/Log.h"
30 #include "lldb/Utility/RegisterValue.h"
31 #include "lldb/Utility/Status.h"
32
33 using namespace lldb;
34 using namespace lldb_private;
35
36 LLDB_PLUGIN_DEFINE(ABIWindows_x86_64)
37
38 enum dwarf_regnums {
39 dwarf_rax = 0,
40 dwarf_rdx,
41 dwarf_rcx,
42 dwarf_rbx,
43 dwarf_rsi,
44 dwarf_rdi,
45 dwarf_rbp,
46 dwarf_rsp,
47 dwarf_r8,
48 dwarf_r9,
49 dwarf_r10,
50 dwarf_r11,
51 dwarf_r12,
52 dwarf_r13,
53 dwarf_r14,
54 dwarf_r15,
55 dwarf_rip,
56 dwarf_xmm0,
57 dwarf_xmm1,
58 dwarf_xmm2,
59 dwarf_xmm3,
60 dwarf_xmm4,
61 dwarf_xmm5,
62 dwarf_xmm6,
63 dwarf_xmm7,
64 dwarf_xmm8,
65 dwarf_xmm9,
66 dwarf_xmm10,
67 dwarf_xmm11,
68 dwarf_xmm12,
69 dwarf_xmm13,
70 dwarf_xmm14,
71 dwarf_xmm15,
72 dwarf_stmm0,
73 dwarf_stmm1,
74 dwarf_stmm2,
75 dwarf_stmm3,
76 dwarf_stmm4,
77 dwarf_stmm5,
78 dwarf_stmm6,
79 dwarf_stmm7,
80 dwarf_ymm0,
81 dwarf_ymm1,
82 dwarf_ymm2,
83 dwarf_ymm3,
84 dwarf_ymm4,
85 dwarf_ymm5,
86 dwarf_ymm6,
87 dwarf_ymm7,
88 dwarf_ymm8,
89 dwarf_ymm9,
90 dwarf_ymm10,
91 dwarf_ymm11,
92 dwarf_ymm12,
93 dwarf_ymm13,
94 dwarf_ymm14,
95 dwarf_ymm15,
96 dwarf_bnd0 = 126,
97 dwarf_bnd1,
98 dwarf_bnd2,
99 dwarf_bnd3
100 };
101
GetPointerReturnRegister(const char * & name)102 bool ABIWindows_x86_64::GetPointerReturnRegister(const char *&name) {
103 name = "rax";
104 return true;
105 }
106
GetRedZoneSize() const107 size_t ABIWindows_x86_64::GetRedZoneSize() const { return 0; }
108
109 //------------------------------------------------------------------
110 // Static Functions
111 //------------------------------------------------------------------
112
113 ABISP
CreateInstance(lldb::ProcessSP process_sp,const ArchSpec & arch)114 ABIWindows_x86_64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
115 if (arch.GetTriple().getArch() == llvm::Triple::x86_64 &&
116 arch.GetTriple().isOSWindows()) {
117 return ABISP(
118 new ABIWindows_x86_64(std::move(process_sp), MakeMCRegisterInfo(arch)));
119 }
120 return ABISP();
121 }
122
PrepareTrivialCall(Thread & thread,addr_t sp,addr_t func_addr,addr_t return_addr,llvm::ArrayRef<addr_t> args) const123 bool ABIWindows_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp,
124 addr_t func_addr, addr_t return_addr,
125 llvm::ArrayRef<addr_t> args) const {
126 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
127
128 if (log) {
129 StreamString s;
130 s.Printf("ABIWindows_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64
131 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
132 ", return_addr = 0x%" PRIx64,
133 thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
134 (uint64_t)return_addr);
135
136 for (size_t i = 0; i < args.size(); ++i)
137 s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1),
138 args[i]);
139 s.PutCString(")");
140 log->PutString(s.GetString());
141 }
142
143 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
144 if (!reg_ctx)
145 return false;
146
147 const RegisterInfo *reg_info = nullptr;
148
149 if (args.size() > 4) // Windows x64 only put first 4 arguments into registers
150 return false;
151
152 for (size_t i = 0; i < args.size(); ++i) {
153 reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
154 LLDB_REGNUM_GENERIC_ARG1 + i);
155 LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
156 static_cast<uint64_t>(i + 1), args[i], reg_info->name);
157 if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
158 return false;
159 }
160
161 // First, align the SP
162
163 LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
164 (uint64_t)sp, (uint64_t)(sp & ~0xfull));
165
166 sp &= ~(0xfull); // 16-byte alignment
167
168 sp -= 8; // return address
169
170 Status error;
171 const RegisterInfo *pc_reg_info =
172 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
173 const RegisterInfo *sp_reg_info =
174 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
175 ProcessSP process_sp(thread.GetProcess());
176
177 RegisterValue reg_value;
178 LLDB_LOGF(log,
179 "Pushing the return address onto the stack: 0x%" PRIx64
180 ": 0x%" PRIx64,
181 (uint64_t)sp, (uint64_t)return_addr);
182
183 // Save return address onto the stack
184 if (!process_sp->WritePointerToMemory(sp, return_addr, error))
185 return false;
186
187 // %rsp is set to the actual stack value.
188
189 LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
190
191 if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
192 return false;
193
194 // %rip is set to the address of the called function.
195
196 LLDB_LOGF(log, "Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
197
198 if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
199 return false;
200
201 return true;
202 }
203
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)204 static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,
205 bool is_signed, Thread &thread,
206 uint32_t *argument_register_ids,
207 unsigned int ¤t_argument_register,
208 addr_t ¤t_stack_argument) {
209 if (bit_width > 64)
210 return false; // Scalar can't hold large integer arguments
211
212 if (current_argument_register < 4) { // Windows pass first 4 arguments to register
213 scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
214 argument_register_ids[current_argument_register], 0);
215 current_argument_register++;
216 if (is_signed)
217 scalar.SignExtend(bit_width);
218 return true;
219 }
220 uint32_t byte_size = (bit_width + (CHAR_BIT - 1)) / CHAR_BIT;
221 Status error;
222 if (thread.GetProcess()->ReadScalarIntegerFromMemory(
223 current_stack_argument, byte_size, is_signed, scalar, error)) {
224 current_stack_argument += byte_size;
225 return true;
226 }
227 return false;
228 }
229
GetArgumentValues(Thread & thread,ValueList & values) const230 bool ABIWindows_x86_64::GetArgumentValues(Thread &thread,
231 ValueList &values) const {
232 unsigned int num_values = values.GetSize();
233 unsigned int value_index;
234
235 // Extract the register context so we can read arguments from registers
236
237 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
238
239 if (!reg_ctx)
240 return false;
241
242 // Get the pointer to the first stack argument so we have a place to start
243 // when reading data
244
245 addr_t sp = reg_ctx->GetSP(0);
246
247 if (!sp)
248 return false;
249
250 addr_t current_stack_argument = sp + 8; // jump over return address
251
252 uint32_t argument_register_ids[4];
253
254 argument_register_ids[0] =
255 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)
256 ->kinds[eRegisterKindLLDB];
257 argument_register_ids[1] =
258 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)
259 ->kinds[eRegisterKindLLDB];
260 argument_register_ids[2] =
261 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)
262 ->kinds[eRegisterKindLLDB];
263 argument_register_ids[3] =
264 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)
265 ->kinds[eRegisterKindLLDB];
266
267 unsigned int current_argument_register = 0;
268
269 for (value_index = 0; value_index < num_values; ++value_index) {
270 Value *value = values.GetValueAtIndex(value_index);
271
272 if (!value)
273 return false;
274
275 CompilerType compiler_type = value->GetCompilerType();
276 llvm::Optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread);
277 if (!bit_size)
278 return false;
279 bool is_signed;
280
281 if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
282 ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread,
283 argument_register_ids, current_argument_register,
284 current_stack_argument);
285 } else if (compiler_type.IsPointerType()) {
286 ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread,
287 argument_register_ids, current_argument_register,
288 current_stack_argument);
289 }
290 }
291
292 return true;
293 }
294
SetReturnValueObject(lldb::StackFrameSP & frame_sp,lldb::ValueObjectSP & new_value_sp)295 Status ABIWindows_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
296 lldb::ValueObjectSP &new_value_sp) {
297 Status error;
298 if (!new_value_sp) {
299 error.SetErrorString("Empty value object for return value.");
300 return error;
301 }
302
303 CompilerType compiler_type = new_value_sp->GetCompilerType();
304 if (!compiler_type) {
305 error.SetErrorString("Null clang type for return value.");
306 return error;
307 }
308
309 Thread *thread = frame_sp->GetThread().get();
310
311 bool is_signed;
312 uint32_t count;
313 bool is_complex;
314
315 RegisterContext *reg_ctx = thread->GetRegisterContext().get();
316
317 bool set_it_simple = false;
318 if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
319 compiler_type.IsPointerType()) {
320 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("rax", 0);
321
322 DataExtractor data;
323 Status data_error;
324 size_t num_bytes = new_value_sp->GetData(data, data_error);
325 if (data_error.Fail()) {
326 error.SetErrorStringWithFormat(
327 "Couldn't convert return value to raw data: %s",
328 data_error.AsCString());
329 return error;
330 }
331 lldb::offset_t offset = 0;
332 if (num_bytes <= 8) {
333 uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
334
335 if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value))
336 set_it_simple = true;
337 } else {
338 error.SetErrorString("We don't support returning longer than 64 bit "
339 "integer values at present.");
340 }
341 } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
342 if (is_complex)
343 error.SetErrorString(
344 "We don't support returning complex values at present");
345 else {
346 llvm::Optional<uint64_t> bit_width =
347 compiler_type.GetBitSize(frame_sp.get());
348 if (!bit_width) {
349 error.SetErrorString("can't get type size");
350 return error;
351 }
352 if (*bit_width <= 64) {
353 const RegisterInfo *xmm0_info =
354 reg_ctx->GetRegisterInfoByName("xmm0", 0);
355 RegisterValue xmm0_value;
356 DataExtractor data;
357 Status data_error;
358 size_t num_bytes = new_value_sp->GetData(data, data_error);
359 if (data_error.Fail()) {
360 error.SetErrorStringWithFormat(
361 "Couldn't convert return value to raw data: %s",
362 data_error.AsCString());
363 return error;
364 }
365
366 unsigned char buffer[16];
367 ByteOrder byte_order = data.GetByteOrder();
368
369 data.CopyByteOrderedData(0, num_bytes, buffer, 16, byte_order);
370 xmm0_value.SetBytes(buffer, 16, byte_order);
371 reg_ctx->WriteRegister(xmm0_info, xmm0_value);
372 set_it_simple = true;
373 } else {
374 // Windows doesn't support 80 bit FP
375 error.SetErrorString(
376 "Windows-x86_64 doesn't allow FP larger than 64 bits.");
377 }
378 }
379 }
380
381 if (!set_it_simple) {
382 // Okay we've got a structure or something that doesn't fit in a simple
383 // register.
384 // TODO(wanyi): On Windows, if the return type is a struct:
385 // 1) smaller that 64 bits and return by value -> RAX
386 // 2) bigger than 64 bits, the caller will allocate memory for that struct
387 // and pass the struct pointer in RCX then return the pointer in RAX
388 error.SetErrorString("We only support setting simple integer and float "
389 "return types at present.");
390 }
391
392 return error;
393 }
394
GetReturnValueObjectSimple(Thread & thread,CompilerType & return_compiler_type) const395 ValueObjectSP ABIWindows_x86_64::GetReturnValueObjectSimple(
396 Thread &thread, CompilerType &return_compiler_type) const {
397 ValueObjectSP return_valobj_sp;
398 Value value;
399
400 if (!return_compiler_type)
401 return return_valobj_sp;
402
403 value.SetCompilerType(return_compiler_type);
404
405 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
406 if (!reg_ctx)
407 return return_valobj_sp;
408
409 const uint32_t type_flags = return_compiler_type.GetTypeInfo();
410 if (type_flags & eTypeIsScalar) {
411 value.SetValueType(Value::eValueTypeScalar);
412
413 bool success = false;
414 if (type_flags & eTypeIsInteger) {
415 // Extract the register context so we can read arguments from registers
416 llvm::Optional<uint64_t> byte_size =
417 return_compiler_type.GetByteSize(nullptr);
418 if (!byte_size)
419 return return_valobj_sp;
420 uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
421 reg_ctx->GetRegisterInfoByName("rax", 0), 0);
422 const bool is_signed = (type_flags & eTypeIsSigned) != 0;
423 switch (*byte_size) {
424 default:
425 break;
426
427 case sizeof(uint64_t):
428 if (is_signed)
429 value.GetScalar() = (int64_t)(raw_value);
430 else
431 value.GetScalar() = (uint64_t)(raw_value);
432 success = true;
433 break;
434
435 case sizeof(uint32_t):
436 if (is_signed)
437 value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
438 else
439 value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
440 success = true;
441 break;
442
443 case sizeof(uint16_t):
444 if (is_signed)
445 value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
446 else
447 value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
448 success = true;
449 break;
450
451 case sizeof(uint8_t):
452 if (is_signed)
453 value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
454 else
455 value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
456 success = true;
457 break;
458 }
459 } else if (type_flags & eTypeIsFloat) {
460 if (type_flags & eTypeIsComplex) {
461 // Don't handle complex yet.
462 } else {
463 llvm::Optional<uint64_t> byte_size =
464 return_compiler_type.GetByteSize(nullptr);
465 if (byte_size && *byte_size <= sizeof(long double)) {
466 const RegisterInfo *xmm0_info =
467 reg_ctx->GetRegisterInfoByName("xmm0", 0);
468 RegisterValue xmm0_value;
469 if (reg_ctx->ReadRegister(xmm0_info, xmm0_value)) {
470 DataExtractor data;
471 if (xmm0_value.GetData(data)) {
472 lldb::offset_t offset = 0;
473 if (*byte_size == sizeof(float)) {
474 value.GetScalar() = (float)data.GetFloat(&offset);
475 success = true;
476 } else if (*byte_size == sizeof(double)) {
477 // double and long double are the same on windows
478 value.GetScalar() = (double)data.GetDouble(&offset);
479 success = true;
480 }
481 }
482 }
483 }
484 }
485 }
486
487 if (success)
488 return_valobj_sp = ValueObjectConstResult::Create(
489 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
490 } else if ((type_flags & eTypeIsPointer) ||
491 (type_flags & eTypeInstanceIsPointer)) {
492 unsigned rax_id =
493 reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
494 value.GetScalar() =
495 (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
496 0);
497 value.SetValueType(Value::eValueTypeScalar);
498 return_valobj_sp = ValueObjectConstResult::Create(
499 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
500 } else if (type_flags & eTypeIsVector) {
501 llvm::Optional<uint64_t> byte_size =
502 return_compiler_type.GetByteSize(nullptr);
503 if (byte_size && *byte_size > 0) {
504 const RegisterInfo *xmm_reg =
505 reg_ctx->GetRegisterInfoByName("xmm0", 0);
506 if (xmm_reg == nullptr)
507 xmm_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
508
509 if (xmm_reg) {
510 if (*byte_size <= xmm_reg->byte_size) {
511 ProcessSP process_sp(thread.GetProcess());
512 if (process_sp) {
513 std::unique_ptr<DataBufferHeap> heap_data_up(
514 new DataBufferHeap(*byte_size, 0));
515 const ByteOrder byte_order = process_sp->GetByteOrder();
516 RegisterValue reg_value;
517 if (reg_ctx->ReadRegister(xmm_reg, reg_value)) {
518 Status error;
519 if (reg_value.GetAsMemoryData(
520 xmm_reg, heap_data_up->GetBytes(),
521 heap_data_up->GetByteSize(), byte_order, error)) {
522 DataExtractor data(DataBufferSP(heap_data_up.release()),
523 byte_order,
524 process_sp->GetTarget()
525 .GetArchitecture()
526 .GetAddressByteSize());
527 return_valobj_sp = ValueObjectConstResult::Create(
528 &thread, return_compiler_type, ConstString(""), data);
529 }
530 }
531 }
532 }
533 }
534 }
535 }
536
537 return return_valobj_sp;
538 }
539
540 // The compiler will flatten the nested aggregate type into single
541 // layer and push the value to stack
542 // This helper function will flatten an aggregate type
543 // and return true if it can be returned in register(s) by value
544 // return false if the aggregate is in memory
FlattenAggregateType(Thread & thread,ExecutionContext & exe_ctx,CompilerType & return_compiler_type,uint32_t data_byte_offset,std::vector<uint32_t> & aggregate_field_offsets,std::vector<CompilerType> & aggregate_compiler_types)545 static bool FlattenAggregateType(
546 Thread &thread, ExecutionContext &exe_ctx,
547 CompilerType &return_compiler_type,
548 uint32_t data_byte_offset,
549 std::vector<uint32_t> &aggregate_field_offsets,
550 std::vector<CompilerType> &aggregate_compiler_types) {
551
552 const uint32_t num_children = return_compiler_type.GetNumFields();
553 for (uint32_t idx = 0; idx < num_children; ++idx) {
554 std::string name;
555 bool is_signed;
556 uint32_t count;
557 bool is_complex;
558
559 uint64_t field_bit_offset = 0;
560 CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(
561 idx, name, &field_bit_offset, nullptr, nullptr);
562 llvm::Optional<uint64_t> field_bit_width =
563 field_compiler_type.GetBitSize(&thread);
564
565 // if we don't know the size of the field (e.g. invalid type), exit
566 if (!field_bit_width || *field_bit_width == 0) {
567 return false;
568 }
569 // If there are any unaligned fields, this is stored in memory.
570 if (field_bit_offset % *field_bit_width != 0) {
571 return false;
572 }
573
574 // add overall offset
575 uint32_t field_byte_offset = field_bit_offset / 8 + data_byte_offset;
576
577 const uint32_t field_type_flags = field_compiler_type.GetTypeInfo();
578 if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
579 field_compiler_type.IsPointerType() ||
580 field_compiler_type.IsFloatingPointType(count, is_complex)) {
581 aggregate_field_offsets.push_back(field_byte_offset);
582 aggregate_compiler_types.push_back(field_compiler_type);
583 } else if (field_type_flags & eTypeHasChildren) {
584 if (!FlattenAggregateType(thread, exe_ctx, field_compiler_type,
585 field_byte_offset, aggregate_field_offsets,
586 aggregate_compiler_types)) {
587 return false;
588 }
589 }
590 }
591 return true;
592 }
593
GetReturnValueObjectImpl(Thread & thread,CompilerType & return_compiler_type) const594 ValueObjectSP ABIWindows_x86_64::GetReturnValueObjectImpl(
595 Thread &thread, CompilerType &return_compiler_type) const {
596 ValueObjectSP return_valobj_sp;
597
598 if (!return_compiler_type) {
599 return return_valobj_sp;
600 }
601
602 // try extract value as if it's a simple type
603 return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
604 if (return_valobj_sp) {
605 return return_valobj_sp;
606 }
607
608 RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
609 if (!reg_ctx_sp) {
610 return return_valobj_sp;
611 }
612
613 llvm::Optional<uint64_t> bit_width = return_compiler_type.GetBitSize(&thread);
614 if (!bit_width) {
615 return return_valobj_sp;
616 }
617
618 // if it's not simple or aggregate type, then we don't know how to handle it
619 if (!return_compiler_type.IsAggregateType()) {
620 return return_valobj_sp;
621 }
622
623 ExecutionContext exe_ctx(thread.shared_from_this());
624 Target *target = exe_ctx.GetTargetPtr();
625 uint32_t max_register_value_bit_width = 64;
626
627 // The scenario here is to have a struct/class which is POD
628 // if the return struct/class size is larger than 64 bits,
629 // the caller will allocate memory for it and pass the return addr in RCX
630 // then return the address in RAX
631
632 // if the struct is returned by value in register (RAX)
633 // its size has to be: 1, 2, 4, 8, 16, 32, or 64 bits (aligned)
634 // for floating point, the return value will be copied over to RAX
635 bool is_memory = *bit_width > max_register_value_bit_width ||
636 *bit_width & (*bit_width - 1);
637 std::vector<uint32_t> aggregate_field_offsets;
638 std::vector<CompilerType> aggregate_compiler_types;
639 if (!is_memory &&
640 FlattenAggregateType(thread, exe_ctx, return_compiler_type,
641 0, aggregate_field_offsets,
642 aggregate_compiler_types)) {
643 ByteOrder byte_order = target->GetArchitecture().GetByteOrder();
644 DataBufferSP data_sp(
645 new DataBufferHeap(max_register_value_bit_width / 8, 0));
646 DataExtractor return_ext(data_sp, byte_order,
647 target->GetArchitecture().GetAddressByteSize());
648
649 // The only register used to return struct/class by value
650 const RegisterInfo *rax_info =
651 reg_ctx_sp->GetRegisterInfoByName("rax", 0);
652 RegisterValue rax_value;
653 reg_ctx_sp->ReadRegister(rax_info, rax_value);
654 DataExtractor rax_data;
655 rax_value.GetData(rax_data);
656
657 uint32_t used_bytes =
658 0; // Tracks how much of the rax registers we've consumed so far
659
660 // in case of the returned type is a subclass of non-abstract-base class
661 // it will have a padding to skip the base content
662 if (aggregate_field_offsets.size())
663 used_bytes = aggregate_field_offsets[0];
664
665 const uint32_t num_children = aggregate_compiler_types.size();
666 for (uint32_t idx = 0; idx < num_children; idx++) {
667 bool is_signed;
668 bool is_complex;
669 uint32_t count;
670
671 CompilerType field_compiler_type = aggregate_compiler_types[idx];
672 uint32_t field_byte_width = (uint32_t) (*field_compiler_type.GetByteSize(&thread));
673 uint32_t field_byte_offset = aggregate_field_offsets[idx];
674
675 // this is unlikely w/o the overall size being greater than 8 bytes
676 // For now, return a nullptr return value object.
677 if (used_bytes >= 8 || used_bytes + field_byte_width > 8) {
678 return return_valobj_sp;
679 }
680
681 DataExtractor *copy_from_extractor = nullptr;
682 uint32_t copy_from_offset = 0;
683 if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
684 field_compiler_type.IsPointerType() ||
685 field_compiler_type.IsFloatingPointType(count, is_complex)) {
686 copy_from_extractor = &rax_data;
687 copy_from_offset = used_bytes;
688 used_bytes += field_byte_width;
689 }
690 // These two tests are just sanity checks. If I somehow get the type
691 // calculation wrong above it is better to just return nothing than to
692 // assert or crash.
693 if (!copy_from_extractor) {
694 return return_valobj_sp;
695 }
696 if (copy_from_offset + field_byte_width >
697 copy_from_extractor->GetByteSize()) {
698 return return_valobj_sp;
699 }
700 copy_from_extractor->CopyByteOrderedData(copy_from_offset,
701 field_byte_width, data_sp->GetBytes() + field_byte_offset,
702 field_byte_width, byte_order);
703 }
704 if (!is_memory) {
705 // The result is in our data buffer. Let's make a variable object out
706 // of it:
707 return_valobj_sp = ValueObjectConstResult::Create(
708 &thread, return_compiler_type, ConstString(""), return_ext);
709 }
710 }
711
712 // The Windows x86_64 ABI specifies that the return address for MEMORY
713 // objects be placed in rax on exit from the function.
714
715 // FIXME: This is just taking a guess, rax may very well no longer hold the
716 // return storage location.
717 // If we are going to do this right, when we make a new frame we should
718 // check to see if it uses a memory return, and if we are at the first
719 // instruction and if so stash away the return location. Then we would
720 // only return the memory return value if we know it is valid.
721 if (is_memory) {
722 unsigned rax_id =
723 reg_ctx_sp->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
724 lldb::addr_t storage_addr =
725 (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
726 0);
727 return_valobj_sp = ValueObjectMemory::Create(
728 &thread, "", Address(storage_addr, nullptr), return_compiler_type);
729 }
730 return return_valobj_sp;
731 }
732
733 // This defines the CFA as rsp+8
734 // the saved pc is at CFA-8 (i.e. rsp+0)
735 // The saved rsp is CFA+0
736
CreateFunctionEntryUnwindPlan(UnwindPlan & unwind_plan)737 bool ABIWindows_x86_64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
738 unwind_plan.Clear();
739 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
740
741 uint32_t sp_reg_num = dwarf_rsp;
742 uint32_t pc_reg_num = dwarf_rip;
743
744 UnwindPlan::RowSP row(new UnwindPlan::Row);
745 row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 8);
746 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
747 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
748 unwind_plan.AppendRow(row);
749 unwind_plan.SetSourceName("x86_64 at-func-entry default");
750 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
751 return true;
752 }
753
754 // Windows-x86_64 doesn't use %rbp
755 // No available Unwind information for Windows-x86_64 (section .pdata)
756 // Let's use SysV-x86_64 one for now
CreateDefaultUnwindPlan(UnwindPlan & unwind_plan)757 bool ABIWindows_x86_64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
758 unwind_plan.Clear();
759 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
760
761 uint32_t fp_reg_num = dwarf_rbp;
762 uint32_t sp_reg_num = dwarf_rsp;
763 uint32_t pc_reg_num = dwarf_rip;
764
765 UnwindPlan::RowSP row(new UnwindPlan::Row);
766
767 const int32_t ptr_size = 8;
768 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp, 2 * ptr_size);
769 row->SetOffset(0);
770
771 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
772 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
773 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
774
775 unwind_plan.AppendRow(row);
776 unwind_plan.SetSourceName("x86_64 default unwind plan");
777 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
778 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
779
780 return true;
781 }
782
RegisterIsVolatile(const RegisterInfo * reg_info)783 bool ABIWindows_x86_64::RegisterIsVolatile(const RegisterInfo *reg_info) {
784 return !RegisterIsCalleeSaved(reg_info);
785 }
786
RegisterIsCalleeSaved(const RegisterInfo * reg_info)787 bool ABIWindows_x86_64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
788 if (!reg_info)
789 return false;
790 assert(reg_info->name != nullptr && "unnamed register?");
791 std::string Name = std::string(reg_info->name);
792 bool IsCalleeSaved =
793 llvm::StringSwitch<bool>(Name)
794 .Cases("rbx", "ebx", "rbp", "ebp", "rdi", "edi", "rsi", "esi", true)
795 .Cases("rsp", "esp", "r12", "r13", "r14", "r15", "sp", "fp", true)
796 .Cases("xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12",
797 "xmm13", "xmm14", "xmm15", true)
798 .Default(false);
799 return IsCalleeSaved;
800 }
801
GetGenericNum(llvm::StringRef reg)802 uint32_t ABIWindows_x86_64::GetGenericNum(llvm::StringRef reg) {
803 return llvm::StringSwitch<uint32_t>(reg)
804 .Case("rip", LLDB_REGNUM_GENERIC_PC)
805 .Case("rsp", LLDB_REGNUM_GENERIC_SP)
806 .Case("rbp", LLDB_REGNUM_GENERIC_FP)
807 .Case("rflags", LLDB_REGNUM_GENERIC_FLAGS)
808 .Case("rcx", LLDB_REGNUM_GENERIC_ARG1)
809 .Case("rdx", LLDB_REGNUM_GENERIC_ARG2)
810 .Case("r8", LLDB_REGNUM_GENERIC_ARG3)
811 .Case("r9", LLDB_REGNUM_GENERIC_ARG4)
812 .Default(LLDB_INVALID_REGNUM);
813 }
814
Initialize()815 void ABIWindows_x86_64::Initialize() {
816 PluginManager::RegisterPlugin(
817 GetPluginNameStatic(), "Windows ABI for x86_64 targets", CreateInstance);
818 }
819
Terminate()820 void ABIWindows_x86_64::Terminate() {
821 PluginManager::UnregisterPlugin(CreateInstance);
822 }
823
GetPluginNameStatic()824 lldb_private::ConstString ABIWindows_x86_64::GetPluginNameStatic() {
825 static ConstString g_name("windows-x86_64");
826 return g_name;
827 }
828
829 //------------------------------------------------------------------
830 // PluginInterface protocol
831 //------------------------------------------------------------------
832
GetPluginName()833 lldb_private::ConstString ABIWindows_x86_64::GetPluginName() {
834 return GetPluginNameStatic();
835 }
836
GetPluginVersion()837 uint32_t ABIWindows_x86_64::GetPluginVersion() { return 1; }
838