Update hurd/intr-msg.c to be more portable

Summary of the changes:
- Introduce BAD_TYPECHECK from MiG to make it simpler to do type
  checking.
- Replace int type with mach_msg_type_t. This assumes that
  mach_msg_type_t is always the same size as int which is not true for
  x86_64.
- Calculate the size and align using PTR_ALIGN_UP, which is a bit
  cleaner and similar to what we do elsewhere.
- Define mach_msg_type_t to check using designated initializers.
Message-Id: <ZFMvrIkvoCSxqB/C@jupiter.tail36e24.ts.net>
This commit is contained in:
Flavio Cruz 2023-05-04 00:08:12 -04:00 committed by Samuel Thibault
parent 3f433cb895
commit 4571fb8fe6

View File

@ -28,6 +28,11 @@
# define mig_reply_header_t mig_reply_error_t # define mig_reply_header_t mig_reply_error_t
#endif #endif
/* Macro used by MIG to cleanly check the type. */
#define BAD_TYPECHECK(type, check) __glibc_unlikely (({ \
union { mach_msg_type_t t; uint32_t w; } _t, _c; \
_t.t = *(type); _c.t = *(check);_t.w != _c.w; }))
error_t error_t
_hurd_intr_rpc_mach_msg (mach_msg_header_t *msg, _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
mach_msg_option_t option, mach_msg_option_t option,
@ -61,7 +66,7 @@ _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
#ifdef NDR_CHAR_ASCII #ifdef NDR_CHAR_ASCII
NDR_record_t ndr; NDR_record_t ndr;
#else #else
int type; mach_msg_type_t type;
#endif #endif
int code; int code;
} check; } check;
@ -222,11 +227,12 @@ _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
if (ty->msgtl_header.msgt_inline) if (ty->msgtl_header.msgt_inline)
{ {
/* Calculate length of data in bytes. */
const vm_size_t length = ((number * size) + 7) >> 3;
clean_ports ((void *) ty, 0); clean_ports ((void *) ty, 0);
/* calculate length of data in bytes, rounding up */ /* Move to the next argument. */
ty = (void *) ty + (((((number * size) + 7) >> 3) ty = (void *) PTR_ALIGN_UP ((char *) ty + length,
+ sizeof (mach_msg_type_t) - 1) __alignof__ (uintptr_t));
&~ (sizeof (mach_msg_type_t) - 1));
} }
else else
{ {
@ -354,19 +360,21 @@ _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
{ {
/* We got a reply. Was it EINTR? */ /* We got a reply. Was it EINTR? */
#ifdef MACH_MSG_TYPE_BIT #ifdef MACH_MSG_TYPE_BIT
const union static const mach_msg_type_t type_check = {
{ .msgt_name = MACH_MSG_TYPE_INTEGER_T,
mach_msg_type_t t; .msgt_size = sizeof (integer_t) * 8,
int i; .msgt_number = 1,
} check = .msgt_inline = TRUE,
{ t: { MACH_MSG_TYPE_INTEGER_T, sizeof (integer_t) * 8, .msgt_longform = FALSE,
1, TRUE, FALSE, FALSE, 0 } }; .msgt_deallocate = FALSE,
.msgt_unused = 0
};
#endif #endif
if (m->reply.RetCode == EINTR if (m->reply.RetCode == EINTR
&& m->header.msgh_size == sizeof m->reply && m->header.msgh_size == sizeof m->reply
#ifdef MACH_MSG_TYPE_BIT #ifdef MACH_MSG_TYPE_BIT
&& m->check.type == check.i && !BAD_TYPECHECK(&m->check.type, &type_check)
#endif #endif
&& !(m->header.msgh_bits & MACH_MSGH_BITS_COMPLEX)) && !(m->header.msgh_bits & MACH_MSGH_BITS_COMPLEX))
{ {