ABISysV_x86_64.cpp revision 360784
1//===-- ABISysV_x86_64.cpp --------------------------------------*- C++ -*-===// 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 "ABISysV_x86_64.h" 10 11#include "llvm/ADT/STLExtras.h" 12#include "llvm/ADT/StringSwitch.h" 13#include "llvm/ADT/Triple.h" 14 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" 32 33#include <vector> 34 35using namespace lldb; 36using namespace lldb_private; 37 38enum dwarf_regnums { 39 dwarf_rax = 0, 40 dwarf_rdx, 41 dwarf_rcx, 42 dwarf_rbx, 43 dwarf_rsi, 44 dwarf_rdi, 45 dwarf_rbp, 46 dwarf_rsp, 47 dwarf_r8, 48 dwarf_r9, 49 dwarf_r10, 50 dwarf_r11, 51 dwarf_r12, 52 dwarf_r13, 53 dwarf_r14, 54 dwarf_r15, 55 dwarf_rip, 56 dwarf_xmm0, 57 dwarf_xmm1, 58 dwarf_xmm2, 59 dwarf_xmm3, 60 dwarf_xmm4, 61 dwarf_xmm5, 62 dwarf_xmm6, 63 dwarf_xmm7, 64 dwarf_xmm8, 65 dwarf_xmm9, 66 dwarf_xmm10, 67 dwarf_xmm11, 68 dwarf_xmm12, 69 dwarf_xmm13, 70 dwarf_xmm14, 71 dwarf_xmm15, 72 dwarf_stmm0, 73 dwarf_stmm1, 74 dwarf_stmm2, 75 dwarf_stmm3, 76 dwarf_stmm4, 77 dwarf_stmm5, 78 dwarf_stmm6, 79 dwarf_stmm7, 80 dwarf_ymm0, 81 dwarf_ymm1, 82 dwarf_ymm2, 83 dwarf_ymm3, 84 dwarf_ymm4, 85 dwarf_ymm5, 86 dwarf_ymm6, 87 dwarf_ymm7, 88 dwarf_ymm8, 89 dwarf_ymm9, 90 dwarf_ymm10, 91 dwarf_ymm11, 92 dwarf_ymm12, 93 dwarf_ymm13, 94 dwarf_ymm14, 95 dwarf_ymm15, 96 dwarf_bnd0 = 126, 97 dwarf_bnd1, 98 dwarf_bnd2, 99 dwarf_bnd3 100}; 101 102static RegisterInfo g_register_infos[] = { 103 // clang-format off 104 // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC LLDB NATIVE 105 // ======== ======= == === ============= =================== ======================= ===================== =========================== ===================== ====================== 106 {"rax", nullptr, 8, 0, eEncodingUint, eFormatHex, {dwarf_rax, dwarf_rax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 107 {"rbx", nullptr, 8, 0, eEncodingUint, eFormatHex, {dwarf_rbx, dwarf_rbx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 108 {"rcx", "arg4", 8, 0, eEncodingUint, eFormatHex, {dwarf_rcx, dwarf_rcx, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 109 {"rdx", "arg3", 8, 0, eEncodingUint, eFormatHex, {dwarf_rdx, dwarf_rdx, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 110 {"rsi", "arg2", 8, 0, eEncodingUint, eFormatHex, {dwarf_rsi, dwarf_rsi, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 111 {"rdi", "arg1", 8, 0, eEncodingUint, eFormatHex, {dwarf_rdi, dwarf_rdi, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 112 {"rbp", "fp", 8, 0, eEncodingUint, eFormatHex, {dwarf_rbp, dwarf_rbp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 113 {"rsp", "sp", 8, 0, eEncodingUint, eFormatHex, {dwarf_rsp, dwarf_rsp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 114 {"r8", "arg5", 8, 0, eEncodingUint, eFormatHex, {dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 115 {"r9", "arg6", 8, 0, eEncodingUint, eFormatHex, {dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 116 {"r10", nullptr, 8, 0, eEncodingUint, eFormatHex, {dwarf_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 117 {"r11", nullptr, 8, 0, eEncodingUint, eFormatHex, {dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 118 {"r12", nullptr, 8, 0, eEncodingUint, eFormatHex, {dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 119 {"r13", nullptr, 8, 0, eEncodingUint, eFormatHex, {dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 120 {"r14", nullptr, 8, 0, eEncodingUint, eFormatHex, {dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 121 {"r15", nullptr, 8, 0, eEncodingUint, eFormatHex, {dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 122 {"rip", "pc", 8, 0, eEncodingUint, eFormatHex, {dwarf_rip, dwarf_rip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 123 {"rflags", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 124 {"cs", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 125 {"ss", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 126 {"ds", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 127 {"es", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 128 {"fs", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 129 {"gs", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 130 {"stmm0", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_stmm0, dwarf_stmm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 131 {"stmm1", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_stmm1, dwarf_stmm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 132 {"stmm2", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_stmm2, dwarf_stmm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 133 {"stmm3", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_stmm3, dwarf_stmm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 134 {"stmm4", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_stmm4, dwarf_stmm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 135 {"stmm5", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_stmm5, dwarf_stmm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 136 {"stmm6", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_stmm6, dwarf_stmm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 137 {"stmm7", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_stmm7, dwarf_stmm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 138 {"fctrl", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 139 {"fstat", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 140 {"ftag", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 141 {"fiseg", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 142 {"fioff", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 143 {"foseg", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 144 {"fooff", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 145 {"fop", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 146 {"xmm0", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm0, dwarf_xmm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 147 {"xmm1", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm1, dwarf_xmm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 148 {"xmm2", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm2, dwarf_xmm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 149 {"xmm3", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm3, dwarf_xmm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 150 {"xmm4", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm4, dwarf_xmm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 151 {"xmm5", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm5, dwarf_xmm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 152 {"xmm6", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm6, dwarf_xmm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 153 {"xmm7", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm7, dwarf_xmm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 154 {"xmm8", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm8, dwarf_xmm8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 155 {"xmm9", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm9, dwarf_xmm9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 156 {"xmm10", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm10, dwarf_xmm10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 157 {"xmm11", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm11, dwarf_xmm11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 158 {"xmm12", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm12, dwarf_xmm12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 159 {"xmm13", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm13, dwarf_xmm13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 160 {"xmm14", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm14, dwarf_xmm14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 161 {"xmm15", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_xmm15, dwarf_xmm15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 162 {"mxcsr", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 163 {"ymm0", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm0, dwarf_ymm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 164 {"ymm1", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm1, dwarf_ymm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 165 {"ymm2", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm2, dwarf_ymm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 166 {"ymm3", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm3, dwarf_ymm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 167 {"ymm4", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm4, dwarf_ymm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 168 {"ymm5", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm5, dwarf_ymm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 169 {"ymm6", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm6, dwarf_ymm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 170 {"ymm7", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm7, dwarf_ymm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 171 {"ymm8", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm8, dwarf_ymm8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 172 {"ymm9", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm9, dwarf_ymm9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 173 {"ymm10", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm10, dwarf_ymm10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 174 {"ymm11", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm11, dwarf_ymm11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 175 {"ymm12", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm12, dwarf_ymm12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 176 {"ymm13", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm13, dwarf_ymm13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 177 {"ymm14", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm14, dwarf_ymm14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 178 {"ymm15", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {dwarf_ymm15, dwarf_ymm15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 179 {"bnd0", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64, {dwarf_bnd0, dwarf_bnd0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 180 {"bnd1", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64, {dwarf_bnd1, dwarf_bnd1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 181 {"bnd2", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64, {dwarf_bnd2, dwarf_bnd2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 182 {"bnd3", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64, {dwarf_bnd3, dwarf_bnd3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 183 {"bndcfgu", nullptr, 8, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 184 {"bndstatus",nullptr, 8, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 185 // clang-format on 186}; 187 188static const uint32_t k_num_register_infos = 189 llvm::array_lengthof(g_register_infos); 190static bool g_register_info_names_constified = false; 191 192const lldb_private::RegisterInfo * 193ABISysV_x86_64::GetRegisterInfoArray(uint32_t &count) { 194 // Make the C-string names and alt_names for the register infos into const 195 // C-string values by having the ConstString unique the names in the global 196 // constant C-string pool. 197 if (!g_register_info_names_constified) { 198 g_register_info_names_constified = true; 199 for (uint32_t i = 0; i < k_num_register_infos; ++i) { 200 if (g_register_infos[i].name) 201 g_register_infos[i].name = 202 ConstString(g_register_infos[i].name).GetCString(); 203 if (g_register_infos[i].alt_name) 204 g_register_infos[i].alt_name = 205 ConstString(g_register_infos[i].alt_name).GetCString(); 206 } 207 } 208 count = k_num_register_infos; 209 return g_register_infos; 210} 211 212bool ABISysV_x86_64::GetPointerReturnRegister(const char *&name) { 213 name = "rax"; 214 return true; 215} 216 217size_t ABISysV_x86_64::GetRedZoneSize() const { return 128; } 218 219// Static Functions 220 221ABISP 222ABISysV_x86_64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { 223 const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch(); 224 const llvm::Triple::OSType os_type = arch.GetTriple().getOS(); 225 const llvm::Triple::EnvironmentType os_env = 226 arch.GetTriple().getEnvironment(); 227 if (arch_type == llvm::Triple::x86_64) { 228 switch(os_type) { 229 case llvm::Triple::OSType::IOS: 230 case llvm::Triple::OSType::TvOS: 231 case llvm::Triple::OSType::WatchOS: 232 switch (os_env) { 233 case llvm::Triple::EnvironmentType::MacABI: 234 case llvm::Triple::EnvironmentType::Simulator: 235 case llvm::Triple::EnvironmentType::UnknownEnvironment: 236 // UnknownEnvironment is needed for older compilers that don't 237 // support the simulator environment. 238 return ABISP(new ABISysV_x86_64(std::move(process_sp), 239 MakeMCRegisterInfo(arch))); 240 default: 241 return ABISP(); 242 } 243 case llvm::Triple::OSType::Darwin: 244 case llvm::Triple::OSType::FreeBSD: 245 case llvm::Triple::OSType::Linux: 246 case llvm::Triple::OSType::MacOSX: 247 case llvm::Triple::OSType::NetBSD: 248 case llvm::Triple::OSType::Solaris: 249 case llvm::Triple::OSType::UnknownOS: 250 return ABISP( 251 new ABISysV_x86_64(std::move(process_sp), MakeMCRegisterInfo(arch))); 252 default: 253 return ABISP(); 254 } 255 } 256 return ABISP(); 257} 258 259bool ABISysV_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp, 260 addr_t func_addr, addr_t return_addr, 261 llvm::ArrayRef<addr_t> args) const { 262 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 263 264 if (log) { 265 StreamString s; 266 s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64 267 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 268 ", return_addr = 0x%" PRIx64, 269 thread.GetID(), (uint64_t)sp, (uint64_t)func_addr, 270 (uint64_t)return_addr); 271 272 for (size_t i = 0; i < args.size(); ++i) 273 s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1), 274 args[i]); 275 s.PutCString(")"); 276 log->PutString(s.GetString()); 277 } 278 279 RegisterContext *reg_ctx = thread.GetRegisterContext().get(); 280 if (!reg_ctx) 281 return false; 282 283 const RegisterInfo *reg_info = nullptr; 284 285 if (args.size() > 6) // TODO handle more than 6 arguments 286 return false; 287 288 for (size_t i = 0; i < args.size(); ++i) { 289 reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, 290 LLDB_REGNUM_GENERIC_ARG1 + i); 291 LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s", 292 static_cast<uint64_t>(i + 1), args[i], reg_info->name); 293 if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i])) 294 return false; 295 } 296 297 // First, align the SP 298 299 LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, 300 (uint64_t)sp, (uint64_t)(sp & ~0xfull)); 301 302 sp &= ~(0xfull); // 16-byte alignment 303 304 sp -= 8; 305 306 Status error; 307 const RegisterInfo *pc_reg_info = 308 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 309 const RegisterInfo *sp_reg_info = 310 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 311 ProcessSP process_sp(thread.GetProcess()); 312 313 RegisterValue reg_value; 314 LLDB_LOGF(log, 315 "Pushing the return address onto the stack: 0x%" PRIx64 316 ": 0x%" PRIx64, 317 (uint64_t)sp, (uint64_t)return_addr); 318 319 // Save return address onto the stack 320 if (!process_sp->WritePointerToMemory(sp, return_addr, error)) 321 return false; 322 323 // %rsp is set to the actual stack value. 324 325 LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp); 326 327 if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp)) 328 return false; 329 330 // %rip is set to the address of the called function. 331 332 LLDB_LOGF(log, "Writing IP: 0x%" PRIx64, (uint64_t)func_addr); 333 334 if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr)) 335 return false; 336 337 return true; 338} 339 340static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width, 341 bool is_signed, Thread &thread, 342 uint32_t *argument_register_ids, 343 unsigned int ¤t_argument_register, 344 addr_t ¤t_stack_argument) { 345 if (bit_width > 64) 346 return false; // Scalar can't hold large integer arguments 347 348 if (current_argument_register < 6) { 349 scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned( 350 argument_register_ids[current_argument_register], 0); 351 current_argument_register++; 352 if (is_signed) 353 scalar.SignExtend(bit_width); 354 } else { 355 uint32_t byte_size = (bit_width + (8 - 1)) / 8; 356 Status error; 357 if (thread.GetProcess()->ReadScalarIntegerFromMemory( 358 current_stack_argument, byte_size, is_signed, scalar, error)) { 359 current_stack_argument += byte_size; 360 return true; 361 } 362 return false; 363 } 364 return true; 365} 366 367bool ABISysV_x86_64::GetArgumentValues(Thread &thread, 368 ValueList &values) const { 369 unsigned int num_values = values.GetSize(); 370 unsigned int value_index; 371 372 // Extract the register context so we can read arguments from registers 373 374 RegisterContext *reg_ctx = thread.GetRegisterContext().get(); 375 376 if (!reg_ctx) 377 return false; 378 379 // Get the pointer to the first stack argument so we have a place to start 380 // when reading data 381 382 addr_t sp = reg_ctx->GetSP(0); 383 384 if (!sp) 385 return false; 386 387 addr_t current_stack_argument = sp + 8; // jump over return address 388 389 uint32_t argument_register_ids[6]; 390 391 argument_register_ids[0] = 392 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1) 393 ->kinds[eRegisterKindLLDB]; 394 argument_register_ids[1] = 395 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2) 396 ->kinds[eRegisterKindLLDB]; 397 argument_register_ids[2] = 398 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3) 399 ->kinds[eRegisterKindLLDB]; 400 argument_register_ids[3] = 401 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4) 402 ->kinds[eRegisterKindLLDB]; 403 argument_register_ids[4] = 404 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5) 405 ->kinds[eRegisterKindLLDB]; 406 argument_register_ids[5] = 407 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG6) 408 ->kinds[eRegisterKindLLDB]; 409 410 unsigned int current_argument_register = 0; 411 412 for (value_index = 0; value_index < num_values; ++value_index) { 413 Value *value = values.GetValueAtIndex(value_index); 414 415 if (!value) 416 return false; 417 418 // We currently only support extracting values with Clang QualTypes. Do we 419 // care about others? 420 CompilerType compiler_type = value->GetCompilerType(); 421 llvm::Optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread); 422 if (!bit_size) 423 return false; 424 bool is_signed; 425 426 if (compiler_type.IsIntegerOrEnumerationType(is_signed)) { 427 ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread, 428 argument_register_ids, current_argument_register, 429 current_stack_argument); 430 } else if (compiler_type.IsPointerType()) { 431 ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread, 432 argument_register_ids, current_argument_register, 433 current_stack_argument); 434 } 435 } 436 437 return true; 438} 439 440Status ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, 441 lldb::ValueObjectSP &new_value_sp) { 442 Status error; 443 if (!new_value_sp) { 444 error.SetErrorString("Empty value object for return value."); 445 return error; 446 } 447 448 CompilerType compiler_type = new_value_sp->GetCompilerType(); 449 if (!compiler_type) { 450 error.SetErrorString("Null clang type for return value."); 451 return error; 452 } 453 454 Thread *thread = frame_sp->GetThread().get(); 455 456 bool is_signed; 457 uint32_t count; 458 bool is_complex; 459 460 RegisterContext *reg_ctx = thread->GetRegisterContext().get(); 461 462 bool set_it_simple = false; 463 if (compiler_type.IsIntegerOrEnumerationType(is_signed) || 464 compiler_type.IsPointerType()) { 465 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("rax", 0); 466 467 DataExtractor data; 468 Status data_error; 469 size_t num_bytes = new_value_sp->GetData(data, data_error); 470 if (data_error.Fail()) { 471 error.SetErrorStringWithFormat( 472 "Couldn't convert return value to raw data: %s", 473 data_error.AsCString()); 474 return error; 475 } 476 lldb::offset_t offset = 0; 477 if (num_bytes <= 8) { 478 uint64_t raw_value = data.GetMaxU64(&offset, num_bytes); 479 480 if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value)) 481 set_it_simple = true; 482 } else { 483 error.SetErrorString("We don't support returning longer than 64 bit " 484 "integer values at present."); 485 } 486 } else if (compiler_type.IsFloatingPointType(count, is_complex)) { 487 if (is_complex) 488 error.SetErrorString( 489 "We don't support returning complex values at present"); 490 else { 491 llvm::Optional<uint64_t> bit_width = 492 compiler_type.GetBitSize(frame_sp.get()); 493 if (!bit_width) { 494 error.SetErrorString("can't get type size"); 495 return error; 496 } 497 if (*bit_width <= 64) { 498 const RegisterInfo *xmm0_info = 499 reg_ctx->GetRegisterInfoByName("xmm0", 0); 500 RegisterValue xmm0_value; 501 DataExtractor data; 502 Status data_error; 503 size_t num_bytes = new_value_sp->GetData(data, data_error); 504 if (data_error.Fail()) { 505 error.SetErrorStringWithFormat( 506 "Couldn't convert return value to raw data: %s", 507 data_error.AsCString()); 508 return error; 509 } 510 511 unsigned char buffer[16]; 512 ByteOrder byte_order = data.GetByteOrder(); 513 514 data.CopyByteOrderedData(0, num_bytes, buffer, 16, byte_order); 515 xmm0_value.SetBytes(buffer, 16, byte_order); 516 reg_ctx->WriteRegister(xmm0_info, xmm0_value); 517 set_it_simple = true; 518 } else { 519 // FIXME - don't know how to do 80 bit long doubles yet. 520 error.SetErrorString( 521 "We don't support returning float values > 64 bits at present"); 522 } 523 } 524 } 525 526 if (!set_it_simple) { 527 // Okay we've got a structure or something that doesn't fit in a simple 528 // register. We should figure out where it really goes, but we don't 529 // support this yet. 530 error.SetErrorString("We only support setting simple integer and float " 531 "return types at present."); 532 } 533 534 return error; 535} 536 537ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple( 538 Thread &thread, CompilerType &return_compiler_type) const { 539 ValueObjectSP return_valobj_sp; 540 Value value; 541 542 if (!return_compiler_type) 543 return return_valobj_sp; 544 545 // value.SetContext (Value::eContextTypeClangType, return_value_type); 546 value.SetCompilerType(return_compiler_type); 547 548 RegisterContext *reg_ctx = thread.GetRegisterContext().get(); 549 if (!reg_ctx) 550 return return_valobj_sp; 551 552 const uint32_t type_flags = return_compiler_type.GetTypeInfo(); 553 if (type_flags & eTypeIsScalar) { 554 value.SetValueType(Value::eValueTypeScalar); 555 556 bool success = false; 557 if (type_flags & eTypeIsInteger) { 558 // Extract the register context so we can read arguments from registers 559 560 llvm::Optional<uint64_t> byte_size = 561 return_compiler_type.GetByteSize(nullptr); 562 if (!byte_size) 563 return return_valobj_sp; 564 uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned( 565 reg_ctx->GetRegisterInfoByName("rax", 0), 0); 566 const bool is_signed = (type_flags & eTypeIsSigned) != 0; 567 switch (*byte_size) { 568 default: 569 break; 570 571 case sizeof(uint64_t): 572 if (is_signed) 573 value.GetScalar() = (int64_t)(raw_value); 574 else 575 value.GetScalar() = (uint64_t)(raw_value); 576 success = true; 577 break; 578 579 case sizeof(uint32_t): 580 if (is_signed) 581 value.GetScalar() = (int32_t)(raw_value & UINT32_MAX); 582 else 583 value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX); 584 success = true; 585 break; 586 587 case sizeof(uint16_t): 588 if (is_signed) 589 value.GetScalar() = (int16_t)(raw_value & UINT16_MAX); 590 else 591 value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX); 592 success = true; 593 break; 594 595 case sizeof(uint8_t): 596 if (is_signed) 597 value.GetScalar() = (int8_t)(raw_value & UINT8_MAX); 598 else 599 value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX); 600 success = true; 601 break; 602 } 603 } else if (type_flags & eTypeIsFloat) { 604 if (type_flags & eTypeIsComplex) { 605 // Don't handle complex yet. 606 } else { 607 llvm::Optional<uint64_t> byte_size = 608 return_compiler_type.GetByteSize(nullptr); 609 if (byte_size && *byte_size <= sizeof(long double)) { 610 const RegisterInfo *xmm0_info = 611 reg_ctx->GetRegisterInfoByName("xmm0", 0); 612 RegisterValue xmm0_value; 613 if (reg_ctx->ReadRegister(xmm0_info, xmm0_value)) { 614 DataExtractor data; 615 if (xmm0_value.GetData(data)) { 616 lldb::offset_t offset = 0; 617 if (*byte_size == sizeof(float)) { 618 value.GetScalar() = (float)data.GetFloat(&offset); 619 success = true; 620 } else if (*byte_size == sizeof(double)) { 621 value.GetScalar() = (double)data.GetDouble(&offset); 622 success = true; 623 } else if (*byte_size == sizeof(long double)) { 624 // Don't handle long double since that can be encoded as 80 bit 625 // floats... 626 } 627 } 628 } 629 } 630 } 631 } 632 633 if (success) 634 return_valobj_sp = ValueObjectConstResult::Create( 635 thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); 636 } else if (type_flags & eTypeIsPointer) { 637 unsigned rax_id = 638 reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB]; 639 value.GetScalar() = 640 (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 641 0); 642 value.SetValueType(Value::eValueTypeScalar); 643 return_valobj_sp = ValueObjectConstResult::Create( 644 thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); 645 } else if (type_flags & eTypeIsVector) { 646 llvm::Optional<uint64_t> byte_size = 647 return_compiler_type.GetByteSize(nullptr); 648 if (byte_size && *byte_size > 0) { 649 const RegisterInfo *altivec_reg = 650 reg_ctx->GetRegisterInfoByName("xmm0", 0); 651 if (altivec_reg == nullptr) 652 altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0); 653 654 if (altivec_reg) { 655 if (*byte_size <= altivec_reg->byte_size) { 656 ProcessSP process_sp(thread.GetProcess()); 657 if (process_sp) { 658 std::unique_ptr<DataBufferHeap> heap_data_up( 659 new DataBufferHeap(*byte_size, 0)); 660 const ByteOrder byte_order = process_sp->GetByteOrder(); 661 RegisterValue reg_value; 662 if (reg_ctx->ReadRegister(altivec_reg, reg_value)) { 663 Status error; 664 if (reg_value.GetAsMemoryData( 665 altivec_reg, heap_data_up->GetBytes(), 666 heap_data_up->GetByteSize(), byte_order, error)) { 667 DataExtractor data(DataBufferSP(heap_data_up.release()), 668 byte_order, 669 process_sp->GetTarget() 670 .GetArchitecture() 671 .GetAddressByteSize()); 672 return_valobj_sp = ValueObjectConstResult::Create( 673 &thread, return_compiler_type, ConstString(""), data); 674 } 675 } 676 } 677 } else if (*byte_size <= altivec_reg->byte_size * 2) { 678 const RegisterInfo *altivec_reg2 = 679 reg_ctx->GetRegisterInfoByName("xmm1", 0); 680 if (altivec_reg2) { 681 ProcessSP process_sp(thread.GetProcess()); 682 if (process_sp) { 683 std::unique_ptr<DataBufferHeap> heap_data_up( 684 new DataBufferHeap(*byte_size, 0)); 685 const ByteOrder byte_order = process_sp->GetByteOrder(); 686 RegisterValue reg_value; 687 RegisterValue reg_value2; 688 if (reg_ctx->ReadRegister(altivec_reg, reg_value) && 689 reg_ctx->ReadRegister(altivec_reg2, reg_value2)) { 690 691 Status error; 692 if (reg_value.GetAsMemoryData( 693 altivec_reg, heap_data_up->GetBytes(), 694 altivec_reg->byte_size, byte_order, error) && 695 reg_value2.GetAsMemoryData( 696 altivec_reg2, 697 heap_data_up->GetBytes() + altivec_reg->byte_size, 698 heap_data_up->GetByteSize() - altivec_reg->byte_size, 699 byte_order, error)) { 700 DataExtractor data(DataBufferSP(heap_data_up.release()), 701 byte_order, 702 process_sp->GetTarget() 703 .GetArchitecture() 704 .GetAddressByteSize()); 705 return_valobj_sp = ValueObjectConstResult::Create( 706 &thread, return_compiler_type, ConstString(""), data); 707 } 708 } 709 } 710 } 711 } 712 } 713 } 714 } 715 716 return return_valobj_sp; 717} 718 719// The compiler will flatten the nested aggregate type into single 720// layer and push the value to stack 721// This helper function will flatten an aggregate type 722// and return true if it can be returned in register(s) by value 723// return false if the aggregate is in memory 724static bool FlattenAggregateType( 725 Thread &thread, ExecutionContext &exe_ctx, 726 CompilerType &return_compiler_type, 727 uint32_t data_byte_offset, 728 std::vector<uint32_t> &aggregate_field_offsets, 729 std::vector<CompilerType> &aggregate_compiler_types) { 730 731 const uint32_t num_children = return_compiler_type.GetNumFields(); 732 for (uint32_t idx = 0; idx < num_children; ++idx) { 733 std::string name; 734 bool is_signed; 735 uint32_t count; 736 bool is_complex; 737 738 uint64_t field_bit_offset = 0; 739 CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex( 740 idx, name, &field_bit_offset, nullptr, nullptr); 741 llvm::Optional<uint64_t> field_bit_width = 742 field_compiler_type.GetBitSize(&thread); 743 744 // if we don't know the size of the field (e.g. invalid type), exit 745 if (!field_bit_width || *field_bit_width == 0) { 746 return false; 747 } 748 749 uint32_t field_byte_offset = field_bit_offset / 8 + data_byte_offset; 750 751 const uint32_t field_type_flags = field_compiler_type.GetTypeInfo(); 752 if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) || 753 field_compiler_type.IsPointerType() || 754 field_compiler_type.IsFloatingPointType(count, is_complex)) { 755 aggregate_field_offsets.push_back(field_byte_offset); 756 aggregate_compiler_types.push_back(field_compiler_type); 757 } else if (field_type_flags & eTypeHasChildren) { 758 if (!FlattenAggregateType(thread, exe_ctx, field_compiler_type, 759 field_byte_offset, aggregate_field_offsets, 760 aggregate_compiler_types)) { 761 return false; 762 } 763 } 764 } 765 return true; 766} 767 768ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl( 769 Thread &thread, CompilerType &return_compiler_type) const { 770 ValueObjectSP return_valobj_sp; 771 772 if (!return_compiler_type) 773 return return_valobj_sp; 774 775 ExecutionContext exe_ctx(thread.shared_from_this()); 776 return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type); 777 if (return_valobj_sp) 778 return return_valobj_sp; 779 780 RegisterContextSP reg_ctx_sp = thread.GetRegisterContext(); 781 if (!reg_ctx_sp) 782 return return_valobj_sp; 783 784 llvm::Optional<uint64_t> bit_width = return_compiler_type.GetBitSize(&thread); 785 if (!bit_width) 786 return return_valobj_sp; 787 if (return_compiler_type.IsAggregateType()) { 788 Target *target = exe_ctx.GetTargetPtr(); 789 bool is_memory = true; 790 std::vector<uint32_t> aggregate_field_offsets; 791 std::vector<CompilerType> aggregate_compiler_types; 792 if (return_compiler_type.GetTypeSystem()->CanPassInRegisters( 793 return_compiler_type) && 794 *bit_width <= 128 && 795 FlattenAggregateType(thread, exe_ctx, return_compiler_type, 796 0, aggregate_field_offsets, 797 aggregate_compiler_types)) { 798 ByteOrder byte_order = target->GetArchitecture().GetByteOrder(); 799 DataBufferSP data_sp(new DataBufferHeap(16, 0)); 800 DataExtractor return_ext(data_sp, byte_order, 801 target->GetArchitecture().GetAddressByteSize()); 802 803 const RegisterInfo *rax_info = 804 reg_ctx_sp->GetRegisterInfoByName("rax", 0); 805 const RegisterInfo *rdx_info = 806 reg_ctx_sp->GetRegisterInfoByName("rdx", 0); 807 const RegisterInfo *xmm0_info = 808 reg_ctx_sp->GetRegisterInfoByName("xmm0", 0); 809 const RegisterInfo *xmm1_info = 810 reg_ctx_sp->GetRegisterInfoByName("xmm1", 0); 811 812 RegisterValue rax_value, rdx_value, xmm0_value, xmm1_value; 813 reg_ctx_sp->ReadRegister(rax_info, rax_value); 814 reg_ctx_sp->ReadRegister(rdx_info, rdx_value); 815 reg_ctx_sp->ReadRegister(xmm0_info, xmm0_value); 816 reg_ctx_sp->ReadRegister(xmm1_info, xmm1_value); 817 818 DataExtractor rax_data, rdx_data, xmm0_data, xmm1_data; 819 820 rax_value.GetData(rax_data); 821 rdx_value.GetData(rdx_data); 822 xmm0_value.GetData(xmm0_data); 823 xmm1_value.GetData(xmm1_data); 824 825 uint32_t fp_bytes = 826 0; // Tracks how much of the xmm registers we've consumed so far 827 uint32_t integer_bytes = 828 0; // Tracks how much of the rax/rds registers we've consumed so far 829 830 // in case of the returned type is a subclass of non-abstract-base class 831 // it will have a padding to skip the base content 832 if (aggregate_field_offsets.size()) { 833 fp_bytes = aggregate_field_offsets[0]; 834 integer_bytes = aggregate_field_offsets[0]; 835 } 836 837 const uint32_t num_children = aggregate_compiler_types.size(); 838 839 // Since we are in the small struct regime, assume we are not in memory. 840 is_memory = false; 841 for (uint32_t idx = 0; idx < num_children; idx++) { 842 bool is_signed; 843 uint32_t count; 844 bool is_complex; 845 846 CompilerType field_compiler_type = aggregate_compiler_types[idx]; 847 uint32_t field_byte_width = (uint32_t) (*field_compiler_type.GetByteSize(&thread)); 848 uint32_t field_byte_offset = aggregate_field_offsets[idx]; 849 850 uint32_t field_bit_width = field_byte_width * 8; 851 852 DataExtractor *copy_from_extractor = nullptr; 853 uint32_t copy_from_offset = 0; 854 855 if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) || 856 field_compiler_type.IsPointerType()) { 857 if (integer_bytes < 8) { 858 if (integer_bytes + field_byte_width <= 8) { 859 // This is in RAX, copy from register to our result structure: 860 copy_from_extractor = &rax_data; 861 copy_from_offset = integer_bytes; 862 integer_bytes += field_byte_width; 863 } else { 864 // The next field wouldn't fit in the remaining space, so we 865 // pushed it to rdx. 866 copy_from_extractor = &rdx_data; 867 copy_from_offset = 0; 868 integer_bytes = 8 + field_byte_width; 869 } 870 } else if (integer_bytes + field_byte_width <= 16) { 871 copy_from_extractor = &rdx_data; 872 copy_from_offset = integer_bytes - 8; 873 integer_bytes += field_byte_width; 874 } else { 875 // The last field didn't fit. I can't see how that would happen 876 // w/o the overall size being greater than 16 bytes. For now, 877 // return a nullptr return value object. 878 return return_valobj_sp; 879 } 880 } else if (field_compiler_type.IsFloatingPointType(count, is_complex)) { 881 // Structs with long doubles are always passed in memory. 882 if (field_bit_width == 128) { 883 is_memory = true; 884 break; 885 } else if (field_bit_width == 64) { 886 // These have to be in a single xmm register. 887 if (fp_bytes == 0) 888 copy_from_extractor = &xmm0_data; 889 else 890 copy_from_extractor = &xmm1_data; 891 892 copy_from_offset = 0; 893 fp_bytes += field_byte_width; 894 } else if (field_bit_width == 32) { 895 // This one is kind of complicated. If we are in an "eightbyte" 896 // with another float, we'll be stuffed into an xmm register with 897 // it. If we are in an "eightbyte" with one or more ints, then we 898 // will be stuffed into the appropriate GPR with them. 899 bool in_gpr; 900 if (field_byte_offset % 8 == 0) { 901 // We are at the beginning of one of the eightbytes, so check the 902 // next element (if any) 903 if (idx == num_children - 1) { 904 in_gpr = false; 905 } else { 906 CompilerType next_field_compiler_type = 907 aggregate_compiler_types[idx + 1]; 908 if (next_field_compiler_type.IsIntegerOrEnumerationType( 909 is_signed)) { 910 in_gpr = true; 911 } else { 912 copy_from_offset = 0; 913 in_gpr = false; 914 } 915 } 916 } else if (field_byte_offset % 4 == 0) { 917 // We are inside of an eightbyte, so see if the field before us 918 // is floating point: This could happen if somebody put padding 919 // in the structure. 920 if (idx == 0) { 921 in_gpr = false; 922 } else { 923 CompilerType prev_field_compiler_type = 924 aggregate_compiler_types[idx - 1]; 925 if (prev_field_compiler_type.IsIntegerOrEnumerationType( 926 is_signed)) { 927 in_gpr = true; 928 } else { 929 copy_from_offset = 4; 930 in_gpr = false; 931 } 932 } 933 } else { 934 is_memory = true; 935 continue; 936 } 937 938 // Okay, we've figured out whether we are in GPR or XMM, now figure 939 // out which one. 940 if (in_gpr) { 941 if (integer_bytes < 8) { 942 // This is in RAX, copy from register to our result structure: 943 copy_from_extractor = &rax_data; 944 copy_from_offset = integer_bytes; 945 integer_bytes += field_byte_width; 946 } else { 947 copy_from_extractor = &rdx_data; 948 copy_from_offset = integer_bytes - 8; 949 integer_bytes += field_byte_width; 950 } 951 } else { 952 if (fp_bytes < 8) 953 copy_from_extractor = &xmm0_data; 954 else 955 copy_from_extractor = &xmm1_data; 956 957 fp_bytes += field_byte_width; 958 } 959 } 960 } 961 // These two tests are just sanity checks. If I somehow get the type 962 // calculation wrong above it is better to just return nothing than to 963 // assert or crash. 964 if (!copy_from_extractor) 965 return return_valobj_sp; 966 if (copy_from_offset + field_byte_width > 967 copy_from_extractor->GetByteSize()) 968 return return_valobj_sp; 969 copy_from_extractor->CopyByteOrderedData( 970 copy_from_offset, field_byte_width, 971 data_sp->GetBytes() + field_byte_offset, field_byte_width, 972 byte_order); 973 } 974 if (!is_memory) { 975 // The result is in our data buffer. Let's make a variable object out 976 // of it: 977 return_valobj_sp = ValueObjectConstResult::Create( 978 &thread, return_compiler_type, ConstString(""), return_ext); 979 } 980 } 981 982 // FIXME: This is just taking a guess, rax may very well no longer hold the 983 // return storage location. 984 // If we are going to do this right, when we make a new frame we should 985 // check to see if it uses a memory return, and if we are at the first 986 // instruction and if so stash away the return location. Then we would 987 // only return the memory return value if we know it is valid. 988 989 if (is_memory) { 990 unsigned rax_id = 991 reg_ctx_sp->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB]; 992 lldb::addr_t storage_addr = 993 (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 994 0); 995 return_valobj_sp = ValueObjectMemory::Create( 996 &thread, "", Address(storage_addr, nullptr), return_compiler_type); 997 } 998 } 999 1000 return return_valobj_sp; 1001} 1002 1003// This defines the CFA as rsp+8 1004// the saved pc is at CFA-8 (i.e. rsp+0) 1005// The saved rsp is CFA+0 1006 1007bool ABISysV_x86_64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { 1008 unwind_plan.Clear(); 1009 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 1010 1011 uint32_t sp_reg_num = dwarf_rsp; 1012 uint32_t pc_reg_num = dwarf_rip; 1013 1014 UnwindPlan::RowSP row(new UnwindPlan::Row); 1015 row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 8); 1016 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false); 1017 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true); 1018 unwind_plan.AppendRow(row); 1019 unwind_plan.SetSourceName("x86_64 at-func-entry default"); 1020 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 1021 return true; 1022} 1023 1024// This defines the CFA as rbp+16 1025// The saved pc is at CFA-8 (i.e. rbp+8) 1026// The saved rbp is at CFA-16 (i.e. rbp+0) 1027// The saved rsp is CFA+0 1028 1029bool ABISysV_x86_64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { 1030 unwind_plan.Clear(); 1031 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 1032 1033 uint32_t fp_reg_num = dwarf_rbp; 1034 uint32_t sp_reg_num = dwarf_rsp; 1035 uint32_t pc_reg_num = dwarf_rip; 1036 1037 UnwindPlan::RowSP row(new UnwindPlan::Row); 1038 1039 const int32_t ptr_size = 8; 1040 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp, 2 * ptr_size); 1041 row->SetOffset(0); 1042 1043 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true); 1044 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true); 1045 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true); 1046 1047 unwind_plan.AppendRow(row); 1048 unwind_plan.SetSourceName("x86_64 default unwind plan"); 1049 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 1050 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); 1051 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); 1052 return true; 1053} 1054 1055bool ABISysV_x86_64::RegisterIsVolatile(const RegisterInfo *reg_info) { 1056 return !RegisterIsCalleeSaved(reg_info); 1057} 1058 1059// See "Register Usage" in the 1060// "System V Application Binary Interface" 1061// "AMD64 Architecture Processor Supplement" (or "x86-64(tm) Architecture 1062// Processor Supplement" in earlier revisions) (this doc is also commonly 1063// referred to as the x86-64/AMD64 psABI) Edited by Michael Matz, Jan Hubicka, 1064// Andreas Jaeger, and Mark Mitchell current version is 0.99.6 released 1065// 2012-07-02 at http://refspecs.linuxfoundation.org/elf/x86-64-abi-0.99.pdf 1066// It's being revised & updated at https://github.com/hjl-tools/x86-psABI/ 1067 1068bool ABISysV_x86_64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) { 1069 if (!reg_info) 1070 return false; 1071 assert(reg_info->name != nullptr && "unnamed register?"); 1072 std::string Name = std::string(reg_info->name); 1073 bool IsCalleeSaved = 1074 llvm::StringSwitch<bool>(Name) 1075 .Cases("r12", "r13", "r14", "r15", "rbp", "ebp", "rbx", "ebx", true) 1076 .Cases("rip", "eip", "rsp", "esp", "sp", "fp", "pc", true) 1077 .Default(false); 1078 return IsCalleeSaved; 1079} 1080 1081void ABISysV_x86_64::Initialize() { 1082 PluginManager::RegisterPlugin( 1083 GetPluginNameStatic(), "System V ABI for x86_64 targets", CreateInstance); 1084} 1085 1086void ABISysV_x86_64::Terminate() { 1087 PluginManager::UnregisterPlugin(CreateInstance); 1088} 1089 1090lldb_private::ConstString ABISysV_x86_64::GetPluginNameStatic() { 1091 static ConstString g_name("sysv-x86_64"); 1092 return g_name; 1093} 1094 1095// PluginInterface protocol 1096 1097lldb_private::ConstString ABISysV_x86_64::GetPluginName() { 1098 return GetPluginNameStatic(); 1099} 1100 1101uint32_t ABISysV_x86_64::GetPluginVersion() { return 1; } 1102