xref: /titanic_44/usr/src/tools/ctf/dwarf/common/pro_alloc.c (revision 07dc1947c362e187fb955d283b692f8769dd5def)
149d3bc91SRichard Lowe /*
249d3bc91SRichard Lowe 
349d3bc91SRichard Lowe   Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
4*07dc1947SRichard Lowe   Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
549d3bc91SRichard Lowe 
649d3bc91SRichard Lowe   This program is free software; you can redistribute it and/or modify it
749d3bc91SRichard Lowe   under the terms of version 2.1 of the GNU Lesser General Public License
849d3bc91SRichard Lowe   as published by the Free Software Foundation.
949d3bc91SRichard Lowe 
1049d3bc91SRichard Lowe   This program is distributed in the hope that it would be useful, but
1149d3bc91SRichard Lowe   WITHOUT ANY WARRANTY; without even the implied warranty of
1249d3bc91SRichard Lowe   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1349d3bc91SRichard Lowe 
1449d3bc91SRichard Lowe   Further, this software is distributed without any warranty that it is
1549d3bc91SRichard Lowe   free of the rightful claim of any third person regarding infringement
1649d3bc91SRichard Lowe   or the like.  Any license provided herein, whether implied or
1749d3bc91SRichard Lowe   otherwise, applies only to this software file.  Patent licenses, if
1849d3bc91SRichard Lowe   any, provided herein do not apply to combinations of this program with
1949d3bc91SRichard Lowe   other software, or any other product whatsoever.
2049d3bc91SRichard Lowe 
2149d3bc91SRichard Lowe   You should have received a copy of the GNU Lesser General Public
2249d3bc91SRichard Lowe   License along with this program; if not, write the Free Software
23*07dc1947SRichard Lowe   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
2449d3bc91SRichard Lowe   USA.
2549d3bc91SRichard Lowe 
26*07dc1947SRichard Lowe   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
2749d3bc91SRichard Lowe   Mountain View, CA 94043, or:
2849d3bc91SRichard Lowe 
2949d3bc91SRichard Lowe   http://www.sgi.com
3049d3bc91SRichard Lowe 
3149d3bc91SRichard Lowe   For further information regarding this notice, see:
3249d3bc91SRichard Lowe 
3349d3bc91SRichard Lowe   http://oss.sgi.com/projects/GenInfo/NoticeExplan
3449d3bc91SRichard Lowe 
3549d3bc91SRichard Lowe */
3649d3bc91SRichard Lowe 
3749d3bc91SRichard Lowe 
3849d3bc91SRichard Lowe 
3949d3bc91SRichard Lowe #include "config.h"
40*07dc1947SRichard Lowe #include "pro_incl.h"
41*07dc1947SRichard Lowe #ifdef HAVE_STDLIB_H
4249d3bc91SRichard Lowe #include <stdlib.h>
43*07dc1947SRichard Lowe #endif /* HAVE_STDLIB_H */
44*07dc1947SRichard Lowe #ifdef HAVE_STRING_H
45*07dc1947SRichard Lowe #include <string.h>
46*07dc1947SRichard Lowe #endif /* HAVE_STRING_H */
47*07dc1947SRichard Lowe #include <malloc.h>
4849d3bc91SRichard Lowe 
4949d3bc91SRichard Lowe /*
50*07dc1947SRichard Lowe  When each block is allocated, there is a two-word structure
51*07dc1947SRichard Lowe  allocated at the beginning so the block can go on a list.
52*07dc1947SRichard Lowe  The address returned is the address *after* the two pointers
53*07dc1947SRichard Lowe  at the start.  But this allows us to be given a pointer to
54*07dc1947SRichard Lowe  a generic block, and go backwards to find the list-node.  Then
55*07dc1947SRichard Lowe  we can remove this block from it's list without the need to search
56*07dc1947SRichard Lowe  through a linked list in order to remove the node.  It also allows
57*07dc1947SRichard Lowe  us to 'delete' a memory block without needing the dbg structure.
58*07dc1947SRichard Lowe  We still need the dbg structure on allocation so that we know which
59*07dc1947SRichard Lowe  linked list to add the block to.
60*07dc1947SRichard Lowe 
61*07dc1947SRichard Lowe  Only the allocation of the dbg structure itself cannot use _dwarf_p_get_alloc.
62*07dc1947SRichard Lowe  That structure should be set up by hand, and the two list pointers
63*07dc1947SRichard Lowe  should be initialized to point at the node itself.  That initializes
64*07dc1947SRichard Lowe  the doubly linked list.
6549d3bc91SRichard Lowe */
66*07dc1947SRichard Lowe 
67*07dc1947SRichard Lowe #define LIST_TO_BLOCK(lst) ((void*) (((char *)lst) + sizeof(memory_list_t)))
68*07dc1947SRichard Lowe #define BLOCK_TO_LIST(blk) ((memory_list_t*) (((char*)blk) - sizeof(memory_list_t)))
69*07dc1947SRichard Lowe 
70*07dc1947SRichard Lowe 
71*07dc1947SRichard Lowe /*
72*07dc1947SRichard Lowe   dbg should be NULL only when allocating dbg itself.  In that
73*07dc1947SRichard Lowe   case we initialize it to an empty circular doubly-linked list.
74*07dc1947SRichard Lowe */
75*07dc1947SRichard Lowe 
76*07dc1947SRichard Lowe Dwarf_Ptr
_dwarf_p_get_alloc(Dwarf_P_Debug dbg,Dwarf_Unsigned size)77*07dc1947SRichard Lowe _dwarf_p_get_alloc(Dwarf_P_Debug dbg, Dwarf_Unsigned size)
7849d3bc91SRichard Lowe {
7949d3bc91SRichard Lowe     void *sp;
80*07dc1947SRichard Lowe     memory_list_t *lp = NULL;
81*07dc1947SRichard Lowe     memory_list_t *dbglp = NULL;
82*07dc1947SRichard Lowe     memory_list_t *nextblock = NULL;
8349d3bc91SRichard Lowe 
84*07dc1947SRichard Lowe     /* alloc control struct and data block together for performance reasons */
85*07dc1947SRichard Lowe     lp = (memory_list_t *) malloc(size + sizeof(memory_list_t));
86*07dc1947SRichard Lowe     if (lp == NULL) {
87*07dc1947SRichard Lowe         /* should throw an error */
88*07dc1947SRichard Lowe         return NULL;
89*07dc1947SRichard Lowe     }
90*07dc1947SRichard Lowe 
91*07dc1947SRichard Lowe     /* point to 'size' bytes just beyond lp struct */
92*07dc1947SRichard Lowe     sp = LIST_TO_BLOCK(lp);
93*07dc1947SRichard Lowe     memset(sp, 0, size);
94*07dc1947SRichard Lowe 
95*07dc1947SRichard Lowe     if (dbg == NULL) {
96*07dc1947SRichard Lowe         lp->next = lp->prev = lp;
97*07dc1947SRichard Lowe     } else {
98*07dc1947SRichard Lowe         /* I always have to draw a picture to understand this part. */
99*07dc1947SRichard Lowe 
100*07dc1947SRichard Lowe         dbglp = BLOCK_TO_LIST(dbg);
101*07dc1947SRichard Lowe         nextblock = dbglp->next;
102*07dc1947SRichard Lowe 
103*07dc1947SRichard Lowe         /* Insert between dbglp and nextblock */
104*07dc1947SRichard Lowe         dbglp->next = lp;
105*07dc1947SRichard Lowe         lp->prev = dbglp;
106*07dc1947SRichard Lowe         lp->next = nextblock;
107*07dc1947SRichard Lowe         nextblock->prev = lp;
108*07dc1947SRichard Lowe     }
109*07dc1947SRichard Lowe 
11049d3bc91SRichard Lowe     return sp;
11149d3bc91SRichard Lowe }
11249d3bc91SRichard Lowe 
113*07dc1947SRichard Lowe /*
114*07dc1947SRichard Lowe   This routine is only here in case a caller of an older version of the
115*07dc1947SRichard Lowe   library is calling this for some reason.
116*07dc1947SRichard Lowe   We will clean up any stray blocks when the session is closed.
117*07dc1947SRichard Lowe   No need to remove this block.  In theory the user might be
118*07dc1947SRichard Lowe   depending on the fact that we used to just 'free' this.
119*07dc1947SRichard Lowe   In theory they might also be
120*07dc1947SRichard Lowe   passing a block that they got from libdwarf.  So we don't know if we
121*07dc1947SRichard Lowe   should try to remove this block from our global list.  Safest just to
122*07dc1947SRichard Lowe   do nothing at this point.
12349d3bc91SRichard Lowe 
124*07dc1947SRichard Lowe   !!!
125*07dc1947SRichard Lowe   This function is deprecated!  Don't call it inside libdwarf or outside of it.
126*07dc1947SRichard Lowe   !!!
127*07dc1947SRichard Lowe */
128*07dc1947SRichard Lowe 
129*07dc1947SRichard Lowe void
dwarf_p_dealloc(Dwarf_Small * ptr)130*07dc1947SRichard Lowe dwarf_p_dealloc(Dwarf_Small * ptr)
13149d3bc91SRichard Lowe {
13249d3bc91SRichard Lowe     return;
13349d3bc91SRichard Lowe }
13449d3bc91SRichard Lowe 
135*07dc1947SRichard Lowe /*
136*07dc1947SRichard Lowe   The dbg structure is not needed here anymore.
137*07dc1947SRichard Lowe */
13849d3bc91SRichard Lowe 
139*07dc1947SRichard Lowe void
_dwarf_p_dealloc(Dwarf_P_Debug dbg,Dwarf_Small * ptr)140*07dc1947SRichard Lowe _dwarf_p_dealloc(Dwarf_P_Debug dbg, Dwarf_Small * ptr) /* ARGSUSED */
14149d3bc91SRichard Lowe {
142*07dc1947SRichard Lowe   memory_list_t *lp;
143*07dc1947SRichard Lowe   lp = BLOCK_TO_LIST(ptr);
144*07dc1947SRichard Lowe 
145*07dc1947SRichard Lowe   /*
146*07dc1947SRichard Lowe     Remove from a doubly linked, circular list.
147*07dc1947SRichard Lowe     Read carefully, use a white board if necessary.
148*07dc1947SRichard Lowe     If this is an empty list, the following statements are no-ops, and
149*07dc1947SRichard Lowe     will write to the same memory location they read from.
150*07dc1947SRichard Lowe     This should only happen when we deallocate the dbg structure itself.
151*07dc1947SRichard Lowe   */
152*07dc1947SRichard Lowe 
153*07dc1947SRichard Lowe   lp->prev->next = lp->next;
154*07dc1947SRichard Lowe   lp->next->prev = lp->prev;
155*07dc1947SRichard Lowe 
156*07dc1947SRichard Lowe   free((void*)lp);
15749d3bc91SRichard Lowe }
158*07dc1947SRichard Lowe 
159*07dc1947SRichard Lowe 
160*07dc1947SRichard Lowe /*
161*07dc1947SRichard Lowe   This routine deallocates all the nodes on the dbg list,
162*07dc1947SRichard Lowe   and then deallocates the dbg structure itself.
163*07dc1947SRichard Lowe */
164*07dc1947SRichard Lowe 
165*07dc1947SRichard Lowe void
_dwarf_p_dealloc_all(Dwarf_P_Debug dbg)166*07dc1947SRichard Lowe _dwarf_p_dealloc_all(Dwarf_P_Debug dbg)
167*07dc1947SRichard Lowe {
168*07dc1947SRichard Lowe     memory_list_t *dbglp;
169*07dc1947SRichard Lowe 
170*07dc1947SRichard Lowe     if (dbg == NULL) {
171*07dc1947SRichard Lowe         /* should throw an error */
172*07dc1947SRichard Lowe         return;
173*07dc1947SRichard Lowe     }
174*07dc1947SRichard Lowe 
175*07dc1947SRichard Lowe     dbglp = BLOCK_TO_LIST(dbg);
176*07dc1947SRichard Lowe     while (dbglp->next != dbglp) {
177*07dc1947SRichard Lowe         _dwarf_p_dealloc(dbg, LIST_TO_BLOCK(dbglp->next));
178*07dc1947SRichard Lowe     }
179*07dc1947SRichard Lowe     if (dbglp->next != dbglp ||
180*07dc1947SRichard Lowe         dbglp->prev != dbglp) {
181*07dc1947SRichard Lowe 
182*07dc1947SRichard Lowe         /* should throw error */
183*07dc1947SRichard Lowe         /* For some reason we couldn't free all the blocks? */
184*07dc1947SRichard Lowe         return;
185*07dc1947SRichard Lowe     }
186*07dc1947SRichard Lowe     _dwarf_p_dealloc(NULL, (void*)dbg);
187*07dc1947SRichard Lowe }
188*07dc1947SRichard Lowe 
189