Exemplo n.º 1
0
int
__mprotect (__ptr_t addr, size_t len, int prot)
{
  kern_return_t err;
  vm_prot_t vmprot;

  vmprot = VM_PROT_NONE;
  if (prot & PROT_READ)
    vmprot |= VM_PROT_READ;
  if (prot & PROT_WRITE)
    vmprot |= VM_PROT_WRITE;
  if (prot & PROT_EXEC)
    vmprot |= VM_PROT_EXECUTE;

  if (err = __vm_protect (__mach_task_self (),
			  (vm_address_t) addr, (vm_size_t) len,
			  0, vmprot))
    {
      errno = err;
      return -1;
    }
  return 0;
}
Exemplo n.º 2
0
kern_return_t
__mach_setup_thread (task_t task, thread_t thread, void *pc,
                     vm_address_t *stack_base, vm_size_t *stack_size)
{
    kern_return_t error;
    struct machine_thread_state ts;
    mach_msg_type_number_t tssize = MACHINE_THREAD_STATE_COUNT;
    vm_address_t stack;
    vm_size_t size;
    int anywhere = 0;

    size = stack_size ? *stack_size ? : STACK_SIZE : STACK_SIZE;

    if (stack_base && *stack_base)
        stack = *stack_base;
    else if (size == STACK_SIZE)
    {
        /* Cthreads has a bug that makes its stack-probing code fail if
        the stack is too low in memory.  It's bad to try and fix it there
         until cthreads is integrated into libc, so we'll just do it here
         by requesting a high address.  When the cthreads bug is fixed,
         this assignment to STACK should be changed to 0, and the ANYWHERE
         argument to vm_allocate should be changed to 0.  This comment should
         be left, however, in order to confuse people who wonder why its
         here.  (Though perhaps that last sentence (and this one) should
         be deleted to maximize the effect.)  */
#ifdef STACK_GROWTH_DOWN
        stack = VM_MAX_ADDRESS - size - __vm_page_size;
#else
        stack = VM_MIN_ADDRESS;
#endif
    }
    else
        anywhere = 1;

    if (error = __vm_allocate (task, &stack, size + __vm_page_size, anywhere))
        return error;

    if (stack_size)
        *stack_size = size;

    memset (&ts, 0, sizeof (ts));
    MACHINE_THREAD_STATE_SET_PC (&ts, pc);
#ifdef STACK_GROWTH_DOWN
    if (stack_base)
        *stack_base = stack + __vm_page_size;
    ts.SP = stack + __vm_page_size + size;
#elif defined (STACK_GROWTH_UP)
    if (stack_base)
        *stack_base = stack;
    ts.SP = stack;
    stack += size;
#else
#error stack direction unknown
#endif

    /* Create the red zone.  */
    if (error = __vm_protect (task, stack, __vm_page_size, 0, VM_PROT_NONE))
        return error;

    return __thread_set_state (thread, MACHINE_THREAD_STATE_FLAVOR,
                               (int *) &ts, tssize);
}