Applied, thanks! Sergey Bugaev, le mer. 27 mars 2024 19:18:36 +0300, a ecrit: > --- > tests/include/testlib.h | 16 ++++++ > tests/test-syscalls.c | 40 +------------ > tests/testlib.c | 123 ++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 142 insertions(+), 37 deletions(-) > > diff --git a/tests/include/testlib.h b/tests/include/testlib.h > index cdb2ce13..d2367124 100644 > --- a/tests/include/testlib.h > +++ b/tests/include/testlib.h > @@ -70,6 +70,22 @@ thread_t test_thread_start(task_t task, > void(*routine)(void*), void* arg); > mach_port_t host_priv(void); > mach_port_t device_priv(void); > > +extern void mach_msg_destroy(mach_msg_header_t *msg); > + > +extern mach_msg_return_t mach_msg_server( > + boolean_t (*demux) (mach_msg_header_t *request, > + mach_msg_header_t *reply), > + mach_msg_size_t max_size, > + mach_port_t rcv_name, > + mach_msg_option_t options); > + > +extern mach_msg_return_t mach_msg_server_once( > + boolean_t (*demux) (mach_msg_header_t *request, > + mach_msg_header_t *reply), > + mach_msg_size_t max_size, > + mach_port_t rcv_name, > + mach_msg_option_t options); > + > int main(int argc, char *argv[], int envc, char *envp[]); > > #endif /* TESTLIB_H */ > diff --git a/tests/test-syscalls.c b/tests/test-syscalls.c > index be4df8c3..63c2690a 100644 > --- a/tests/test-syscalls.c > +++ b/tests/test-syscalls.c > @@ -49,44 +49,10 @@ kern_return_t catch_exception_raise(mach_port_t > exception_port, > last_exc.exception = exception; > last_exc.code = code; > last_exc.subcode = subcode; > + thread_terminate(thread); > return KERN_SUCCESS; > } > > -static char simple_request_data[PAGE_SIZE]; > -static char simple_reply_data[PAGE_SIZE]; > -int simple_msg_server(boolean_t (*demuxer) (mach_msg_header_t *request, > - mach_msg_header_t *reply), > - mach_port_t rcv_port_name, > - int num_msgs) > -{ > - int midx = 0, mok = 0; > - int ret; > - mig_reply_header_t *request = (mig_reply_header_t*)simple_request_data; > - mig_reply_header_t *reply = (mig_reply_header_t*)simple_reply_data; > - while ((midx - num_msgs) < 0) > - { > - ret = mach_msg(&request->Head, MACH_RCV_MSG, 0, PAGE_SIZE, > - rcv_port_name, 0, MACH_PORT_NULL); > - switch (ret) > - { > - case MACH_MSG_SUCCESS: > - if ((*demuxer)(&request->Head, &reply->Head)) > - mok++; // TODO send reply > - else > - FAILURE("demuxer didn't handle the message"); > - break; > - default: > - ASSERT_RET(ret, "receiving in msg_server"); > - break; > - } > - midx++; > - } > - if (mok != midx) > - FAILURE("wrong number of message received"); > - return mok != midx; > -} > - > - > void test_syscall_bad_arg_on_stack(void *arg) > { > /* mach_msg() has 7 arguments, so the last one should be always > @@ -152,13 +118,13 @@ int main(int argc, char *argv[], int envc, char *envp[]) > > memset(&last_exc, 0, sizeof(last_exc)); > test_thread_start(mach_task_self(), test_bad_syscall_num, NULL); > - ASSERT_RET(simple_msg_server(exc_server, excp, 1), "error in exc server"); > + ASSERT_RET(mach_msg_server_once(exc_server, 4096, excp, > MACH_MSG_OPTION_NONE), "error in exc server"); > ASSERT((last_exc.exception == EXC_BAD_INSTRUCTION) && (last_exc.code == > EXC_I386_INVOP), > "bad exception for test_bad_syscall_num()"); > > memset(&last_exc, 0, sizeof(last_exc)); > test_thread_start(mach_task_self(), test_syscall_bad_arg_on_stack, NULL); > - ASSERT_RET(simple_msg_server(exc_server, excp, 1), "error in exc server"); > + ASSERT_RET(mach_msg_server_once(exc_server, 4096, excp, > MACH_MSG_OPTION_NONE), "error in exc server"); > ASSERT((last_exc.exception == EXC_BAD_ACCESS) && (last_exc.code == > KERN_INVALID_ADDRESS), > "bad exception for test_syscall_bad_arg_on_stack()"); > > diff --git a/tests/testlib.c b/tests/testlib.c > index d2198830..baf1ce5c 100644 > --- a/tests/testlib.c > +++ b/tests/testlib.c > @@ -26,6 +26,7 @@ > #include <sys/reboot.h> > > #include <mach.user.h> > +#include <mach_port.user.h> > #include <mach_host.user.h> > > > @@ -81,6 +82,128 @@ const char* e2s(int err) > } > } > > +void mach_msg_destroy(mach_msg_header_t *msg) > +{ > + mach_port_t tmp; > + > + tmp = mach_reply_port(); > + > + msg->msgh_local_port = msg->msgh_remote_port; > + msg->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, > + MACH_MSGH_BITS_REMOTE(msg->msgh_bits)) > + | MACH_MSGH_BITS_OTHER(msg->msgh_bits); > + > + mach_msg(msg, MACH_SEND_MSG, msg->msgh_size, 0, MACH_PORT_NULL, > + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); > + > + mach_port_mod_refs(mach_task_self(), tmp, MACH_PORT_RIGHT_RECEIVE, -1); > +} > + > +mach_msg_return_t mach_msg_server( > + boolean_t (*demux) (mach_msg_header_t *request, > + mach_msg_header_t *reply), > + mach_msg_size_t max_size, > + mach_port_t rcv_name, > + mach_msg_option_t options) > +{ > + mach_msg_return_t mr; > + mig_reply_header_t *request; > + mig_reply_header_t *reply; > + mig_reply_header_t *tmp; > + boolean_t handled; > + > + request = __builtin_alloca(max_size); > + reply = __builtin_alloca(max_size); > + > +GetRequest: > + mr = mach_msg(&request->Head, MACH_RCV_MSG|options, > + 0, max_size, rcv_name, > + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); > + if (mr) > + return mr; > + > +Handle: > + handled = demux(&request->Head, &reply->Head); > + if (!handled) > + reply->RetCode = MIG_BAD_ID; > + > + if (reply->RetCode == MIG_NO_REPLY) > + goto GetRequest; > + else if (reply->RetCode != KERN_SUCCESS) { > + request->Head.msgh_remote_port = MACH_PORT_NULL; > + mach_msg_destroy(&request->Head); > + } > + > + if (!MACH_PORT_VALID(reply->Head.msgh_remote_port)) { > + mach_msg_destroy(&reply->Head); > + goto GetRequest; > + } > + > + tmp = request; > + request = reply; > + reply = tmp; > + > + mr = mach_msg(&request->Head, MACH_SEND_MSG|MACH_RCV_MSG|options, > + request->Head.msgh_size, max_size, rcv_name, > + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); > + > + if (mr == MACH_MSG_SUCCESS) > + goto Handle; > + else if (mr == MACH_SEND_INVALID_DEST) { > + mach_msg_destroy(&request->Head); > + goto GetRequest; > + } > + > + return mr; > +} > + > +mach_msg_return_t mach_msg_server_once( > + boolean_t (*demux) (mach_msg_header_t *request, > + mach_msg_header_t *reply), > + mach_msg_size_t max_size, > + mach_port_t rcv_name, > + mach_msg_option_t options) > +{ > + mach_msg_return_t mr; > + mig_reply_header_t *request; > + mig_reply_header_t *reply; > + boolean_t handled; > + > + request = __builtin_alloca(max_size); > + reply = __builtin_alloca(max_size); > + > + mr = mach_msg(&request->Head, MACH_RCV_MSG|options, > + 0, max_size, rcv_name, > + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); > + if (mr) > + return mr; > + > + handled = demux(&request->Head, &reply->Head); > + if (!handled) > + reply->RetCode = MIG_BAD_ID; > + > + if (reply->RetCode == MIG_NO_REPLY) > + return MACH_MSG_SUCCESS; > + else if (reply->RetCode != KERN_SUCCESS) { > + request->Head.msgh_remote_port = MACH_PORT_NULL; > + mach_msg_destroy(&request->Head); > + } > + > + if (!MACH_PORT_VALID(reply->Head.msgh_remote_port)) { > + mach_msg_destroy(&reply->Head); > + return MACH_MSG_SUCCESS; > + } > + > + mr = mach_msg(&reply->Head, MACH_SEND_MSG|options, > + reply->Head.msgh_size, 0, MACH_PORT_NULL, > + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); > + > + if (mr == MACH_SEND_INVALID_DEST) > + mach_msg_destroy(&reply->Head); > + > + return mr; > +} > + > /* > * Minimal _start() for test modules, we just take the arguments from the > * kernel, call main() and reboot. As in glibc, we expect the argument > pointer > -- > 2.44.0 > >
-- Samuel --- Pour une évaluation indépendante, transparente et rigoureuse ! Je soutiens la Commission d'Évaluation de l'Inria.