1 //===-- ABISysV_x86_64.cpp --------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "ABISysV_x86_64.h"
14 // Other libraries and framework includes
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/Triple.h"
19 #include "lldb/Core/Module.h"
20 #include "lldb/Core/PluginManager.h"
21 #include "lldb/Core/RegisterValue.h"
22 #include "lldb/Core/Value.h"
23 #include "lldb/Core/ValueObjectConstResult.h"
24 #include "lldb/Core/ValueObjectMemory.h"
25 #include "lldb/Core/ValueObjectRegister.h"
26 #include "lldb/Symbol/UnwindPlan.h"
27 #include "lldb/Target/Process.h"
28 #include "lldb/Target/RegisterContext.h"
29 #include "lldb/Target/StackFrame.h"
30 #include "lldb/Target/Target.h"
31 #include "lldb/Target/Thread.h"
32 #include "lldb/Utility/ConstString.h"
33 #include "lldb/Utility/DataExtractor.h"
34 #include "lldb/Utility/Log.h"
35 #include "lldb/Utility/Status.h"
38 using namespace lldb_private;
104 static RegisterInfo g_register_infos[] = {
105 // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
106 // DWARF GENERIC PROCESS PLUGIN
108 // ======== ======= == === ============= ===================
109 // ======================= =====================
110 // =========================== ===================== ======================
117 {dwarf_rax, dwarf_rax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
118 LLDB_INVALID_REGNUM},
129 {dwarf_rbx, dwarf_rbx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
130 LLDB_INVALID_REGNUM},
141 {dwarf_rcx, dwarf_rcx, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
142 LLDB_INVALID_REGNUM},
153 {dwarf_rdx, dwarf_rdx, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
154 LLDB_INVALID_REGNUM},
165 {dwarf_rsi, dwarf_rsi, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
166 LLDB_INVALID_REGNUM},
177 {dwarf_rdi, dwarf_rdi, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
178 LLDB_INVALID_REGNUM},
189 {dwarf_rbp, dwarf_rbp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
190 LLDB_INVALID_REGNUM},
201 {dwarf_rsp, dwarf_rsp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
202 LLDB_INVALID_REGNUM},
213 {dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM,
214 LLDB_INVALID_REGNUM},
225 {dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM,
226 LLDB_INVALID_REGNUM},
237 {dwarf_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
238 LLDB_INVALID_REGNUM},
249 {dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
250 LLDB_INVALID_REGNUM},
261 {dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
262 LLDB_INVALID_REGNUM},
273 {dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
274 LLDB_INVALID_REGNUM},
285 {dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
286 LLDB_INVALID_REGNUM},
297 {dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
298 LLDB_INVALID_REGNUM},
309 {dwarf_rip, dwarf_rip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
310 LLDB_INVALID_REGNUM},
321 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS,
322 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
333 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
334 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
345 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
346 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
357 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
358 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
369 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
370 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
381 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
382 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
393 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
394 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
404 eFormatVectorOfUInt8,
405 {dwarf_stmm0, dwarf_stmm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
406 LLDB_INVALID_REGNUM},
416 eFormatVectorOfUInt8,
417 {dwarf_stmm1, dwarf_stmm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
418 LLDB_INVALID_REGNUM},
428 eFormatVectorOfUInt8,
429 {dwarf_stmm2, dwarf_stmm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
430 LLDB_INVALID_REGNUM},
440 eFormatVectorOfUInt8,
441 {dwarf_stmm3, dwarf_stmm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
442 LLDB_INVALID_REGNUM},
452 eFormatVectorOfUInt8,
453 {dwarf_stmm4, dwarf_stmm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
454 LLDB_INVALID_REGNUM},
464 eFormatVectorOfUInt8,
465 {dwarf_stmm5, dwarf_stmm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
466 LLDB_INVALID_REGNUM},
476 eFormatVectorOfUInt8,
477 {dwarf_stmm6, dwarf_stmm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
478 LLDB_INVALID_REGNUM},
488 eFormatVectorOfUInt8,
489 {dwarf_stmm7, dwarf_stmm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
490 LLDB_INVALID_REGNUM},
501 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
502 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
513 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
514 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
525 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
526 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
537 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
538 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
549 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
550 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
561 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
562 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
573 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
574 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
585 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
586 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
596 eFormatVectorOfUInt8,
597 {dwarf_xmm0, dwarf_xmm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
598 LLDB_INVALID_REGNUM},
608 eFormatVectorOfUInt8,
609 {dwarf_xmm1, dwarf_xmm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
610 LLDB_INVALID_REGNUM},
620 eFormatVectorOfUInt8,
621 {dwarf_xmm2, dwarf_xmm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
622 LLDB_INVALID_REGNUM},
632 eFormatVectorOfUInt8,
633 {dwarf_xmm3, dwarf_xmm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
634 LLDB_INVALID_REGNUM},
644 eFormatVectorOfUInt8,
645 {dwarf_xmm4, dwarf_xmm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
646 LLDB_INVALID_REGNUM},
656 eFormatVectorOfUInt8,
657 {dwarf_xmm5, dwarf_xmm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
658 LLDB_INVALID_REGNUM},
668 eFormatVectorOfUInt8,
669 {dwarf_xmm6, dwarf_xmm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
670 LLDB_INVALID_REGNUM},
680 eFormatVectorOfUInt8,
681 {dwarf_xmm7, dwarf_xmm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
682 LLDB_INVALID_REGNUM},
692 eFormatVectorOfUInt8,
693 {dwarf_xmm8, dwarf_xmm8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
694 LLDB_INVALID_REGNUM},
704 eFormatVectorOfUInt8,
705 {dwarf_xmm9, dwarf_xmm9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
706 LLDB_INVALID_REGNUM},
716 eFormatVectorOfUInt8,
717 {dwarf_xmm10, dwarf_xmm10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
718 LLDB_INVALID_REGNUM},
728 eFormatVectorOfUInt8,
729 {dwarf_xmm11, dwarf_xmm11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
730 LLDB_INVALID_REGNUM},
740 eFormatVectorOfUInt8,
741 {dwarf_xmm12, dwarf_xmm12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
742 LLDB_INVALID_REGNUM},
752 eFormatVectorOfUInt8,
753 {dwarf_xmm13, dwarf_xmm13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
754 LLDB_INVALID_REGNUM},
764 eFormatVectorOfUInt8,
765 {dwarf_xmm14, dwarf_xmm14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
766 LLDB_INVALID_REGNUM},
776 eFormatVectorOfUInt8,
777 {dwarf_xmm15, dwarf_xmm15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
778 LLDB_INVALID_REGNUM},
789 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
790 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
800 eFormatVectorOfUInt8,
801 {dwarf_ymm0, dwarf_ymm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
802 LLDB_INVALID_REGNUM},
812 eFormatVectorOfUInt8,
813 {dwarf_ymm1, dwarf_ymm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
814 LLDB_INVALID_REGNUM},
824 eFormatVectorOfUInt8,
825 {dwarf_ymm2, dwarf_ymm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
826 LLDB_INVALID_REGNUM},
836 eFormatVectorOfUInt8,
837 {dwarf_ymm3, dwarf_ymm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
838 LLDB_INVALID_REGNUM},
848 eFormatVectorOfUInt8,
849 {dwarf_ymm4, dwarf_ymm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
850 LLDB_INVALID_REGNUM},
860 eFormatVectorOfUInt8,
861 {dwarf_ymm5, dwarf_ymm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
862 LLDB_INVALID_REGNUM},
872 eFormatVectorOfUInt8,
873 {dwarf_ymm6, dwarf_ymm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
874 LLDB_INVALID_REGNUM},
884 eFormatVectorOfUInt8,
885 {dwarf_ymm7, dwarf_ymm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
886 LLDB_INVALID_REGNUM},
896 eFormatVectorOfUInt8,
897 {dwarf_ymm8, dwarf_ymm8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
898 LLDB_INVALID_REGNUM},
908 eFormatVectorOfUInt8,
909 {dwarf_ymm9, dwarf_ymm9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
910 LLDB_INVALID_REGNUM},
920 eFormatVectorOfUInt8,
921 {dwarf_ymm10, dwarf_ymm10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
922 LLDB_INVALID_REGNUM},
932 eFormatVectorOfUInt8,
933 {dwarf_ymm11, dwarf_ymm11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
934 LLDB_INVALID_REGNUM},
944 eFormatVectorOfUInt8,
945 {dwarf_ymm12, dwarf_ymm12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
946 LLDB_INVALID_REGNUM},
956 eFormatVectorOfUInt8,
957 {dwarf_ymm13, dwarf_ymm13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
958 LLDB_INVALID_REGNUM},
968 eFormatVectorOfUInt8,
969 {dwarf_ymm14, dwarf_ymm14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
970 LLDB_INVALID_REGNUM},
980 eFormatVectorOfUInt8,
981 {dwarf_ymm15, dwarf_ymm15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
982 LLDB_INVALID_REGNUM},
992 eFormatVectorOfUInt64,
993 {dwarf_bnd0, dwarf_bnd0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
994 LLDB_INVALID_REGNUM},
1004 eFormatVectorOfUInt64,
1005 {dwarf_bnd1, dwarf_bnd1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1006 LLDB_INVALID_REGNUM},
1016 eFormatVectorOfUInt64,
1017 {dwarf_bnd2, dwarf_bnd2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1018 LLDB_INVALID_REGNUM},
1028 eFormatVectorOfUInt64,
1029 {dwarf_bnd3, dwarf_bnd3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1030 LLDB_INVALID_REGNUM},
1040 eFormatVectorOfUInt8,
1041 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1042 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1052 eFormatVectorOfUInt8,
1053 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1054 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1060 static const uint32_t k_num_register_infos =
1061 llvm::array_lengthof(g_register_infos);
1062 static bool g_register_info_names_constified = false;
1064 const lldb_private::RegisterInfo *
1065 ABISysV_x86_64::GetRegisterInfoArray(uint32_t &count) {
1066 // Make the C-string names and alt_names for the register infos into const
1067 // C-string values by having the ConstString unique the names in the global
1068 // constant C-string pool.
1069 if (!g_register_info_names_constified) {
1070 g_register_info_names_constified = true;
1071 for (uint32_t i = 0; i < k_num_register_infos; ++i) {
1072 if (g_register_infos[i].name)
1073 g_register_infos[i].name =
1074 ConstString(g_register_infos[i].name).GetCString();
1075 if (g_register_infos[i].alt_name)
1076 g_register_infos[i].alt_name =
1077 ConstString(g_register_infos[i].alt_name).GetCString();
1080 count = k_num_register_infos;
1081 return g_register_infos;
1084 bool ABISysV_x86_64::GetPointerReturnRegister(const char *&name) {
1089 size_t ABISysV_x86_64::GetRedZoneSize() const { return 128; }
1091 //------------------------------------------------------------------
1093 //------------------------------------------------------------------
1096 ABISysV_x86_64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
1097 static ABISP g_abi_sp;
1098 if (arch.GetTriple().getArch() == llvm::Triple::x86_64) {
1100 g_abi_sp.reset(new ABISysV_x86_64(process_sp));
1106 bool ABISysV_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp,
1107 addr_t func_addr, addr_t return_addr,
1108 llvm::ArrayRef<addr_t> args) const {
1109 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1113 s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64
1114 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
1115 ", return_addr = 0x%" PRIx64,
1116 thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
1117 (uint64_t)return_addr);
1119 for (size_t i = 0; i < args.size(); ++i)
1120 s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1),
1123 log->PutString(s.GetString());
1126 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1130 const RegisterInfo *reg_info = nullptr;
1132 if (args.size() > 6) // TODO handle more than 6 arguments
1135 for (size_t i = 0; i < args.size(); ++i) {
1136 reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
1137 LLDB_REGNUM_GENERIC_ARG1 + i);
1139 log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
1140 static_cast<uint64_t>(i + 1), args[i], reg_info->name);
1141 if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
1145 // First, align the SP
1148 log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
1149 (uint64_t)sp, (uint64_t)(sp & ~0xfull));
1151 sp &= ~(0xfull); // 16-byte alignment
1156 const RegisterInfo *pc_reg_info =
1157 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
1158 const RegisterInfo *sp_reg_info =
1159 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
1160 ProcessSP process_sp(thread.GetProcess());
1162 RegisterValue reg_value;
1165 // This code adds an extra frame so that we don't lose the function that we came from
1166 // by pushing the PC and the FP and then writing the current FP to point to the FP value
1167 // we just pushed. It is disabled for now until the stack backtracing code can be debugged.
1170 const RegisterInfo *fp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
1171 if (reg_ctx->ReadRegister(pc_reg_info, reg_value))
1174 log->Printf("Pushing the current PC onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, reg_value.GetAsUInt64());
1176 if (!process_sp->WritePointerToMemory(sp, reg_value.GetAsUInt64(), error))
1182 if (reg_ctx->ReadRegister(fp_reg_info, reg_value))
1185 log->Printf("Pushing the current FP onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, reg_value.GetAsUInt64());
1187 if (!process_sp->WritePointerToMemory(sp, reg_value.GetAsUInt64(), error))
1190 // Setup FP backchain
1191 reg_value.SetUInt64 (sp);
1194 log->Printf("Writing FP: 0x%" PRIx64 " (for FP backchain)", reg_value.GetAsUInt64());
1196 if (!reg_ctx->WriteRegister(fp_reg_info, reg_value))
1206 log->Printf("Pushing the return address onto the stack: 0x%" PRIx64
1208 (uint64_t)sp, (uint64_t)return_addr);
1210 // Save return address onto the stack
1211 if (!process_sp->WritePointerToMemory(sp, return_addr, error))
1214 // %rsp is set to the actual stack value.
1217 log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
1219 if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
1222 // %rip is set to the address of the called function.
1225 log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
1227 if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
1233 static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,
1234 bool is_signed, Thread &thread,
1235 uint32_t *argument_register_ids,
1236 unsigned int ¤t_argument_register,
1237 addr_t ¤t_stack_argument) {
1239 return false; // Scalar can't hold large integer arguments
1241 if (current_argument_register < 6) {
1242 scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
1243 argument_register_ids[current_argument_register], 0);
1244 current_argument_register++;
1246 scalar.SignExtend(bit_width);
1248 uint32_t byte_size = (bit_width + (8 - 1)) / 8;
1250 if (thread.GetProcess()->ReadScalarIntegerFromMemory(
1251 current_stack_argument, byte_size, is_signed, scalar, error)) {
1252 current_stack_argument += byte_size;
1260 bool ABISysV_x86_64::GetArgumentValues(Thread &thread,
1261 ValueList &values) const {
1262 unsigned int num_values = values.GetSize();
1263 unsigned int value_index;
1265 // Extract the register context so we can read arguments from registers
1267 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1272 // Get the pointer to the first stack argument so we have a place to start
1273 // when reading data
1275 addr_t sp = reg_ctx->GetSP(0);
1280 addr_t current_stack_argument = sp + 8; // jump over return address
1282 uint32_t argument_register_ids[6];
1284 argument_register_ids[0] =
1285 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)
1286 ->kinds[eRegisterKindLLDB];
1287 argument_register_ids[1] =
1288 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)
1289 ->kinds[eRegisterKindLLDB];
1290 argument_register_ids[2] =
1291 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)
1292 ->kinds[eRegisterKindLLDB];
1293 argument_register_ids[3] =
1294 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)
1295 ->kinds[eRegisterKindLLDB];
1296 argument_register_ids[4] =
1297 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5)
1298 ->kinds[eRegisterKindLLDB];
1299 argument_register_ids[5] =
1300 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG6)
1301 ->kinds[eRegisterKindLLDB];
1303 unsigned int current_argument_register = 0;
1305 for (value_index = 0; value_index < num_values; ++value_index) {
1306 Value *value = values.GetValueAtIndex(value_index);
1311 // We currently only support extracting values with Clang QualTypes.
1312 // Do we care about others?
1313 CompilerType compiler_type = value->GetCompilerType();
1318 if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
1319 ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread),
1320 is_signed, thread, argument_register_ids,
1321 current_argument_register, current_stack_argument);
1322 } else if (compiler_type.IsPointerType()) {
1323 ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread),
1324 false, thread, argument_register_ids,
1325 current_argument_register, current_stack_argument);
1332 Status ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
1333 lldb::ValueObjectSP &new_value_sp) {
1335 if (!new_value_sp) {
1336 error.SetErrorString("Empty value object for return value.");
1340 CompilerType compiler_type = new_value_sp->GetCompilerType();
1341 if (!compiler_type) {
1342 error.SetErrorString("Null clang type for return value.");
1346 Thread *thread = frame_sp->GetThread().get();
1352 RegisterContext *reg_ctx = thread->GetRegisterContext().get();
1354 bool set_it_simple = false;
1355 if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1356 compiler_type.IsPointerType()) {
1357 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("rax", 0);
1361 size_t num_bytes = new_value_sp->GetData(data, data_error);
1362 if (data_error.Fail()) {
1363 error.SetErrorStringWithFormat(
1364 "Couldn't convert return value to raw data: %s",
1365 data_error.AsCString());
1368 lldb::offset_t offset = 0;
1369 if (num_bytes <= 8) {
1370 uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
1372 if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value))
1373 set_it_simple = true;
1375 error.SetErrorString("We don't support returning longer than 64 bit "
1376 "integer values at present.");
1378 } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
1380 error.SetErrorString(
1381 "We don't support returning complex values at present");
1383 size_t bit_width = compiler_type.GetBitSize(frame_sp.get());
1384 if (bit_width <= 64) {
1385 const RegisterInfo *xmm0_info =
1386 reg_ctx->GetRegisterInfoByName("xmm0", 0);
1387 RegisterValue xmm0_value;
1390 size_t num_bytes = new_value_sp->GetData(data, data_error);
1391 if (data_error.Fail()) {
1392 error.SetErrorStringWithFormat(
1393 "Couldn't convert return value to raw data: %s",
1394 data_error.AsCString());
1398 unsigned char buffer[16];
1399 ByteOrder byte_order = data.GetByteOrder();
1401 data.CopyByteOrderedData(0, num_bytes, buffer, 16, byte_order);
1402 xmm0_value.SetBytes(buffer, 16, byte_order);
1403 reg_ctx->WriteRegister(xmm0_info, xmm0_value);
1404 set_it_simple = true;
1406 // FIXME - don't know how to do 80 bit long doubles yet.
1407 error.SetErrorString(
1408 "We don't support returning float values > 64 bits at present");
1413 if (!set_it_simple) {
1414 // Okay we've got a structure or something that doesn't fit in a simple
1416 // We should figure out where it really goes, but we don't support this yet.
1417 error.SetErrorString("We only support setting simple integer and float "
1418 "return types at present.");
1424 ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple(
1425 Thread &thread, CompilerType &return_compiler_type) const {
1426 ValueObjectSP return_valobj_sp;
1429 if (!return_compiler_type)
1430 return return_valobj_sp;
1432 // value.SetContext (Value::eContextTypeClangType, return_value_type);
1433 value.SetCompilerType(return_compiler_type);
1435 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1437 return return_valobj_sp;
1439 const uint32_t type_flags = return_compiler_type.GetTypeInfo();
1440 if (type_flags & eTypeIsScalar) {
1441 value.SetValueType(Value::eValueTypeScalar);
1443 bool success = false;
1444 if (type_flags & eTypeIsInteger) {
1445 // Extract the register context so we can read arguments from registers
1447 const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
1448 uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
1449 reg_ctx->GetRegisterInfoByName("rax", 0), 0);
1450 const bool is_signed = (type_flags & eTypeIsSigned) != 0;
1451 switch (byte_size) {
1455 case sizeof(uint64_t):
1457 value.GetScalar() = (int64_t)(raw_value);
1459 value.GetScalar() = (uint64_t)(raw_value);
1463 case sizeof(uint32_t):
1465 value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
1467 value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
1471 case sizeof(uint16_t):
1473 value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
1475 value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
1479 case sizeof(uint8_t):
1481 value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
1483 value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
1487 } else if (type_flags & eTypeIsFloat) {
1488 if (type_flags & eTypeIsComplex) {
1489 // Don't handle complex yet.
1491 const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
1492 if (byte_size <= sizeof(long double)) {
1493 const RegisterInfo *xmm0_info =
1494 reg_ctx->GetRegisterInfoByName("xmm0", 0);
1495 RegisterValue xmm0_value;
1496 if (reg_ctx->ReadRegister(xmm0_info, xmm0_value)) {
1498 if (xmm0_value.GetData(data)) {
1499 lldb::offset_t offset = 0;
1500 if (byte_size == sizeof(float)) {
1501 value.GetScalar() = (float)data.GetFloat(&offset);
1503 } else if (byte_size == sizeof(double)) {
1504 value.GetScalar() = (double)data.GetDouble(&offset);
1506 } else if (byte_size == sizeof(long double)) {
1507 // Don't handle long double since that can be encoded as 80 bit
1517 return_valobj_sp = ValueObjectConstResult::Create(
1518 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
1519 } else if (type_flags & eTypeIsPointer) {
1521 reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
1523 (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
1525 value.SetValueType(Value::eValueTypeScalar);
1526 return_valobj_sp = ValueObjectConstResult::Create(
1527 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
1528 } else if (type_flags & eTypeIsVector) {
1529 const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
1530 if (byte_size > 0) {
1531 const RegisterInfo *altivec_reg =
1532 reg_ctx->GetRegisterInfoByName("xmm0", 0);
1533 if (altivec_reg == nullptr)
1534 altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
1537 if (byte_size <= altivec_reg->byte_size) {
1538 ProcessSP process_sp(thread.GetProcess());
1540 std::unique_ptr<DataBufferHeap> heap_data_ap(
1541 new DataBufferHeap(byte_size, 0));
1542 const ByteOrder byte_order = process_sp->GetByteOrder();
1543 RegisterValue reg_value;
1544 if (reg_ctx->ReadRegister(altivec_reg, reg_value)) {
1546 if (reg_value.GetAsMemoryData(
1547 altivec_reg, heap_data_ap->GetBytes(),
1548 heap_data_ap->GetByteSize(), byte_order, error)) {
1549 DataExtractor data(DataBufferSP(heap_data_ap.release()),
1550 byte_order, process_sp->GetTarget()
1552 .GetAddressByteSize());
1553 return_valobj_sp = ValueObjectConstResult::Create(
1554 &thread, return_compiler_type, ConstString(""), data);
1558 } else if (byte_size <= altivec_reg->byte_size * 2) {
1559 const RegisterInfo *altivec_reg2 =
1560 reg_ctx->GetRegisterInfoByName("xmm1", 0);
1562 ProcessSP process_sp(thread.GetProcess());
1564 std::unique_ptr<DataBufferHeap> heap_data_ap(
1565 new DataBufferHeap(byte_size, 0));
1566 const ByteOrder byte_order = process_sp->GetByteOrder();
1567 RegisterValue reg_value;
1568 RegisterValue reg_value2;
1569 if (reg_ctx->ReadRegister(altivec_reg, reg_value) &&
1570 reg_ctx->ReadRegister(altivec_reg2, reg_value2)) {
1573 if (reg_value.GetAsMemoryData(
1574 altivec_reg, heap_data_ap->GetBytes(),
1575 altivec_reg->byte_size, byte_order, error) &&
1576 reg_value2.GetAsMemoryData(
1578 heap_data_ap->GetBytes() + altivec_reg->byte_size,
1579 heap_data_ap->GetByteSize() - altivec_reg->byte_size,
1580 byte_order, error)) {
1581 DataExtractor data(DataBufferSP(heap_data_ap.release()),
1582 byte_order, process_sp->GetTarget()
1584 .GetAddressByteSize());
1585 return_valobj_sp = ValueObjectConstResult::Create(
1586 &thread, return_compiler_type, ConstString(""), data);
1596 return return_valobj_sp;
1599 ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl(
1600 Thread &thread, CompilerType &return_compiler_type) const {
1601 ValueObjectSP return_valobj_sp;
1603 if (!return_compiler_type)
1604 return return_valobj_sp;
1606 ExecutionContext exe_ctx(thread.shared_from_this());
1607 return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
1608 if (return_valobj_sp)
1609 return return_valobj_sp;
1611 RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
1613 return return_valobj_sp;
1615 const size_t bit_width = return_compiler_type.GetBitSize(&thread);
1616 if (return_compiler_type.IsAggregateType()) {
1617 Target *target = exe_ctx.GetTargetPtr();
1618 bool is_memory = true;
1619 if (bit_width <= 128) {
1620 ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder();
1621 DataBufferSP data_sp(new DataBufferHeap(16, 0));
1622 DataExtractor return_ext(data_sp, target_byte_order,
1623 target->GetArchitecture().GetAddressByteSize());
1625 const RegisterInfo *rax_info =
1626 reg_ctx_sp->GetRegisterInfoByName("rax", 0);
1627 const RegisterInfo *rdx_info =
1628 reg_ctx_sp->GetRegisterInfoByName("rdx", 0);
1629 const RegisterInfo *xmm0_info =
1630 reg_ctx_sp->GetRegisterInfoByName("xmm0", 0);
1631 const RegisterInfo *xmm1_info =
1632 reg_ctx_sp->GetRegisterInfoByName("xmm1", 0);
1634 RegisterValue rax_value, rdx_value, xmm0_value, xmm1_value;
1635 reg_ctx_sp->ReadRegister(rax_info, rax_value);
1636 reg_ctx_sp->ReadRegister(rdx_info, rdx_value);
1637 reg_ctx_sp->ReadRegister(xmm0_info, xmm0_value);
1638 reg_ctx_sp->ReadRegister(xmm1_info, xmm1_value);
1640 DataExtractor rax_data, rdx_data, xmm0_data, xmm1_data;
1642 rax_value.GetData(rax_data);
1643 rdx_value.GetData(rdx_data);
1644 xmm0_value.GetData(xmm0_data);
1645 xmm1_value.GetData(xmm1_data);
1648 0; // Tracks how much of the xmm registers we've consumed so far
1649 uint32_t integer_bytes =
1650 0; // Tracks how much of the rax/rds registers we've consumed so far
1652 const uint32_t num_children = return_compiler_type.GetNumFields();
1654 // Since we are in the small struct regime, assume we are not in memory.
1657 for (uint32_t idx = 0; idx < num_children; idx++) {
1659 uint64_t field_bit_offset = 0;
1664 CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(
1665 idx, name, &field_bit_offset, nullptr, nullptr);
1666 const size_t field_bit_width = field_compiler_type.GetBitSize(&thread);
1668 // if we don't know the size of the field (e.g. invalid type), just bail
1670 if (field_bit_width == 0)
1673 // If there are any unaligned fields, this is stored in memory.
1674 if (field_bit_offset % field_bit_width != 0) {
1679 uint32_t field_byte_width = field_bit_width / 8;
1680 uint32_t field_byte_offset = field_bit_offset / 8;
1682 DataExtractor *copy_from_extractor = nullptr;
1683 uint32_t copy_from_offset = 0;
1685 if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1686 field_compiler_type.IsPointerType()) {
1687 if (integer_bytes < 8) {
1688 if (integer_bytes + field_byte_width <= 8) {
1689 // This is in RAX, copy from register to our result structure:
1690 copy_from_extractor = &rax_data;
1691 copy_from_offset = integer_bytes;
1692 integer_bytes += field_byte_width;
1694 // The next field wouldn't fit in the remaining space, so we
1695 // pushed it to rdx.
1696 copy_from_extractor = &rdx_data;
1697 copy_from_offset = 0;
1698 integer_bytes = 8 + field_byte_width;
1700 } else if (integer_bytes + field_byte_width <= 16) {
1701 copy_from_extractor = &rdx_data;
1702 copy_from_offset = integer_bytes - 8;
1703 integer_bytes += field_byte_width;
1705 // The last field didn't fit. I can't see how that would happen w/o
1706 // the overall size being
1707 // greater than 16 bytes. For now, return a nullptr return value
1709 return return_valobj_sp;
1711 } else if (field_compiler_type.IsFloatingPointType(count, is_complex)) {
1712 // Structs with long doubles are always passed in memory.
1713 if (field_bit_width == 128) {
1716 } else if (field_bit_width == 64) {
1717 // These have to be in a single xmm register.
1719 copy_from_extractor = &xmm0_data;
1721 copy_from_extractor = &xmm1_data;
1723 copy_from_offset = 0;
1724 fp_bytes += field_byte_width;
1725 } else if (field_bit_width == 32) {
1726 // This one is kind of complicated. If we are in an "eightbyte"
1727 // with another float, we'll
1728 // be stuffed into an xmm register with it. If we are in an
1729 // "eightbyte" with one or more ints,
1730 // then we will be stuffed into the appropriate GPR with them.
1732 if (field_byte_offset % 8 == 0) {
1733 // We are at the beginning of one of the eightbytes, so check the
1734 // next element (if any)
1735 if (idx == num_children - 1)
1738 uint64_t next_field_bit_offset = 0;
1739 CompilerType next_field_compiler_type =
1740 return_compiler_type.GetFieldAtIndex(idx + 1, name,
1741 &next_field_bit_offset,
1743 if (next_field_compiler_type.IsIntegerOrEnumerationType(
1747 copy_from_offset = 0;
1751 } else if (field_byte_offset % 4 == 0) {
1752 // We are inside of an eightbyte, so see if the field before us is
1754 // This could happen if somebody put padding in the structure.
1758 uint64_t prev_field_bit_offset = 0;
1759 CompilerType prev_field_compiler_type =
1760 return_compiler_type.GetFieldAtIndex(idx - 1, name,
1761 &prev_field_bit_offset,
1763 if (prev_field_compiler_type.IsIntegerOrEnumerationType(
1767 copy_from_offset = 4;
1776 // Okay, we've figured out whether we are in GPR or XMM, now figure
1779 if (integer_bytes < 8) {
1780 // This is in RAX, copy from register to our result structure:
1781 copy_from_extractor = &rax_data;
1782 copy_from_offset = integer_bytes;
1783 integer_bytes += field_byte_width;
1785 copy_from_extractor = &rdx_data;
1786 copy_from_offset = integer_bytes - 8;
1787 integer_bytes += field_byte_width;
1791 copy_from_extractor = &xmm0_data;
1793 copy_from_extractor = &xmm1_data;
1795 fp_bytes += field_byte_width;
1800 // These two tests are just sanity checks. If I somehow get the
1801 // type calculation wrong above it is better to just return nothing
1802 // than to assert or crash.
1803 if (!copy_from_extractor)
1804 return return_valobj_sp;
1805 if (copy_from_offset + field_byte_width >
1806 copy_from_extractor->GetByteSize())
1807 return return_valobj_sp;
1809 copy_from_extractor->CopyByteOrderedData(
1810 copy_from_offset, field_byte_width,
1811 data_sp->GetBytes() + field_byte_offset, field_byte_width,
1816 // The result is in our data buffer. Let's make a variable object out
1818 return_valobj_sp = ValueObjectConstResult::Create(
1819 &thread, return_compiler_type, ConstString(""), return_ext);
1823 // FIXME: This is just taking a guess, rax may very well no longer hold the
1824 // return storage location.
1825 // If we are going to do this right, when we make a new frame we should
1826 // check to see if it uses a memory
1827 // return, and if we are at the first instruction and if so stash away the
1828 // return location. Then we would
1829 // only return the memory return value if we know it is valid.
1833 reg_ctx_sp->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
1834 lldb::addr_t storage_addr =
1835 (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
1837 return_valobj_sp = ValueObjectMemory::Create(
1838 &thread, "", Address(storage_addr, nullptr), return_compiler_type);
1842 return return_valobj_sp;
1845 // This defines the CFA as rsp+8
1846 // the saved pc is at CFA-8 (i.e. rsp+0)
1847 // The saved rsp is CFA+0
1849 bool ABISysV_x86_64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
1850 unwind_plan.Clear();
1851 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1853 uint32_t sp_reg_num = dwarf_rsp;
1854 uint32_t pc_reg_num = dwarf_rip;
1856 UnwindPlan::RowSP row(new UnwindPlan::Row);
1857 row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 8);
1858 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
1859 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1860 unwind_plan.AppendRow(row);
1861 unwind_plan.SetSourceName("x86_64 at-func-entry default");
1862 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1866 // This defines the CFA as rbp+16
1867 // The saved pc is at CFA-8 (i.e. rbp+8)
1868 // The saved rbp is at CFA-16 (i.e. rbp+0)
1869 // The saved rsp is CFA+0
1871 bool ABISysV_x86_64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
1872 unwind_plan.Clear();
1873 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1875 uint32_t fp_reg_num = dwarf_rbp;
1876 uint32_t sp_reg_num = dwarf_rsp;
1877 uint32_t pc_reg_num = dwarf_rip;
1879 UnwindPlan::RowSP row(new UnwindPlan::Row);
1881 const int32_t ptr_size = 8;
1882 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp, 2 * ptr_size);
1885 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
1886 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
1887 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1889 unwind_plan.AppendRow(row);
1890 unwind_plan.SetSourceName("x86_64 default unwind plan");
1891 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1892 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1896 bool ABISysV_x86_64::RegisterIsVolatile(const RegisterInfo *reg_info) {
1897 return !RegisterIsCalleeSaved(reg_info);
1900 // See "Register Usage" in the
1901 // "System V Application Binary Interface"
1902 // "AMD64 Architecture Processor Supplement"
1903 // (or "x86-64(tm) Architecture Processor Supplement" in earlier revisions)
1904 // (this doc is also commonly referred to as the x86-64/AMD64 psABI)
1905 // Edited by Michael Matz, Jan Hubicka, Andreas Jaeger, and Mark Mitchell
1906 // current version is 0.99.6 released 2012-07-02 at
1907 // http://refspecs.linuxfoundation.org/elf/x86-64-abi-0.99.pdf
1908 // It's being revised & updated at https://github.com/hjl-tools/x86-psABI/
1910 bool ABISysV_x86_64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
1912 // Preserved registers are :
1913 // rbx, rsp, rbp, r12, r13, r14, r15
1914 // mxcsr (partially preserved)
1917 const char *name = reg_info->name;
1918 if (name[0] == 'r') {
1920 case '1': // r12, r13, r14, r15
1921 if (name[2] >= '2' && name[2] <= '5')
1922 return name[3] == '\0';
1930 // Accept shorter-variant versions, rbx/ebx, rip/ eip, etc.
1931 if (name[0] == 'r' || name[0] == 'e') {
1933 case 'b': // rbp, rbx
1934 if (name[2] == 'p' || name[2] == 'x')
1935 return name[3] == '\0';
1940 return name[3] == '\0';
1945 return name[3] == '\0';
1949 if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
1951 if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
1953 if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
1959 void ABISysV_x86_64::Initialize() {
1960 PluginManager::RegisterPlugin(
1961 GetPluginNameStatic(), "System V ABI for x86_64 targets", CreateInstance);
1964 void ABISysV_x86_64::Terminate() {
1965 PluginManager::UnregisterPlugin(CreateInstance);
1968 lldb_private::ConstString ABISysV_x86_64::GetPluginNameStatic() {
1969 static ConstString g_name("sysv-x86_64");
1973 //------------------------------------------------------------------
1974 // PluginInterface protocol
1975 //------------------------------------------------------------------
1977 lldb_private::ConstString ABISysV_x86_64::GetPluginName() {
1978 return GetPluginNameStatic();
1981 uint32_t ABISysV_x86_64::GetPluginVersion() { return 1; }