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
316 RegisterContext *reg_ctx = thread->GetRegisterContext().get();
317
318 bool set_it_simple = false;
319 if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
320 compiler_type.IsPointerType()) {
321 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("rax", 0);
322
323 DataExtractor data;
324 Status data_error;
325 size_t num_bytes = new_value_sp->GetData(data, data_error);
326 if (data_error.Fail()) {
328 "Couldn't convert return value to raw data: %s",
329 data_error.AsCString());
330 return error;
331 }
332 lldb::offset_t offset = 0;
333 if (num_bytes <= 8) {
334 uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
335
336 if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value))
337 set_it_simple = true;
338 } else {
340 "We don't support returning longer than 64 bit "
341 "integer values at present.");
342 }
343 } else if (compiler_type.IsRealFloatingPointType()) {
344 std::optional<uint64_t> bit_width =
345 llvm::expectedToOptional(compiler_type.GetBitSize(frame_sp.get()));
346 if (!bit_width) {
347 error = Status::FromErrorString("can't get type size");
348 return error;
349 }
350 if (*bit_width <= 64) {
351 const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
352 RegisterValue xmm0_value;
353 DataExtractor data;
354 Status data_error;
355 size_t num_bytes = new_value_sp->GetData(data, data_error);
356 if (data_error.Fail()) {
358 "Couldn't convert return value to raw data: %s",
359 data_error.AsCString());
360 return error;
361 }
362
363 unsigned char buffer[16];
364 ByteOrder byte_order = data.GetByteOrder();
365
366 data.CopyByteOrderedData(0, num_bytes, buffer, 16, byte_order);
367 xmm0_value.SetBytes(buffer, 16, byte_order);
368 reg_ctx->WriteRegister(xmm0_info, xmm0_value);
369 set_it_simple = true;
370 } else {
371 // Windows doesn't support 80 bit FP
373 "Windows-x86_64 doesn't allow FP larger than 64 bits.");
374 }
375 }
376
377 if (!set_it_simple) {
378 // Okay we've got a structure or something that doesn't fit in a simple
379 // register.
380 // TODO(wanyi): On Windows, if the return type is a struct:
381 // 1) smaller that 64 bits and return by value -> RAX
382 // 2) bigger than 64 bits, the caller will allocate memory for that struct
383 // and pass the struct pointer in RCX then return the pointer in RAX
385 "We only support setting simple integer and float "
386 "return types at present.");
387 }
388
389 return error;
390}
391
393 Thread &thread, CompilerType &return_compiler_type) const {
394 ValueObjectSP return_valobj_sp;
395 Value value;
396
397 if (!return_compiler_type)
398 return return_valobj_sp;
399
400 value.SetCompilerType(return_compiler_type);
401
402 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
403 if (!reg_ctx)
404 return return_valobj_sp;
405
406 const uint32_t type_flags = return_compiler_type.GetTypeInfo();
407 if (type_flags & eTypeIsScalar) {
409
410 bool success = false;
411 if (type_flags & eTypeIsInteger) {
412 // Extract the register context so we can read arguments from registers
413 std::optional<uint64_t> byte_size =
414 llvm::expectedToOptional(return_compiler_type.GetByteSize(&thread));
415 if (!byte_size)
416 return return_valobj_sp;
417 uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
418 reg_ctx->GetRegisterInfoByName("rax", 0), 0);
419 const bool is_signed = (type_flags & eTypeIsSigned) != 0;
420 switch (*byte_size) {
421 default:
422 break;
423
424 case sizeof(uint64_t):
425 if (is_signed)
426 value.GetScalar() = (int64_t)(raw_value);
427 else
428 value.GetScalar() = (uint64_t)(raw_value);
429 success = true;
430 break;
431
432 case sizeof(uint32_t):
433 if (is_signed)
434 value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
435 else
436 value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
437 success = true;
438 break;
439
440 case sizeof(uint16_t):
441 if (is_signed)
442 value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
443 else
444 value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
445 success = true;
446 break;
447
448 case sizeof(uint8_t):
449 if (is_signed)
450 value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
451 else
452 value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
453 success = true;
454 break;
455 }
456 } else if (type_flags & eTypeIsFloat) {
457 if (type_flags & eTypeIsComplex) {
458 // Don't handle complex yet.
459 } else {
460 std::optional<uint64_t> byte_size =
461 llvm::expectedToOptional(return_compiler_type.GetByteSize(&thread));
462 if (byte_size && *byte_size <= sizeof(long double)) {
463 const RegisterInfo *xmm0_info =
464 reg_ctx->GetRegisterInfoByName("xmm0", 0);
465 RegisterValue xmm0_value;
466 if (reg_ctx->ReadRegister(xmm0_info, xmm0_value)) {
467 DataExtractor data;
468 if (xmm0_value.GetData(data)) {
469 lldb::offset_t offset = 0;
470 if (*byte_size == sizeof(float)) {
471 value.GetScalar() = (float)data.GetFloat(&offset);
472 success = true;
473 } else if (*byte_size == sizeof(double)) {
474 // double and long double are the same on windows
475 value.GetScalar() = (double)data.GetDouble(&offset);
476 success = true;
477 }
478 }
479 }
480 }
481 }
482 }
483
484 if (success)
485 return_valobj_sp = ValueObjectConstResult::Create(
486 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
487 } else if ((type_flags & eTypeIsPointer) ||
488 (type_flags & eTypeInstanceIsPointer)) {
489 unsigned rax_id =
490 reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
491 value.GetScalar() =
492 (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
493 0);
495 return_valobj_sp = ValueObjectConstResult::Create(
496 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
497 } else if (type_flags & eTypeIsVector) {
498 std::optional<uint64_t> byte_size =
499 llvm::expectedToOptional(return_compiler_type.GetByteSize(&thread));
500 if (byte_size && *byte_size > 0) {
501 const RegisterInfo *xmm_reg =
502 reg_ctx->GetRegisterInfoByName("xmm0", 0);
503 if (xmm_reg == nullptr)
504 xmm_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
505
506 if (xmm_reg) {
507 if (*byte_size <= xmm_reg->byte_size) {
508 ProcessSP process_sp(thread.GetProcess());
509 if (process_sp) {
510 std::unique_ptr<DataBufferHeap> heap_data_up(
511 new DataBufferHeap(*byte_size, 0));
512 const ByteOrder byte_order = process_sp->GetByteOrder();
513 RegisterValue reg_value;
514 if (reg_ctx->ReadRegister(xmm_reg, reg_value)) {
516 if (reg_value.GetAsMemoryData(*xmm_reg, heap_data_up->GetBytes(),
517 heap_data_up->GetByteSize(),
518 byte_order, error)) {
519 DataExtractor data(DataBufferSP(heap_data_up.release()),
520 byte_order,
521 process_sp->GetTarget()
522 .GetArchitecture()
523 .GetAddressByteSize());
524 return_valobj_sp = ValueObjectConstResult::Create(
525 &thread, return_compiler_type, ConstString(""), data);
526 }
527 }
528 }
529 }
530 }
531 }
532 }
533
534 return return_valobj_sp;
535}
536
537// The compiler will flatten the nested aggregate type into single
538// layer and push the value to stack
539// This helper function will flatten an aggregate type
540// and return true if it can be returned in register(s) by value
541// return false if the aggregate is in memory
543 Thread &thread, ExecutionContext &exe_ctx,
544 CompilerType &return_compiler_type,
545 uint32_t data_byte_offset,
546 std::vector<uint32_t> &aggregate_field_offsets,
547 std::vector<CompilerType> &aggregate_compiler_types) {
548
549 const uint32_t num_children = return_compiler_type.GetNumFields();
550 for (uint32_t idx = 0; idx < num_children; ++idx) {
551 std::string name;
552 bool is_signed;
553
554 uint64_t field_bit_offset = 0;
555 CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(
556 idx, name, &field_bit_offset, nullptr, nullptr);
557 std::optional<uint64_t> field_bit_width =
558 llvm::expectedToOptional(field_compiler_type.GetBitSize(&thread));
559
560 // if we don't know the size of the field (e.g. invalid type), exit
561 if (!field_bit_width || *field_bit_width == 0) {
562 return false;
563 }
564 // If there are any unaligned fields, this is stored in memory.
565 if (field_bit_offset % *field_bit_width != 0) {
566 return false;
567 }
568
569 // add overall offset
570 uint32_t field_byte_offset = field_bit_offset / 8 + data_byte_offset;
571
572 const uint32_t field_type_flags = field_compiler_type.GetTypeInfo();
573 if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
574 field_compiler_type.IsPointerType() ||
575 // FIXME: is this correct for complex floats or float vector types?
576 field_type_flags & eTypeIsFloat) {
577 aggregate_field_offsets.push_back(field_byte_offset);
578 aggregate_compiler_types.push_back(field_compiler_type);
579 } else if (field_type_flags & eTypeHasChildren) {
580 if (!FlattenAggregateType(thread, exe_ctx, field_compiler_type,
581 field_byte_offset, aggregate_field_offsets,
582 aggregate_compiler_types)) {
583 return false;
584 }
585 }
586 }
587 return true;
588}
589
591 Thread &thread, CompilerType &return_compiler_type) const {
592 ValueObjectSP return_valobj_sp;
593
594 if (!return_compiler_type) {
595 return return_valobj_sp;
596 }
597
598 // try extract value as if it's a simple type
599 return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
600 if (return_valobj_sp) {
601 return return_valobj_sp;
602 }
603
604 RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
605 if (!reg_ctx_sp) {
606 return return_valobj_sp;
607 }
608
609 std::optional<uint64_t> bit_width =
610 llvm::expectedToOptional(return_compiler_type.GetBitSize(&thread));
611 if (!bit_width) {
612 return return_valobj_sp;
613 }
614
615 // if it's not simple or aggregate type, then we don't know how to handle it
616 if (!return_compiler_type.IsAggregateType()) {
617 return return_valobj_sp;
618 }
619
620 ExecutionContext exe_ctx(thread.shared_from_this());
621 Target *target = exe_ctx.GetTargetPtr();
622 uint32_t max_register_value_bit_width = 64;
623
624 // The scenario here is to have a struct/class which is POD
625 // if the return struct/class size is larger than 64 bits,
626 // the caller will allocate memory for it and pass the return addr in RCX
627 // then return the address in RAX
628
629 // if the struct is returned by value in register (RAX)
630 // its size has to be: 1, 2, 4, 8, 16, 32, or 64 bits (aligned)
631 // for floating point, the return value will be copied over to RAX
632 bool is_memory = *bit_width > max_register_value_bit_width ||
633 *bit_width & (*bit_width - 1);
634 std::vector<uint32_t> aggregate_field_offsets;
635 std::vector<CompilerType> aggregate_compiler_types;
636 if (!is_memory &&
637 FlattenAggregateType(thread, exe_ctx, return_compiler_type,
638 0, aggregate_field_offsets,
639 aggregate_compiler_types)) {
640 ByteOrder byte_order = target->GetArchitecture().GetByteOrder();
641 WritableDataBufferSP data_sp(
642 new DataBufferHeap(max_register_value_bit_width / 8, 0));
643 DataExtractor return_ext(data_sp, byte_order,
645
646 // The only register used to return struct/class by value
647 const RegisterInfo *rax_info =
648 reg_ctx_sp->GetRegisterInfoByName("rax", 0);
649 RegisterValue rax_value;
650 reg_ctx_sp->ReadRegister(rax_info, rax_value);
651 DataExtractor rax_data;
652 rax_value.GetData(rax_data);
653
654 uint32_t used_bytes =
655 0; // Tracks how much of the rax registers we've consumed so far
656
657 // in case of the returned type is a subclass of non-abstract-base class
658 // it will have a padding to skip the base content
659 if (aggregate_field_offsets.size())
660 used_bytes = aggregate_field_offsets[0];
661
662 const uint32_t num_children = aggregate_compiler_types.size();
663 for (uint32_t idx = 0; idx < num_children; idx++) {
664 bool is_signed;
665
666 CompilerType field_compiler_type = aggregate_compiler_types[idx];
667 uint32_t field_byte_width =
668 (uint32_t)(llvm::expectedToOptional(
669 field_compiler_type.GetByteSize(&thread))
670 .value_or(0));
671 uint32_t field_byte_offset = aggregate_field_offsets[idx];
672
673 // this is unlikely w/o the overall size being greater than 8 bytes
674 // For now, return a nullptr return value object.
675 if (used_bytes >= 8 || used_bytes + field_byte_width > 8) {
676 return return_valobj_sp;
677 }
678
679 DataExtractor *copy_from_extractor = nullptr;
680 uint32_t copy_from_offset = 0;
681 if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
682 field_compiler_type.IsPointerType() ||
683 // FIXME: is this correct for complex floats or float vector types?
684 field_compiler_type.GetTypeInfo() & eTypeIsFloat) {
685 copy_from_extractor = &rax_data;
686 copy_from_offset = used_bytes;
687 used_bytes += field_byte_width;
688 }
689 // These two tests are just sanity checks. If I somehow get the type
690 // calculation wrong above it is better to just return nothing than to
691 // assert or crash.
692 if (!copy_from_extractor) {
693 return return_valobj_sp;
694 }
695 if (copy_from_offset + field_byte_width >
696 copy_from_extractor->GetByteSize()) {
697 return return_valobj_sp;
698 }
699 copy_from_extractor->CopyByteOrderedData(copy_from_offset,
700 field_byte_width, data_sp->GetBytes() + field_byte_offset,
701 field_byte_width, byte_order);
702 }
703 if (!is_memory) {
704 // The result is in our data buffer. Let's make a variable object out
705 // of it:
706 return_valobj_sp = ValueObjectConstResult::Create(
707 &thread, return_compiler_type, ConstString(""), return_ext);
708 }
709 }
710
711 // The Windows x86_64 ABI specifies that the return address for MEMORY
712 // objects be placed in rax on exit from the function.
713
714 // FIXME: This is just taking a guess, rax may very well no longer hold the
715 // return storage location.
716 // If we are going to do this right, when we make a new frame we should
717 // check to see if it uses a memory return, and if we are at the first
718 // instruction and if so stash away the return location. Then we would
719 // only return the memory return value if we know it is valid.
720 if (is_memory) {
721 unsigned rax_id =
722 reg_ctx_sp->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
723 lldb::addr_t storage_addr =
724 (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
725 0);
726 return_valobj_sp = ValueObjectMemory::Create(
727 &thread, "", Address(storage_addr, nullptr), return_compiler_type);
728 }
729 return return_valobj_sp;
730}
731
732// This defines the CFA as rsp+8
733// the saved pc is at CFA-8 (i.e. rsp+0)
734// The saved rsp is CFA+0
735
737 uint32_t sp_reg_num = dwarf_rsp;
738 uint32_t pc_reg_num = dwarf_rip;
739
740 UnwindPlan::Row row;
741 row.GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 8);
742 row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
743 row.SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
744
745 auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
746 plan_sp->AppendRow(std::move(row));
747 plan_sp->SetSourceName("x86_64 at-func-entry default");
748 plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
749 return plan_sp;
750}
751
752// Windows-x86_64 doesn't use %rbp
753// No available Unwind information for Windows-x86_64 (section .pdata)
754// Let's use SysV-x86_64 one for now
756 uint32_t fp_reg_num = dwarf_rbp;
757 uint32_t sp_reg_num = dwarf_rsp;
758 uint32_t pc_reg_num = dwarf_rip;
759
760 UnwindPlan::Row row;
761
762 const int32_t ptr_size = 8;
763 row.GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp, 2 * ptr_size);
764 row.SetOffset(0);
766
767 row.SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
768 row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
769 row.SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
770
771 auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
772 plan_sp->AppendRow(std::move(row));
773 plan_sp->SetSourceName("x86_64 default unwind plan");
774 plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
775 plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
776 return plan_sp;
777}
778
780 return !RegisterIsCalleeSaved(reg_info);
781}
782
784 if (!reg_info)
785 return false;
786 assert(reg_info->name != nullptr && "unnamed register?");
787 std::string Name = std::string(reg_info->name);
788 bool IsCalleeSaved =
789 llvm::StringSwitch<bool>(Name)
790 .Cases({"rbx", "ebx", "rbp", "ebp", "rdi", "edi", "rsi", "esi"}, true)
791 .Cases({"rsp", "esp", "r12", "r13", "r14", "r15", "sp", "fp"}, true)
792 .Cases({"xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12",
793 "xmm13", "xmm14", "xmm15"},
794 true)
795 .Default(false);
796 return IsCalleeSaved;
797}
798
799uint32_t ABIWindows_x86_64::GetGenericNum(llvm::StringRef reg) {
800 return llvm::StringSwitch<uint32_t>(reg)
801 .Case("rip", LLDB_REGNUM_GENERIC_PC)
802 .Case("rsp", LLDB_REGNUM_GENERIC_SP)
803 .Case("rbp", LLDB_REGNUM_GENERIC_FP)
804 .Case("rflags", LLDB_REGNUM_GENERIC_FLAGS)
805 // gdbserver uses eflags
806 .Case("eflags", LLDB_REGNUM_GENERIC_FLAGS)
807 .Case("rcx", LLDB_REGNUM_GENERIC_ARG1)
808 .Case("rdx", LLDB_REGNUM_GENERIC_ARG2)
809 .Case("r8", LLDB_REGNUM_GENERIC_ARG3)
810 .Case("r9", LLDB_REGNUM_GENERIC_ARG4)
811 .Default(LLDB_INVALID_REGNUM);
812}
813
816 GetPluginNameStatic(), "Windows ABI for x86_64 targets", CreateInstance);
817}
818
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:225
A section + offset based address class.
Definition Address.h:62
An architecture specification class.
Definition ArchSpec.h:32
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition ArchSpec.cpp:681
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition ArchSpec.h:457
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition ArchSpec.cpp:730
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
bool IsRealFloatingPointType() const
Returns true for non-complex float types.
llvm::Expected< uint64_t > GetBitSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bits.
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.
virtual 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:293
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition Status.cpp:194
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:1183
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.