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>
This commit is contained in:
Warner Losh 2023-08-13 10:41:24 +02:00
parent 15b950ecd1
commit 6538c682db
2 changed files with 35 additions and 51 deletions

View File

@ -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 * These are usually used to access struct data members once the struct has been
* locked - usually with lock_user_struct(). * locked - usually with lock_user_struct().
*/ */
#define __put_user(x, hptr)\ #define __put_user_e(x, hptr, e) \
({\ do { \
int size = sizeof(*hptr);\ PRAGMA_DISABLE_PACKED_WARNING; \
switch (size) {\ (__builtin_choose_expr(sizeof(*(hptr)) == 1, stb_p, \
case 1:\ __builtin_choose_expr(sizeof(*(hptr)) == 2, stw_##e##_p, \
*(uint8_t *)(hptr) = (uint8_t)(typeof(*hptr))(x);\ __builtin_choose_expr(sizeof(*(hptr)) == 4, stl_##e##_p, \
break;\ __builtin_choose_expr(sizeof(*(hptr)) == 8, stq_##e##_p, abort)))) \
case 2:\ ((hptr), (x)), (void)0); \
*(uint16_t *)(hptr) = tswap16((typeof(*hptr))(x));\ PRAGMA_REENABLE_PACKED_WARNING; \
break;\ } while (0)
case 4:\
*(uint32_t *)(hptr) = tswap32((typeof(*hptr))(x));\
break;\
case 8:\
*(uint64_t *)(hptr) = tswap64((typeof(*hptr))(x));\
break;\
default:\
abort();\
} \
0;\
})
#define __get_user(x, hptr) \ #define __get_user_e(x, hptr, e) \
({\ do { \
int size = sizeof(*hptr);\ PRAGMA_DISABLE_PACKED_WARNING; \
switch (size) {\ ((x) = (typeof(*hptr))( \
case 1:\ __builtin_choose_expr(sizeof(*(hptr)) == 1, ldub_p, \
x = (typeof(*hptr))*(uint8_t *)(hptr);\ __builtin_choose_expr(sizeof(*(hptr)) == 2, lduw_##e##_p, \
break;\ __builtin_choose_expr(sizeof(*(hptr)) == 4, ldl_##e##_p, \
case 2:\ __builtin_choose_expr(sizeof(*(hptr)) == 8, ldq_##e##_p, abort)))) \
x = (typeof(*hptr))tswap16(*(uint16_t *)(hptr));\ (hptr)), (void)0); \
break;\ PRAGMA_REENABLE_PACKED_WARNING; \
case 4:\ } while (0)
x = (typeof(*hptr))tswap32(*(uint32_t *)(hptr));\
break;\
case 8:\ #if TARGET_BIG_ENDIAN
x = (typeof(*hptr))tswap64(*(uint64_t *)(hptr));\ # define __put_user(x, hptr) __put_user_e(x, hptr, be)
break;\ # define __get_user(x, hptr) __get_user_e(x, hptr, be)
default:\ #else
x = 0;\ # define __put_user(x, hptr) __put_user_e(x, hptr, le)
abort();\ # define __get_user(x, hptr) __get_user_e(x, hptr, le)
} \ #endif
0;\
})
/* /*
* put_user()/get_user() take a guest address and check access * 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); \ abi_ulong __gaddr = (gaddr); \
target_type *__hptr; \ target_type *__hptr; \
abi_long __ret; \ abi_long __ret = 0; \
__hptr = lock_user(VERIFY_WRITE, __gaddr, sizeof(target_type), 0); \ __hptr = lock_user(VERIFY_WRITE, __gaddr, sizeof(target_type), 0); \
if (__hptr) { \ if (__hptr) { \
__ret = __put_user((x), __hptr); \ __put_user((x), __hptr); \
unlock_user(__hptr, __gaddr, sizeof(target_type)); \ unlock_user(__hptr, __gaddr, sizeof(target_type)); \
} else \ } else \
__ret = -TARGET_EFAULT; \ __ret = -TARGET_EFAULT; \
@ -342,10 +329,10 @@ static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
({ \ ({ \
abi_ulong __gaddr = (gaddr); \ abi_ulong __gaddr = (gaddr); \
target_type *__hptr; \ target_type *__hptr; \
abi_long __ret; \ abi_long __ret = 0; \
__hptr = lock_user(VERIFY_READ, __gaddr, sizeof(target_type), 1); \ __hptr = lock_user(VERIFY_READ, __gaddr, sizeof(target_type), 1); \
if (__hptr) { \ if (__hptr) { \
__ret = __get_user((x), __hptr); \ __get_user((x), __hptr); \
unlock_user(__hptr, __gaddr, 0); \ unlock_user(__hptr, __gaddr, 0); \
} else { \ } else { \
(x) = 0; \ (x) = 0; \

View File

@ -787,10 +787,7 @@ static int reset_signal_mask(target_ucontext_t *ucontext)
TaskState *ts = (TaskState *)thread_cpu->opaque; TaskState *ts = (TaskState *)thread_cpu->opaque;
for (i = 0; i < TARGET_NSIG_WORDS; i++) { for (i = 0; i < TARGET_NSIG_WORDS; i++) {
if (__get_user(target_set.__bits[i], __get_user(target_set.__bits[i], &ucontext->uc_sigmask.__bits[i]);
&ucontext->uc_sigmask.__bits[i])) {
return -TARGET_EFAULT;
}
} }
target_to_host_sigset_internal(&blocked, &target_set); target_to_host_sigset_internal(&blocked, &target_set);
ts->signal_mask = blocked; ts->signal_mask = blocked;