Yaakov Selkowitz
2015-09-01 21:41:59 UTC
This allows programs to override malloc/free/etc. while still being able
to access the internally provided implementation.
* common.din (__libc_calloc): Export.
(__libc_free): Export.
(__libc_mallinfo): Export.
(__libc_malloc): Export.
(__libc_mallopt): Export.
(__libc_memalign): Export.
(__libc_realloc): Export.
(__libc_valloc): Export.
* malloc_wrapper.cc (__libc_free, free): Split out builtin dlmalloc
implementation into separate function.
(__libc_malloc, malloc): Ditto.
(__libc_realloc, realloc): Ditto.
(__libc_calloc, calloc): Ditto.
(__libc_memalign, posix_memalign, memalign): Ditto.
(__libc_valloc, valloc): Ditto.
(__libc_mallopt, mallopt): Ditto.
(__libc_mallinfo, mallinfo): Ditto.
---
This came to my attention due to:
https://git.gnome.org/browse/gdk-pixbuf/commit/?id=b07c3bf
Although this will likely be changed due to it being unable to link
on anything not using glibc.
The one question I have about this patch is that I see in a couple other
places that malloc-overriding code tries to override the __libc_* variants
as well on Linux (where they are just weak aliases to the main functions).
This particular method wouldn't allow that, but I'm not sure if we want or
need to allow that either.
winsup/cygwin/common.din | 8 +++
winsup/cygwin/malloc_wrapper.cc | 129 ++++++++++++++++++++++++++--------------
2 files changed, 94 insertions(+), 43 deletions(-)
diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din
index 71a0c9b..3381c61 100644
--- a/winsup/cygwin/common.din
+++ b/winsup/cygwin/common.din
@@ -67,6 +67,14 @@ __isinfd NOSIGFE
__isinff NOSIGFE
__isnand NOSIGFE
__isnanf NOSIGFE
+__libc_calloc SIGFE
+__libc_free SIGFE
+__libc_mallinfo SIGFE
+__libc_malloc SIGFE
+__libc_mallopt SIGFE
+__libc_memalign SIGFE
+__libc_realloc SIGFE
+__libc_valloc SIGFE
__locale_mb_cur_max NOSIGFE
__main NOSIGFE
__mempcpy = mempcpy NOSIGFE
diff --git a/winsup/cygwin/malloc_wrapper.cc b/winsup/cygwin/malloc_wrapper.cc
index 43b8144..1375a46 100644
--- a/winsup/cygwin/malloc_wrapper.cc
+++ b/winsup/cygwin/malloc_wrapper.cc
@@ -36,17 +36,31 @@ static bool internal_malloc_determined;
doesn't provide its own malloc. */
extern "C" void
+__libc_free (void *p)
+{
+ __malloc_lock ();
+ dlfree (p);
+ __malloc_unlock ();
+}
+
+extern "C" void
free (void *p)
{
malloc_printf ("(%p), called by %p", p, caller_return_address ());
if (!use_internal)
user_data->free (p);
else
- {
- __malloc_lock ();
- dlfree (p);
- __malloc_unlock ();
- }
+ __libc_free (p);
+}
+
+extern "C" void *
+__libc_malloc (size_t size)
+{
+ void *res;
+ __malloc_lock ();
+ res = dlmalloc (size);
+ __malloc_unlock ();
+ return res;
}
extern "C" void *
@@ -56,28 +70,30 @@ malloc (size_t size)
if (!use_internal)
res = user_data->malloc (size);
else
- {
- __malloc_lock ();
- res = dlmalloc (size);
- __malloc_unlock ();
- }
+ res = __libc_malloc (size);
malloc_printf ("(%ld) = %p, called by %p", size, res,
caller_return_address ());
return res;
}
extern "C" void *
+__libc_realloc (void *p, size_t size)
+{
+ void *res;
+ __malloc_lock ();
+ res = dlrealloc (p, size);
+ __malloc_unlock ();
+ return res;
+}
+
+extern "C" void *
realloc (void *p, size_t size)
{
void *res;
if (!use_internal)
res = user_data->realloc (p, size);
else
- {
- __malloc_lock ();
- res = dlrealloc (p, size);
- __malloc_unlock ();
- }
+ res = __libc_realloc (p, size);
malloc_printf ("(%p, %ld) = %p, called by %p", p, size, res,
caller_return_address ());
return res;
@@ -95,22 +111,38 @@ reallocf (void *p, size_t size)
}
extern "C" void *
+__libc_calloc (size_t nmemb, size_t size)
+{
+ void *res;
+ __malloc_lock ();
+ res = dlcalloc (nmemb, size);
+ __malloc_unlock ();
+ return res;
+}
+
+extern "C" void *
calloc (size_t nmemb, size_t size)
{
void *res;
if (!use_internal)
res = user_data->calloc (nmemb, size);
else
- {
- __malloc_lock ();
- res = dlcalloc (nmemb, size);
- __malloc_unlock ();
- }
+ res = __libc_calloc (nmemb, size);
malloc_printf ("(%ld, %ld) = %p, called by %p", nmemb, size, res,
caller_return_address ());
return res;
}
+extern "C" void *
+__libc_memalign (size_t alignment, size_t bytes)
+{
+ void *res;
+ __malloc_lock ();
+ res = dlmemalign (alignment, bytes);
+ __malloc_unlock ();
+ return res;
+}
+
extern "C" int
posix_memalign (void **memptr, size_t alignment, size_t bytes)
{
@@ -121,9 +153,7 @@ posix_memalign (void **memptr, size_t alignment, size_t bytes)
return user_data->posix_memalign (memptr, alignment, bytes);
if ((alignment & (alignment - 1)) != 0)
return EINVAL;
- __malloc_lock ();
- res = dlmemalign (alignment, bytes);
- __malloc_unlock ();
+ res = __libc_memalign (alignment, bytes);
if (!res)
return ENOMEM;
if (memptr)
@@ -141,12 +171,17 @@ memalign (size_t alignment, size_t bytes)
res = NULL;
}
else
- {
- __malloc_lock ();
- res = dlmemalign (alignment, bytes);
- __malloc_unlock ();
- }
+ res = __libc_memalign (alignment, bytes);
+ return res;
+}
+extern "C" void *
+__libc_valloc (size_t bytes)
+{
+ void *res;
+ __malloc_lock ();
+ res = dlvalloc (bytes);
+ __malloc_unlock ();
return res;
}
@@ -160,11 +195,7 @@ valloc (size_t bytes)
res = NULL;
}
else
- {
- __malloc_lock ();
- res = dlvalloc (bytes);
- __malloc_unlock ();
- }
+ res = __libc_valloc (bytes);
return res;
}
@@ -208,6 +239,16 @@ malloc_trim (size_t pad)
}
extern "C" int
+__libc_mallopt (int p, int v)
+{
+ int res;
+ __malloc_lock ();
+ res = dlmallopt (p, v);
+ __malloc_unlock ();
+ return res;
+}
+
+extern "C" int
mallopt (int p, int v)
{
int res;
@@ -217,11 +258,7 @@ mallopt (int p, int v)
res = 0;
}
else
- {
- __malloc_lock ();
- res = dlmallopt (p, v);
- __malloc_unlock ();
- }
+ res = __libc_mallopt (p, v);
return res;
}
@@ -240,6 +277,16 @@ malloc_stats ()
}
extern "C" struct mallinfo
+__libc_mallinfo ()
+{
+ struct mallinfo m;
+ __malloc_lock ();
+ m = dlmallinfo ();
+ __malloc_unlock ();
+ return m;
+}
+
+extern "C" struct mallinfo
mallinfo ()
{
struct mallinfo m;
@@ -249,11 +296,7 @@ mallinfo ()
set_errno (ENOSYS);
}
else
- {
- __malloc_lock ();
- m = dlmallinfo ();
- __malloc_unlock ();
- }
+ m = __libc_mallinfo ();
return m;
}
to access the internally provided implementation.
* common.din (__libc_calloc): Export.
(__libc_free): Export.
(__libc_mallinfo): Export.
(__libc_malloc): Export.
(__libc_mallopt): Export.
(__libc_memalign): Export.
(__libc_realloc): Export.
(__libc_valloc): Export.
* malloc_wrapper.cc (__libc_free, free): Split out builtin dlmalloc
implementation into separate function.
(__libc_malloc, malloc): Ditto.
(__libc_realloc, realloc): Ditto.
(__libc_calloc, calloc): Ditto.
(__libc_memalign, posix_memalign, memalign): Ditto.
(__libc_valloc, valloc): Ditto.
(__libc_mallopt, mallopt): Ditto.
(__libc_mallinfo, mallinfo): Ditto.
---
This came to my attention due to:
https://git.gnome.org/browse/gdk-pixbuf/commit/?id=b07c3bf
Although this will likely be changed due to it being unable to link
on anything not using glibc.
The one question I have about this patch is that I see in a couple other
places that malloc-overriding code tries to override the __libc_* variants
as well on Linux (where they are just weak aliases to the main functions).
This particular method wouldn't allow that, but I'm not sure if we want or
need to allow that either.
winsup/cygwin/common.din | 8 +++
winsup/cygwin/malloc_wrapper.cc | 129 ++++++++++++++++++++++++++--------------
2 files changed, 94 insertions(+), 43 deletions(-)
diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din
index 71a0c9b..3381c61 100644
--- a/winsup/cygwin/common.din
+++ b/winsup/cygwin/common.din
@@ -67,6 +67,14 @@ __isinfd NOSIGFE
__isinff NOSIGFE
__isnand NOSIGFE
__isnanf NOSIGFE
+__libc_calloc SIGFE
+__libc_free SIGFE
+__libc_mallinfo SIGFE
+__libc_malloc SIGFE
+__libc_mallopt SIGFE
+__libc_memalign SIGFE
+__libc_realloc SIGFE
+__libc_valloc SIGFE
__locale_mb_cur_max NOSIGFE
__main NOSIGFE
__mempcpy = mempcpy NOSIGFE
diff --git a/winsup/cygwin/malloc_wrapper.cc b/winsup/cygwin/malloc_wrapper.cc
index 43b8144..1375a46 100644
--- a/winsup/cygwin/malloc_wrapper.cc
+++ b/winsup/cygwin/malloc_wrapper.cc
@@ -36,17 +36,31 @@ static bool internal_malloc_determined;
doesn't provide its own malloc. */
extern "C" void
+__libc_free (void *p)
+{
+ __malloc_lock ();
+ dlfree (p);
+ __malloc_unlock ();
+}
+
+extern "C" void
free (void *p)
{
malloc_printf ("(%p), called by %p", p, caller_return_address ());
if (!use_internal)
user_data->free (p);
else
- {
- __malloc_lock ();
- dlfree (p);
- __malloc_unlock ();
- }
+ __libc_free (p);
+}
+
+extern "C" void *
+__libc_malloc (size_t size)
+{
+ void *res;
+ __malloc_lock ();
+ res = dlmalloc (size);
+ __malloc_unlock ();
+ return res;
}
extern "C" void *
@@ -56,28 +70,30 @@ malloc (size_t size)
if (!use_internal)
res = user_data->malloc (size);
else
- {
- __malloc_lock ();
- res = dlmalloc (size);
- __malloc_unlock ();
- }
+ res = __libc_malloc (size);
malloc_printf ("(%ld) = %p, called by %p", size, res,
caller_return_address ());
return res;
}
extern "C" void *
+__libc_realloc (void *p, size_t size)
+{
+ void *res;
+ __malloc_lock ();
+ res = dlrealloc (p, size);
+ __malloc_unlock ();
+ return res;
+}
+
+extern "C" void *
realloc (void *p, size_t size)
{
void *res;
if (!use_internal)
res = user_data->realloc (p, size);
else
- {
- __malloc_lock ();
- res = dlrealloc (p, size);
- __malloc_unlock ();
- }
+ res = __libc_realloc (p, size);
malloc_printf ("(%p, %ld) = %p, called by %p", p, size, res,
caller_return_address ());
return res;
@@ -95,22 +111,38 @@ reallocf (void *p, size_t size)
}
extern "C" void *
+__libc_calloc (size_t nmemb, size_t size)
+{
+ void *res;
+ __malloc_lock ();
+ res = dlcalloc (nmemb, size);
+ __malloc_unlock ();
+ return res;
+}
+
+extern "C" void *
calloc (size_t nmemb, size_t size)
{
void *res;
if (!use_internal)
res = user_data->calloc (nmemb, size);
else
- {
- __malloc_lock ();
- res = dlcalloc (nmemb, size);
- __malloc_unlock ();
- }
+ res = __libc_calloc (nmemb, size);
malloc_printf ("(%ld, %ld) = %p, called by %p", nmemb, size, res,
caller_return_address ());
return res;
}
+extern "C" void *
+__libc_memalign (size_t alignment, size_t bytes)
+{
+ void *res;
+ __malloc_lock ();
+ res = dlmemalign (alignment, bytes);
+ __malloc_unlock ();
+ return res;
+}
+
extern "C" int
posix_memalign (void **memptr, size_t alignment, size_t bytes)
{
@@ -121,9 +153,7 @@ posix_memalign (void **memptr, size_t alignment, size_t bytes)
return user_data->posix_memalign (memptr, alignment, bytes);
if ((alignment & (alignment - 1)) != 0)
return EINVAL;
- __malloc_lock ();
- res = dlmemalign (alignment, bytes);
- __malloc_unlock ();
+ res = __libc_memalign (alignment, bytes);
if (!res)
return ENOMEM;
if (memptr)
@@ -141,12 +171,17 @@ memalign (size_t alignment, size_t bytes)
res = NULL;
}
else
- {
- __malloc_lock ();
- res = dlmemalign (alignment, bytes);
- __malloc_unlock ();
- }
+ res = __libc_memalign (alignment, bytes);
+ return res;
+}
+extern "C" void *
+__libc_valloc (size_t bytes)
+{
+ void *res;
+ __malloc_lock ();
+ res = dlvalloc (bytes);
+ __malloc_unlock ();
return res;
}
@@ -160,11 +195,7 @@ valloc (size_t bytes)
res = NULL;
}
else
- {
- __malloc_lock ();
- res = dlvalloc (bytes);
- __malloc_unlock ();
- }
+ res = __libc_valloc (bytes);
return res;
}
@@ -208,6 +239,16 @@ malloc_trim (size_t pad)
}
extern "C" int
+__libc_mallopt (int p, int v)
+{
+ int res;
+ __malloc_lock ();
+ res = dlmallopt (p, v);
+ __malloc_unlock ();
+ return res;
+}
+
+extern "C" int
mallopt (int p, int v)
{
int res;
@@ -217,11 +258,7 @@ mallopt (int p, int v)
res = 0;
}
else
- {
- __malloc_lock ();
- res = dlmallopt (p, v);
- __malloc_unlock ();
- }
+ res = __libc_mallopt (p, v);
return res;
}
@@ -240,6 +277,16 @@ malloc_stats ()
}
extern "C" struct mallinfo
+__libc_mallinfo ()
+{
+ struct mallinfo m;
+ __malloc_lock ();
+ m = dlmallinfo ();
+ __malloc_unlock ();
+ return m;
+}
+
+extern "C" struct mallinfo
mallinfo ()
{
struct mallinfo m;
@@ -249,11 +296,7 @@ mallinfo ()
set_errno (ENOSYS);
}
else
- {
- __malloc_lock ();
- m = dlmallinfo ();
- __malloc_unlock ();
- }
+ m = __libc_mallinfo ();
return m;
}
--
2.4.5
2.4.5