From c1ec1c2ababa18aa05f9ab715d10f80ce56a9528 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 2 Feb 2021 20:17:36 -0800 Subject: [PATCH] arch,sim: Add a UintPtr type to the ABI types for GuestABI. This type is primarily used to determine the size of a pointer when using that ABI, similar to the uintptr_t type, but also less directly to determine the "native" size of the ABI. For instance, for 32 bit ARM ABIs, it should be defined as uint32_t since that's both the size of a uintptr_t, and, less directly, the size of a 32 bit ARM register and "naturally" sized types in that ABI. This type can be used by the VPtr template to retrieve its actual value from a simcall's parameters. In general, when accepting or returning a pointer or address in a simcall, the VPtr template should be used so that it's managed correctly by GuestABI. Addr will be treated as a uint64_t allways which will be incorrect for 32 bit ABIs. Change-Id: I3af046917387541d6faff96a21a1f1dbf7317e06 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40496 Maintainer: Gabe Black Tested-by: kokoro Reviewed-by: Bobby R. Bruce --- src/arch/arm/aapcs64.hh | 2 ++ src/arch/arm/semihosting.hh | 4 ++++ src/sim/proxy_ptr.hh | 5 +++-- src/sim/proxy_ptr.test.cc | 1 + src/sim/syscall_abi.hh | 10 +++++++--- 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/arch/arm/aapcs64.hh b/src/arch/arm/aapcs64.hh index 8a5e4374c..fb7b8f8df 100644 --- a/src/arch/arm/aapcs64.hh +++ b/src/arch/arm/aapcs64.hh @@ -44,6 +44,8 @@ class ThreadContext; struct Aapcs64 { + using UintPtr = uint64_t; + struct State { int ngrn=0; // Next general purpose register number. diff --git a/src/arch/arm/semihosting.hh b/src/arch/arm/semihosting.hh index 74697f408..7566887fc 100644 --- a/src/arch/arm/semihosting.hh +++ b/src/arch/arm/semihosting.hh @@ -133,6 +133,8 @@ class ArmSemihosting : public SimObject struct Abi64 : public AbiBase { + using UintPtr = uint64_t; + class State : public StateBase { public: @@ -145,6 +147,8 @@ class ArmSemihosting : public SimObject struct Abi32 : public AbiBase { + using UintPtr = uint32_t; + class State : public StateBase { public: diff --git a/src/sim/proxy_ptr.hh b/src/sim/proxy_ptr.hh index 02263bae4..968c1560c 100644 --- a/src/sim/proxy_ptr.hh +++ b/src/sim/proxy_ptr.hh @@ -338,7 +338,8 @@ struct Argument> static ProxyPtr get(ThreadContext *tc, typename ABI::State &state) { - return ProxyPtr(Argument::get(tc, state), tc); + return ProxyPtr( + Argument::get(tc, state), tc); } }; @@ -349,7 +350,7 @@ struct Argument> get(ThreadContext *tc, typename ABI::State &state) { return ConstProxyPtr( - Argument::get(tc, state), tc); + Argument::get(tc, state), tc); } }; diff --git a/src/sim/proxy_ptr.test.cc b/src/sim/proxy_ptr.test.cc index b9f46e623..de0194d1b 100644 --- a/src/sim/proxy_ptr.test.cc +++ b/src/sim/proxy_ptr.test.cc @@ -465,6 +465,7 @@ TEST(ProxyPtr, NonConstOperators) struct TestABI { + using UintPtr = uint64_t; using State = int; }; diff --git a/src/sim/syscall_abi.hh b/src/sim/syscall_abi.hh index 984f0e025..9d552028f 100644 --- a/src/sim/syscall_abi.hh +++ b/src/sim/syscall_abi.hh @@ -54,10 +54,14 @@ struct GenericSyscallABI }; struct GenericSyscallABI64 : public GenericSyscallABI -{}; +{ + using UintPtr = uint64_t; +}; struct GenericSyscallABI32 : public GenericSyscallABI { + using UintPtr = uint32_t; + // Is this argument too big for a single register? template struct IsWide; @@ -65,7 +69,7 @@ struct GenericSyscallABI32 : public GenericSyscallABI template struct IsWide::value && - (sizeof(T) < sizeof(uint64_t) || + (sizeof(T) <= sizeof(UintPtr) || GuestABI::IsConforming::value)>> { static const bool value = false; @@ -74,7 +78,7 @@ struct GenericSyscallABI32 : public GenericSyscallABI template struct IsWide::value && - sizeof(T) == sizeof(uint64_t) && + (sizeof(T) > sizeof(UintPtr)) && !GuestABI::IsConforming::value>> { static const bool value = true; -- 2.30.2