summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
diff options
context:
space:
mode:
authorJason Molenda <jmolenda@apple.com>2015-11-05 22:51:29 +0000
committerJason Molenda <jmolenda@apple.com>2015-11-05 22:51:29 +0000
commit9b6b069a387b5c7ecbc7e406a60bbab988cf4b2b (patch)
tree97c36d9bc2d41afa019849fc9976a714c38dfb20 /lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
parent13c30d2f7d6802683e667a542c80e51eb6d7dcca (diff)
downloadbcm5719-llvm-9b6b069a387b5c7ecbc7e406a60bbab988cf4b2b.tar.gz
bcm5719-llvm-9b6b069a387b5c7ecbc7e406a60bbab988cf4b2b.zip
Add support for the armv7k ABI which has some small
changes from the normal armv7 ABI used on darwin. llvm-svn: 252225
Diffstat (limited to 'lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp')
-rw-r--r--lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp111
1 files changed, 109 insertions, 2 deletions
diff --git a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
index da03a5e7136..3b9b0f34607 100644
--- a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
+++ b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
@@ -238,8 +238,8 @@ ABIMacOSX_arm::PrepareTrivialCall (Thread &thread,
size_t num_stack_regs = ae - ai;
sp -= (num_stack_regs * 4);
- // Keep the stack 8 byte aligned, not that we need to
- sp &= ~(8ull-1ull);
+ // Keep the stack 16 byte aligned
+ sp &= ~(16ull-1ull);
// just using arg1 to get the right size
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
@@ -413,6 +413,26 @@ ABIMacOSX_arm::GetArgumentValues (Thread &thread,
return true;
}
+bool
+ABIMacOSX_arm::IsArmv7kProcess (Thread *thread) const
+{
+ bool is_armv7k = false;
+ if (thread)
+ {
+ ProcessSP process_sp (thread->GetProcess());
+ if (process_sp)
+ {
+ const ArchSpec &arch (process_sp->GetTarget().GetArchitecture());
+ const ArchSpec::Core system_core = arch.GetCore();
+ if (system_core == ArchSpec::eCore_arm_armv7k)
+ {
+ is_armv7k = true;
+ }
+ }
+ }
+ return is_armv7k;
+}
+
ValueObjectSP
ABIMacOSX_arm::GetReturnValueObjectImpl (Thread &thread,
lldb_private::CompilerType &compiler_type) const
@@ -443,6 +463,60 @@ ABIMacOSX_arm::GetReturnValueObjectImpl (Thread &thread,
{
default:
return return_valobj_sp;
+ case 128:
+ if (IsArmv7kProcess (&thread))
+ {
+ // "A composite type not larger than 16 bytes is returned in r0-r3. The format is
+ // as if the result had been stored in memory at a word-aligned address and then
+ // loaded into r0-r3 with an ldm instruction"
+ {
+ const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfoByName("r1", 0);
+ const RegisterInfo *r2_reg_info = reg_ctx->GetRegisterInfoByName("r2", 0);
+ const RegisterInfo *r3_reg_info = reg_ctx->GetRegisterInfoByName("r3", 0);
+ if (r1_reg_info && r2_reg_info && r3_reg_info)
+ {
+ const size_t byte_size = compiler_type.GetByteSize(&thread);
+ ProcessSP process_sp (thread.GetProcess());
+ if (byte_size <= r0_reg_info->byte_size + r1_reg_info->byte_size + r2_reg_info->byte_size + r3_reg_info->byte_size
+ && process_sp)
+ {
+ std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
+ const ByteOrder byte_order = process_sp->GetByteOrder();
+ RegisterValue r0_reg_value;
+ RegisterValue r1_reg_value;
+ RegisterValue r2_reg_value;
+ RegisterValue r3_reg_value;
+ if (reg_ctx->ReadRegister(r0_reg_info, r0_reg_value)
+ && reg_ctx->ReadRegister(r1_reg_info, r1_reg_value)
+ && reg_ctx->ReadRegister(r2_reg_info, r2_reg_value)
+ && reg_ctx->ReadRegister(r3_reg_info, r3_reg_value))
+ {
+ Error error;
+ if (r0_reg_value.GetAsMemoryData (r0_reg_info, heap_data_ap->GetBytes()+0, 4, byte_order, error)
+ && r1_reg_value.GetAsMemoryData (r1_reg_info, heap_data_ap->GetBytes()+4, 4, byte_order, error)
+ && r2_reg_value.GetAsMemoryData (r2_reg_info, heap_data_ap->GetBytes()+8, 4, byte_order, error)
+ && r3_reg_value.GetAsMemoryData (r3_reg_info, heap_data_ap->GetBytes()+12, 4, byte_order, error))
+ {
+ DataExtractor data (DataBufferSP (heap_data_ap.release()),
+ byte_order,
+ process_sp->GetAddressByteSize());
+
+ return_valobj_sp = ValueObjectConstResult::Create (&thread,
+ compiler_type,
+ ConstString(""),
+ data);
+ return return_valobj_sp;
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ return return_valobj_sp;
+ }
+ break;
case 64:
{
const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfoByName("r1", 0);
@@ -555,6 +629,39 @@ ABIMacOSX_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObj
}
}
}
+ else if (num_bytes <= 16 && IsArmv7kProcess (frame_sp->GetThread().get()))
+ {
+ // "A composite type not larger than 16 bytes is returned in r0-r3. The format is
+ // as if the result had been stored in memory at a word-aligned address and then
+ // loaded into r0-r3 with an ldm instruction"
+
+ const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("r0", 0);
+ const RegisterInfo *r1_info = reg_ctx->GetRegisterInfoByName("r1", 0);
+ const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
+ const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0);
+ lldb::offset_t offset = 0;
+ uint32_t bytes_written = 4;
+ uint32_t raw_value = data.GetMaxU64(&offset, 4);
+ if (reg_ctx->WriteRegisterFromUnsigned (r0_info, raw_value) && bytes_written <= num_bytes)
+ {
+ bytes_written += 4;
+ raw_value = data.GetMaxU64(&offset, 4);
+ if (bytes_written <= num_bytes && reg_ctx->WriteRegisterFromUnsigned (r1_info, raw_value))
+ {
+ bytes_written += 4;
+ raw_value = data.GetMaxU64(&offset, 4);
+ if (bytes_written <= num_bytes && reg_ctx->WriteRegisterFromUnsigned (r2_info, raw_value))
+ {
+ bytes_written += 4;
+ raw_value = data.GetMaxU64(&offset, 4);
+ if (bytes_written <= num_bytes && reg_ctx->WriteRegisterFromUnsigned (r3_info, raw_value))
+ {
+ set_it_simple = true;
+ }
+ }
+ }
+ }
+ }
else
{
error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
OpenPOWER on IntegriCloud