aboutsummaryrefslogtreecommitdiff
path: root/bsd-user/qemu.h
diff options
context:
space:
mode:
authorWarner Losh <imp@bsdimp.com>2023-08-13 10:41:24 +0200
committerWarner Losh <imp@bsdimp.com>2023-08-28 12:16:18 -0600
commit6538c682db9c2b34fbffc22e111a4bcd8f4b02de (patch)
treef06c7599a07a7fe294002680a06faadaff708c20 /bsd-user/qemu.h
parent15b950ecd16ecc6e9a1f21e1f9f185ee61a5a1d5 (diff)
bsd-user; Update the definitions of __put_user and __get_user macros
Use __builtin_choose_expr to avoid type promotion from ?: in __put_user_e and __get_user_e macros. Copied from linux-user/qemu.h, originally by Blue Swirl. Signed-off-by: Warner Losh <imp@bsdimp.com> Signed-off-by: Karim Taha <kariem.taha2.7@gmail.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'bsd-user/qemu.h')
-rw-r--r--bsd-user/qemu.h81
1 files changed, 34 insertions, 47 deletions
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 61501c321b..ca791e18b2 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -272,50 +272,37 @@ static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
* These are usually used to access struct data members once the struct has been
* locked - usually with lock_user_struct().
*/
-#define __put_user(x, hptr)\
-({\
- int size = sizeof(*hptr);\
- switch (size) {\
- case 1:\
- *(uint8_t *)(hptr) = (uint8_t)(typeof(*hptr))(x);\
- break;\
- case 2:\
- *(uint16_t *)(hptr) = tswap16((typeof(*hptr))(x));\
- break;\
- case 4:\
- *(uint32_t *)(hptr) = tswap32((typeof(*hptr))(x));\
- break;\
- case 8:\
- *(uint64_t *)(hptr) = tswap64((typeof(*hptr))(x));\
- break;\
- default:\
- abort();\
- } \
- 0;\
-})
+#define __put_user_e(x, hptr, e) \
+ do { \
+ PRAGMA_DISABLE_PACKED_WARNING; \
+ (__builtin_choose_expr(sizeof(*(hptr)) == 1, stb_p, \
+ __builtin_choose_expr(sizeof(*(hptr)) == 2, stw_##e##_p, \
+ __builtin_choose_expr(sizeof(*(hptr)) == 4, stl_##e##_p, \
+ __builtin_choose_expr(sizeof(*(hptr)) == 8, stq_##e##_p, abort)))) \
+ ((hptr), (x)), (void)0); \
+ PRAGMA_REENABLE_PACKED_WARNING; \
+ } while (0)
+
+#define __get_user_e(x, hptr, e) \
+ do { \
+ PRAGMA_DISABLE_PACKED_WARNING; \
+ ((x) = (typeof(*hptr))( \
+ __builtin_choose_expr(sizeof(*(hptr)) == 1, ldub_p, \
+ __builtin_choose_expr(sizeof(*(hptr)) == 2, lduw_##e##_p, \
+ __builtin_choose_expr(sizeof(*(hptr)) == 4, ldl_##e##_p, \
+ __builtin_choose_expr(sizeof(*(hptr)) == 8, ldq_##e##_p, abort)))) \
+ (hptr)), (void)0); \
+ PRAGMA_REENABLE_PACKED_WARNING; \
+ } while (0)
-#define __get_user(x, hptr) \
-({\
- int size = sizeof(*hptr);\
- switch (size) {\
- case 1:\
- x = (typeof(*hptr))*(uint8_t *)(hptr);\
- break;\
- case 2:\
- x = (typeof(*hptr))tswap16(*(uint16_t *)(hptr));\
- break;\
- case 4:\
- x = (typeof(*hptr))tswap32(*(uint32_t *)(hptr));\
- break;\
- case 8:\
- x = (typeof(*hptr))tswap64(*(uint64_t *)(hptr));\
- break;\
- default:\
- x = 0;\
- abort();\
- } \
- 0;\
-})
+
+#if TARGET_BIG_ENDIAN
+# define __put_user(x, hptr) __put_user_e(x, hptr, be)
+# define __get_user(x, hptr) __get_user_e(x, hptr, be)
+#else
+# define __put_user(x, hptr) __put_user_e(x, hptr, le)
+# define __get_user(x, hptr) __get_user_e(x, hptr, le)
+#endif
/*
* put_user()/get_user() take a guest address and check access
@@ -328,10 +315,10 @@ static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
({ \
abi_ulong __gaddr = (gaddr); \
target_type *__hptr; \
- abi_long __ret; \
+ abi_long __ret = 0; \
__hptr = lock_user(VERIFY_WRITE, __gaddr, sizeof(target_type), 0); \
if (__hptr) { \
- __ret = __put_user((x), __hptr); \
+ __put_user((x), __hptr); \
unlock_user(__hptr, __gaddr, sizeof(target_type)); \
} else \
__ret = -TARGET_EFAULT; \
@@ -342,10 +329,10 @@ static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
({ \
abi_ulong __gaddr = (gaddr); \
target_type *__hptr; \
- abi_long __ret; \
+ abi_long __ret = 0; \
__hptr = lock_user(VERIFY_READ, __gaddr, sizeof(target_type), 1); \
if (__hptr) { \
- __ret = __get_user((x), __hptr); \
+ __get_user((x), __hptr); \
unlock_user(__hptr, __gaddr, 0); \
} else { \
(x) = 0; \