/* Handle faults in the signal thread.
   Copyright (C) 1994-2014 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#include <hurd.h>
#include <hurd/signal.h>
#include "hurdfault.h"
#include <errno.h>
#include <string.h>
#include <setjmp.h>
#include <stdio.h>
#include <thread_state.h>
#include "faultexc_server.h"	/* mig-generated header for our exc server.  */
#include <assert.h>

jmp_buf _hurdsig_fault_env;
struct hurd_signal_preemptor _hurdsig_fault_preemptor = {0};

/* XXX temporary to deal with spelling fix */
weak_alias (_hurdsig_fault_preemptor, _hurdsig_fault_preempter)

static mach_port_t forward_sigexc;

kern_return_t
_hurdsig_fault_catch_exception_raise (mach_port_t port,
				      thread_t thread,
				      task_t task,
#ifdef EXC_MASK_ALL		/* New interface flavor.  */
				      exception_type_t exception,
				      exception_data_t code,
				      mach_msg_type_number_t codeCnt
#else				/* Vanilla Mach 3.0 interface.  */
				      integer_t exception,
				      integer_t code, integer_t subcode
#endif
				      )
{
  int signo;
  struct hurd_signal_detail d;

  if (port != forward_sigexc ||
      thread != _hurd_msgport_thread || task != __mach_task_self ())
    return EPERM;		/* Strange bogosity.  */

  d.exc = exception;
#ifdef EXC_MASK_ALL
  assert (codeCnt >= 2);
  d.exc_code = code[0];
  d.exc_subcode = code[1];
#else
  d.exc_code = code;
  d.exc_subcode = subcode;
#endif

  /* Call the machine-dependent function to translate the Mach exception
     codes into a signal number and subcode.  */
  _hurd_exception2signal (&d, &signo);

  return HURD_PREEMPT_SIGNAL_P (&_hurdsig_fault_preemptor, signo, d.code)
    ? 0 : EGREGIOUS;
}

#ifdef EXC_MASK_ALL
/* XXX New interface flavor has additional RPCs that we could be using
   instead.  These RPCs roll a thread_get_state/thread_set_state into
   the message, so the signal thread ought to use these to save some calls.
 */
kern_return_t
_hurdsig_fault_catch_exception_raise_state
(mach_port_t port,
 exception_type_t exception,
 exception_data_t code,
 mach_msg_type_number_t codeCnt,
 int *flavor,
 thread_state_t old_state,
 mach_msg_type_number_t old_stateCnt,
 thread_state_t new_state,
 mach_msg_type_number_t *new_stateCnt)
{
  abort ();
  return KERN_FAILURE;
}

kern_return_t
_hurdsig_fault_catch_exception_raise_state_identity
(mach_port_t exception_port,
 thread_t thread,
 task_t task,
 exception_type_t exception,
 exception_data_t code,
 mach_msg_type_number_t codeCnt,
 int *flavor,
 thread_state_t old_state,
 mach_msg_type_number_t old_stateCnt,
 thread_state_t new_state,
 mach_msg_type_number_t *new_stateCnt)
{
  abort ();
  return KERN_FAILURE;
}
#endif


#ifdef NDR_CHAR_ASCII		/* OSF Mach flavors have different names.  */
# define mig_reply_header_t	mig_reply_error_t
#endif

