Print this page
libc: adjust brk(0) to return the existing break, and use it to initialize sbrk()

*** 22,33 **** /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - #pragma ident "%Z%%M% %I% %E% SMI" - #pragma weak _sbrk = sbrk #pragma weak _brk = brk #include "lint.h" #include <synch.h> --- 22,31 ----
*** 38,53 **** #include <inttypes.h> #include <unistd.h> #include "mtlib.h" #include "libc.h" ! extern int _end; ! void *_nd = &_end; mutex_t __sbrk_lock = DEFAULTMUTEX; ! extern int _brk_unlocked(void *); ! extern void *_sbrk_unlocked(intptr_t); /* * The break must always be at least 8-byte aligned */ #if (_MAX_ALIGNMENT < 8) --- 36,50 ---- #include <inttypes.h> #include <unistd.h> #include "mtlib.h" #include "libc.h" ! void *_nd = NULL; mutex_t __sbrk_lock = DEFAULTMUTEX; ! extern intptr_t _brk_unlocked(void *); ! void *_sbrk_unlocked(intptr_t); /* * The break must always be at least 8-byte aligned */ #if (_MAX_ALIGNMENT < 8)
*** 85,96 **** * - the addend is positive and brk + addend > ULONG_MAX */ void * _sbrk_unlocked(intptr_t addend) { ! char *old_brk = BRKALIGN(_nd); ! char *new_brk = BRKALIGN(old_brk + addend); if ((addend > 0 && new_brk < old_brk) || (addend < 0 && new_brk > old_brk)) { errno = ENOMEM; return ((void *)-1); --- 82,100 ---- * - the addend is positive and brk + addend > ULONG_MAX */ void * _sbrk_unlocked(intptr_t addend) { ! char *old_brk; ! char *new_brk; ! ! if (_nd == NULL) { ! _nd = (void *)_brk_unlocked(0); ! } ! ! old_brk = BRKALIGN(_nd); ! new_brk = BRKALIGN(old_brk + addend); if ((addend > 0 && new_brk < old_brk) || (addend < 0 && new_brk > old_brk)) { errno = ENOMEM; return ((void *)-1);
*** 132,141 **** --- 136,149 ---- low_align = MAX(low_align, ALIGNSZ); high_align = MAX(high_align, ALIGNSZ); lmutex_lock(&__sbrk_lock); + if (_nd == NULL) { + _nd = (void *)_brk_unlocked(0); + } + old_brk = (uintptr_t)BRKALIGN(_nd); ret_brk = P2ROUNDUP(old_brk, low_align); high_brk = ret_brk + min_size; new_brk = P2ROUNDUP(high_brk, high_align);
*** 146,156 **** lmutex_unlock(&__sbrk_lock); errno = ENOMEM; return ((void *)-1); } ! if ((brk_result = _brk_unlocked((void *)new_brk)) == 0) _nd = (void *)new_brk; lmutex_unlock(&__sbrk_lock); if (brk_result != 0) return ((void *)-1); --- 154,164 ---- lmutex_unlock(&__sbrk_lock); errno = ENOMEM; return ((void *)-1); } ! if ((brk_result = (int)_brk_unlocked((void *)new_brk)) == 0) _nd = (void *)new_brk; lmutex_unlock(&__sbrk_lock); if (brk_result != 0) return ((void *)-1);
*** 163,183 **** int brk(void *new_brk) { int result; if (!primary_link_map) { errno = ENOTSUP; return (-1); } /* * Need to align this here; _brk_unlocked won't do it for us. */ new_brk = BRKALIGN(new_brk); lmutex_lock(&__sbrk_lock); ! if ((result = _brk_unlocked(new_brk)) == 0) _nd = new_brk; lmutex_unlock(&__sbrk_lock); return (result); } --- 171,200 ---- int brk(void *new_brk) { int result; + /* + * brk(2) will return the current brk if given an argument of 0, so we + * need to fail it here + */ + if (new_brk == 0) { + errno = ENOMEM; + return (-1); + } + if (!primary_link_map) { errno = ENOTSUP; return (-1); } /* * Need to align this here; _brk_unlocked won't do it for us. */ new_brk = BRKALIGN(new_brk); lmutex_lock(&__sbrk_lock); ! if ((result = (int)_brk_unlocked(new_brk)) == 0) _nd = new_brk; lmutex_unlock(&__sbrk_lock); return (result); }