LLDB mainline
ABIWindows_x86_64.cpp
Go to the documentation of this file.
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"
17#include "lldb/Core/Value.h"
19#include "lldb/Target/Process.h"
22#include "lldb/Target/Target.h"
23#include "lldb/Target/Thread.h"
27#include "lldb/Utility/Log.h"
29#include "lldb/Utility/Status.h"
33#include <optional>
34
35using namespace lldb;
36using namespace lldb_private;
37
39
103
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
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
126 addr_t func_addr, addr_t return_addr,
127 llvm::ArrayRef<addr_t> args) const {
129
130 if (log) {
131 StreamString s;
132 s.Printf("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(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1),
140 args[i]);
141 s.PutCString(")");
142 log->PutString(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(eRegisterKindGeneric,
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, 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
173 const RegisterInfo *pc_reg_info =
175 const RegisterInfo *sp_reg_info =
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(sp, 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(sp_reg_info, 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(pc_reg_info, 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 argument_register_ids[current_argument_register], 0);
217 current_argument_register++;
218 if (is_signed)
219 scalar.SignExtend(bit_width);
220 return true;
221 }
222 uint32_t byte_size = (bit_width + (CHAR_BIT - 1)) / CHAR_BIT;
224 if (thread.GetProcess()->ReadScalarIntegerFromMemory(
225 current_stack_argument, byte_size, is_signed, scalar, error)) {
226 current_stack_argument += byte_size;
227 return true;
228 }
229 return false;
230}
231
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(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] =
259 argument_register_ids[1] =
262 argument_register_ids[2] =
265 argument_register_ids[3] =
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(value_index);
273
274 if (!value)
275 return false;
276
277 CompilerType compiler_type = value->GetCompilerType();
278 std::optional<uint64_t> bit_size =
279 llvm::expectedToOptional(compiler_type.GetBitSize(&thread));
280 if (!bit_size)
281 return false;
282 bool is_signed;
283
284 if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
285 ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread,
286 argument_register_ids, current_argument_register,
287 current_stack_argument);
288 } else if (compiler_type.IsPointerType()) {
289 ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread,
290 argument_register_ids, current_argument_register,
291 current_stack_argument);
292 }
293 }
294
295 return true;
296}
297
299 lldb::ValueObjectSP &new_value_sp) {
301 if (!new_value_sp) {
302 error = Status::FromErrorString("Empty value object for return value.");
303 return error;
304 }
305
306 CompilerType compiler_type = new_value_sp->GetCompilerType();
307 if (!compiler_type) {
308 error = Status::FromErrorString("Null clang type for return value.");
309 return error;
310 }
311
312 Thread *thread = frame_sp->GetThread().get();
313
314 bool is_signed;
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("rax", 0);
323
324 DataExtractor data;
325 Status data_error;
326 size_t num_bytes = new_value_sp->GetData(data, data_error);
327 if (data_error.Fail()) {
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, num_bytes);
336
337 if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value))
338 set_it_simple = true;
339 } else {
341 "We don't support returning longer than 64 bit "
342 "integer values at present.");
343 }
344 } else if (compiler_type.IsFloatingPointType(is_complex)) {
345 if (is_complex)
347 "We don't support returning complex values at present");
348 else {
349 std::optional<uint64_t> bit_width =
350 llvm::expectedToOptional(compiler_type.GetBitSize(frame_sp.get()));
351 if (!bit_width) {
352 error = Status::FromErrorString("can't get type size");
353 return error;
354 }
355 if (*bit_width <= 64) {
356 const RegisterInfo *xmm0_info =
357 reg_ctx->GetRegisterInfoByName("xmm0", 0);
358 RegisterValue xmm0_value;
359 DataExtractor data;
360 Status data_error;
361 size_t num_bytes = new_value_sp->GetData(data, data_error);
362 if (data_error.Fail()) {
364 "Couldn't convert return value to raw data: %s",
365 data_error.AsCString());
366 return error;
367 }
368
369 unsigned char buffer[16];
370 ByteOrder byte_order = data.GetByteOrder();
371
372 data.CopyByteOrderedData(0, num_bytes, buffer, 16, byte_order);
373 xmm0_value.SetBytes(buffer, 16, byte_order);
374 reg_ctx->WriteRegister(xmm0_info, xmm0_value);
375 set_it_simple = true;
376 } else {
377 // Windows doesn't support 80 bit FP
379 "Windows-x86_64 doesn't allow FP larger than 64 bits.");
380 }
381 }
382 }
383
384 if (!set_it_simple) {
385 // Okay we've got a structure or something that doesn't fit in a simple
386 // register.
387 // TODO(wanyi): On Windows, if the return type is a struct:
388 // 1) smaller that 64 bits and return by value -> RAX
389 // 2) bigger than 64 bits, the caller will allocate memory for that struct
390 // and pass the struct pointer in RCX then return the pointer in RAX
392 "We only support setting simple integer and float "
393 "return types at present.");
394 }
395
396 return error;
397}
398
400 Thread &thread, CompilerType &return_compiler_type) const {
401 ValueObjectSP return_valobj_sp;
402 Value value;
403
404 if (!return_compiler_type)
405 return return_valobj_sp;
406
407 value.SetCompilerType(return_compiler_type);
408
409 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
410 if (!reg_ctx)
411 return return_valobj_sp;
412
413 const uint32_t type_flags = return_compiler_type.GetTypeInfo();
414 if (type_flags & eTypeIsScalar) {
416
417 bool success = false;
418 if (type_flags & eTypeIsInteger) {
419 // Extract the register context so we can read arguments from registers
420 std::optional<uint64_t> byte_size =
421 llvm::expectedToOptional(return_compiler_type.GetByteSize(&thread));
422 if (!byte_size)
423 return return_valobj_sp;
424 uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
425 reg_ctx->GetRegisterInfoByName("rax", 0), 0);
426 const bool is_signed = (type_flags & eTypeIsSigned) != 0;
427 switch (*byte_size) {
428 default:
429 break;
430
431 case sizeof(uint64_t):
432 if (is_signed)
433 value.GetScalar() = (int64_t)(raw_value);
434 else
435 value.GetScalar() = (uint64_t)(raw_value);
436 success = true;
437 break;
438
439 case sizeof(uint32_t):
440 if (is_signed)
441 value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
442 else
443 value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
444 success = true;
445 break;
446
447 case sizeof(uint16_t):
448 if (is_signed)
449 value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
450 else
451 value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
452 success = true;
453 break;
454
455 case sizeof(uint8_t):
456 if (is_signed)
457 value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
458 else
459 value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
460 success = true;
461 break;
462 }
463 } else if (type_flags & eTypeIsFloat) {
464 if (type_flags & eTypeIsComplex) {
465 // Don't handle complex yet.
466 } else {
467 std::optional<uint64_t> byte_size =
468 llvm::expectedToOptional(return_compiler_type.GetByteSize(&thread));
469 if (byte_size && *byte_size <= sizeof(long double)) {
470 const RegisterInfo *xmm0_info =
471 reg_ctx->GetRegisterInfoByName("xmm0", 0);
472 RegisterValue xmm0_value;
473 if (reg_ctx->ReadRegister(xmm0_info, xmm0_value)) {
474 DataExtractor data;
475 if (xmm0_value.GetData(data)) {
476 lldb::offset_t offset = 0;
477 if (*byte_size == sizeof(float)) {
478 value.GetScalar() = (float)data.GetFloat(&offset);
479 success = true;
480 } else if (*byte_size == sizeof(double)) {
481 // double and long double are the same on windows
482 value.GetScalar() = (double)data.GetDouble(&offset);
483 success = true;
484 }
485 }
486 }
487 }
488 }
489 }
490
491 if (success)
492 return_valobj_sp = ValueObjectConstResult::Create(
493 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
494 } else if ((type_flags & eTypeIsPointer) ||
495 (type_flags & eTypeInstanceIsPointer)) {
496 unsigned rax_id =
497 reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
498 value.GetScalar() =
499 (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
500 0);
502 return_valobj_sp = ValueObjectConstResult::Create(
503 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
504 } else if (type_flags & eTypeIsVector) {
505 std::optional<uint64_t> byte_size =
506 llvm::expectedToOptional(return_compiler_type.GetByteSize(&thread));
507 if (byte_size && *byte_size > 0) {
508 const RegisterInfo *xmm_reg =
509 reg_ctx->GetRegisterInfoByName("xmm0", 0);
510 if (xmm_reg == nullptr)
511 xmm_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
512
513 if (xmm_reg) {
514 if (*byte_size <= xmm_reg->byte_size) {
515 ProcessSP process_sp(thread.GetProcess());
516 if (process_sp) {
517 std::unique_ptr<DataBufferHeap> heap_data_up(
518 new DataBufferHeap(*byte_size, 0));
519 const ByteOrder byte_order = process_sp->GetByteOrder();
520 RegisterValue reg_value;
521 if (reg_ctx->ReadRegister(xmm_reg, reg_value)) {
523 if (reg_value.GetAsMemoryData(*xmm_reg, heap_data_up->GetBytes(),
524 heap_data_up->GetByteSize(),
525 byte_order, error)) {
526 DataExtractor data(DataBufferSP(heap_data_up.release()),
527 byte_order,
528 process_sp->GetTarget()
529 .GetArchitecture()
530 .GetAddressByteSize());
531 return_valobj_sp = ValueObjectConstResult::Create(
532 &thread, return_compiler_type, ConstString(""), data);
533 }
534 }
535 }
536 }
537 }
538 }
539 }
540
541 return return_valobj_sp;
542}
543
544// The compiler will flatten the nested aggregate type into single
545// layer and push the value to stack
546// This helper function will flatten an aggregate type
547// and return true if it can be returned in register(s) by value
548// return false if the aggregate is in memory
550 Thread &thread, ExecutionContext &exe_ctx,
551 CompilerType &return_compiler_type,
552 uint32_t data_byte_offset,
553 std::vector<uint32_t> &aggregate_field_offsets,
554 std::vector<CompilerType> &aggregate_compiler_types) {
555
556 const uint32_t num_children = return_compiler_type.GetNumFields();
557 for (uint32_t idx = 0; idx < num_children; ++idx) {
558 std::string name;
559 bool is_signed;
560 bool is_complex;
561
562 uint64_t field_bit_offset = 0;
563 CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(
564 idx, name, &field_bit_offset, nullptr, nullptr);
565 std::optional<uint64_t> field_bit_width =
566 llvm::expectedToOptional(field_compiler_type.GetBitSize(&thread));
567
568 // if we don't know the size of the field (e.g. invalid type), exit
569 if (!field_bit_width || *field_bit_width == 0) {
570 return false;
571 }
572 // If there are any unaligned fields, this is stored in memory.
573 if (field_bit_offset % *field_bit_width != 0) {
574 return false;
575 }
576
577 // add overall offset
578 uint32_t field_byte_offset = field_bit_offset / 8 + data_byte_offset;
579
580 const uint32_t field_type_flags = field_compiler_type.GetTypeInfo();
581 if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
582 field_compiler_type.IsPointerType() ||
583 field_compiler_type.IsFloatingPointType(is_complex)) {
584 aggregate_field_offsets.push_back(field_byte_offset);
585 aggregate_compiler_types.push_back(field_compiler_type);
586 } else if (field_type_flags & eTypeHasChildren) {
587 if (!FlattenAggregateType(thread, exe_ctx, field_compiler_type,
588 field_byte_offset, aggregate_field_offsets,
589 aggregate_compiler_types)) {
590 return false;
591 }
592 }
593 }
594 return true;
595}
596
598 Thread &thread, CompilerType &return_compiler_type) const {
599 ValueObjectSP return_valobj_sp;
600
601 if (!return_compiler_type) {
602 return return_valobj_sp;
603 }
604
605 // try extract value as if it's a simple type
606 return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
607 if (return_valobj_sp) {
608 return return_valobj_sp;
609 }
610
611 RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
612 if (!reg_ctx_sp) {
613 return return_valobj_sp;
614 }
615
616 std::optional<uint64_t> bit_width =
617 llvm::expectedToOptional(return_compiler_type.GetBitSize(&thread));
618 if (!bit_width) {
619 return return_valobj_sp;
620 }
621
622 // if it's not simple or aggregate type, then we don't know how to handle it
623 if (!return_compiler_type.IsAggregateType()) {
624 return return_valobj_sp;
625 }
626
627 ExecutionContext exe_ctx(thread.shared_from_this());
628 Target *target = exe_ctx.GetTargetPtr();
629 uint32_t max_register_value_bit_width = 64;
630
631 // The scenario here is to have a struct/class which is POD
632 // if the return struct/class size is larger than 64 bits,
633 // the caller will allocate memory for it and pass the return addr in RCX
634 // then return the address in RAX
635
636 // if the struct is returned by value in register (RAX)
637 // its size has to be: 1, 2, 4, 8, 16, 32, or 64 bits (aligned)
638 // for floating point, the return value will be copied over to RAX
639 bool is_memory = *bit_width > max_register_value_bit_width ||
640 *bit_width & (*bit_width - 1);
641 std::vector<uint32_t> aggregate_field_offsets;
642 std::vector<CompilerType> aggregate_compiler_types;
643 if (!is_memory &&
644 FlattenAggregateType(thread, exe_ctx, return_compiler_type,
645 0, aggregate_field_offsets,
646 aggregate_compiler_types)) {
647 ByteOrder byte_order = target->GetArchitecture().GetByteOrder();
648 WritableDataBufferSP data_sp(
649 new DataBufferHeap(max_register_value_bit_width / 8, 0));
650 DataExtractor return_ext(data_sp, byte_order,
652
653 // The only register used to return struct/class by value
654 const RegisterInfo *rax_info =
655 reg_ctx_sp->GetRegisterInfoByName("rax", 0);
656 RegisterValue rax_value;
657 reg_ctx_sp->ReadRegister(rax_info, rax_value);
658 DataExtractor rax_data;
659 rax_value.GetData(rax_data);
660
661 uint32_t used_bytes =
662 0; // Tracks how much of the rax registers we've consumed so far
663
664 // in case of the returned type is a subclass of non-abstract-base class
665 // it will have a padding to skip the base content
666 if (aggregate_field_offsets.size())
667 used_bytes = aggregate_field_offsets[0];
668
669 const uint32_t num_children = aggregate_compiler_types.size();
670 for (uint32_t idx = 0; idx < num_children; idx++) {
671 bool is_signed;
672 bool is_complex;
673
674 CompilerType field_compiler_type = aggregate_compiler_types[idx];
675 uint32_t field_byte_width =
676 (uint32_t)(llvm::expectedToOptional(
677 field_compiler_type.GetByteSize(&thread))
678 .value_or(0));
679 uint32_t field_byte_offset = aggregate_field_offsets[idx];
680
681 // this is unlikely w/o the overall size being greater than 8 bytes
682 // For now, return a nullptr return value object.
683 if (used_bytes >= 8 || used_bytes + field_byte_width > 8) {
684 return return_valobj_sp;
685 }
686
687 DataExtractor *copy_from_extractor = nullptr;
688 uint32_t copy_from_offset = 0;
689 if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
690 field_compiler_type.IsPointerType() ||
691 field_compiler_type.IsFloatingPointType(is_complex)) {
692 copy_from_extractor = &rax_data;
693 copy_from_offset = used_bytes;
694 used_bytes += field_byte_width;
695 }
696 // These two tests are just sanity checks. If I somehow get the type
697 // calculation wrong above it is better to just return nothing than to
698 // assert or crash.
699 if (!copy_from_extractor) {
700 return return_valobj_sp;
701 }
702 if (copy_from_offset + field_byte_width >
703 copy_from_extractor->GetByteSize()) {
704 return return_valobj_sp;
705 }
706 copy_from_extractor->CopyByteOrderedData(copy_from_offset,
707 field_byte_width, data_sp->GetBytes() + field_byte_offset,
708 field_byte_width, byte_order);
709 }
710 if (!is_memory) {
711 // The result is in our data buffer. Let's make a variable object out
712 // of it:
713 return_valobj_sp = ValueObjectConstResult::Create(
714 &thread, return_compiler_type, ConstString(""), return_ext);
715 }
716 }
717
718 // The Windows x86_64 ABI specifies that the return address for MEMORY
719 // objects be placed in rax on exit from the function.
720
721 // FIXME: This is just taking a guess, rax may very well no longer hold the
722 // return storage location.
723 // If we are going to do this right, when we make a new frame we should
724 // check to see if it uses a memory return, and if we are at the first
725 // instruction and if so stash away the return location. Then we would
726 // only return the memory return value if we know it is valid.
727 if (is_memory) {
728 unsigned rax_id =
729 reg_ctx_sp->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
730 lldb::addr_t storage_addr =
731 (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
732 0);
733 return_valobj_sp = ValueObjectMemory::Create(
734 &thread, "", Address(storage_addr, nullptr), return_compiler_type);
735 }
736 return return_valobj_sp;
737}
738
739// This defines the CFA as rsp+8
740// the saved pc is at CFA-8 (i.e. rsp+0)
741// The saved rsp is CFA+0
742
744 uint32_t sp_reg_num = dwarf_rsp;
745 uint32_t pc_reg_num = dwarf_rip;
746
747 UnwindPlan::Row row;
748 row.GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 8);
749 row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
750 row.SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
751
752 auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
753 plan_sp->AppendRow(std::move(row));
754 plan_sp->SetSourceName("x86_64 at-func-entry default");
755 plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
756 return plan_sp;
757}
758
759// Windows-x86_64 doesn't use %rbp
760// No available Unwind information for Windows-x86_64 (section .pdata)
761// Let's use SysV-x86_64 one for now
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::Row row;
768
769 const int32_t ptr_size = 8;
770 row.GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp, 2 * ptr_size);
771 row.SetOffset(0);
773
774 row.SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
775 row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
776 row.SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
777
778 auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
779 plan_sp->AppendRow(std::move(row));
780 plan_sp->SetSourceName("x86_64 default unwind plan");
781 plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
782 plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
783 return plan_sp;
784}
785
787 return !RegisterIsCalleeSaved(reg_info);
788}
789
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({"rbx", "ebx", "rbp", "ebp", "rdi", "edi", "rsi", "esi"}, true)
798 .Cases({"rsp", "esp", "r12", "r13", "r14", "r15", "sp", "fp"}, true)
799 .Cases({"xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12",
800 "xmm13", "xmm14", "xmm15"},
801 true)
802 .Default(false);
803 return IsCalleeSaved;
804}
805
806uint32_t ABIWindows_x86_64::GetGenericNum(llvm::StringRef reg) {
807 return llvm::StringSwitch<uint32_t>(reg)
808 .Case("rip", LLDB_REGNUM_GENERIC_PC)
809 .Case("rsp", LLDB_REGNUM_GENERIC_SP)
810 .Case("rbp", LLDB_REGNUM_GENERIC_FP)
811 .Case("rflags", LLDB_REGNUM_GENERIC_FLAGS)
812 // gdbserver uses eflags
813 .Case("eflags", LLDB_REGNUM_GENERIC_FLAGS)
814 .Case("rcx", LLDB_REGNUM_GENERIC_ARG1)
815 .Case("rdx", LLDB_REGNUM_GENERIC_ARG2)
816 .Case("r8", LLDB_REGNUM_GENERIC_ARG3)
817 .Case("r9", LLDB_REGNUM_GENERIC_ARG4)
818 .Default(LLDB_INVALID_REGNUM);
819}
820
823 GetPluginNameStatic(), "Windows ABI for x86_64 targets", CreateInstance);
824}
825
dwarf_regnums
@ dwarf_r12
@ dwarf_r13
@ dwarf_r8
@ dwarf_r11
@ dwarf_r9
@ dwarf_r15
@ dwarf_r10
@ dwarf_r14
static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width, bool is_signed, Thread &thread, uint32_t *argument_register_ids, unsigned int &current_argument_register, addr_t &current_stack_argument)
static bool 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)
@ dwarf_rdi
@ dwarf_rcx
@ dwarf_rip
@ dwarf_rsi
@ dwarf_rax
@ dwarf_rsp
@ dwarf_rbp
@ dwarf_rdx
@ dwarf_rbx
static bool 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)
@ dwarf_ymm3
@ dwarf_ymm13
@ dwarf_xmm11
@ dwarf_stmm0
@ dwarf_xmm0
@ dwarf_xmm10
@ dwarf_ymm4
@ dwarf_xmm4
@ dwarf_ymm10
@ dwarf_ymm12
@ dwarf_xmm7
@ dwarf_stmm5
@ dwarf_ymm14
@ dwarf_ymm7
@ dwarf_stmm3
@ dwarf_ymm0
@ dwarf_xmm6
@ dwarf_xmm5
@ dwarf_bnd0
@ dwarf_bnd1
@ dwarf_ymm9
@ dwarf_stmm7
@ dwarf_stmm2
@ dwarf_xmm9
@ dwarf_xmm3
@ dwarf_ymm1
@ dwarf_stmm6
@ dwarf_xmm13
@ dwarf_xmm15
@ dwarf_ymm11
@ dwarf_xmm8
@ dwarf_ymm5
@ dwarf_xmm2
@ dwarf_ymm8
@ dwarf_ymm2
@ dwarf_xmm14
@ dwarf_xmm1
@ dwarf_stmm1
@ dwarf_ymm6
@ dwarf_stmm4
@ dwarf_xmm12
@ dwarf_ymm15
static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width, bool is_signed, Thread &thread, uint32_t *argument_register_ids, unsigned int &current_argument_register, addr_t &current_stack_argument)
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOGF(log,...)
Definition Log.h:376
#define LLDB_PLUGIN_DEFINE(PluginName)
lldb_private::Status SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override
static llvm::StringRef GetPluginNameStatic()
static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch)
lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &type) const override
lldb::ValueObjectSP GetReturnValueObjectSimple(lldb_private::Thread &thread, lldb_private::CompilerType &ast_type) const
bool GetPointerReturnRegister(const char *&name) override
bool GetArgumentValues(lldb_private::Thread &thread, lldb_private::ValueList &values) const override
size_t GetRedZoneSize() const override
bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override
lldb::UnwindPlanSP CreateFunctionEntryUnwindPlan() override
bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, lldb::addr_t functionAddress, lldb::addr_t returnAddress, llvm::ArrayRef< lldb::addr_t > args) const override
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info)
lldb::UnwindPlanSP CreateDefaultUnwindPlan() override
uint32_t GetGenericNum(llvm::StringRef reg) override
Return the generic number of the given register.
static std::unique_ptr< llvm::MCRegisterInfo > MakeMCRegisterInfo(const ArchSpec &arch)
Utility function to construct a MCRegisterInfo using the ArchSpec triple.
Definition ABI.cpp:234
A section + offset based address class.
Definition Address.h:62
An architecture specification class.
Definition ArchSpec.h:31
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition ArchSpec.cpp:685
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition ArchSpec.h:468
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition ArchSpec.cpp:732
Generic representation of a type in a programming language.
CompilerType GetFieldAtIndex(size_t idx, std::string &name, uint64_t *bit_offset_ptr, uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr) const
llvm::Expected< uint64_t > GetByteSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bytes.
uint32_t GetNumFields() const
bool IsIntegerOrEnumerationType(bool &is_signed) const
uint32_t GetTypeInfo(CompilerType *pointee_or_element_compiler_type=nullptr) const
llvm::Expected< uint64_t > GetBitSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bits.
bool IsFloatingPointType(bool &is_complex) const
bool IsPointerType(CompilerType *pointee_type=nullptr) const
A uniqued constant string class.
Definition ConstString.h:40
A subclass of DataBuffer that stores a data buffer on the heap.
An data extractor class.
float GetFloat(lldb::offset_t *offset_ptr) const
Extract a float from *offset_ptr.
uint64_t GetByteSize() const
Get the number of bytes contained in this object.
uint64_t GetMaxU64(lldb::offset_t *offset_ptr, size_t byte_size) const
Extract an unsigned integer of size byte_size from *offset_ptr.
lldb::ByteOrder GetByteOrder() const
Get the current byte order value.
lldb::offset_t CopyByteOrderedData(lldb::offset_t src_offset, lldb::offset_t src_len, void *dst, lldb::offset_t dst_len, lldb::ByteOrder dst_byte_order) const
Copy dst_len bytes from *offset_ptr and ensure the copied data is treated as a value that can be swap...
double GetDouble(lldb::offset_t *offset_ptr) const
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
Target * GetTargetPtr() const
Returns a pointer to the target object.
void PutString(llvm::StringRef str)
Definition Log.cpp:147
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
uint64_t GetSP(uint64_t fail_value=LLDB_INVALID_ADDRESS)
virtual bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value)=0
const RegisterInfo * GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num)
bool WriteRegisterFromUnsigned(uint32_t reg, uint64_t uval)
const RegisterInfo * GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx=0)
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)=0
bool GetData(DataExtractor &data) const
uint32_t GetAsMemoryData(const RegisterInfo &reg_info, void *dst, uint32_t dst_len, lldb::ByteOrder dst_byte_order, Status &error) const
void SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order)
bool SignExtend(uint32_t bit_pos)
Definition Scalar.cpp:762
An error handling class.
Definition Status.h:118
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromErrorString(const char *str)
Definition Status.h:141
bool Fail() const
Test for error condition.
Definition Status.cpp:294
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition Status.cpp:195
llvm::StringRef GetString() const
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition Stream.cpp:65
const ArchSpec & GetArchitecture() const
Definition Target.h:1067
void SetIsRegisterPlusOffset(uint32_t reg_num, int32_t offset)
Definition UnwindPlan.h:240
bool SetRegisterLocationToIsCFAPlusOffset(uint32_t reg_num, int32_t offset, bool can_replace)
void SetOffset(int64_t offset)
Definition UnwindPlan.h:361
bool SetRegisterLocationToAtCFAPlusOffset(uint32_t reg_num, int32_t offset, bool can_replace)
const FAValue & GetCFAValue() const
Definition UnwindPlan.h:365
void SetUnspecifiedRegistersAreUndefined(bool unspec_is_undef)
Definition UnwindPlan.h:408
Value * GetValueAtIndex(size_t idx)
Definition Value.cpp:698
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size, lldb::addr_t address=LLDB_INVALID_ADDRESS)
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, llvm::StringRef name, const Address &address, lldb::TypeSP &type_sp)
const Scalar & GetScalar() const
See comment on m_scalar to understand what GetScalar returns.
Definition Value.h:113
@ Scalar
A raw scalar value.
Definition Value.h:45
void SetCompilerType(const CompilerType &compiler_type)
Definition Value.cpp:276
void SetValueType(ValueType value_type)
Definition Value.h:89
const CompilerType & GetCompilerType()
Definition Value.cpp:247
#define LLDB_REGNUM_GENERIC_SP
#define LLDB_REGNUM_GENERIC_ARG4
#define LLDB_REGNUM_GENERIC_ARG3
#define LLDB_REGNUM_GENERIC_ARG1
#define LLDB_REGNUM_GENERIC_FLAGS
#define UINT32_MAX
#define LLDB_INVALID_REGNUM
#define LLDB_REGNUM_GENERIC_ARG2
#define LLDB_REGNUM_GENERIC_PC
#define LLDB_REGNUM_GENERIC_FP
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:332
std::shared_ptr< lldb_private::ABI > ABISP
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
uint64_t offset_t
Definition lldb-types.h:85
std::shared_ptr< lldb_private::Process > ProcessSP
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::UnwindPlan > UnwindPlanSP
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
@ eRegisterKindLLDB
lldb's internal register numbers
@ eRegisterKindDWARF
the register numbers seen DWARF
Every register is described in detail including its name, alternate name (optional),...
uint32_t kinds[lldb::kNumRegisterKinds]
Holds all of the various register numbers for all register kinds.
const char * name
Name of this register, can't be NULL.