diff options
author | Flavio Cruz <flaviocruz@gmail.com> | 2023-06-13 00:01:25 -0400 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2023-09-25 10:58:14 +0200 |
commit | 25ece371fb21dfd874187f623593064c476d9ca2 (patch) | |
tree | 8cd1b4932b994a42884cbed7ac671acba994a6fa /x86_64 | |
parent | b3921098e2807d6225d277986bc8063b6a271e88 (diff) | |
download | gnumach-25ece371fb21dfd874187f623593064c476d9ca2.tar.gz gnumach-25ece371fb21dfd874187f623593064c476d9ca2.tar.bz2 gnumach-25ece371fb21dfd874187f623593064c476d9ca2.zip |
Update the 64bit RPC ABI to be simpler
* Make full use of the 8 bytes available in mach_msg_type_t by moving
into the unused 4 bytes. This allows us to use 32bits for
mach_msg_type_number_t whether we use the longform or not.
* Make mach_msg_type_long_t exactly the same as mach_msg_type_t.
Updating MiG is strongly encouraged since it will generate better code
to handle this new format.
After this change, any compatibility with compiled binaries for Hurd x86_64
will break since the message format is different. However, the new
schema simplifies the overall ABI, without having "holes" and also
avoids the need to have a 16 byte mach_msg_type_long_t.
Was able to boot a basic system up to a bash shell.
Message-Id: <ZIfqFe5bPNPeH4xg@jupiter.lan>
Diffstat (limited to 'x86_64')
-rw-r--r-- | x86_64/copy_user.c | 88 |
1 files changed, 72 insertions, 16 deletions
diff --git a/x86_64/copy_user.c b/x86_64/copy_user.c index 6ff50e12..548d9d7d 100644 --- a/x86_64/copy_user.c +++ b/x86_64/copy_user.c @@ -87,12 +87,74 @@ static inline void unpack_msg_type(vm_offset_t addr, } } +#ifdef USER32 +static inline void mach_msg_user_type_to_kernel(const mach_msg_user_type_t *u, + mach_msg_type_t* k) { + k->msgt_name = u->msgt_name; + k->msgt_size = u->msgt_size; + k->msgt_number = u->msgt_number; + k->msgt_inline = u->msgt_inline; + k->msgt_longform = u->msgt_longform; + k->msgt_deallocate = u->msgt_deallocate; + k->msgt_unused = 0; +} + +static inline void mach_msg_user_type_to_kernel_long(const mach_msg_user_type_long_t *u, + mach_msg_type_long_t* k) { + const mach_msg_type_long_t kernel = { + .msgtl_header = { + .msgt_name = u->msgtl_name, + .msgt_size = u->msgtl_size, + .msgt_number = u->msgtl_number, + .msgt_inline = u->msgtl_header.msgt_inline, + .msgt_longform = u->msgtl_header.msgt_longform, + .msgt_deallocate = u->msgtl_header.msgt_deallocate, + .msgt_unused = 0 + } + }; + *k = kernel; +} + +static inline void mach_msg_kernel_type_to_user(const mach_msg_type_t *k, + mach_msg_user_type_t *u) { + u->msgt_name = k->msgt_name; + u->msgt_size = k->msgt_size; + u->msgt_number = k->msgt_number; + u->msgt_inline = k->msgt_inline; + u->msgt_longform = k->msgt_longform; + u->msgt_deallocate = k->msgt_deallocate; + u->msgt_unused = 0; +} + +static inline void mach_msg_kernel_type_to_user_long(const mach_msg_type_long_t *k, + mach_msg_user_type_long_t *u) { + const mach_msg_user_type_long_t user = { + .msgtl_header = { + .msgt_name = 0, + .msgt_size = 0, + .msgt_number = 0, + .msgt_inline = k->msgtl_header.msgt_inline, + .msgt_longform = k->msgtl_header.msgt_longform, + .msgt_deallocate = k->msgtl_header.msgt_deallocate, + .msgt_unused = 0 + }, + .msgtl_name = k->msgtl_header.msgt_name, + .msgtl_size = k->msgtl_header.msgt_size, + .msgtl_number = k->msgtl_header.msgt_number + }; + *u = user; +} +#endif + static inline int copyin_mach_msg_type(const rpc_vm_offset_t *uaddr, mach_msg_type_t *kaddr) { #ifdef USER32 - int ret; - ret = copyin(uaddr, kaddr, sizeof(mach_msg_user_type_t)); - kaddr->unused_msgtl_number = 0; - return ret; + mach_msg_user_type_t user; + int ret = copyin(uaddr, &user, sizeof(mach_msg_user_type_t)); + if (ret) { + return ret; + } + mach_msg_user_type_to_kernel(&user, kaddr); + return 0; #else return copyin(uaddr, kaddr, sizeof(mach_msg_type_t)); #endif @@ -100,7 +162,9 @@ static inline int copyin_mach_msg_type(const rpc_vm_offset_t *uaddr, mach_msg_ty static inline int copyout_mach_msg_type(const mach_msg_type_t *kaddr, rpc_vm_offset_t *uaddr) { #ifdef USER32 - return copyout(kaddr, uaddr, sizeof(mach_msg_user_type_t)); + mach_msg_user_type_t user; + mach_msg_kernel_type_to_user(kaddr, &user); + return copyout(&user, uaddr, sizeof(mach_msg_user_type_t)); #else return copyout(kaddr, uaddr, sizeof(mach_msg_type_t)); #endif @@ -109,15 +173,10 @@ static inline int copyout_mach_msg_type(const mach_msg_type_t *kaddr, rpc_vm_off static inline int copyin_mach_msg_type_long(const rpc_vm_offset_t *uaddr, mach_msg_type_long_t *kaddr) { #ifdef USER32 mach_msg_user_type_long_t user; - int ret; - ret = copyin(uaddr, &user, sizeof(mach_msg_user_type_long_t)); + int ret = copyin(uaddr, &user, sizeof(mach_msg_user_type_long_t)); if (ret) return ret; - /* The first 4 bytes are laid out in the same way. */ - memcpy(&kaddr->msgtl_header, &user.msgtl_header, sizeof(mach_msg_user_type_t)); - kaddr->msgtl_name = user.msgtl_name; - kaddr->msgtl_size = user.msgtl_size; - kaddr->msgtl_number = user.msgtl_number; + mach_msg_user_type_to_kernel_long(&user, kaddr); return 0; #else return copyin(uaddr, kaddr, sizeof(mach_msg_type_long_t)); @@ -127,10 +186,7 @@ static inline int copyin_mach_msg_type_long(const rpc_vm_offset_t *uaddr, mach_m static inline int copyout_mach_msg_type_long(const mach_msg_type_long_t *kaddr, rpc_vm_offset_t *uaddr) { #ifdef USER32 mach_msg_user_type_long_t user; - memcpy(&user.msgtl_header, &kaddr->msgtl_header, sizeof(mach_msg_user_type_t)); - user.msgtl_name = kaddr->msgtl_name; - user.msgtl_size = kaddr->msgtl_size; - user.msgtl_number = kaddr->msgtl_number; + mach_msg_kernel_type_to_user_long(kaddr, &user); return copyout(&user, uaddr, sizeof(mach_msg_user_type_long_t)); #else return copyout(kaddr, uaddr, sizeof(mach_msg_type_long_t)); |