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