1//===----------------------- ABISysV_i386.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#include "ABISysV_i386.h" 9 10#include "llvm/ADT/STLExtras.h" 11#include "llvm/ADT/Triple.h" 12 13#include "lldb/Core/Module.h" 14#include "lldb/Core/PluginManager.h" 15#include "lldb/Core/Value.h" 16#include "lldb/Core/ValueObjectConstResult.h" 17#include "lldb/Core/ValueObjectMemory.h" 18#include "lldb/Core/ValueObjectRegister.h" 19#include "lldb/Symbol/UnwindPlan.h" 20#include "lldb/Target/Process.h" 21#include "lldb/Target/RegisterContext.h" 22#include "lldb/Target/StackFrame.h" 23#include "lldb/Target/Target.h" 24#include "lldb/Target/Thread.h" 25#include "lldb/Utility/ConstString.h" 26#include "lldb/Utility/DataExtractor.h" 27#include "lldb/Utility/Log.h" 28#include "lldb/Utility/RegisterValue.h" 29#include "lldb/Utility/Status.h" 30 31using namespace lldb; 32using namespace lldb_private; 33 34// This source file uses the following document as a reference: 35//==================================================================== 36// System V Application Binary Interface 37// Intel386 Architecture Processor Supplement, Version 1.0 38// Edited by 39// H.J. Lu, David L Kreitzer, Milind Girkar, Zia Ansari 40// 41// (Based on 42// System V Application Binary Interface, 43// AMD64 Architecture Processor Supplement, 44// Edited by 45// H.J. Lu, Michael Matz, Milind Girkar, Jan Hubicka, 46// Andreas Jaeger, Mark Mitchell) 47// 48// February 3, 2015 49//==================================================================== 50 51// DWARF Register Number Mapping 52// See Table 2.14 of the reference document (specified on top of this file) 53// Comment: Table 2.14 is followed till 'mm' entries. After that, all entries 54// are ignored here. 55 56enum dwarf_regnums { 57 dwarf_eax = 0, 58 dwarf_ecx, 59 dwarf_edx, 60 dwarf_ebx, 61 dwarf_esp, 62 dwarf_ebp, 63 dwarf_esi, 64 dwarf_edi, 65 dwarf_eip, 66 dwarf_eflags, 67 68 dwarf_st0 = 11, 69 dwarf_st1, 70 dwarf_st2, 71 dwarf_st3, 72 dwarf_st4, 73 dwarf_st5, 74 dwarf_st6, 75 dwarf_st7, 76 77 dwarf_xmm0 = 21, 78 dwarf_xmm1, 79 dwarf_xmm2, 80 dwarf_xmm3, 81 dwarf_xmm4, 82 dwarf_xmm5, 83 dwarf_xmm6, 84 dwarf_xmm7, 85 dwarf_ymm0 = dwarf_xmm0, 86 dwarf_ymm1 = dwarf_xmm1, 87 dwarf_ymm2 = dwarf_xmm2, 88 dwarf_ymm3 = dwarf_xmm3, 89 dwarf_ymm4 = dwarf_xmm4, 90 dwarf_ymm5 = dwarf_xmm5, 91 dwarf_ymm6 = dwarf_xmm6, 92 dwarf_ymm7 = dwarf_xmm7, 93 94 dwarf_mm0 = 29, 95 dwarf_mm1, 96 dwarf_mm2, 97 dwarf_mm3, 98 dwarf_mm4, 99 dwarf_mm5, 100 dwarf_mm6, 101 dwarf_mm7, 102 103 dwarf_bnd0 = 101, 104 dwarf_bnd1, 105 dwarf_bnd2, 106 dwarf_bnd3 107}; 108 109static RegisterInfo g_register_infos[] = { 110 // clang-format off 111 //NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE VALUE INVAL DYN EXPR SZ 112 //========== ======= == === ============= ==================== =================== =================== ========================= =================== =================== ======= ======= ======== == 113 {"eax", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_eax, dwarf_eax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 114 {"ebx", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 115 {"ecx", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_ecx, dwarf_ecx, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 116 {"edx", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_edx, dwarf_edx, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 117 {"esi", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_esi, dwarf_esi, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 118 {"edi", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_edi, dwarf_edi, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 119 {"ebp", "fp", 4, 0, eEncodingUint, eFormatHex, {dwarf_ebp, dwarf_ebp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 120 {"esp", "sp", 4, 0, eEncodingUint, eFormatHex, {dwarf_esp, dwarf_esp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 121 {"eip", "pc", 4, 0, eEncodingUint, eFormatHex, {dwarf_eip, dwarf_eip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 122 {"eflags", 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}, 123 {"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}, 124 {"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}, 125 {"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}, 126 {"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}, 127 {"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}, 128 {"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}, 129 {"st0", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 130 {"st1", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 131 {"st2", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 132 {"st3", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 133 {"st4", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 134 {"st5", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 135 {"st6", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 136 {"st7", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 137 {"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}, 138 {"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}, 139 {"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}, 140 {"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}, 141 {"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}, 142 {"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}, 143 {"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}, 144 {"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}, 145 {"xmm0", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 146 {"xmm1", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 147 {"xmm2", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 148 {"xmm3", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 149 {"xmm4", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 150 {"xmm5", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 151 {"xmm6", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 152 {"xmm7", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 153 {"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}, 154 {"ymm0", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 155 {"ymm1", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 156 {"ymm2", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 157 {"ymm3", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 158 {"ymm4", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 159 {"ymm5", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 160 {"ymm6", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 161 {"ymm7", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 162 {"bnd0", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64,{dwarf_bnd0, dwarf_bnd0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 163 {"bnd1", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64,{dwarf_bnd1, dwarf_bnd1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 164 {"bnd2", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64,{dwarf_bnd2, dwarf_bnd2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 165 {"bnd3", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64,{dwarf_bnd3, dwarf_bnd3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}, 166 {"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}, 167 {"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} 168 // clang-format on 169}; 170 171static const uint32_t k_num_register_infos = 172 llvm::array_lengthof(g_register_infos); 173static bool g_register_info_names_constified = false; 174 175const lldb_private::RegisterInfo * 176ABISysV_i386::GetRegisterInfoArray(uint32_t &count) { 177 // Make the C-string names and alt_names for the register infos into const 178 // C-string values by having the ConstString unique the names in the global 179 // constant C-string pool. 180 if (!g_register_info_names_constified) { 181 g_register_info_names_constified = true; 182 for (uint32_t i = 0; i < k_num_register_infos; ++i) { 183 if (g_register_infos[i].name) 184 g_register_infos[i].name = 185 ConstString(g_register_infos[i].name).GetCString(); 186 if (g_register_infos[i].alt_name) 187 g_register_infos[i].alt_name = 188 ConstString(g_register_infos[i].alt_name).GetCString(); 189 } 190 } 191 count = k_num_register_infos; 192 return g_register_infos; 193} 194 195// Static Functions 196 197ABISP 198ABISysV_i386::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { 199 if (arch.GetTriple().getVendor() != llvm::Triple::Apple) { 200 if (arch.GetTriple().getArch() == llvm::Triple::x86) { 201 return ABISP( 202 new ABISysV_i386(std::move(process_sp), MakeMCRegisterInfo(arch))); 203 } 204 } 205 return ABISP(); 206} 207 208bool ABISysV_i386::PrepareTrivialCall(Thread &thread, addr_t sp, 209 addr_t func_addr, addr_t return_addr, 210 llvm::ArrayRef<addr_t> args) const { 211 RegisterContext *reg_ctx = thread.GetRegisterContext().get(); 212 213 if (!reg_ctx) 214 return false; 215 216 uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( 217 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 218 uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( 219 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 220 221 // While using register info to write a register value to memory, the 222 // register info just needs to have the correct size of a 32 bit register, 223 // the actual register it pertains to is not important, just the size needs 224 // to be correct. "eax" is used here for this purpose. 225 const RegisterInfo *reg_info_32 = reg_ctx->GetRegisterInfoByName("eax"); 226 if (!reg_info_32) 227 return false; // TODO this should actually never happen 228 229 Status error; 230 RegisterValue reg_value; 231 232 // Make room for the argument(s) on the stack 233 sp -= 4 * args.size(); 234 235 // SP Alignment 236 sp &= ~(16ull - 1ull); // 16-byte alignment 237 238 // Write arguments onto the stack 239 addr_t arg_pos = sp; 240 for (addr_t arg : args) { 241 reg_value.SetUInt32(arg); 242 error = reg_ctx->WriteRegisterValueToMemory( 243 reg_info_32, arg_pos, reg_info_32->byte_size, reg_value); 244 if (error.Fail()) 245 return false; 246 arg_pos += 4; 247 } 248 249 // The return address is pushed onto the stack 250 sp -= 4; 251 reg_value.SetUInt32(return_addr); 252 error = reg_ctx->WriteRegisterValueToMemory( 253 reg_info_32, sp, reg_info_32->byte_size, reg_value); 254 if (error.Fail()) 255 return false; 256 257 // Setting %esp to the actual stack value. 258 if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp)) 259 return false; 260 261 // Setting %eip to the address of the called function. 262 if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, func_addr)) 263 return false; 264 265 return true; 266} 267 268static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width, 269 bool is_signed, Process *process, 270 addr_t ¤t_stack_argument) { 271 uint32_t byte_size = (bit_width + (8 - 1)) / 8; 272 Status error; 273 274 if (!process) 275 return false; 276 277 if (process->ReadScalarIntegerFromMemory(current_stack_argument, byte_size, 278 is_signed, scalar, error)) { 279 current_stack_argument += byte_size; 280 return true; 281 } 282 return false; 283} 284 285bool ABISysV_i386::GetArgumentValues(Thread &thread, ValueList &values) const { 286 unsigned int num_values = values.GetSize(); 287 unsigned int value_index; 288 289 RegisterContext *reg_ctx = thread.GetRegisterContext().get(); 290 291 if (!reg_ctx) 292 return false; 293 294 // Get pointer to the first stack argument 295 addr_t sp = reg_ctx->GetSP(0); 296 if (!sp) 297 return false; 298 299 addr_t current_stack_argument = sp + 4; // jump over return address 300 301 for (value_index = 0; value_index < num_values; ++value_index) { 302 Value *value = values.GetValueAtIndex(value_index); 303 304 if (!value) 305 return false; 306 307 // Currently: Support for extracting values with Clang QualTypes only. 308 CompilerType compiler_type(value->GetCompilerType()); 309 llvm::Optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread); 310 if (bit_size) { 311 bool is_signed; 312 if (compiler_type.IsIntegerOrEnumerationType(is_signed)) { 313 ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, 314 thread.GetProcess().get(), current_stack_argument); 315 } else if (compiler_type.IsPointerType()) { 316 ReadIntegerArgument(value->GetScalar(), *bit_size, false, 317 thread.GetProcess().get(), current_stack_argument); 318 } 319 } 320 } 321 return true; 322} 323 324Status ABISysV_i386::SetReturnValueObject(lldb::StackFrameSP &frame_sp, 325 lldb::ValueObjectSP &new_value_sp) { 326 Status error; 327 if (!new_value_sp) { 328 error.SetErrorString("Empty value object for return value."); 329 return error; 330 } 331 332 CompilerType compiler_type = new_value_sp->GetCompilerType(); 333 if (!compiler_type) { 334 error.SetErrorString("Null clang type for return value."); 335 return error; 336 } 337 338 const uint32_t type_flags = compiler_type.GetTypeInfo(); 339 Thread *thread = frame_sp->GetThread().get(); 340 RegisterContext *reg_ctx = thread->GetRegisterContext().get(); 341 DataExtractor data; 342 Status data_error; 343 size_t num_bytes = new_value_sp->GetData(data, data_error); 344 bool register_write_successful = true; 345 346 if (data_error.Fail()) { 347 error.SetErrorStringWithFormat( 348 "Couldn't convert return value to raw data: %s", 349 data_error.AsCString()); 350 return error; 351 } 352 353 // Following "IF ELSE" block categorizes various 'Fundamental Data Types'. 354 // The terminology 'Fundamental Data Types' used here is adopted from Table 355 // 2.1 of the reference document (specified on top of this file) 356 357 if (type_flags & eTypeIsPointer) // 'Pointer' 358 { 359 if (num_bytes != sizeof(uint32_t)) { 360 error.SetErrorString("Pointer to be returned is not 4 bytes wide"); 361 return error; 362 } 363 lldb::offset_t offset = 0; 364 const RegisterInfo *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0); 365 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes); 366 register_write_successful = 367 reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value); 368 } else if ((type_flags & eTypeIsScalar) || 369 (type_flags & eTypeIsEnumeration)) //'Integral' + 'Floating Point' 370 { 371 lldb::offset_t offset = 0; 372 const RegisterInfo *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0); 373 374 if (type_flags & eTypeIsInteger) // 'Integral' except enum 375 { 376 switch (num_bytes) { 377 default: 378 break; 379 case 16: 380 // For clang::BuiltinType::UInt128 & Int128 ToDo: Need to decide how to 381 // handle it 382 break; 383 case 8: { 384 uint32_t raw_value_low = data.GetMaxU32(&offset, 4); 385 const RegisterInfo *edx_info = reg_ctx->GetRegisterInfoByName("edx", 0); 386 uint32_t raw_value_high = data.GetMaxU32(&offset, num_bytes - offset); 387 register_write_successful = 388 (reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value_low) && 389 reg_ctx->WriteRegisterFromUnsigned(edx_info, raw_value_high)); 390 break; 391 } 392 case 4: 393 case 2: 394 case 1: { 395 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes); 396 register_write_successful = 397 reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value); 398 break; 399 } 400 } 401 } else if (type_flags & eTypeIsEnumeration) // handles enum 402 { 403 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes); 404 register_write_successful = 405 reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value); 406 } else if (type_flags & eTypeIsFloat) // 'Floating Point' 407 { 408 RegisterValue st0_value, fstat_value, ftag_value; 409 const RegisterInfo *st0_info = reg_ctx->GetRegisterInfoByName("st0", 0); 410 const RegisterInfo *fstat_info = 411 reg_ctx->GetRegisterInfoByName("fstat", 0); 412 const RegisterInfo *ftag_info = reg_ctx->GetRegisterInfoByName("ftag", 0); 413 414 /* According to Page 3-12 of document 415 System V Application Binary Interface, Intel386 Architecture Processor 416 Supplement, Fourth Edition 417 To return Floating Point values, all st% registers except st0 should be 418 empty after exiting from 419 a function. This requires setting fstat and ftag registers to specific 420 values. 421 fstat: The TOP field of fstat should be set to a value [0,7]. ABI doesn't 422 specify the specific 423 value of TOP in case of function return. Hence, we set the TOP field to 7 424 by our choice. */ 425 uint32_t value_fstat_u32 = 0x00003800; 426 427 /* ftag: Implication of setting TOP to 7 and indicating all st% registers 428 empty except st0 is to set 429 7th bit of 4th byte of FXSAVE area to 1 and all other bits of this byte to 430 0. This is in accordance 431 with the document Intel 64 and IA-32 Architectures Software Developer's 432 Manual, January 2015 */ 433 uint32_t value_ftag_u32 = 0x00000080; 434 435 if (num_bytes <= 12) // handles float, double, long double, __float80 436 { 437 long double value_long_dbl = 0.0; 438 if (num_bytes == 4) 439 value_long_dbl = data.GetFloat(&offset); 440 else if (num_bytes == 8) 441 value_long_dbl = data.GetDouble(&offset); 442 else if (num_bytes == 12) 443 value_long_dbl = data.GetLongDouble(&offset); 444 else { 445 error.SetErrorString("Invalid number of bytes for this return type"); 446 return error; 447 } 448 st0_value.SetLongDouble(value_long_dbl); 449 fstat_value.SetUInt32(value_fstat_u32); 450 ftag_value.SetUInt32(value_ftag_u32); 451 register_write_successful = 452 reg_ctx->WriteRegister(st0_info, st0_value) && 453 reg_ctx->WriteRegister(fstat_info, fstat_value) && 454 reg_ctx->WriteRegister(ftag_info, ftag_value); 455 } else if (num_bytes == 16) // handles __float128 456 { 457 error.SetErrorString("Implementation is missing for this clang type."); 458 } 459 } else { 460 // Neither 'Integral' nor 'Floating Point'. If flow reaches here then 461 // check type_flags. This type_flags is not a valid type. 462 error.SetErrorString("Invalid clang type"); 463 } 464 } else { 465 /* 'Complex Floating Point', 'Packed', 'Decimal Floating Point' and 466 'Aggregate' data types 467 are yet to be implemented */ 468 error.SetErrorString("Currently only Integral and Floating Point clang " 469 "types are supported."); 470 } 471 if (!register_write_successful) 472 error.SetErrorString("Register writing failed"); 473 return error; 474} 475 476ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple( 477 Thread &thread, CompilerType &return_compiler_type) const { 478 ValueObjectSP return_valobj_sp; 479 Value value; 480 481 if (!return_compiler_type) 482 return return_valobj_sp; 483 484 value.SetCompilerType(return_compiler_type); 485 486 RegisterContext *reg_ctx = thread.GetRegisterContext().get(); 487 if (!reg_ctx) 488 return return_valobj_sp; 489 490 const uint32_t type_flags = return_compiler_type.GetTypeInfo(); 491 492 unsigned eax_id = 493 reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB]; 494 unsigned edx_id = 495 reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB]; 496 497 // Following "IF ELSE" block categorizes various 'Fundamental Data Types'. 498 // The terminology 'Fundamental Data Types' used here is adopted from Table 499 // 2.1 of the reference document (specified on top of this file) 500 501 if (type_flags & eTypeIsPointer) // 'Pointer' 502 { 503 uint32_t ptr = 504 thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 505 0xffffffff; 506 value.SetValueType(Value::eValueTypeScalar); 507 value.GetScalar() = ptr; 508 return_valobj_sp = ValueObjectConstResult::Create( 509 thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); 510 } else if ((type_flags & eTypeIsScalar) || 511 (type_flags & eTypeIsEnumeration)) //'Integral' + 'Floating Point' 512 { 513 value.SetValueType(Value::eValueTypeScalar); 514 llvm::Optional<uint64_t> byte_size = 515 return_compiler_type.GetByteSize(nullptr); 516 if (!byte_size) 517 return return_valobj_sp; 518 bool success = false; 519 520 if (type_flags & eTypeIsInteger) // 'Integral' except enum 521 { 522 const bool is_signed = ((type_flags & eTypeIsSigned) != 0); 523 uint64_t raw_value = 524 thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 525 0xffffffff; 526 raw_value |= 527 (thread.GetRegisterContext()->ReadRegisterAsUnsigned(edx_id, 0) & 528 0xffffffff) 529 << 32; 530 531 switch (*byte_size) { 532 default: 533 break; 534 535 case 16: 536 // For clang::BuiltinType::UInt128 & Int128 ToDo: Need to decide how to 537 // handle it 538 break; 539 540 case 8: 541 if (is_signed) 542 value.GetScalar() = (int64_t)(raw_value); 543 else 544 value.GetScalar() = (uint64_t)(raw_value); 545 success = true; 546 break; 547 548 case 4: 549 if (is_signed) 550 value.GetScalar() = (int32_t)(raw_value & UINT32_MAX); 551 else 552 value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX); 553 success = true; 554 break; 555 556 case 2: 557 if (is_signed) 558 value.GetScalar() = (int16_t)(raw_value & UINT16_MAX); 559 else 560 value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX); 561 success = true; 562 break; 563 564 case 1: 565 if (is_signed) 566 value.GetScalar() = (int8_t)(raw_value & UINT8_MAX); 567 else 568 value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX); 569 success = true; 570 break; 571 } 572 573 if (success) 574 return_valobj_sp = ValueObjectConstResult::Create( 575 thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); 576 } else if (type_flags & eTypeIsEnumeration) // handles enum 577 { 578 uint32_t enm = 579 thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 580 0xffffffff; 581 value.SetValueType(Value::eValueTypeScalar); 582 value.GetScalar() = enm; 583 return_valobj_sp = ValueObjectConstResult::Create( 584 thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); 585 } else if (type_flags & eTypeIsFloat) // 'Floating Point' 586 { 587 if (*byte_size <= 12) // handles float, double, long double, __float80 588 { 589 const RegisterInfo *st0_info = reg_ctx->GetRegisterInfoByName("st0", 0); 590 RegisterValue st0_value; 591 592 if (reg_ctx->ReadRegister(st0_info, st0_value)) { 593 DataExtractor data; 594 if (st0_value.GetData(data)) { 595 lldb::offset_t offset = 0; 596 long double value_long_double = data.GetLongDouble(&offset); 597 598 // float is 4 bytes. 599 if (*byte_size == 4) { 600 float value_float = (float)value_long_double; 601 value.GetScalar() = value_float; 602 success = true; 603 } else if (*byte_size == 8) { 604 // double is 8 bytes 605 // On Android Platform: long double is also 8 bytes It will be 606 // handled here only. 607 double value_double = (double)value_long_double; 608 value.GetScalar() = value_double; 609 success = true; 610 } else if (*byte_size == 12) { 611 // long double and __float80 are 12 bytes on i386. 612 value.GetScalar() = value_long_double; 613 success = true; 614 } 615 } 616 } 617 618 if (success) 619 return_valobj_sp = ValueObjectConstResult::Create( 620 thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); 621 } else if (*byte_size == 16) // handles __float128 622 { 623 lldb::addr_t storage_addr = (uint32_t)( 624 thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 625 0xffffffff); 626 return_valobj_sp = ValueObjectMemory::Create( 627 &thread, "", Address(storage_addr, nullptr), return_compiler_type); 628 } 629 } else // Neither 'Integral' nor 'Floating Point' 630 { 631 // If flow reaches here then check type_flags This type_flags is 632 // unhandled 633 } 634 } else if (type_flags & eTypeIsComplex) // 'Complex Floating Point' 635 { 636 // ToDo: Yet to be implemented 637 } else if (type_flags & eTypeIsVector) // 'Packed' 638 { 639 llvm::Optional<uint64_t> byte_size = 640 return_compiler_type.GetByteSize(nullptr); 641 if (byte_size && *byte_size > 0) { 642 const RegisterInfo *vec_reg = reg_ctx->GetRegisterInfoByName("xmm0", 0); 643 if (vec_reg == nullptr) 644 vec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0); 645 646 if (vec_reg) { 647 if (*byte_size <= vec_reg->byte_size) { 648 ProcessSP process_sp(thread.GetProcess()); 649 if (process_sp) { 650 std::unique_ptr<DataBufferHeap> heap_data_up( 651 new DataBufferHeap(*byte_size, 0)); 652 const ByteOrder byte_order = process_sp->GetByteOrder(); 653 RegisterValue reg_value; 654 if (reg_ctx->ReadRegister(vec_reg, reg_value)) { 655 Status error; 656 if (reg_value.GetAsMemoryData(vec_reg, heap_data_up->GetBytes(), 657 heap_data_up->GetByteSize(), 658 byte_order, error)) { 659 DataExtractor data(DataBufferSP(heap_data_up.release()), 660 byte_order, 661 process_sp->GetTarget() 662 .GetArchitecture() 663 .GetAddressByteSize()); 664 return_valobj_sp = ValueObjectConstResult::Create( 665 &thread, return_compiler_type, ConstString(""), data); 666 } 667 } 668 } 669 } else if (*byte_size <= vec_reg->byte_size * 2) { 670 const RegisterInfo *vec_reg2 = 671 reg_ctx->GetRegisterInfoByName("xmm1", 0); 672 if (vec_reg2) { 673 ProcessSP process_sp(thread.GetProcess()); 674 if (process_sp) { 675 std::unique_ptr<DataBufferHeap> heap_data_up( 676 new DataBufferHeap(*byte_size, 0)); 677 const ByteOrder byte_order = process_sp->GetByteOrder(); 678 RegisterValue reg_value; 679 RegisterValue reg_value2; 680 if (reg_ctx->ReadRegister(vec_reg, reg_value) && 681 reg_ctx->ReadRegister(vec_reg2, reg_value2)) { 682 683 Status error; 684 if (reg_value.GetAsMemoryData(vec_reg, heap_data_up->GetBytes(), 685 vec_reg->byte_size, byte_order, 686 error) && 687 reg_value2.GetAsMemoryData( 688 vec_reg2, heap_data_up->GetBytes() + vec_reg->byte_size, 689 heap_data_up->GetByteSize() - vec_reg->byte_size, 690 byte_order, error)) { 691 DataExtractor data(DataBufferSP(heap_data_up.release()), 692 byte_order, 693 process_sp->GetTarget() 694 .GetArchitecture() 695 .GetAddressByteSize()); 696 return_valobj_sp = ValueObjectConstResult::Create( 697 &thread, return_compiler_type, ConstString(""), data); 698 } 699 } 700 } 701 } 702 } 703 } 704 } 705 } else // 'Decimal Floating Point' 706 { 707 // ToDo: Yet to be implemented 708 } 709 return return_valobj_sp; 710} 711 712ValueObjectSP ABISysV_i386::GetReturnValueObjectImpl( 713 Thread &thread, CompilerType &return_compiler_type) const { 714 ValueObjectSP return_valobj_sp; 715 716 if (!return_compiler_type) 717 return return_valobj_sp; 718 719 ExecutionContext exe_ctx(thread.shared_from_this()); 720 return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type); 721 if (return_valobj_sp) 722 return return_valobj_sp; 723 724 RegisterContextSP reg_ctx_sp = thread.GetRegisterContext(); 725 if (!reg_ctx_sp) 726 return return_valobj_sp; 727 728 if (return_compiler_type.IsAggregateType()) { 729 unsigned eax_id = 730 reg_ctx_sp->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB]; 731 lldb::addr_t storage_addr = (uint32_t)( 732 thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 733 0xffffffff); 734 return_valobj_sp = ValueObjectMemory::Create( 735 &thread, "", Address(storage_addr, nullptr), return_compiler_type); 736 } 737 738 return return_valobj_sp; 739} 740 741// This defines CFA as esp+4 742// The saved pc is at CFA-4 (i.e. esp+0) 743// The saved esp is CFA+0 744 745bool ABISysV_i386::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { 746 unwind_plan.Clear(); 747 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 748 749 uint32_t sp_reg_num = dwarf_esp; 750 uint32_t pc_reg_num = dwarf_eip; 751 752 UnwindPlan::RowSP row(new UnwindPlan::Row); 753 row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 4); 754 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, false); 755 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true); 756 unwind_plan.AppendRow(row); 757 unwind_plan.SetSourceName("i386 at-func-entry default"); 758 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 759 return true; 760} 761 762// This defines CFA as ebp+8 763// The saved pc is at CFA-4 (i.e. ebp+4) 764// The saved ebp is at CFA-8 (i.e. ebp+0) 765// The saved esp is CFA+0 766 767bool ABISysV_i386::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { 768 unwind_plan.Clear(); 769 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 770 771 uint32_t fp_reg_num = dwarf_ebp; 772 uint32_t sp_reg_num = dwarf_esp; 773 uint32_t pc_reg_num = dwarf_eip; 774 775 UnwindPlan::RowSP row(new UnwindPlan::Row); 776 const int32_t ptr_size = 4; 777 778 row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size); 779 row->SetOffset(0); 780 781 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true); 782 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true); 783 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true); 784 785 unwind_plan.AppendRow(row); 786 unwind_plan.SetSourceName("i386 default unwind plan"); 787 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 788 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); 789 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); 790 return true; 791} 792 793// According to "Register Usage" in reference document (specified on top of 794// this source file) ebx, ebp, esi, edi and esp registers are preserved i.e. 795// non-volatile i.e. callee-saved on i386 796bool ABISysV_i386::RegisterIsCalleeSaved(const RegisterInfo *reg_info) { 797 if (!reg_info) 798 return false; 799 800 // Saved registers are ebx, ebp, esi, edi, esp, eip 801 const char *name = reg_info->name; 802 if (name[0] == 'e') { 803 switch (name[1]) { 804 case 'b': 805 if (name[2] == 'x' || name[2] == 'p') 806 return name[3] == '\0'; 807 break; 808 case 'd': 809 if (name[2] == 'i') 810 return name[3] == '\0'; 811 break; 812 case 'i': 813 if (name[2] == 'p') 814 return name[3] == '\0'; 815 break; 816 case 's': 817 if (name[2] == 'i' || name[2] == 'p') 818 return name[3] == '\0'; 819 break; 820 } 821 } 822 823 if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp 824 return true; 825 if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp 826 return true; 827 if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc 828 return true; 829 830 return false; 831} 832 833void ABISysV_i386::Initialize() { 834 PluginManager::RegisterPlugin( 835 GetPluginNameStatic(), "System V ABI for i386 targets", CreateInstance); 836} 837 838void ABISysV_i386::Terminate() { 839 PluginManager::UnregisterPlugin(CreateInstance); 840} 841 842// PluginInterface protocol 843 844lldb_private::ConstString ABISysV_i386::GetPluginNameStatic() { 845 static ConstString g_name("sysv-i386"); 846 return g_name; 847} 848 849lldb_private::ConstString ABISysV_i386::GetPluginName() { 850 return GetPluginNameStatic(); 851} 852