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