static void
faulted (void)
{
  struct
    {
      mach_msg_header_t head;
      char buf[64];
    } request;
  mig_reply_header_t reply;
  extern int _hurdsig_fault_exc_server (mach_msg_header_t *,
					mach_msg_header_t *);

 /* Wait for the exception_raise message forwarded by the proc server.  */

 if (__mach_msg (&request.head, MACH_RCV_MSG, 0,
		  sizeof request, forward_sigexc,
		  MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL)
      != MACH_MSG_SUCCESS)
    __libc_fatal ("msg receive failed on signal thread exc\n");

  /* Run the exc demuxer which should call the server function above.
     That function returns 0 if the exception was expected.  */
  _hurdsig_fault_exc_server (&request.head, &reply.Head);
  if (reply.Head.msgh_remote_port != MACH_PORT_NULL)
    __mach_msg (&reply.Head, MACH_SEND_MSG, reply.Head.msgh_size,
		0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
  if (reply.RetCode == MIG_BAD_ID)
    __mach_msg_destroy (&request.head);

  if (reply.RetCode)
    __libc_fatal ("BUG: unexpected fault in signal thread\n");

  _hurdsig_fault_preemptor.signals = 0;
  longjmp (_hurdsig_fault_env, 1);
}

static char faultstack[1024];

/* Send exceptions for the signal thread to the proc server.
   It will forward the message on to our message port,
   and then restore the thread's state to code which
   does `longjmp (_hurd_sigthread_fault_env, 1)'.  */

void
_hurdsig_fault_init (void)
{
  error_t err;
  struct machine_thread_state state;
  mach_port_t sigexc;

  /* Allocate a port to receive signal thread exceptions.
     We will move this receive right to the proc server.  */
  err = __mach_port_allocate (__mach_task_self (),
			      MACH_PORT_RIGHT_RECEIVE, &sigexc);
  assert_perror (err);
  err = __mach_port_allocate (__mach_task_self (),
			      MACH_PORT_RIGHT_RECEIVE, &forward_sigexc);
  assert_perror (err);

  /* Allocate a port to receive the exception msgs forwarded
     from the proc server.  */
  err = __mach_port_insert_right (__mach_task_self (), sigexc,
				  sigexc, MACH_MSG_TYPE_MAKE_SEND);
  assert_perror (err);

  /* Set the queue limit for this port to just one.  The proc server will
     notice if we ever get a second exception while one remains queued and
     unreceived, and decide we are hopelessly buggy.  */
#ifdef MACH_PORT_RECEIVE_STATUS_COUNT
  {
    const mach_port_limits_t lim = { mpl_qlimit: 1 };
    assert (MACH_PORT_RECEIVE_STATUS_COUNT == sizeof lim / sizeof (natural_t));
    err = __mach_port_set_attributes (__mach_task_self (), forward_sigexc,
				      MACH_PORT_RECEIVE_STATUS,
				      (mach_port_info_t) &lim,
				      MACH_PORT_RECEIVE_STATUS_COUNT);
  }
#else
  err = __mach_port_set_qlimit (__mach_task_self (), forward_sigexc, 1);
#endif
  assert_perror (err);

  /* This state will be restored when we fault.
     It runs the function above.  */
  memset (&state, 0, sizeof state);
  MACHINE_THREAD_STATE_SET_PC (&state, faulted);
  MACHINE_THREAD_STATE_SET_SP (&state, faultstack, sizeof faultstack);

  err = __USEPORT
    (PROC,
     __proc_handle_exceptions (port,
			       sigexc,
			       forward_sigexc, MACH_MSG_TYPE_MAKE_SEND,
			       MACHINE_THREAD_STATE_FLAVOR,
			       (natural_t *) &state,
			       MACHINE_THREAD_STATE_COUNT));
  assert_perror (err);

  /* Direct signal thread exceptions to the proc server.  */
#ifdef THREAD_EXCEPTION_PORT
  err = __thread_set_special_port (_hurd_msgport_thread,
				   THREAD_EXCEPTION_PORT, sigexc);
#elif defined (EXC_MASK_ALL)
  __thread_set_exception_ports (_hurd_msgport_thread,
				EXC_MASK_ALL & ~(EXC_MASK_SYSCALL
						 | EXC_MASK_MACH_SYSCALL
						 | EXC_MASK_RPC_ALERT),
				sigexc,
				EXCEPTION_STATE_IDENTITY,
				MACHINE_THREAD_STATE);
#else
# error thread_set_exception_ports?
#endif
  __mach_port_deallocate (__mach_task_self (), sigexc);
  assert_perror (err);
}
