1 //===-- ABIWindows_x86_64.cpp --------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "ABIWindows_x86_64.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/StringSwitch.h"
13 #include "llvm/ADT/Triple.h"
15 #include "lldb/Core/Module.h"
16 #include "lldb/Core/PluginManager.h"
17 #include "lldb/Core/Value.h"
18 #include "lldb/Core/ValueObjectConstResult.h"
19 #include "lldb/Core/ValueObjectMemory.h"
20 #include "lldb/Core/ValueObjectRegister.h"
21 #include "lldb/Symbol/UnwindPlan.h"
22 #include "lldb/Target/Process.h"
23 #include "lldb/Target/RegisterContext.h"
24 #include "lldb/Target/StackFrame.h"
25 #include "lldb/Target/Target.h"
26 #include "lldb/Target/Thread.h"
27 #include "lldb/Utility/ConstString.h"
28 #include "lldb/Utility/DataExtractor.h"
29 #include "lldb/Utility/Log.h"
30 #include "lldb/Utility/RegisterValue.h"
31 #include "lldb/Utility/Status.h"
34 using namespace lldb_private;
100 static RegisterInfo g_register_infos[] = {
101 // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
102 // DWARF GENERIC PROCESS PLUGIN
104 // ======== ======= == === ============= ===================
105 // ======================= =====================
106 // =========================== ===================== ======================
113 {dwarf_rax, dwarf_rax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
114 LLDB_INVALID_REGNUM},
125 {dwarf_rbx, dwarf_rbx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
126 LLDB_INVALID_REGNUM},
137 {dwarf_rcx, dwarf_rcx, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
138 LLDB_INVALID_REGNUM},
149 {dwarf_rdx, dwarf_rdx, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
150 LLDB_INVALID_REGNUM},
161 {dwarf_rsi, dwarf_rsi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
162 LLDB_INVALID_REGNUM},
173 {dwarf_rdi, dwarf_rdi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
174 LLDB_INVALID_REGNUM},
185 {dwarf_rbp, dwarf_rbp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
186 LLDB_INVALID_REGNUM},
197 {dwarf_rsp, dwarf_rsp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
198 LLDB_INVALID_REGNUM},
209 {dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
210 LLDB_INVALID_REGNUM},
221 {dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
222 LLDB_INVALID_REGNUM},
233 {dwarf_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
234 LLDB_INVALID_REGNUM},
245 {dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
246 LLDB_INVALID_REGNUM},
257 {dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
258 LLDB_INVALID_REGNUM},
269 {dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
270 LLDB_INVALID_REGNUM},
281 {dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
282 LLDB_INVALID_REGNUM},
293 {dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
294 LLDB_INVALID_REGNUM},
305 {dwarf_rip, dwarf_rip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
306 LLDB_INVALID_REGNUM},
317 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS,
318 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
329 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
330 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
341 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
342 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
353 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
354 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
365 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
366 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
377 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
378 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
389 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
390 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
400 eFormatVectorOfUInt8,
401 {dwarf_stmm0, dwarf_stmm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
402 LLDB_INVALID_REGNUM},
412 eFormatVectorOfUInt8,
413 {dwarf_stmm1, dwarf_stmm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
414 LLDB_INVALID_REGNUM},
424 eFormatVectorOfUInt8,
425 {dwarf_stmm2, dwarf_stmm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
426 LLDB_INVALID_REGNUM},
436 eFormatVectorOfUInt8,
437 {dwarf_stmm3, dwarf_stmm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
438 LLDB_INVALID_REGNUM},
448 eFormatVectorOfUInt8,
449 {dwarf_stmm4, dwarf_stmm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
450 LLDB_INVALID_REGNUM},
460 eFormatVectorOfUInt8,
461 {dwarf_stmm5, dwarf_stmm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
462 LLDB_INVALID_REGNUM},
472 eFormatVectorOfUInt8,
473 {dwarf_stmm6, dwarf_stmm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
474 LLDB_INVALID_REGNUM},
484 eFormatVectorOfUInt8,
485 {dwarf_stmm7, dwarf_stmm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
486 LLDB_INVALID_REGNUM},
497 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
498 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
509 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
510 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
521 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
522 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
533 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
534 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
545 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
546 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
557 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
558 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
569 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
570 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
581 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
582 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
592 eFormatVectorOfUInt8,
593 {dwarf_xmm0, dwarf_xmm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
594 LLDB_INVALID_REGNUM},
604 eFormatVectorOfUInt8,
605 {dwarf_xmm1, dwarf_xmm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
606 LLDB_INVALID_REGNUM},
616 eFormatVectorOfUInt8,
617 {dwarf_xmm2, dwarf_xmm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
618 LLDB_INVALID_REGNUM},
628 eFormatVectorOfUInt8,
629 {dwarf_xmm3, dwarf_xmm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
630 LLDB_INVALID_REGNUM},
640 eFormatVectorOfUInt8,
641 {dwarf_xmm4, dwarf_xmm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
642 LLDB_INVALID_REGNUM},
652 eFormatVectorOfUInt8,
653 {dwarf_xmm5, dwarf_xmm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
654 LLDB_INVALID_REGNUM},
664 eFormatVectorOfUInt8,
665 {dwarf_xmm6, dwarf_xmm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
666 LLDB_INVALID_REGNUM},
676 eFormatVectorOfUInt8,
677 {dwarf_xmm7, dwarf_xmm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
678 LLDB_INVALID_REGNUM},
688 eFormatVectorOfUInt8,
689 {dwarf_xmm8, dwarf_xmm8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
690 LLDB_INVALID_REGNUM},
700 eFormatVectorOfUInt8,
701 {dwarf_xmm9, dwarf_xmm9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
702 LLDB_INVALID_REGNUM},
712 eFormatVectorOfUInt8,
713 {dwarf_xmm10, dwarf_xmm10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
714 LLDB_INVALID_REGNUM},
724 eFormatVectorOfUInt8,
725 {dwarf_xmm11, dwarf_xmm11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
726 LLDB_INVALID_REGNUM},
736 eFormatVectorOfUInt8,
737 {dwarf_xmm12, dwarf_xmm12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
738 LLDB_INVALID_REGNUM},
748 eFormatVectorOfUInt8,
749 {dwarf_xmm13, dwarf_xmm13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
750 LLDB_INVALID_REGNUM},
760 eFormatVectorOfUInt8,
761 {dwarf_xmm14, dwarf_xmm14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
762 LLDB_INVALID_REGNUM},
772 eFormatVectorOfUInt8,
773 {dwarf_xmm15, dwarf_xmm15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
774 LLDB_INVALID_REGNUM},
785 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
786 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
796 eFormatVectorOfUInt8,
797 {dwarf_ymm0, dwarf_ymm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
798 LLDB_INVALID_REGNUM},
808 eFormatVectorOfUInt8,
809 {dwarf_ymm1, dwarf_ymm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
810 LLDB_INVALID_REGNUM},
820 eFormatVectorOfUInt8,
821 {dwarf_ymm2, dwarf_ymm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
822 LLDB_INVALID_REGNUM},
832 eFormatVectorOfUInt8,
833 {dwarf_ymm3, dwarf_ymm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
834 LLDB_INVALID_REGNUM},
844 eFormatVectorOfUInt8,
845 {dwarf_ymm4, dwarf_ymm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
846 LLDB_INVALID_REGNUM},
856 eFormatVectorOfUInt8,
857 {dwarf_ymm5, dwarf_ymm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
858 LLDB_INVALID_REGNUM},
868 eFormatVectorOfUInt8,
869 {dwarf_ymm6, dwarf_ymm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
870 LLDB_INVALID_REGNUM},
880 eFormatVectorOfUInt8,
881 {dwarf_ymm7, dwarf_ymm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
882 LLDB_INVALID_REGNUM},
892 eFormatVectorOfUInt8,
893 {dwarf_ymm8, dwarf_ymm8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
894 LLDB_INVALID_REGNUM},
904 eFormatVectorOfUInt8,
905 {dwarf_ymm9, dwarf_ymm9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
906 LLDB_INVALID_REGNUM},
916 eFormatVectorOfUInt8,
917 {dwarf_ymm10, dwarf_ymm10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
918 LLDB_INVALID_REGNUM},
928 eFormatVectorOfUInt8,
929 {dwarf_ymm11, dwarf_ymm11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
930 LLDB_INVALID_REGNUM},
940 eFormatVectorOfUInt8,
941 {dwarf_ymm12, dwarf_ymm12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
942 LLDB_INVALID_REGNUM},
952 eFormatVectorOfUInt8,
953 {dwarf_ymm13, dwarf_ymm13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
954 LLDB_INVALID_REGNUM},
964 eFormatVectorOfUInt8,
965 {dwarf_ymm14, dwarf_ymm14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
966 LLDB_INVALID_REGNUM},
976 eFormatVectorOfUInt8,
977 {dwarf_ymm15, dwarf_ymm15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
978 LLDB_INVALID_REGNUM},
988 eFormatVectorOfUInt64,
989 {dwarf_bnd0, dwarf_bnd0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
990 LLDB_INVALID_REGNUM},
1000 eFormatVectorOfUInt64,
1001 {dwarf_bnd1, dwarf_bnd1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1002 LLDB_INVALID_REGNUM},
1012 eFormatVectorOfUInt64,
1013 {dwarf_bnd2, dwarf_bnd2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1014 LLDB_INVALID_REGNUM},
1024 eFormatVectorOfUInt64,
1025 {dwarf_bnd3, dwarf_bnd3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1026 LLDB_INVALID_REGNUM},
1036 eFormatVectorOfUInt8,
1037 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1038 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1048 eFormatVectorOfUInt8,
1049 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1050 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1056 static const uint32_t k_num_register_infos =
1057 llvm::array_lengthof(g_register_infos);
1058 static bool g_register_info_names_constified = false;
1060 const lldb_private::RegisterInfo *
1061 ABIWindows_x86_64::GetRegisterInfoArray(uint32_t &count) {
1062 // Make the C-string names and alt_names for the register infos into const
1063 // C-string values by having the ConstString unique the names in the global
1064 // constant C-string pool.
1065 if (!g_register_info_names_constified) {
1066 g_register_info_names_constified = true;
1067 for (uint32_t i = 0; i < k_num_register_infos; ++i) {
1068 if (g_register_infos[i].name)
1069 g_register_infos[i].name =
1070 ConstString(g_register_infos[i].name).GetCString();
1071 if (g_register_infos[i].alt_name)
1072 g_register_infos[i].alt_name =
1073 ConstString(g_register_infos[i].alt_name).GetCString();
1076 count = k_num_register_infos;
1077 return g_register_infos;
1080 bool ABIWindows_x86_64::GetPointerReturnRegister(const char *&name) {
1085 size_t ABIWindows_x86_64::GetRedZoneSize() const { return 0; }
1087 //------------------------------------------------------------------
1089 //------------------------------------------------------------------
1092 ABIWindows_x86_64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
1093 if (arch.GetTriple().getArch() == llvm::Triple::x86_64 &&
1094 arch.GetTriple().isOSWindows()) {
1096 new ABIWindows_x86_64(std::move(process_sp), MakeMCRegisterInfo(arch)));
1101 bool ABIWindows_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp,
1102 addr_t func_addr, addr_t return_addr,
1103 llvm::ArrayRef<addr_t> args) const {
1104 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1108 s.Printf("ABIWindows_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64
1109 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
1110 ", return_addr = 0x%" PRIx64,
1111 thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
1112 (uint64_t)return_addr);
1114 for (size_t i = 0; i < args.size(); ++i)
1115 s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1),
1118 log->PutString(s.GetString());
1121 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1125 const RegisterInfo *reg_info = nullptr;
1127 if (args.size() > 4) // Windows x64 only put first 4 arguments into registers
1130 for (size_t i = 0; i < args.size(); ++i) {
1131 reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
1132 LLDB_REGNUM_GENERIC_ARG1 + i);
1133 LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
1134 static_cast<uint64_t>(i + 1), args[i], reg_info->name);
1135 if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
1139 // First, align the SP
1141 LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
1142 (uint64_t)sp, (uint64_t)(sp & ~0xfull));
1144 sp &= ~(0xfull); // 16-byte alignment
1146 sp -= 8; // return address
1149 const RegisterInfo *pc_reg_info =
1150 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
1151 const RegisterInfo *sp_reg_info =
1152 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
1153 ProcessSP process_sp(thread.GetProcess());
1155 RegisterValue reg_value;
1157 "Pushing the return address onto the stack: 0x%" PRIx64
1159 (uint64_t)sp, (uint64_t)return_addr);
1161 // Save return address onto the stack
1162 if (!process_sp->WritePointerToMemory(sp, return_addr, error))
1165 // %rsp is set to the actual stack value.
1167 LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
1169 if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
1172 // %rip is set to the address of the called function.
1174 LLDB_LOGF(log, "Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
1176 if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
1182 static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,
1183 bool is_signed, Thread &thread,
1184 uint32_t *argument_register_ids,
1185 unsigned int ¤t_argument_register,
1186 addr_t ¤t_stack_argument) {
1188 return false; // Scalar can't hold large integer arguments
1190 if (current_argument_register < 4) { // Windows pass first 4 arguments to register
1191 scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
1192 argument_register_ids[current_argument_register], 0);
1193 current_argument_register++;
1195 scalar.SignExtend(bit_width);
1198 uint32_t byte_size = (bit_width + (CHAR_BIT - 1)) / CHAR_BIT;
1200 if (thread.GetProcess()->ReadScalarIntegerFromMemory(
1201 current_stack_argument, byte_size, is_signed, scalar, error)) {
1202 current_stack_argument += byte_size;
1208 bool ABIWindows_x86_64::GetArgumentValues(Thread &thread,
1209 ValueList &values) const {
1210 unsigned int num_values = values.GetSize();
1211 unsigned int value_index;
1213 // Extract the register context so we can read arguments from registers
1215 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1220 // Get the pointer to the first stack argument so we have a place to start
1221 // when reading data
1223 addr_t sp = reg_ctx->GetSP(0);
1228 addr_t current_stack_argument = sp + 8; // jump over return address
1230 uint32_t argument_register_ids[4];
1232 argument_register_ids[0] =
1233 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)
1234 ->kinds[eRegisterKindLLDB];
1235 argument_register_ids[1] =
1236 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)
1237 ->kinds[eRegisterKindLLDB];
1238 argument_register_ids[2] =
1239 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)
1240 ->kinds[eRegisterKindLLDB];
1241 argument_register_ids[3] =
1242 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)
1243 ->kinds[eRegisterKindLLDB];
1245 unsigned int current_argument_register = 0;
1247 for (value_index = 0; value_index < num_values; ++value_index) {
1248 Value *value = values.GetValueAtIndex(value_index);
1253 CompilerType compiler_type = value->GetCompilerType();
1254 llvm::Optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread);
1259 if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
1260 ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread,
1261 argument_register_ids, current_argument_register,
1262 current_stack_argument);
1263 } else if (compiler_type.IsPointerType()) {
1264 ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread,
1265 argument_register_ids, current_argument_register,
1266 current_stack_argument);
1273 Status ABIWindows_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
1274 lldb::ValueObjectSP &new_value_sp) {
1276 if (!new_value_sp) {
1277 error.SetErrorString("Empty value object for return value.");
1281 CompilerType compiler_type = new_value_sp->GetCompilerType();
1282 if (!compiler_type) {
1283 error.SetErrorString("Null clang type for return value.");
1287 Thread *thread = frame_sp->GetThread().get();
1293 RegisterContext *reg_ctx = thread->GetRegisterContext().get();
1295 bool set_it_simple = false;
1296 if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1297 compiler_type.IsPointerType()) {
1298 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("rax", 0);
1302 size_t num_bytes = new_value_sp->GetData(data, data_error);
1303 if (data_error.Fail()) {
1304 error.SetErrorStringWithFormat(
1305 "Couldn't convert return value to raw data: %s",
1306 data_error.AsCString());
1309 lldb::offset_t offset = 0;
1310 if (num_bytes <= 8) {
1311 uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
1313 if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value))
1314 set_it_simple = true;
1316 error.SetErrorString("We don't support returning longer than 64 bit "
1317 "integer values at present.");
1319 } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
1321 error.SetErrorString(
1322 "We don't support returning complex values at present");
1324 llvm::Optional<uint64_t> bit_width =
1325 compiler_type.GetBitSize(frame_sp.get());
1327 error.SetErrorString("can't get type size");
1330 if (*bit_width <= 64) {
1331 const RegisterInfo *xmm0_info =
1332 reg_ctx->GetRegisterInfoByName("xmm0", 0);
1333 RegisterValue xmm0_value;
1336 size_t num_bytes = new_value_sp->GetData(data, data_error);
1337 if (data_error.Fail()) {
1338 error.SetErrorStringWithFormat(
1339 "Couldn't convert return value to raw data: %s",
1340 data_error.AsCString());
1344 unsigned char buffer[16];
1345 ByteOrder byte_order = data.GetByteOrder();
1347 data.CopyByteOrderedData(0, num_bytes, buffer, 16, byte_order);
1348 xmm0_value.SetBytes(buffer, 16, byte_order);
1349 reg_ctx->WriteRegister(xmm0_info, xmm0_value);
1350 set_it_simple = true;
1352 // Windows doesn't support 80 bit FP
1353 error.SetErrorString(
1354 "Windows-x86_64 doesn't allow FP larger than 64 bits.");
1359 if (!set_it_simple) {
1360 // Okay we've got a structure or something that doesn't fit in a simple
1362 // TODO(wanyi): On Windows, if the return type is a struct:
1363 // 1) smaller that 64 bits and return by value -> RAX
1364 // 2) bigger than 64 bits, the caller will allocate memory for that struct
1365 // and pass the struct pointer in RCX then return the pointer in RAX
1366 error.SetErrorString("We only support setting simple integer and float "
1367 "return types at present.");
1373 ValueObjectSP ABIWindows_x86_64::GetReturnValueObjectSimple(
1374 Thread &thread, CompilerType &return_compiler_type) const {
1375 ValueObjectSP return_valobj_sp;
1378 if (!return_compiler_type)
1379 return return_valobj_sp;
1381 value.SetCompilerType(return_compiler_type);
1383 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1385 return return_valobj_sp;
1387 const uint32_t type_flags = return_compiler_type.GetTypeInfo();
1388 if (type_flags & eTypeIsScalar) {
1389 value.SetValueType(Value::eValueTypeScalar);
1391 bool success = false;
1392 if (type_flags & eTypeIsInteger) {
1393 // Extract the register context so we can read arguments from registers
1394 llvm::Optional<uint64_t> byte_size =
1395 return_compiler_type.GetByteSize(nullptr);
1397 return return_valobj_sp;
1398 uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
1399 reg_ctx->GetRegisterInfoByName("rax", 0), 0);
1400 const bool is_signed = (type_flags & eTypeIsSigned) != 0;
1401 switch (*byte_size) {
1405 case sizeof(uint64_t):
1407 value.GetScalar() = (int64_t)(raw_value);
1409 value.GetScalar() = (uint64_t)(raw_value);
1413 case sizeof(uint32_t):
1415 value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
1417 value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
1421 case sizeof(uint16_t):
1423 value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
1425 value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
1429 case sizeof(uint8_t):
1431 value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
1433 value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
1437 } else if (type_flags & eTypeIsFloat) {
1438 if (type_flags & eTypeIsComplex) {
1439 // Don't handle complex yet.
1441 llvm::Optional<uint64_t> byte_size =
1442 return_compiler_type.GetByteSize(nullptr);
1443 if (byte_size && *byte_size <= sizeof(long double)) {
1444 const RegisterInfo *xmm0_info =
1445 reg_ctx->GetRegisterInfoByName("xmm0", 0);
1446 RegisterValue xmm0_value;
1447 if (reg_ctx->ReadRegister(xmm0_info, xmm0_value)) {
1449 if (xmm0_value.GetData(data)) {
1450 lldb::offset_t offset = 0;
1451 if (*byte_size == sizeof(float)) {
1452 value.GetScalar() = (float)data.GetFloat(&offset);
1454 } else if (*byte_size == sizeof(double)) {
1455 // double and long double are the same on windows
1456 value.GetScalar() = (double)data.GetDouble(&offset);
1466 return_valobj_sp = ValueObjectConstResult::Create(
1467 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
1468 } else if ((type_flags & eTypeIsPointer) ||
1469 (type_flags & eTypeInstanceIsPointer)) {
1471 reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
1473 (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
1475 value.SetValueType(Value::eValueTypeScalar);
1476 return_valobj_sp = ValueObjectConstResult::Create(
1477 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
1478 } else if (type_flags & eTypeIsVector) {
1479 llvm::Optional<uint64_t> byte_size =
1480 return_compiler_type.GetByteSize(nullptr);
1481 if (byte_size && *byte_size > 0) {
1482 const RegisterInfo *xmm_reg =
1483 reg_ctx->GetRegisterInfoByName("xmm0", 0);
1484 if (xmm_reg == nullptr)
1485 xmm_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
1488 if (*byte_size <= xmm_reg->byte_size) {
1489 ProcessSP process_sp(thread.GetProcess());
1491 std::unique_ptr<DataBufferHeap> heap_data_up(
1492 new DataBufferHeap(*byte_size, 0));
1493 const ByteOrder byte_order = process_sp->GetByteOrder();
1494 RegisterValue reg_value;
1495 if (reg_ctx->ReadRegister(xmm_reg, reg_value)) {
1497 if (reg_value.GetAsMemoryData(
1498 xmm_reg, heap_data_up->GetBytes(),
1499 heap_data_up->GetByteSize(), byte_order, error)) {
1500 DataExtractor data(DataBufferSP(heap_data_up.release()),
1502 process_sp->GetTarget()
1504 .GetAddressByteSize());
1505 return_valobj_sp = ValueObjectConstResult::Create(
1506 &thread, return_compiler_type, ConstString(""), data);
1515 return return_valobj_sp;
1518 // The compiler will flatten the nested aggregate type into single
1519 // layer and push the value to stack
1520 // This helper function will flatten an aggregate type
1521 // and return true if it can be returned in register(s) by value
1522 // return false if the aggregate is in memory
1523 static bool FlattenAggregateType(
1524 Thread &thread, ExecutionContext &exe_ctx,
1525 CompilerType &return_compiler_type,
1526 uint32_t data_byte_offset,
1527 std::vector<uint32_t> &aggregate_field_offsets,
1528 std::vector<CompilerType> &aggregate_compiler_types) {
1530 const uint32_t num_children = return_compiler_type.GetNumFields();
1531 for (uint32_t idx = 0; idx < num_children; ++idx) {
1537 uint64_t field_bit_offset = 0;
1538 CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(
1539 idx, name, &field_bit_offset, nullptr, nullptr);
1540 llvm::Optional<uint64_t> field_bit_width =
1541 field_compiler_type.GetBitSize(&thread);
1543 // if we don't know the size of the field (e.g. invalid type), exit
1544 if (!field_bit_width || *field_bit_width == 0) {
1547 // If there are any unaligned fields, this is stored in memory.
1548 if (field_bit_offset % *field_bit_width != 0) {
1552 // add overall offset
1553 uint32_t field_byte_offset = field_bit_offset / 8 + data_byte_offset;
1555 const uint32_t field_type_flags = field_compiler_type.GetTypeInfo();
1556 if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1557 field_compiler_type.IsPointerType() ||
1558 field_compiler_type.IsFloatingPointType(count, is_complex)) {
1559 aggregate_field_offsets.push_back(field_byte_offset);
1560 aggregate_compiler_types.push_back(field_compiler_type);
1561 } else if (field_type_flags & eTypeHasChildren) {
1562 if (!FlattenAggregateType(thread, exe_ctx, field_compiler_type,
1563 field_byte_offset, aggregate_field_offsets,
1564 aggregate_compiler_types)) {
1572 ValueObjectSP ABIWindows_x86_64::GetReturnValueObjectImpl(
1573 Thread &thread, CompilerType &return_compiler_type) const {
1574 ValueObjectSP return_valobj_sp;
1576 if (!return_compiler_type) {
1577 return return_valobj_sp;
1580 // try extract value as if it's a simple type
1581 return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
1582 if (return_valobj_sp) {
1583 return return_valobj_sp;
1586 RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
1588 return return_valobj_sp;
1591 llvm::Optional<uint64_t> bit_width = return_compiler_type.GetBitSize(&thread);
1593 return return_valobj_sp;
1596 // if it's not simple or aggregate type, then we don't know how to handle it
1597 if (!return_compiler_type.IsAggregateType()) {
1598 return return_valobj_sp;
1601 ExecutionContext exe_ctx(thread.shared_from_this());
1602 Target *target = exe_ctx.GetTargetPtr();
1603 uint32_t max_register_value_bit_width = 64;
1605 // The scenario here is to have a struct/class which is POD
1606 // if the return struct/class size is larger than 64 bits,
1607 // the caller will allocate memory for it and pass the return addr in RCX
1608 // then return the address in RAX
1610 // if the struct is returned by value in register (RAX)
1611 // its size has to be: 1, 2, 4, 8, 16, 32, or 64 bits (aligned)
1612 // for floating point, the return value will be copied over to RAX
1613 bool is_memory = *bit_width > max_register_value_bit_width ||
1614 *bit_width & (*bit_width - 1);
1615 std::vector<uint32_t> aggregate_field_offsets;
1616 std::vector<CompilerType> aggregate_compiler_types;
1618 FlattenAggregateType(thread, exe_ctx, return_compiler_type,
1619 0, aggregate_field_offsets,
1620 aggregate_compiler_types)) {
1621 ByteOrder byte_order = target->GetArchitecture().GetByteOrder();
1622 DataBufferSP data_sp(
1623 new DataBufferHeap(max_register_value_bit_width / 8, 0));
1624 DataExtractor return_ext(data_sp, byte_order,
1625 target->GetArchitecture().GetAddressByteSize());
1627 // The only register used to return struct/class by value
1628 const RegisterInfo *rax_info =
1629 reg_ctx_sp->GetRegisterInfoByName("rax", 0);
1630 RegisterValue rax_value;
1631 reg_ctx_sp->ReadRegister(rax_info, rax_value);
1632 DataExtractor rax_data;
1633 rax_value.GetData(rax_data);
1635 uint32_t used_bytes =
1636 0; // Tracks how much of the rax registers we've consumed so far
1638 // in case of the returned type is a subclass of non-abstract-base class
1639 // it will have a padding to skip the base content
1640 if (aggregate_field_offsets.size())
1641 used_bytes = aggregate_field_offsets[0];
1643 const uint32_t num_children = aggregate_compiler_types.size();
1644 for (uint32_t idx = 0; idx < num_children; idx++) {
1649 CompilerType field_compiler_type = aggregate_compiler_types[idx];
1650 uint32_t field_byte_width = (uint32_t) (*field_compiler_type.GetByteSize(&thread));
1651 uint32_t field_byte_offset = aggregate_field_offsets[idx];
1653 // this is unlikely w/o the overall size being greater than 8 bytes
1654 // For now, return a nullptr return value object.
1655 if (used_bytes >= 8 || used_bytes + field_byte_width > 8) {
1656 return return_valobj_sp;
1659 DataExtractor *copy_from_extractor = nullptr;
1660 uint32_t copy_from_offset = 0;
1661 if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1662 field_compiler_type.IsPointerType() ||
1663 field_compiler_type.IsFloatingPointType(count, is_complex)) {
1664 copy_from_extractor = &rax_data;
1665 copy_from_offset = used_bytes;
1666 used_bytes += field_byte_width;
1668 // These two tests are just sanity checks. If I somehow get the type
1669 // calculation wrong above it is better to just return nothing than to
1671 if (!copy_from_extractor) {
1672 return return_valobj_sp;
1674 if (copy_from_offset + field_byte_width >
1675 copy_from_extractor->GetByteSize()) {
1676 return return_valobj_sp;
1678 copy_from_extractor->CopyByteOrderedData(copy_from_offset,
1679 field_byte_width, data_sp->GetBytes() + field_byte_offset,
1680 field_byte_width, byte_order);
1683 // The result is in our data buffer. Let's make a variable object out
1685 return_valobj_sp = ValueObjectConstResult::Create(
1686 &thread, return_compiler_type, ConstString(""), return_ext);
1690 // The Windows x86_64 ABI specifies that the return address for MEMORY
1691 // objects be placed in rax on exit from the function.
1693 // FIXME: This is just taking a guess, rax may very well no longer hold the
1694 // return storage location.
1695 // If we are going to do this right, when we make a new frame we should
1696 // check to see if it uses a memory return, and if we are at the first
1697 // instruction and if so stash away the return location. Then we would
1698 // only return the memory return value if we know it is valid.
1701 reg_ctx_sp->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
1702 lldb::addr_t storage_addr =
1703 (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
1705 return_valobj_sp = ValueObjectMemory::Create(
1706 &thread, "", Address(storage_addr, nullptr), return_compiler_type);
1708 return return_valobj_sp;
1711 // This defines the CFA as rsp+8
1712 // the saved pc is at CFA-8 (i.e. rsp+0)
1713 // The saved rsp is CFA+0
1715 bool ABIWindows_x86_64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
1716 unwind_plan.Clear();
1717 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1719 uint32_t sp_reg_num = dwarf_rsp;
1720 uint32_t pc_reg_num = dwarf_rip;
1722 UnwindPlan::RowSP row(new UnwindPlan::Row);
1723 row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 8);
1724 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
1725 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1726 unwind_plan.AppendRow(row);
1727 unwind_plan.SetSourceName("x86_64 at-func-entry default");
1728 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1732 // Windows-x86_64 doesn't use %rbp
1733 // No available Unwind information for Windows-x86_64 (section .pdata)
1734 // Let's use SysV-x86_64 one for now
1735 bool ABIWindows_x86_64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
1736 unwind_plan.Clear();
1737 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1739 uint32_t fp_reg_num = dwarf_rbp;
1740 uint32_t sp_reg_num = dwarf_rsp;
1741 uint32_t pc_reg_num = dwarf_rip;
1743 UnwindPlan::RowSP row(new UnwindPlan::Row);
1745 const int32_t ptr_size = 8;
1746 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp, 2 * ptr_size);
1749 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
1750 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
1751 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1753 unwind_plan.AppendRow(row);
1754 unwind_plan.SetSourceName("x86_64 default unwind plan");
1755 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1756 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1761 bool ABIWindows_x86_64::RegisterIsVolatile(const RegisterInfo *reg_info) {
1762 return !RegisterIsCalleeSaved(reg_info);
1765 bool ABIWindows_x86_64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
1768 assert(reg_info->name != nullptr && "unnamed register?");
1769 std::string Name = std::string(reg_info->name);
1770 bool IsCalleeSaved =
1771 llvm::StringSwitch<bool>(Name)
1772 .Cases("rbx", "ebx", "rbp", "ebp", "rdi", "edi", "rsi", "esi", true)
1773 .Cases("rsp", "esp", "r12", "r13", "r14", "r15", "sp", "fp", true)
1774 .Cases("xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12",
1775 "xmm13", "xmm14", "xmm15", true)
1777 return IsCalleeSaved;
1780 void ABIWindows_x86_64::Initialize() {
1781 PluginManager::RegisterPlugin(
1782 GetPluginNameStatic(), "Windows ABI for x86_64 targets", CreateInstance);
1785 void ABIWindows_x86_64::Terminate() {
1786 PluginManager::UnregisterPlugin(CreateInstance);
1789 lldb_private::ConstString ABIWindows_x86_64::GetPluginNameStatic() {
1790 static ConstString g_name("windows-x86_64");
1794 //------------------------------------------------------------------
1795 // PluginInterface protocol
1796 //------------------------------------------------------------------
1798 lldb_private::ConstString ABIWindows_x86_64::GetPluginName() {
1799 return GetPluginNameStatic();
1802 uint32_t ABIWindows_x86_64::GetPluginVersion() { return 1; }