tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_alloc.c
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /*
       
     2 
       
     3   Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
       
     4   Portions Copyright 2002,2007 Sun Microsystems, Inc. All rights reserved.
       
     5 
       
     6   This program is free software; you can redistribute it and/or modify it
       
     7   under the terms of version 2.1 of the GNU Lesser General Public License 
       
     8   as published by the Free Software Foundation.
       
     9 
       
    10   This program is distributed in the hope that it would be useful, but
       
    11   WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
       
    13 
       
    14   Further, this software is distributed without any warranty that it is
       
    15   free of the rightful claim of any third person regarding infringement 
       
    16   or the like.  Any license provided herein, whether implied or 
       
    17   otherwise, applies only to this software file.  Patent licenses, if
       
    18   any, provided herein do not apply to combinations of this program with 
       
    19   other software, or any other product whatsoever.  
       
    20 
       
    21   You should have received a copy of the GNU Lesser General Public 
       
    22   License along with this program; if not, write the Free Software 
       
    23   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
       
    24   USA.
       
    25 
       
    26   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
       
    27   Mountain View, CA 94043, or:
       
    28 
       
    29   http://www.sgi.com
       
    30 
       
    31   For further information regarding this notice, see:
       
    32 
       
    33   http://oss.sgi.com/projects/GenInfo/NoticeExplan
       
    34 
       
    35 */
       
    36 
       
    37 
       
    38 
       
    39 #include "config.h"
       
    40 #include "pro_incl.h"
       
    41 #ifdef HAVE_STDLIB_H
       
    42 #include <stdlib.h>
       
    43 #endif /* HAVE_STDLIB_H */
       
    44 #ifdef HAVE_STRING_H
       
    45 #include <string.h>
       
    46 #endif /* HAVE_STRING_H */
       
    47 #include <malloc.h>
       
    48 
       
    49 /*
       
    50  When each block is allocated, there is a two-word structure
       
    51  allocated at the beginning so the block can go on a list.
       
    52  The address returned is the address *after* the two pointers
       
    53  at the start.  But this allows us to be given a pointer to
       
    54  a generic block, and go backwards to find the list-node.  Then
       
    55  we can remove this block from it's list without the need to search
       
    56  through a linked list in order to remove the node.  It also allows
       
    57  us to 'delete' a memory block without needing the dbg structure.
       
    58  We still need the dbg structure on allocation so that we know which
       
    59  linked list to add the block to.
       
    60 
       
    61  Only the allocation of the dbg structure itself cannot use _dwarf_p_get_alloc.
       
    62  That structure should be set up by hand, and the two list pointers
       
    63  should be initialized to point at the node itself.  That initializes
       
    64  the doubly linked list.
       
    65 */
       
    66 
       
    67 #define LIST_TO_BLOCK(lst) ((void*) (((char *)lst) + sizeof(memory_list_t)))
       
    68 #define BLOCK_TO_LIST(blk) ((memory_list_t*) (((char*)blk) - sizeof(memory_list_t)))
       
    69 
       
    70 
       
    71 /*
       
    72   dbg should be NULL only when allocating dbg itself.  In that
       
    73   case we initialize it to an empty circular doubly-linked list.
       
    74 */
       
    75 
       
    76 Dwarf_Ptr
       
    77 _dwarf_p_get_alloc(Dwarf_P_Debug dbg, Dwarf_Unsigned size)
       
    78 {
       
    79     void *sp;
       
    80     memory_list_t *lp = NULL;
       
    81     memory_list_t *dbglp = NULL;
       
    82     memory_list_t *nextblock = NULL;
       
    83 
       
    84     /* alloc control struct and data block together for performance reasons */
       
    85     lp = (memory_list_t *) malloc(size + sizeof(memory_list_t));
       
    86     if (lp == NULL) {
       
    87 	/* should throw an error */
       
    88 	return NULL;
       
    89     }
       
    90     
       
    91     /* point to 'size' bytes just beyond lp struct */
       
    92     sp = LIST_TO_BLOCK(lp);
       
    93     memset(sp, 0, size);
       
    94 
       
    95     if (dbg == NULL) {
       
    96 	lp->next = lp->prev = lp;
       
    97     } else {
       
    98 	/* I always have to draw a picture to understand this part. */
       
    99 
       
   100 	dbglp = BLOCK_TO_LIST(dbg);
       
   101 	nextblock = dbglp->next;
       
   102 	
       
   103 	/* Insert between dbglp and nextblock */
       
   104 	dbglp->next = lp;
       
   105 	lp->prev = dbglp;
       
   106 	lp->next = nextblock;
       
   107 	nextblock->prev = lp;
       
   108     }
       
   109 
       
   110     return sp;
       
   111 }
       
   112 
       
   113 /*
       
   114   This routine is only here in case a caller of an older version of the
       
   115   library is calling this for some reason.
       
   116   We will clean up any stray blocks when the session is closed.
       
   117   No need to remove this block.  In theory the user might be depending on the fact
       
   118   that we used to just 'free' this.  In theory they might also be
       
   119   passing a block that they got from libdwarf.  So we don't know if we
       
   120   should try to remove this block from our global list.  Safest just to
       
   121   do nothing at this point.
       
   122 
       
   123   !!!
       
   124   This function is deprecated!  Don't call it inside libdwarf or outside of it.
       
   125   !!!
       
   126 */
       
   127        
       
   128 void
       
   129 dwarf_p_dealloc(Dwarf_Small * ptr)
       
   130 {
       
   131     return;
       
   132 }
       
   133 
       
   134 /*
       
   135   The dbg structure is not needed here anymore.
       
   136 */
       
   137 
       
   138 void
       
   139 _dwarf_p_dealloc(Dwarf_P_Debug dbg, Dwarf_Small * ptr) /* ARGSUSED */
       
   140 {
       
   141   memory_list_t *lp;
       
   142   lp = BLOCK_TO_LIST(ptr);
       
   143 
       
   144   /*
       
   145     Remove from a doubly linked, circular list.
       
   146     Read carefully, use a white board if necessary.
       
   147     If this is an empty list, the following statements are no-ops, and
       
   148     will write to the same memory location they read from.
       
   149     This should only happen when we deallocate the dbg structure itself.
       
   150   */
       
   151   
       
   152   lp->prev->next = lp->next;
       
   153   lp->next->prev = lp->prev;
       
   154 
       
   155   free((void*)lp);
       
   156 }
       
   157 
       
   158 
       
   159 /*
       
   160   This routine deallocates all the nodes on the dbg list,
       
   161   and then deallocates the dbg structure itself.
       
   162 */
       
   163 
       
   164 void
       
   165 _dwarf_p_dealloc_all(Dwarf_P_Debug dbg)
       
   166 {
       
   167     memory_list_t *dbglp;
       
   168 
       
   169     if (dbg == NULL) {
       
   170 	/* should throw an error */
       
   171 	return;
       
   172     }
       
   173     
       
   174     dbglp = BLOCK_TO_LIST(dbg);
       
   175     while (dbglp->next != dbglp) {
       
   176         _dwarf_p_dealloc(dbg, LIST_TO_BLOCK(dbglp->next));
       
   177     }
       
   178     if (dbglp->next != dbglp ||
       
   179 	dbglp->prev != dbglp) {
       
   180 
       
   181 	/* should throw error */
       
   182 	/* For some reason we couldn't free all the blocks? */
       
   183 	return;
       
   184     }
       
   185     _dwarf_p_dealloc(NULL, (void*)dbg);
       
   186 }
       
   187