summaryrefslogtreecommitdiff
path: root/sysdeps/generic/sbrk.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/generic/sbrk.c')
-rw-r--r--sysdeps/generic/sbrk.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/sysdeps/generic/sbrk.c b/sysdeps/generic/sbrk.c
index 698f814e2b..92ad8c4102 100644
--- a/sysdeps/generic/sbrk.c
+++ b/sysdeps/generic/sbrk.c
@@ -22,6 +22,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
extern void *__curbrk;
extern int __brk (void *addr);
+#ifdef PIC
+extern int __libc_is_static;
+weak_extern (__libc_is_static)
+#endif
+
/* Extend the process's data space by INCREMENT.
If INCREMENT is negative, shrink data space by - INCREMENT.
Return start of new space allocated, or -1 for errors. */
@@ -30,12 +35,16 @@ __sbrk (ptrdiff_t increment)
{
void *oldbrk;
- /* Always update __curbrk from the kernel's brk value. That way two
- separate instances of __brk and __sbrk can share the heap, returning
- interleaved pieces of it. This happens when libc.so is loaded by
- dlopen in a statically-linked program that already uses __brk. */
- if (__brk (0) < 0)
- return (void *) -1;
+ /* If this is not part of the dynamic library or the library is used
+ via dynamic loading in a statically linked program update
+ __curbrk from the kernel's brk value. That way two separate
+ instances of __brk and __sbrk can share the heap, returning
+ interleaved pieces of it. */
+#ifdef PIC
+ if (__curbrk == NULL || &__libc_is_static == NULL)
+#endif
+ if (__brk (0) < 0)
+ return (void *) -1;
if (increment == 0)
return __curbrk;