* linux/sbrk is wrong
@ 2011-05-22 14:55 Szabolcs Nagy
2011-05-22 16:09 ` Rich Felker
0 siblings, 1 reply; 2+ messages in thread
From: Szabolcs Nagy @ 2011-05-22 14:55 UTC (permalink / raw)
To: musl
[-- Attachment #1: Type: text/plain, Size: 248 bytes --]
linux brk syscall returns the end pointer
so if it fails then the old one
if it succeeds then the new one
the current implementation of sbrk returns
the end of the allocated area instead of
the begining
i attached a patch that fixes brk and sbrk
[-- Attachment #2: sbrk.diff --]
[-- Type: text/x-diff, Size: 647 bytes --]
diff --git a/src/linux/brk.c b/src/linux/brk.c
index 9f63c5a..c261518 100644
--- a/src/linux/brk.c
+++ b/src/linux/brk.c
@@ -2,5 +2,5 @@
int brk(void *end)
{
- return -(syscall(SYS_brk, end) == -1);
+ return -((void *)syscall(SYS_brk, end) != end);
}
diff --git a/src/linux/sbrk.c b/src/linux/sbrk.c
index b2943a9..478a35e 100644
--- a/src/linux/sbrk.c
+++ b/src/linux/sbrk.c
@@ -3,5 +3,11 @@
void *sbrk(ptrdiff_t inc)
{
- return (void *)syscall(SYS_brk, syscall(SYS_brk, 0)+inc);
+ void *p = (void *)syscall(SYS_brk, 0);
+
+ if (inc == 0)
+ return p;
+ if ((void *)syscall(SYS_brk, p+inc) == p+inc)
+ return p;
+ return (void *)-1;
}
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: linux/sbrk is wrong
2011-05-22 14:55 linux/sbrk is wrong Szabolcs Nagy
@ 2011-05-22 16:09 ` Rich Felker
0 siblings, 0 replies; 2+ messages in thread
From: Rich Felker @ 2011-05-22 16:09 UTC (permalink / raw)
To: musl
On Sun, May 22, 2011 at 04:55:55PM +0200, Szabolcs Nagy wrote:
> linux brk syscall returns the end pointer
> so if it fails then the old one
> if it succeeds then the new one
>
> the current implementation of sbrk returns
> the end of the allocated area instead of
> the begining
IMO there's no way for correct code to use these functions anyway, but
I'll fix them anyway.
> int brk(void *end)
> {
> - return -(syscall(SYS_brk, end) == -1);
> + return -((void *)syscall(SYS_brk, end) != end);
> }
This looks fine.
> void *sbrk(ptrdiff_t inc)
> {
> - return (void *)syscall(SYS_brk, syscall(SYS_brk, 0)+inc);
> + void *p = (void *)syscall(SYS_brk, 0);
> +
> + if (inc == 0)
> + return p;
> + if ((void *)syscall(SYS_brk, p+inc) == p+inc)
This line is invalid C. p+inc is not defined since p has type void *.
The most correct would probably be to use uintptr_t internally
everywhere and just cast to void * in the return statement.
Rich
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2011-05-22 16:09 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-22 14:55 linux/sbrk is wrong Szabolcs Nagy
2011-05-22 16:09 ` Rich Felker
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/musl/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).