Author: omjavaid Date: Fri Feb 5 08:37:53 2016 New Revision: 259885 URL: http://llvm.org/viewvc/llvm-project?rev=259885&view=rev Log: Add support to detect arm hard float ABI based binaries for ABISysV_arm
This patch adds logic to detect if underlying binary is using arm hard float abi and use that information while handling return values in ABISysV_arm. Differential revision: http://reviews.llvm.org/D16627 Modified: lldb/trunk/include/lldb/Core/ArchSpec.h lldb/trunk/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp lldb/trunk/source/Plugins/ABI/SysV-arm/ABISysV_arm.h lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Modified: lldb/trunk/include/lldb/Core/ArchSpec.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ArchSpec.h?rev=259885&r1=259884&r2=259885&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ArchSpec.h (original) +++ lldb/trunk/include/lldb/Core/ArchSpec.h Fri Feb 5 08:37:53 2016 @@ -72,6 +72,13 @@ public: eMIPSABI_mask = 0x000ff000 }; + // ARM specific e_flags + enum ARMeflags + { + eARM_abi_soft_float = 0x00000200, + eARM_abi_hard_float = 0x00000400 + }; + enum Core { eCore_arm_generic, Modified: lldb/trunk/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp?rev=259885&r1=259884&r2=259885&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp (original) +++ lldb/trunk/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp Fri Feb 5 08:37:53 2016 @@ -414,6 +414,20 @@ GetReturnValuePassedInMemory(Thread &thr return true; } +bool +ABISysV_arm::IsArmHardFloat (Thread &thread) const +{ + ProcessSP process_sp (thread.GetProcess()); + if (process_sp) + { + const ArchSpec &arch (process_sp->GetTarget().GetArchitecture()); + + return (arch.GetFlags() & ArchSpec::eARM_abi_hard_float) != 0; + } + + return false; +} + ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl (Thread &thread, lldb_private::CompilerType &compiler_type) const @@ -516,19 +530,42 @@ ABISysV_arm::GetReturnValueObjectImpl (T case 64: { static_assert(sizeof(double) == sizeof(uint64_t), ""); - const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2); - uint64_t raw_value; - raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX; - raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) & UINT32_MAX)) << 32; - value.GetScalar() = *reinterpret_cast<double*>(&raw_value); + + if (IsArmHardFloat(thread)) + { + RegisterValue reg_value; + const RegisterInfo *d0_reg_info = reg_ctx->GetRegisterInfoByName("d0", 0); + reg_ctx->ReadRegister(d0_reg_info, reg_value); + value.GetScalar() = reg_value.GetAsDouble(); + } + else + { + uint64_t raw_value; + const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2); + raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX; + raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) & UINT32_MAX)) << 32; + value.GetScalar() = *reinterpret_cast<double*>(&raw_value); + } break; } case 16: // Half precision returned after a conversion to single precision case 32: { static_assert(sizeof(float) == sizeof(uint32_t), ""); - uint32_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX; - value.GetScalar() = *reinterpret_cast<float*>(&raw_value); + + if (IsArmHardFloat(thread)) + { + RegisterValue reg_value; + const RegisterInfo *s0_reg_info = reg_ctx->GetRegisterInfoByName("s0", 0); + reg_ctx->ReadRegister(s0_reg_info, reg_value); + value.GetScalar() = reg_value.GetAsFloat(); + } + else + { + uint32_t raw_value; + raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX; + value.GetScalar() = *reinterpret_cast<float*>(&raw_value); + } break; } } Modified: lldb/trunk/source/Plugins/ABI/SysV-arm/ABISysV_arm.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-arm/ABISysV_arm.h?rev=259885&r1=259884&r2=259885&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ABI/SysV-arm/ABISysV_arm.h (original) +++ lldb/trunk/source/Plugins/ABI/SysV-arm/ABISysV_arm.h Fri Feb 5 08:37:53 2016 @@ -79,6 +79,9 @@ public: const lldb_private::RegisterInfo * GetRegisterInfoArray (uint32_t &count) override; + bool + IsArmHardFloat (lldb_private::Thread &thread) const; + //------------------------------------------------------------------ // Static Functions //------------------------------------------------------------------ Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp?rev=259885&r1=259884&r2=259885&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original) +++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Fri Feb 5 08:37:53 2016 @@ -1562,6 +1562,15 @@ ObjectFileELF::GetSectionHeaderInfo(Sect } } + if (arch_spec.GetMachine() == llvm::Triple::arm || + arch_spec.GetMachine() == llvm::Triple::thumb) + { + if (header.e_flags & llvm::ELF::EF_ARM_SOFT_FLOAT) + arch_spec.SetFlags (ArchSpec::eARM_abi_soft_float); + else if (header.e_flags & llvm::ELF::EF_ARM_VFP_FLOAT) + arch_spec.SetFlags (ArchSpec::eARM_abi_hard_float); + } + // If there are no section headers we are done. if (header.e_shnum == 0) return 0; _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits