2004-08-15  Roland McGrath  <roland@redhat.com>
	[BZ #227]
	* sysdeps/unix/sysv/linux/kernel-features.h
	(__ASSUME_BRK_PAGE_ROUNDED): New macro.
	* sysdeps/unix/sysv/linux/dl-sysdep.c (frob_brk)
	[! __ASSUME_BRK_PAGE_ROUNDED]: Adjust the break up if it falls within
	the partial page after the dynamic linker's own data segment.
This commit is contained in:
Roland McGrath 2004-08-15 23:33:02 +00:00
parent 2d26a7173c
commit a489c5298d
2 changed files with 30 additions and 1 deletions

View File

@ -1,5 +1,5 @@
/* Dynamic linker system dependencies for Linux.
Copyright (C) 1995, 1997, 2001 Free Software Foundation, Inc.
Copyright (C) 1995, 1997, 2001, 2004 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
@ -21,6 +21,8 @@
the generic dynamic linker system interface code. */
#include <unistd.h>
#include <ldsodefs.h>
#include "kernel-features.h"
#define DL_SYSDEP_INIT frob_brk ()
@ -28,6 +30,27 @@ static inline void
frob_brk (void)
{
__brk (0); /* Initialize the break. */
#if ! __ASSUME_BRK_PAGE_ROUNDED
/* If the dynamic linker was executed as a program, then the break may
start immediately after our data segment. However, dl-minimal.c has
already stolen the remainder of the page for internal allocations.
If we don't adjust the break location recorded by the kernel, the
normal program startup will inquire, find the value at our &_end,
and start allocating its own data there, clobbering dynamic linker
data structures allocated there during startup.
Later Linux kernels have changed this behavior so that the initial
break value is rounded up to the page boundary before we start. */
extern void *__curbrk attribute_hidden;
extern void _end attribute_hidden;
void *const endpage = (void *) 0 + (((__curbrk - (void *) 0)
+ GLRO(dl_pagesize) - 1)
& -GLRO(dl_pagesize));
if (__builtin_expect (__curbrk >= &_end && __curbrk < endpage, 0))
__brk (endpage);
#endif
}
#include <sysdeps/generic/dl-sysdep.c>

View File

@ -400,3 +400,9 @@
#if __LINUX_KERNEL_VERSION >= 132612
# define __ASSUME_GETDENTS32_D_TYPE 1
#endif
/* Starting with version 2.5.3, the initial location returned by `brk'
after exec is always rounded up to the next page. */
#if __LINUX_KERNEL_VERSION >= 132355
# define __ASSUME_BRK_PAGE_ROUNDED 1
#endif