This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Use malloc and free in atexit only when available.


Hi,

Attached is a patch to use malloc and free in in the support functions
for atexit only when available.

The previous version of this patch was posted at:

http://sourceware.org/ml/newlib/2008/msg00560.html

A while ago, Mark Mitchell added --disable-newlib-atexit-dynamic-alloc
to prevent atexit from pulling malloc.  This was a bit inflexible
because once newlib was built with --disable-newlib-atexit-alloc, the
user couldn't enable use of malloc in atexit without rebuilding
newlib.

This patch makes malloc and free weak symbols in the support functions
of atexit.  This way, if malloc is available for some other reason, we
use that.  Otherwise, we don't to conserve space.

Per suggestion from Ralf and Jeff, I am keeping
--disable-newlib-atexit-dynamic-alloc.  I've used the following
construct to expose much of the code to syntax checking by the
compiler even when --disable-newlib-atexit-dynamic-alloc is specified.

      if (!_ATEXIT_DYNAMIC_ALLOC || !malloc)
	return -1;

Tested with m68k-elf.  OK to apply?

Kazu Hirata

2009-01-07  Paul Brook  <paul@codesourcery.com>
	    Kazu Hirata  <kazu@codesourcery.com>

	* libc/stdlib/__atexit.c (__register_exitproc): Use weak reference
	to malloc.  Only allocate dynamically if it is present.  Avoid
	calling malloc if not present.
	* libc/stdlib/__call_atexit.c (__call_exitprocs): Use weak
	reference to free.

Index: newlib/libc/stdlib/__atexit.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdlib/__atexit.c,v
retrieving revision 1.4
diff -c -d -p -r1.4 __atexit.c
*** newlib/libc/stdlib/__atexit.c	21 Mar 2006 00:57:34 -0000	1.4
--- newlib/libc/stdlib/__atexit.c	8 Jan 2009 02:36:09 -0000
***************
*** 8,13 ****
--- 8,19 ----
  #include <sys/lock.h>
  #include "atexit.h"
  
+ #ifndef _ATEXIT_DYNAMIC_ALLOC
+ #define _ATEXIT_DYNAMIC_ALLOC 0
+ #endif
+ 
+ /* Make this a weak reference to avoid pulling in malloc.  */
+ void * malloc(size_t) _ATTRIBUTE((__weak__));
  
  /*
   * Register a function to be performed at exit or on shared library unload.
*************** _DEFUN (__register_exitproc,
*** 35,43 ****
      _GLOBAL_REENT->_atexit = p = &_GLOBAL_REENT->_atexit0;
    if (p->_ind >= _ATEXIT_SIZE)
      {
! #ifndef _ATEXIT_DYNAMIC_ALLOC
!       return -1;
! #else
        p = (struct _atexit *) malloc (sizeof *p);
        if (p == NULL)
  	{
--- 41,52 ----
      _GLOBAL_REENT->_atexit = p = &_GLOBAL_REENT->_atexit0;
    if (p->_ind >= _ATEXIT_SIZE)
      {
!       /* Don't dynamically allocate the atexit array if the user
! 	 doesn't request it via _ATEXIT_DYNAMIC_ALLOC or malloc is not
! 	 available.  */
!       if (!_ATEXIT_DYNAMIC_ALLOC || !malloc)
! 	return -1;
! 
        p = (struct _atexit *) malloc (sizeof *p);
        if (p == NULL)
  	{
*************** _DEFUN (__register_exitproc,
*** 53,59 ****
        p->_on_exit_args._fntypes = 0;
        p->_on_exit_args._is_cxa = 0;
  #endif
- #endif
      }
  
    if (type != __et_atexit)
--- 62,67 ----
*************** _DEFUN (__register_exitproc,
*** 62,68 ****
        args = p->_on_exit_args_ptr;
        if (args == NULL)
  	{
! 	  args = malloc (sizeof * p->_on_exit_args_ptr);
  	  if (args == NULL)
  	    {
  #ifndef __SINGLE_THREAD__
--- 70,78 ----
        args = p->_on_exit_args_ptr;
        if (args == NULL)
  	{
! 	  if (malloc)
! 	    args = malloc (sizeof * p->_on_exit_args_ptr);
! 
  	  if (args == NULL)
  	    {
  #ifndef __SINGLE_THREAD__
Index: newlib/libc/stdlib/__call_atexit.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdlib/__call_atexit.c,v
retrieving revision 1.5
diff -c -d -p -r1.5 __call_atexit.c
*** newlib/libc/stdlib/__call_atexit.c	5 Apr 2007 16:47:38 -0000	1.5
--- newlib/libc/stdlib/__call_atexit.c	8 Jan 2009 02:36:09 -0000
***************
*** 7,12 ****
--- 7,19 ----
  #include <reent.h>
  #include "atexit.h"
  
+ #ifndef _ATEXIT_DYNAMIC_ALLOC
+ #define _ATEXIT_DYNAMIC_ALLOC 0
+ #endif
+ 
+ /* Make this a weak reference to avoid pulling in malloc.  */
+ void free(void *) _ATTRIBUTE((__weak__));
+ 
  /*
   * Call registered exit handlers.  If D is null then all handlers are called,
   * otherwise only the handlers from that DSO are called.
*************** _DEFUN (__call_exitprocs, (code, d),
*** 73,81 ****
  	    goto restart;
  	}
  
! #ifndef _ATEXIT_DYNAMIC_ALLOC
!       break;
! #else
        /* Move to the next block.  Free empty blocks except the last one,
  	 which is part of _GLOBAL_REENT.  */
        if (p->_ind == 0 && p->_next)
--- 80,91 ----
  	    goto restart;
  	}
  
!       /* Don't dynamically free the atexit array if the user doesn't
! 	 request it via _ATEXIT_DYNAMIC_ALLOC or malloc is not
! 	 available.  */
!       if (!_ATEXIT_DYNAMIC_ALLOC || !free)
! 	break;
! 
        /* Move to the next block.  Free empty blocks except the last one,
  	 which is part of _GLOBAL_REENT.  */
        if (p->_ind == 0 && p->_next)
*************** _DEFUN (__call_exitprocs, (code, d),
*** 94,99 ****
  	  lastp = &p->_next;
  	  p = p->_next;
  	}
- #endif
      }
  }
--- 104,108 ----


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]