arch,sim: Add a UintPtr type to the ABI types for GuestABI.
authorGabe Black <gabe.black@gmail.com>
Wed, 3 Feb 2021 04:17:36 +0000 (20:17 -0800)
committerGabe Black <gabe.black@gmail.com>
Sat, 6 Feb 2021 01:13:50 +0000 (01:13 +0000)
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 <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu>
src/arch/arm/aapcs64.hh
src/arch/arm/semihosting.hh
src/sim/proxy_ptr.hh
src/sim/proxy_ptr.test.cc
src/sim/syscall_abi.hh

index 8a5e4374c58c16037306af1565fd882a230f6c56..fb7b8f8dfcc53f8a0a8239824bcb817ac9c5e992 100644 (file)
@@ -44,6 +44,8 @@ class ThreadContext;
 
 struct Aapcs64
 {
+    using UintPtr = uint64_t;
+
     struct State
     {
         int ngrn=0; // Next general purpose register number.
index 74697f408acf92138b20bb6e0f863035d5ada67b..7566887fc6503fc8a5954717f2d779ef0212cb0e 100644 (file)
@@ -133,6 +133,8 @@ class ArmSemihosting : public SimObject
 
     struct Abi64 : public AbiBase
     {
+        using UintPtr = uint64_t;
+
         class State : public StateBase<uint64_t>
         {
           public:
@@ -145,6 +147,8 @@ class ArmSemihosting : public SimObject
 
     struct Abi32 : public AbiBase
     {
+        using UintPtr = uint32_t;
+
         class State : public StateBase<uint64_t>
         {
           public:
index 02263bae45717d0dfeadb3b220674e7b6cc0bcaa..968c1560cb9acd9e721764096b00c264e59d73ee 100644 (file)
@@ -338,7 +338,8 @@ struct Argument<ABI, ProxyPtr<T, Proxy>>
     static ProxyPtr<T, Proxy>
     get(ThreadContext *tc, typename ABI::State &state)
     {
-        return ProxyPtr<T, Proxy>(Argument<ABI, Addr>::get(tc, state), tc);
+        return ProxyPtr<T, Proxy>(
+                Argument<ABI, typename ABI::UintPtr>::get(tc, state), tc);
     }
 };
 
@@ -349,7 +350,7 @@ struct Argument<ABI, ConstProxyPtr<T, Proxy>>
     get(ThreadContext *tc, typename ABI::State &state)
     {
         return ConstProxyPtr<T, Proxy>(
-                Argument<ABI, Addr>::get(tc, state), tc);
+                Argument<ABI, typename ABI::UintPtr>::get(tc, state), tc);
     }
 };
 
index b9f46e623404b6bac42768081eb2ccc0368bb188..de0194d1b30efba90ec8edcf116d5d405714887c 100644 (file)
@@ -465,6 +465,7 @@ TEST(ProxyPtr, NonConstOperators)
 
 struct TestABI
 {
+    using UintPtr = uint64_t;
     using State = int;
 };
 
index 984f0e0252a7c4d6fcec9cb0395d7c203f5ea62d..9d552028f8453955a0af05817f88ab77545579bf 100644 (file)
@@ -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 <typename T, typename Enabled=void>
     struct IsWide;
@@ -65,7 +69,7 @@ struct GenericSyscallABI32 : public GenericSyscallABI
     template <typename T>
     struct IsWide<T, typename std::enable_if_t<
         std::is_integral<T>::value &&
-        (sizeof(T) < sizeof(uint64_t) ||
+        (sizeof(T) <= sizeof(UintPtr) ||
          GuestABI::IsConforming<T>::value)>>
     {
         static const bool value = false;
@@ -74,7 +78,7 @@ struct GenericSyscallABI32 : public GenericSyscallABI
     template <typename T>
     struct IsWide<T, typename std::enable_if_t<
         std::is_integral<T>::value &&
-        sizeof(T) == sizeof(uint64_t) &&
+        (sizeof(T) > sizeof(UintPtr)) &&
         !GuestABI::IsConforming<T>::value>>
     {
         static const bool value = true;