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

source code of lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp