aboutsummaryrefslogtreecommitdiff
path: root/newlib
diff options
context:
space:
mode:
authorAlex Suykov <alex.suykov@gmail.com>2016-08-15 20:32:48 +0300
committerAndrew Waterman <waterman@eecs.berkeley.edu>2016-08-15 10:32:48 -0700
commit006846161cc2f3de5a34f57d77fd8999f183fe48 (patch)
tree159561404d08dac1b77395162e8271b7999b7d2d /newlib
parentbfbfdec43fc89a6bed4e3b823badcc1414e73740 (diff)
downloadriscv-gnu-toolchain-006846161cc2f3de5a34f57d77fd8999f183fe48.zip
riscv-gnu-toolchain-006846161cc2f3de5a34f57d77fd8999f183fe48.tar.gz
riscv-gnu-toolchain-006846161cc2f3de5a34f57d77fd8999f183fe48.tar.bz2
newlib: use brk(0) to get initial program break (#172)
There are no guarantees that the break going to be located exactly at the _end, but brk(0) is guaranteed to return its current value. QEMU ELF loader moves the initial break up to the next page boundary, disabling sbrk-based malloc for any allocations smaller than the adjustment made. And ASLR may do even worse.
Diffstat (limited to 'newlib')
-rw-r--r--newlib/libgloss/riscv/syscalls.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/newlib/libgloss/riscv/syscalls.c b/newlib/libgloss/riscv/syscalls.c
index 50203d6..ae1edc5 100644
--- a/newlib/libgloss/riscv/syscalls.c
+++ b/newlib/libgloss/riscv/syscalls.c
@@ -436,11 +436,15 @@ long sysconf(int name)
void* sbrk(ptrdiff_t incr)
{
- extern unsigned char _end[]; // Defined by linker
static unsigned long heap_end;
- if (heap_end == 0)
- heap_end = (long)_end;
+ if (heap_end == 0) {
+ long brk = syscall_errno(SYS_brk, 0, 0, 0, 0);
+ if(brk == -1)
+ return (void*)-1;
+ heap_end = brk;
+ }
+
if (syscall_errno(SYS_brk, heap_end + incr, 0, 0, 0) != heap_end + incr)
return (void*)-1;