Subject: Re: malloc_usable_size () call under NetBSD
To: None <current-users@netbsd.org>
From: Christos Zoulas <christos@astron.com>
List: current-users
Date: 07/20/2007 16:00:33
In article <46A08CAD.8090603@free.fr>, Vincent <10.50@free.fr> wrote:
>Hi there,
>
>I've tried to compiled the XaraLX vector graphics program that seems to
>have been ported on FreeBSD. However, it fails at the first file,
>complaining to lack the "malloc_usable_size ()" system call. After a bit
>of googling (™), I found that this call had been added on FreeBSD 7 (so
>that's pretty recent). Wherefore, question: how to emulate this call
>under NetBSD, if this is possible.
This is not a system call it is a libc function. It takes as an argument
a pointer that was previously returned by malloc(3) and returns the
allocated space for that pointer.
Here's an untested patch...
christos
Index: malloc.c
===================================================================
RCS file: /cvsroot/src/lib/libc/stdlib/malloc.c,v
retrieving revision 1.48
diff -u -u -r1.48 malloc.c
--- malloc.c 24 Nov 2006 19:37:02 -0000 1.48
+++ malloc.c 20 Jul 2007 15:59:47 -0000
@@ -778,6 +778,63 @@
return result;
}
+size_t
+malloc_usable_size(void *ptr)
+{
+ size_t idx = ptr2idx(ptr);
+ struct pginfo **mp;
+
+ if (idx < malloc_pageshift) {
+ wrtwarning("junk pointer, too low to make sense.\n");
+ return (size_t)-1;
+ }
+
+ if (idx > last_idx) {
+ wrtwarning("junk pointer, too high to make sense.\n");
+ return (size_t)-1;
+ }
+
+ mp = &page_dir[idx];
+
+ if (*mp == MALLOC_FIRST) { /* Page allocation */
+
+ /* Check the pointer */
+ if ((size_t)(uintptr_t)ptr & malloc_pagemask) {
+ wrtwarning("modified (page-) pointer.\n");
+ return (size_t)-1;
+ }
+
+ /* Find the size in bytes */
+ for (osize = malloc_pagesize; *++mp == MALLOC_FOLLOW;)
+ osize += malloc_pagesize;
+
+ return osize;
+
+ } else if (*mp >= MALLOC_MAGIC) { /* Chunk allocation */
+
+ /* Check the pointer for sane values */
+ if (((size_t)(uintptr_t)ptr & ((*mp)->size-1))) {
+ wrtwarning("modified (chunk-) pointer.\n");
+ return (size_t)-1;
+ }
+
+ /* Find the chunk index in the page */
+ i = ((size_t)(uintptr_t)ptr & malloc_pagemask) >> (*mp)->shift;
+
+ /* Verify that it isn't a free chunk already */
+ if ((*mp)->bits[i/MALLOC_BITS] & (1<<(i%MALLOC_BITS))) {
+ wrtwarning("chunk is already free.\n");
+ return (size_t)-1;
+ }
+
+ return (*mp)->size;
+
+ } else {
+ wrtwarning("pointer to wrong page.\n");
+ return (size_t)-1;
+ }
+}
+
/*
* Change the size of an allocation.
*/