summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp51
-rw-r--r--lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.h3
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp9
3 files changed, 56 insertions, 7 deletions
diff --git a/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp b/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
index ef625dece26..14e49ef5991 100644
--- a/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
+++ b/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
@@ -414,6 +414,20 @@ GetReturnValuePassedInMemory(Thread &thread, RegisterContext* reg_ctx, size_t by
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 (Thread &thread,
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;
}
}
diff --git a/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.h b/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.h
index e3b280296a6..11a2601501e 100644
--- a/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.h
+++ b/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.h
@@ -79,6 +79,9 @@ public:
const lldb_private::RegisterInfo *
GetRegisterInfoArray (uint32_t &count) override;
+ bool
+ IsArmHardFloat (lldb_private::Thread &thread) const;
+
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 67be1461d4d..61e5896b862 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -1562,6 +1562,15 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
}
}
+ 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;
OpenPOWER on IntegriCloud