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/Symbol/UnwindPlan.h" 17 #include "lldb/Target/Process.h" 18 #include "lldb/Target/RegisterContext.h" 19 #include "lldb/Target/StackFrame.h" 20 #include "lldb/Target/Target.h" 21 #include "lldb/Target/Thread.h" 22 #include "lldb/Utility/ConstString.h" 23 #include "lldb/Utility/DataExtractor.h" 24 #include "lldb/Utility/Log.h" 25 #include "lldb/Utility/RegisterValue.h" 26 #include "lldb/Utility/Status.h" 27 #include "lldb/ValueObject/ValueObjectConstResult.h" 28 #include "lldb/ValueObject/ValueObjectMemory.h" 29 #include "lldb/ValueObject/ValueObjectRegister.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 = Status::FromErrorString("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 = Status::FromErrorString("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 = Status::FromErrorStringWithFormat( 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 = 237 Status::FromErrorString("Pointer to be returned is not 4 bytes wide"); 238 return error; 239 } 240 lldb::offset_t offset = 0; 241 const RegisterInfo *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0); 242 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes); 243 register_write_successful = 244 reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value); 245 } else if ((type_flags & eTypeIsScalar) || 246 (type_flags & eTypeIsEnumeration)) //'Integral' + 'Floating Point' 247 { 248 lldb::offset_t offset = 0; 249 const RegisterInfo *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0); 250 251 if (type_flags & eTypeIsInteger) // 'Integral' except enum 252 { 253 switch (num_bytes) { 254 default: 255 break; 256 case 16: 257 // For clang::BuiltinType::UInt128 & Int128 ToDo: Need to decide how to 258 // handle it 259 break; 260 case 8: { 261 uint32_t raw_value_low = data.GetMaxU32(&offset, 4); 262 const RegisterInfo *edx_info = reg_ctx->GetRegisterInfoByName("edx", 0); 263 uint32_t raw_value_high = data.GetMaxU32(&offset, num_bytes - offset); 264 register_write_successful = 265 (reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value_low) && 266 reg_ctx->WriteRegisterFromUnsigned(edx_info, raw_value_high)); 267 break; 268 } 269 case 4: 270 case 2: 271 case 1: { 272 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes); 273 register_write_successful = 274 reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value); 275 break; 276 } 277 } 278 } else if (type_flags & eTypeIsEnumeration) // handles enum 279 { 280 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes); 281 register_write_successful = 282 reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value); 283 } else if (type_flags & eTypeIsFloat) // 'Floating Point' 284 { 285 RegisterValue st0_value, fstat_value, ftag_value; 286 const RegisterInfo *st0_info = reg_ctx->GetRegisterInfoByName("st0", 0); 287 const RegisterInfo *fstat_info = 288 reg_ctx->GetRegisterInfoByName("fstat", 0); 289 const RegisterInfo *ftag_info = reg_ctx->GetRegisterInfoByName("ftag", 0); 290 291 /* According to Page 3-12 of document 292 System V Application Binary Interface, Intel386 Architecture Processor 293 Supplement, Fourth Edition 294 To return Floating Point values, all st% registers except st0 should be 295 empty after exiting from 296 a function. This requires setting fstat and ftag registers to specific 297 values. 298 fstat: The TOP field of fstat should be set to a value [0,7]. ABI doesn't 299 specify the specific 300 value of TOP in case of function return. Hence, we set the TOP field to 7 301 by our choice. */ 302 uint32_t value_fstat_u32 = 0x00003800; 303 304 /* ftag: Implication of setting TOP to 7 and indicating all st% registers 305 empty except st0 is to set 306 7th bit of 4th byte of FXSAVE area to 1 and all other bits of this byte to 307 0. This is in accordance 308 with the document Intel 64 and IA-32 Architectures Software Developer's 309 Manual, January 2015 */ 310 uint32_t value_ftag_u32 = 0x00000080; 311 312 if (num_bytes <= 12) // handles float, double, long double, __float80 313 { 314 long double value_long_dbl = 0.0; 315 if (num_bytes == 4) 316 value_long_dbl = data.GetFloat(&offset); 317 else if (num_bytes == 8) 318 value_long_dbl = data.GetDouble(&offset); 319 else if (num_bytes == 12) 320 value_long_dbl = data.GetLongDouble(&offset); 321 else { 322 error = Status::FromErrorString( 323 "Invalid number of bytes for this return type"); 324 return error; 325 } 326 st0_value.SetLongDouble(value_long_dbl); 327 fstat_value.SetUInt32(value_fstat_u32); 328 ftag_value.SetUInt32(value_ftag_u32); 329 register_write_successful = 330 reg_ctx->WriteRegister(st0_info, st0_value) && 331 reg_ctx->WriteRegister(fstat_info, fstat_value) && 332 reg_ctx->WriteRegister(ftag_info, ftag_value); 333 } else if (num_bytes == 16) // handles __float128 334 { 335 error = Status::FromErrorString( 336 "Implementation is missing for this clang type."); 337 } 338 } else { 339 // Neither 'Integral' nor 'Floating Point'. If flow reaches here then 340 // check type_flags. This type_flags is not a valid type. 341 error = Status::FromErrorString("Invalid clang type"); 342 } 343 } else { 344 /* 'Complex Floating Point', 'Packed', 'Decimal Floating Point' and 345 'Aggregate' data types 346 are yet to be implemented */ 347 error = Status::FromErrorString( 348 "Currently only Integral and Floating Point clang " 349 "types are supported."); 350 } 351 if (!register_write_successful) 352 error = Status::FromErrorString("Register writing failed"); 353 return error; 354 } 355 356 ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple( 357 Thread &thread, CompilerType &return_compiler_type) const { 358 ValueObjectSP return_valobj_sp; 359 Value value; 360 361 if (!return_compiler_type) 362 return return_valobj_sp; 363 364 value.SetCompilerType(return_compiler_type); 365 366 RegisterContext *reg_ctx = thread.GetRegisterContext().get(); 367 if (!reg_ctx) 368 return return_valobj_sp; 369 370 const uint32_t type_flags = return_compiler_type.GetTypeInfo(); 371 372 unsigned eax_id = 373 reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB]; 374 unsigned edx_id = 375 reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB]; 376 377 // Following "IF ELSE" block categorizes various 'Fundamental Data Types'. 378 // The terminology 'Fundamental Data Types' used here is adopted from Table 379 // 2.1 of the reference document (specified on top of this file) 380 381 if (type_flags & eTypeIsPointer) // 'Pointer' 382 { 383 uint32_t ptr = 384 thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 385 0xffffffff; 386 value.SetValueType(Value::ValueType::Scalar); 387 value.GetScalar() = ptr; 388 return_valobj_sp = ValueObjectConstResult::Create( 389 thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); 390 } else if ((type_flags & eTypeIsScalar) || 391 (type_flags & eTypeIsEnumeration)) //'Integral' + 'Floating Point' 392 { 393 value.SetValueType(Value::ValueType::Scalar); 394 std::optional<uint64_t> byte_size = 395 return_compiler_type.GetByteSize(&thread); 396 if (!byte_size) 397 return return_valobj_sp; 398 bool success = false; 399 400 if (type_flags & eTypeIsInteger) // 'Integral' except enum 401 { 402 const bool is_signed = ((type_flags & eTypeIsSigned) != 0); 403 uint64_t raw_value = 404 thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 405 0xffffffff; 406 raw_value |= 407 (thread.GetRegisterContext()->ReadRegisterAsUnsigned(edx_id, 0) & 408 0xffffffff) 409 << 32; 410 411 switch (*byte_size) { 412 default: 413 break; 414 415 case 16: 416 // For clang::BuiltinType::UInt128 & Int128 ToDo: Need to decide how to 417 // handle it 418 break; 419 420 case 8: 421 if (is_signed) 422 value.GetScalar() = (int64_t)(raw_value); 423 else 424 value.GetScalar() = (uint64_t)(raw_value); 425 success = true; 426 break; 427 428 case 4: 429 if (is_signed) 430 value.GetScalar() = (int32_t)(raw_value & UINT32_MAX); 431 else 432 value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX); 433 success = true; 434 break; 435 436 case 2: 437 if (is_signed) 438 value.GetScalar() = (int16_t)(raw_value & UINT16_MAX); 439 else 440 value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX); 441 success = true; 442 break; 443 444 case 1: 445 if (is_signed) 446 value.GetScalar() = (int8_t)(raw_value & UINT8_MAX); 447 else 448 value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX); 449 success = true; 450 break; 451 } 452 453 if (success) 454 return_valobj_sp = ValueObjectConstResult::Create( 455 thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); 456 } else if (type_flags & eTypeIsEnumeration) // handles enum 457 { 458 uint32_t enm = 459 thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 460 0xffffffff; 461 value.SetValueType(Value::ValueType::Scalar); 462 value.GetScalar() = enm; 463 return_valobj_sp = ValueObjectConstResult::Create( 464 thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); 465 } else if (type_flags & eTypeIsFloat) // 'Floating Point' 466 { 467 if (*byte_size <= 12) // handles float, double, long double, __float80 468 { 469 const RegisterInfo *st0_info = reg_ctx->GetRegisterInfoByName("st0", 0); 470 RegisterValue st0_value; 471 472 if (reg_ctx->ReadRegister(st0_info, st0_value)) { 473 DataExtractor data; 474 if (st0_value.GetData(data)) { 475 lldb::offset_t offset = 0; 476 long double value_long_double = data.GetLongDouble(&offset); 477 478 // float is 4 bytes. 479 if (*byte_size == 4) { 480 float value_float = (float)value_long_double; 481 value.GetScalar() = value_float; 482 success = true; 483 } else if (*byte_size == 8) { 484 // double is 8 bytes 485 // On Android Platform: long double is also 8 bytes It will be 486 // handled here only. 487 double value_double = (double)value_long_double; 488 value.GetScalar() = value_double; 489 success = true; 490 } else if (*byte_size == 12) { 491 // long double and __float80 are 12 bytes on i386. 492 value.GetScalar() = value_long_double; 493 success = true; 494 } 495 } 496 } 497 498 if (success) 499 return_valobj_sp = ValueObjectConstResult::Create( 500 thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); 501 } else if (*byte_size == 16) // handles __float128 502 { 503 lldb::addr_t storage_addr = (uint32_t)( 504 thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 505 0xffffffff); 506 return_valobj_sp = ValueObjectMemory::Create( 507 &thread, "", Address(storage_addr, nullptr), return_compiler_type); 508 } 509 } else // Neither 'Integral' nor 'Floating Point' 510 { 511 // If flow reaches here then check type_flags This type_flags is 512 // unhandled 513 } 514 } else if (type_flags & eTypeIsComplex) // 'Complex Floating Point' 515 { 516 // ToDo: Yet to be implemented 517 } else if (type_flags & eTypeIsVector) // 'Packed' 518 { 519 std::optional<uint64_t> byte_size = 520 return_compiler_type.GetByteSize(&thread); 521 if (byte_size && *byte_size > 0) { 522 const RegisterInfo *vec_reg = reg_ctx->GetRegisterInfoByName("xmm0", 0); 523 if (vec_reg == nullptr) 524 vec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0); 525 526 if (vec_reg) { 527 if (*byte_size <= vec_reg->byte_size) { 528 ProcessSP process_sp(thread.GetProcess()); 529 if (process_sp) { 530 std::unique_ptr<DataBufferHeap> heap_data_up( 531 new DataBufferHeap(*byte_size, 0)); 532 const ByteOrder byte_order = process_sp->GetByteOrder(); 533 RegisterValue reg_value; 534 if (reg_ctx->ReadRegister(vec_reg, reg_value)) { 535 Status error; 536 if (reg_value.GetAsMemoryData(*vec_reg, heap_data_up->GetBytes(), 537 heap_data_up->GetByteSize(), 538 byte_order, error)) { 539 DataExtractor data(DataBufferSP(heap_data_up.release()), 540 byte_order, 541 process_sp->GetTarget() 542 .GetArchitecture() 543 .GetAddressByteSize()); 544 return_valobj_sp = ValueObjectConstResult::Create( 545 &thread, return_compiler_type, ConstString(""), data); 546 } 547 } 548 } 549 } else if (*byte_size <= vec_reg->byte_size * 2) { 550 const RegisterInfo *vec_reg2 = 551 reg_ctx->GetRegisterInfoByName("xmm1", 0); 552 if (vec_reg2) { 553 ProcessSP process_sp(thread.GetProcess()); 554 if (process_sp) { 555 std::unique_ptr<DataBufferHeap> heap_data_up( 556 new DataBufferHeap(*byte_size, 0)); 557 const ByteOrder byte_order = process_sp->GetByteOrder(); 558 RegisterValue reg_value; 559 RegisterValue reg_value2; 560 if (reg_ctx->ReadRegister(vec_reg, reg_value) && 561 reg_ctx->ReadRegister(vec_reg2, reg_value2)) { 562 563 Status error; 564 if (reg_value.GetAsMemoryData( 565 *vec_reg, heap_data_up->GetBytes(), vec_reg->byte_size, 566 byte_order, error) && 567 reg_value2.GetAsMemoryData( 568 *vec_reg2, 569 heap_data_up->GetBytes() + vec_reg->byte_size, 570 heap_data_up->GetByteSize() - vec_reg->byte_size, 571 byte_order, error)) { 572 DataExtractor data(DataBufferSP(heap_data_up.release()), 573 byte_order, 574 process_sp->GetTarget() 575 .GetArchitecture() 576 .GetAddressByteSize()); 577 return_valobj_sp = ValueObjectConstResult::Create( 578 &thread, return_compiler_type, ConstString(""), data); 579 } 580 } 581 } 582 } 583 } 584 } 585 } 586 } else // 'Decimal Floating Point' 587 { 588 // ToDo: Yet to be implemented 589 } 590 return return_valobj_sp; 591 } 592 593 ValueObjectSP ABISysV_i386::GetReturnValueObjectImpl( 594 Thread &thread, CompilerType &return_compiler_type) const { 595 ValueObjectSP return_valobj_sp; 596 597 if (!return_compiler_type) 598 return return_valobj_sp; 599 600 ExecutionContext exe_ctx(thread.shared_from_this()); 601 return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type); 602 if (return_valobj_sp) 603 return return_valobj_sp; 604 605 RegisterContextSP reg_ctx_sp = thread.GetRegisterContext(); 606 if (!reg_ctx_sp) 607 return return_valobj_sp; 608 609 if (return_compiler_type.IsAggregateType()) { 610 unsigned eax_id = 611 reg_ctx_sp->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB]; 612 lldb::addr_t storage_addr = (uint32_t)( 613 thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 614 0xffffffff); 615 return_valobj_sp = ValueObjectMemory::Create( 616 &thread, "", Address(storage_addr, nullptr), return_compiler_type); 617 } 618 619 return return_valobj_sp; 620 } 621 622 // This defines CFA as esp+4 623 // The saved pc is at CFA-4 (i.e. esp+0) 624 // The saved esp is CFA+0 625 626 bool ABISysV_i386::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { 627 unwind_plan.Clear(); 628 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 629 630 uint32_t sp_reg_num = dwarf_esp; 631 uint32_t pc_reg_num = dwarf_eip; 632 633 UnwindPlan::RowSP row(new UnwindPlan::Row); 634 row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 4); 635 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, false); 636 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true); 637 unwind_plan.AppendRow(row); 638 unwind_plan.SetSourceName("i386 at-func-entry default"); 639 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 640 return true; 641 } 642 643 // This defines CFA as ebp+8 644 // The saved pc is at CFA-4 (i.e. ebp+4) 645 // The saved ebp is at CFA-8 (i.e. ebp+0) 646 // The saved esp is CFA+0 647 648 bool ABISysV_i386::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { 649 unwind_plan.Clear(); 650 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 651 652 uint32_t fp_reg_num = dwarf_ebp; 653 uint32_t sp_reg_num = dwarf_esp; 654 uint32_t pc_reg_num = dwarf_eip; 655 656 UnwindPlan::RowSP row(new UnwindPlan::Row); 657 const int32_t ptr_size = 4; 658 659 row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size); 660 row->SetOffset(0); 661 row->SetUnspecifiedRegistersAreUndefined(true); 662 663 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true); 664 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true); 665 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true); 666 667 unwind_plan.AppendRow(row); 668 unwind_plan.SetSourceName("i386 default unwind plan"); 669 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 670 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); 671 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); 672 return true; 673 } 674 675 // According to "Register Usage" in reference document (specified on top of 676 // this source file) ebx, ebp, esi, edi and esp registers are preserved i.e. 677 // non-volatile i.e. callee-saved on i386 678 bool ABISysV_i386::RegisterIsCalleeSaved(const RegisterInfo *reg_info) { 679 if (!reg_info) 680 return false; 681 682 // Saved registers are ebx, ebp, esi, edi, esp, eip 683 const char *name = reg_info->name; 684 if (name[0] == 'e') { 685 switch (name[1]) { 686 case 'b': 687 if (name[2] == 'x' || name[2] == 'p') 688 return name[3] == '\0'; 689 break; 690 case 'd': 691 if (name[2] == 'i') 692 return name[3] == '\0'; 693 break; 694 case 'i': 695 if (name[2] == 'p') 696 return name[3] == '\0'; 697 break; 698 case 's': 699 if (name[2] == 'i' || name[2] == 'p') 700 return name[3] == '\0'; 701 break; 702 } 703 } 704 705 if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp 706 return true; 707 if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp 708 return true; 709 if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc 710 return true; 711 712 return false; 713 } 714 715 void ABISysV_i386::Initialize() { 716 PluginManager::RegisterPlugin( 717 GetPluginNameStatic(), "System V ABI for i386 targets", CreateInstance); 718 } 719 720 void ABISysV_i386::Terminate() { 721 PluginManager::UnregisterPlugin(CreateInstance); 722 } 723