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