diff options
Diffstat (limited to 'sysdeps/mach/hurd/brk.c')
-rw-r--r-- | sysdeps/mach/hurd/brk.c | 166 |
1 files changed, 0 insertions, 166 deletions
diff --git a/sysdeps/mach/hurd/brk.c b/sysdeps/mach/hurd/brk.c deleted file mode 100644 index a9154bffdd..0000000000 --- a/sysdeps/mach/hurd/brk.c +++ /dev/null @@ -1,166 +0,0 @@ -/* Copyright (C) 1991-2017 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 <errno.h> -#include <hurd.h> -#include <hurd/resource.h> -#include <cthreads.h> /* For `struct mutex'. */ - - -/* Initial maximum size of the data segment (this is arbitrary). */ -#define DATA_SIZE (128 * 1024 * 1024) - -/* Up to the page including this address is allocated from the kernel. - This address is the data resource limit. */ -vm_address_t _hurd_data_end; - -/* Up to this address is actually available to the user. - Pages beyond the one containing this address allow no access. */ -vm_address_t _hurd_brk = 0; - -/* This name is used by the Linux crtbeginS.o for reasons you don't even - want to think about it. It's just easier to provide some definition for - it than even to explain the braindamage involved. */ -weak_alias (_hurd_brk, ___brk_addr) - -struct mutex _hurd_brk_lock; - -extern int __data_start, _end; -weak_extern (__data_start) -static vm_address_t static_data_start; - - -/* Set the end of the process's data space to INADDR. - Return 0 if successful, -1 if not. */ -int -__brk (void *inaddr) -{ - int ret; - HURD_CRITICAL_BEGIN; - __mutex_lock (&_hurd_brk_lock); - ret = _hurd_set_brk ((vm_address_t) inaddr); - __mutex_unlock (&_hurd_brk_lock); - HURD_CRITICAL_END; - return ret; -} -weak_alias (__brk, brk) - - -int -_hurd_set_brk (vm_address_t addr) -{ - error_t err = 0; - vm_address_t pagend = round_page (addr); - vm_address_t pagebrk = round_page (_hurd_brk); - long int rlimit; - - if (pagend <= pagebrk) - { - if (pagend < pagebrk) - { - /* XXX wish this were atomic... */ - /* First deallocate the memory to release its backing space. */ - __vm_deallocate (__mach_task_self (), pagend, pagebrk - pagend); - /* Now reallocate it with no access allowed. */ - err = __vm_map (__mach_task_self (), - &pagend, pagebrk - pagend, - 0, 0, MACH_PORT_NULL, 0, 0, - 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE, - VM_INHERIT_COPY); - /* XXX what if error? */ - } - _hurd_brk = addr; - return 0; - } - - __mutex_lock (&_hurd_rlimit_lock); - rlimit = _hurd_rlimits[RLIMIT_DATA].rlim_cur; - __mutex_unlock (&_hurd_rlimit_lock); - - if (addr - static_data_start > rlimit) - { - /* Need to increase the resource limit. */ - errno = ENOMEM; - return -1; - } - - if (pagend > _hurd_data_end) - { - vm_address_t alloc_start = _hurd_data_end; - - /* We didn't allocate enough space! Hopefully we can get some more! */ - - if (_hurd_data_end > pagebrk) - /* First finish allocation. */ - err = __vm_protect (__mach_task_self (), pagebrk, - alloc_start - pagebrk, 0, - VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); - if (! err) - _hurd_brk = alloc_start; - - if (! err) - err = __vm_allocate (__mach_task_self (), &alloc_start, - pagend - alloc_start, 0); - - if (! err) - _hurd_data_end = pagend; - } - else - /* Make the memory accessible. */ - err = __vm_protect (__mach_task_self (), pagebrk, pagend - pagebrk, - 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); - - if (err) - return __hurd_fail (err); - - _hurd_brk = addr; - return 0; -} - -static void -init_brk (void) -{ - vm_address_t pagend; - - __mutex_init (&_hurd_brk_lock); - - static_data_start = (vm_address_t) (&__data_start ?: &_end); - - /* If _hurd_brk is already set, don't change it. The assumption is that - it was set in a previous run before something like Emacs's unexec was - called and dumped all the data up to the break at that point. */ - if (_hurd_brk == 0) - _hurd_brk = (vm_address_t) &_end; - - pagend = round_page (_hurd_brk); - - _hurd_data_end = round_page (static_data_start + DATA_SIZE); - - if (pagend < _hurd_data_end) - { - /* We use vm_map to allocate and change permissions atomically. */ - if (__vm_map (__mach_task_self (), &pagend, _hurd_data_end - pagend, - 0, 0, MACH_PORT_NULL, 0, 0, - 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE, - VM_INHERIT_COPY)) - /* Couldn't allocate the memory. The break will be very short. */ - _hurd_data_end = pagend; - } - - (void) &init_brk; /* Avoid ``defined but not used'' warning. */ -} -text_set_element (_hurd_preinit_hook, init_brk); |