From b6a04a141cb0f0a6b2832f360cc2aaf4569d5d59 Mon Sep 17 00:00:00 2001 From: Tamas Berghammer Date: Wed, 22 Jul 2015 14:53:37 +0000 Subject: [PATCH] Improve SysV ABI for ARM to handle return values with vector return type This is required to print out the rerun value of funcions returning types with the following attributes: __attribute__((__vector_size__(8))); __attribute__((ext_vector_type(2))); Differential revision: http://reviews.llvm.org/D11416 llvm-svn: 242903 --- lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp | 49 +++++++++++++++---- .../return-value/TestReturnValue.py | 11 +++-- lldb/test/functionalities/return-value/call-func.c | 55 +++++++++++++++++----- 3 files changed, 90 insertions(+), 25 deletions(-) diff --git a/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp b/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp index 50a9863..0d305a3 100644 --- a/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp +++ b/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp @@ -398,6 +398,23 @@ ABISysV_arm::GetArgumentValues (Thread &thread, return true; } +static bool +GetReturnValuePassedInMemory(Thread &thread, RegisterContext* reg_ctx, size_t byte_size, Value& value) +{ + Error error; + DataBufferHeap buffer(byte_size, 0); + + const RegisterInfo *r0_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1); + uint32_t address = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX; + thread.GetProcess()->ReadMemory(address, buffer.GetBytes(), buffer.GetByteSize(), error); + + if (error.Fail()) + return false; + + value.SetBytes(buffer.GetBytes(), buffer.GetByteSize()); + return true; +} + ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl (Thread &thread, lldb_private::ClangASTType &clang_type) const @@ -472,6 +489,27 @@ ABISysV_arm::GetReturnValueObjectImpl (Thread &thread, uint32_t ptr = thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX; value.GetScalar() = ptr; } + else if (clang_type.IsVectorType(nullptr, nullptr)) + { + size_t byte_size = clang_type.GetByteSize(&thread); + if (byte_size <= 16) + { + DataBufferHeap buffer(16, 0); + uint32_t* buffer_ptr = (uint32_t*)buffer.GetBytes(); + + for (uint32_t i = 0; 4*i < byte_size; ++i) + { + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i); + buffer_ptr[i] = reg_ctx->ReadRegisterAsUnsigned(reg_info, 0) & UINT32_MAX; + } + value.SetBytes(buffer.GetBytes(), byte_size); + } + else + { + if (!GetReturnValuePassedInMemory(thread, reg_ctx, byte_size, value)) + return return_valobj_sp; + } + } else if (clang_type.IsFloatingPointType(float_count, is_complex)) { if (float_count == 1 && !is_complex) @@ -517,16 +555,7 @@ ABISysV_arm::GetReturnValueObjectImpl (Thread &thread, } else { - RegisterValue r0_reg_value; - uint32_t address = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX; - - Error error; - DataBufferHeap buffer(byte_size, 0); - thread.GetProcess()->ReadMemory(address, buffer.GetBytes(), buffer.GetByteSize(), error); - - if (error.Success()) - value.SetBytes(buffer.GetBytes(), buffer.GetByteSize()); - else + if (!GetReturnValuePassedInMemory(thread, reg_ctx, byte_size, value)) return return_valobj_sp; } } diff --git a/lldb/test/functionalities/return-value/TestReturnValue.py b/lldb/test/functionalities/return-value/TestReturnValue.py index 8791b88..2c7b866 100644 --- a/lldb/test/functionalities/return-value/TestReturnValue.py +++ b/lldb/test/functionalities/return-value/TestReturnValue.py @@ -81,7 +81,7 @@ class ReturnValueTestCase(TestBase): in_child_str = in_child.GetValue() ret_child_str = ret_child.GetValue() - self.assertTrue (in_child_str == ret_child_str) + self.assertEqual(in_child_str, ret_child_str) def do_return_value(self): """Test getting return values from stepping out.""" @@ -213,10 +213,13 @@ class ReturnValueTestCase(TestBase): # icc and gcc don't support this extension. if self.getCompiler().endswith('clang'): - self.return_and_test_struct_value ("return_vector_size_float32") - self.return_and_test_struct_value ("return_ext_vector_size_float32") + self.return_and_test_struct_value ("return_vector_size_float32_8") + self.return_and_test_struct_value ("return_vector_size_float32_16") + self.return_and_test_struct_value ("return_vector_size_float32_32") + self.return_and_test_struct_value ("return_ext_vector_size_float32_2") + self.return_and_test_struct_value ("return_ext_vector_size_float32_4") + self.return_and_test_struct_value ("return_ext_vector_size_float32_8") - if __name__ == '__main__': import atexit lldb.SBDebugger.Initialize() diff --git a/lldb/test/functionalities/return-value/call-func.c b/lldb/test/functionalities/return-value/call-func.c index c7c68d5..0c026ff 100644 --- a/lldb/test/functionalities/return-value/call-func.c +++ b/lldb/test/functionalities/return-value/call-func.c @@ -301,17 +301,46 @@ return_one_int_one_pointer (struct one_int_one_pointer value) return value; } -typedef float vector_size_float32 __attribute__((__vector_size__(16))); -typedef float ext_vector_size_float32 __attribute__((ext_vector_type(4))); +typedef float vector_size_float32_8 __attribute__((__vector_size__(8))); +typedef float vector_size_float32_16 __attribute__((__vector_size__(16))); +typedef float vector_size_float32_32 __attribute__((__vector_size__(32))); -vector_size_float32 -return_vector_size_float32 (vector_size_float32 value) +typedef float ext_vector_size_float32_2 __attribute__((ext_vector_type(2))); +typedef float ext_vector_size_float32_4 __attribute__((ext_vector_type(4))); +typedef float ext_vector_size_float32_8 __attribute__((ext_vector_type(8))); + +vector_size_float32_8 +return_vector_size_float32_8 (vector_size_float32_8 value) +{ + return value; +} + +vector_size_float32_16 +return_vector_size_float32_16 (vector_size_float32_16 value) { return value; } -ext_vector_size_float32 -return_ext_vector_size_float32 (ext_vector_size_float32 value) +vector_size_float32_32 +return_vector_size_float32_32 (vector_size_float32_32 value) +{ + return value; +} + +ext_vector_size_float32_2 +return_ext_vector_size_float32_2 (ext_vector_size_float32_2 value) +{ + return value; +} + +ext_vector_size_float32_4 +return_ext_vector_size_float32_4 (ext_vector_size_float32_4 value) +{ + return value; +} + +ext_vector_size_float32_8 +return_ext_vector_size_float32_8 (ext_vector_size_float32_8 value) { return value; } @@ -366,9 +395,13 @@ main () return_one_int_one_double_packed ((struct one_int_one_double_packed) {10, 20.0}); return_one_int_one_long ((struct one_int_one_long) {10, 20}); - return_vector_size_float32 (( vector_size_float32 ){1.5, 2.25, 4.125, 8.0625}); - return_ext_vector_size_float32 ((ext_vector_size_float32){ 16.5, 32.25, 64.125, 128.0625}); - - return 0; - + return_vector_size_float32_8 (( vector_size_float32_8 ){1.5, 2.25}); + return_vector_size_float32_16 (( vector_size_float32_16 ){1.5, 2.25, 4.125, 8.0625}); + return_vector_size_float32_32 (( vector_size_float32_32 ){1.5, 2.25, 4.125, 8.0625, 7.89, 8.52, 6.31, 9.12}); + + return_ext_vector_size_float32_2 ((ext_vector_size_float32_2){ 16.5, 32.25}); + return_ext_vector_size_float32_4 ((ext_vector_size_float32_4){ 16.5, 32.25, 64.125, 128.0625}); + return_ext_vector_size_float32_8 ((ext_vector_size_float32_8){ 16.5, 32.25, 64.125, 128.0625, 1.59, 3.57, 8.63, 9.12 }); + + return 0; } -- 2.7.4