xref: /titanic_50/usr/src/lib/libdwarf/common/dwarf_alloc.c (revision f3e7f55e73a39377d55a030f124cc86b3b66a9cc)
1*f3e7f55eSRobert Mustacchi /*
2*f3e7f55eSRobert Mustacchi 
3*f3e7f55eSRobert Mustacchi   Copyright (C) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
4*f3e7f55eSRobert Mustacchi   Portions Copyright (C) 2007-2010  David Anderson. All Rights Reserved.
5*f3e7f55eSRobert Mustacchi 
6*f3e7f55eSRobert Mustacchi   This program is free software; you can redistribute it and/or modify it
7*f3e7f55eSRobert Mustacchi   under the terms of version 2.1 of the GNU Lesser General Public License
8*f3e7f55eSRobert Mustacchi   as published by the Free Software Foundation.
9*f3e7f55eSRobert Mustacchi 
10*f3e7f55eSRobert Mustacchi   This program is distributed in the hope that it would be useful, but
11*f3e7f55eSRobert Mustacchi   WITHOUT ANY WARRANTY; without even the implied warranty of
12*f3e7f55eSRobert Mustacchi   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13*f3e7f55eSRobert Mustacchi 
14*f3e7f55eSRobert Mustacchi   Further, this software is distributed without any warranty that it is
15*f3e7f55eSRobert Mustacchi   free of the rightful claim of any third person regarding infringement
16*f3e7f55eSRobert Mustacchi   or the like.  Any license provided herein, whether implied or
17*f3e7f55eSRobert Mustacchi   otherwise, applies only to this software file.  Patent licenses, if
18*f3e7f55eSRobert Mustacchi   any, provided herein do not apply to combinations of this program with
19*f3e7f55eSRobert Mustacchi   other software, or any other product whatsoever.
20*f3e7f55eSRobert Mustacchi 
21*f3e7f55eSRobert Mustacchi   You should have received a copy of the GNU Lesser General Public
22*f3e7f55eSRobert Mustacchi   License along with this program; if not, write the Free Software
23*f3e7f55eSRobert Mustacchi   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
24*f3e7f55eSRobert Mustacchi   USA.
25*f3e7f55eSRobert Mustacchi 
26*f3e7f55eSRobert Mustacchi   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
27*f3e7f55eSRobert Mustacchi   Mountain View, CA 94043, or:
28*f3e7f55eSRobert Mustacchi 
29*f3e7f55eSRobert Mustacchi   http://www.sgi.com
30*f3e7f55eSRobert Mustacchi 
31*f3e7f55eSRobert Mustacchi   For further information regarding this notice, see:
32*f3e7f55eSRobert Mustacchi 
33*f3e7f55eSRobert Mustacchi   http://oss.sgi.com/projects/GenInfo/NoticeExplan
34*f3e7f55eSRobert Mustacchi 
35*f3e7f55eSRobert Mustacchi */
36*f3e7f55eSRobert Mustacchi /* The address of the Free Software Foundation is
37*f3e7f55eSRobert Mustacchi    Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
38*f3e7f55eSRobert Mustacchi    Boston, MA 02110-1301, USA.
39*f3e7f55eSRobert Mustacchi    SGI has moved from the Crittenden Lane address.
40*f3e7f55eSRobert Mustacchi */
41*f3e7f55eSRobert Mustacchi 
42*f3e7f55eSRobert Mustacchi 
43*f3e7f55eSRobert Mustacchi #undef  DEBUG
44*f3e7f55eSRobert Mustacchi 
45*f3e7f55eSRobert Mustacchi #include "config.h"
46*f3e7f55eSRobert Mustacchi #include "dwarf_incl.h"
47*f3e7f55eSRobert Mustacchi #include <sys/types.h>
48*f3e7f55eSRobert Mustacchi 
49*f3e7f55eSRobert Mustacchi #include <stdlib.h>
50*f3e7f55eSRobert Mustacchi #include <stdio.h>
51*f3e7f55eSRobert Mustacchi #include "malloc_check.h"
52*f3e7f55eSRobert Mustacchi 
53*f3e7f55eSRobert Mustacchi /*
54*f3e7f55eSRobert Mustacchi     These files are included to get the sizes
55*f3e7f55eSRobert Mustacchi     of structs to set the ah_bytes_one_struct field
56*f3e7f55eSRobert Mustacchi     of the Dwarf_Alloc_Hdr_s structs for each
57*f3e7f55eSRobert Mustacchi     allocation type.
58*f3e7f55eSRobert Mustacchi */
59*f3e7f55eSRobert Mustacchi #include "dwarf_line.h"
60*f3e7f55eSRobert Mustacchi #include "dwarf_global.h"
61*f3e7f55eSRobert Mustacchi #include "dwarf_arange.h"
62*f3e7f55eSRobert Mustacchi #include "dwarf_abbrev.h"
63*f3e7f55eSRobert Mustacchi #include "dwarf_die_deliv.h"
64*f3e7f55eSRobert Mustacchi #include "dwarf_frame.h"
65*f3e7f55eSRobert Mustacchi #include "dwarf_loc.h"
66*f3e7f55eSRobert Mustacchi #include "dwarf_funcs.h"
67*f3e7f55eSRobert Mustacchi #include "dwarf_types.h"
68*f3e7f55eSRobert Mustacchi #include "dwarf_vars.h"
69*f3e7f55eSRobert Mustacchi #include "dwarf_weaks.h"
70*f3e7f55eSRobert Mustacchi 
71*f3e7f55eSRobert Mustacchi 
72*f3e7f55eSRobert Mustacchi static void _dwarf_free_special_error(Dwarf_Ptr space);
73*f3e7f55eSRobert Mustacchi 
74*f3e7f55eSRobert Mustacchi #ifdef DWARF_SIMPLE_MALLOC
75*f3e7f55eSRobert Mustacchi static void _dwarf_simple_malloc_add_to_list(Dwarf_Debug dbg,
76*f3e7f55eSRobert Mustacchi     Dwarf_Ptr addr,
77*f3e7f55eSRobert Mustacchi     unsigned long size,
78*f3e7f55eSRobert Mustacchi     short alloc_type);
79*f3e7f55eSRobert Mustacchi static void _dwarf_simple_malloc_delete_from_list(Dwarf_Debug dbg,
80*f3e7f55eSRobert Mustacchi     Dwarf_Ptr space,
81*f3e7f55eSRobert Mustacchi     short alloc_type);
82*f3e7f55eSRobert Mustacchi void _dwarf_simple_malloc_botch(int err);
83*f3e7f55eSRobert Mustacchi 
84*f3e7f55eSRobert Mustacchi #endif /* DWARF_SIMPLE_MALLOC */
85*f3e7f55eSRobert Mustacchi 
86*f3e7f55eSRobert Mustacchi 
87*f3e7f55eSRobert Mustacchi 
88*f3e7f55eSRobert Mustacchi 
89*f3e7f55eSRobert Mustacchi /*
90*f3e7f55eSRobert Mustacchi     This macro adds the size of a pointer to the size of a
91*f3e7f55eSRobert Mustacchi     struct that is given to it.  It rounds up the size to
92*f3e7f55eSRobert Mustacchi     be a multiple of the size of a pointer.  This is done
93*f3e7f55eSRobert Mustacchi     so that every struct returned by _dwarf_get_alloc()
94*f3e7f55eSRobert Mustacchi     can be preceded by a pointer to the chunk it came from.
95*f3e7f55eSRobert Mustacchi     Before allocating, it checks if the size of struct is less than
96*f3e7f55eSRobert Mustacchi     the size of a pointer.  If yes, it returns the size
97*f3e7f55eSRobert Mustacchi     of 2 pointers.  The returned size should be at least
98*f3e7f55eSRobert Mustacchi     the size of 2 pointers, since the first points to the
99*f3e7f55eSRobert Mustacchi     chunk the struct was allocated from, and the second
100*f3e7f55eSRobert Mustacchi     is used to link the free list.
101*f3e7f55eSRobert Mustacchi 
102*f3e7f55eSRobert Mustacchi     We want DW_RESERVE to be at least the size of
103*f3e7f55eSRobert Mustacchi     a long long and at least the size of a pointer because
104*f3e7f55eSRobert Mustacchi     our struct has a long long and we want that aligned right.
105*f3e7f55eSRobert Mustacchi     Now Standard C defines long long as 8 bytes, so lets
106*f3e7f55eSRobert Mustacchi     make that standard. It will become unworkable when
107*f3e7f55eSRobert Mustacchi     long long or pointer grows beyound 8 bytes.
108*f3e7f55eSRobert Mustacchi     Unclear what to do with wierd requirements, like
109*f3e7f55eSRobert Mustacchi     36 bit pointers.
110*f3e7f55eSRobert Mustacchi 
111*f3e7f55eSRobert Mustacchi 
112*f3e7f55eSRobert Mustacchi */
113*f3e7f55eSRobert Mustacchi #define DW_RESERVE 8
114*f3e7f55eSRobert Mustacchi 
115*f3e7f55eSRobert Mustacchi /* Round size up to the next multiple of DW_RESERVE bytes
116*f3e7f55eSRobert Mustacchi */
117*f3e7f55eSRobert Mustacchi #define ROUND_SIZE(inputsize)                 \
118*f3e7f55eSRobert Mustacchi         (((inputsize) % (DW_RESERVE)) == 0 ? \
119*f3e7f55eSRobert Mustacchi             (inputsize):                      \
120*f3e7f55eSRobert Mustacchi             ((inputsize)  +                   \
121*f3e7f55eSRobert Mustacchi                (DW_RESERVE) - ((inputsize) % (DW_RESERVE)) ))
122*f3e7f55eSRobert Mustacchi 
123*f3e7f55eSRobert Mustacchi #define ROUND_SIZE_WITH_POINTER(i_size) (ROUND_SIZE(i_size) + DW_RESERVE)
124*f3e7f55eSRobert Mustacchi 
125*f3e7f55eSRobert Mustacchi /* SMALL_ALLOC is for trivia where allocation is a waste.
126*f3e7f55eSRobert Mustacchi    Things that should be removed, really. */
127*f3e7f55eSRobert Mustacchi #define SMALL_ALLOC 2
128*f3e7f55eSRobert Mustacchi 
129*f3e7f55eSRobert Mustacchi /* BASE_ALLOC is where a basic allocation makes sense, but 'not too large'.
130*f3e7f55eSRobert Mustacchi    No thorough evaluation of this value has been done, though
131*f3e7f55eSRobert Mustacchi    it was found wasteful of memory to have BASE_ALLOC be as large as
132*f3e7f55eSRobert Mustacchi    BIG_ALLOC. */
133*f3e7f55eSRobert Mustacchi #define BASE_ALLOC 64
134*f3e7f55eSRobert Mustacchi 
135*f3e7f55eSRobert Mustacchi /* BIG_ALLOC is where a larger-than-BASE_ALLOC
136*f3e7f55eSRobert Mustacchi    allocation makes sense, but still 'not too large'.
137*f3e7f55eSRobert Mustacchi    No thorough evaluation of this value has been done. */
138*f3e7f55eSRobert Mustacchi #define BIG_ALLOC  128
139*f3e7f55eSRobert Mustacchi 
140*f3e7f55eSRobert Mustacchi /* This translates into de_alloc_hdr index
141*f3e7f55eSRobert Mustacchi ** the 0,1,1 entries are special: they don't use the
142*f3e7f55eSRobert Mustacchi ** table values at all.
143*f3e7f55eSRobert Mustacchi ** Rearranging the DW_DLA values would break binary compatibility
144*f3e7f55eSRobert Mustacchi ** so that is not an option.
145*f3e7f55eSRobert Mustacchi */
146*f3e7f55eSRobert Mustacchi struct ial_s {
147*f3e7f55eSRobert Mustacchi     int ia_al_num;              /* Index into de_alloc_hdr table. */
148*f3e7f55eSRobert Mustacchi 
149*f3e7f55eSRobert Mustacchi     /* In bytes, one struct instance. This does not account for extra
150*f3e7f55eSRobert Mustacchi        space needed per block, but that (DW_RESERVE) will be added in
151*f3e7f55eSRobert Mustacchi        later where it is needed (DW_RESERVE space never added in here).
152*f3e7f55eSRobert Mustacchi      */
153*f3e7f55eSRobert Mustacchi     int ia_struct_size;
154*f3e7f55eSRobert Mustacchi 
155*f3e7f55eSRobert Mustacchi 
156*f3e7f55eSRobert Mustacchi     /* Number of instances per alloc block. MUST be > 0. */
157*f3e7f55eSRobert Mustacchi     int ia_base_count;
158*f3e7f55eSRobert Mustacchi 
159*f3e7f55eSRobert Mustacchi     int (*specialconstructor) (Dwarf_Debug, void *);
160*f3e7f55eSRobert Mustacchi     void (*specialdestructor) (void *);
161*f3e7f55eSRobert Mustacchi };
162*f3e7f55eSRobert Mustacchi 
163*f3e7f55eSRobert Mustacchi static const
164*f3e7f55eSRobert Mustacchi struct ial_s index_into_allocated[ALLOC_AREA_INDEX_TABLE_MAX] = {
165*f3e7f55eSRobert Mustacchi     {0, 1, 1, 0, 0},            /* none */
166*f3e7f55eSRobert Mustacchi     {0, 1, 1, 0, 0},            /* 1 DW_DLA_STRING */
167*f3e7f55eSRobert Mustacchi     {1, sizeof(Dwarf_Loc), BASE_ALLOC, 0, 0}
168*f3e7f55eSRobert Mustacchi     ,                           /* 2 DW_DLA_LOC */
169*f3e7f55eSRobert Mustacchi     {2, sizeof(Dwarf_Locdesc), BASE_ALLOC, 0, 0}
170*f3e7f55eSRobert Mustacchi     ,                           /* 3 DW_DLA_LOCDESC */
171*f3e7f55eSRobert Mustacchi     {0, 1, 1, 0, 0}
172*f3e7f55eSRobert Mustacchi     ,                           /* not used *//* 4 DW_DLA_ELLIST */
173*f3e7f55eSRobert Mustacchi     {0, 1, 1, 0, 0}
174*f3e7f55eSRobert Mustacchi     ,                           /* not used *//* 5 DW_DLA_BOUNDS */
175*f3e7f55eSRobert Mustacchi     {3, sizeof(Dwarf_Block), BASE_ALLOC, 0, 0}
176*f3e7f55eSRobert Mustacchi     ,                           /* 6 DW_DLA_BLOCK */
177*f3e7f55eSRobert Mustacchi     {0, 1, 1, 0, 0}
178*f3e7f55eSRobert Mustacchi     ,                           /* the actual dwarf_debug structure *//* 7 DW_DLA_DEBUG */
179*f3e7f55eSRobert Mustacchi     {4, sizeof(struct Dwarf_Die_s), BIG_ALLOC, 0, 0},   /* 8 DW_DLA_DIE
180*f3e7f55eSRobert Mustacchi                                                          */
181*f3e7f55eSRobert Mustacchi     {5, sizeof(struct Dwarf_Line_s), BIG_ALLOC, 0, 0},  /* 9
182*f3e7f55eSRobert Mustacchi                                                            DW_DLA_LINE */
183*f3e7f55eSRobert Mustacchi     {6, sizeof(struct Dwarf_Attribute_s), BIG_ALLOC * 2, 0, 0},
184*f3e7f55eSRobert Mustacchi     /* 10 DW_DLA_ATTR */
185*f3e7f55eSRobert Mustacchi     {0, 1, 1, 0, 0},            /* not used *//* 11 DW_DLA_TYPE */
186*f3e7f55eSRobert Mustacchi     {0, 1, 1, 0, 0},            /* not used *//* 12 DW_DLA_SUBSCR */
187*f3e7f55eSRobert Mustacchi     {7, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0},       /* 13
188*f3e7f55eSRobert Mustacchi                                                                    DW_DLA_GLOBAL
189*f3e7f55eSRobert Mustacchi                                                                  */
190*f3e7f55eSRobert Mustacchi     {8, sizeof(struct Dwarf_Error_s), BASE_ALLOC, 0, 0},        /* 14
191*f3e7f55eSRobert Mustacchi                                                                    DW_DLA_ERROR
192*f3e7f55eSRobert Mustacchi                                                                  */
193*f3e7f55eSRobert Mustacchi     {0, 1, 1, 0, 0},            /* 15 DW_DLA_LIST */
194*f3e7f55eSRobert Mustacchi     {0, 1, 1, 0, 0},            /* not used *//* 16 DW_DLA_LINEBUF */
195*f3e7f55eSRobert Mustacchi     {9, sizeof(struct Dwarf_Arange_s), BASE_ALLOC, 0, 0},       /* 17
196*f3e7f55eSRobert Mustacchi                                                                    DW_DLA_ARANGE
197*f3e7f55eSRobert Mustacchi                                                                  */
198*f3e7f55eSRobert Mustacchi     {10, sizeof(struct Dwarf_Abbrev_s), BIG_ALLOC, 0, 0},       /* 18
199*f3e7f55eSRobert Mustacchi                                                                    DW_DLA_ABBREV
200*f3e7f55eSRobert Mustacchi                                                                  */
201*f3e7f55eSRobert Mustacchi     {11, sizeof(Dwarf_Frame_Op), BIG_ALLOC, 0, 0}
202*f3e7f55eSRobert Mustacchi     ,                           /* 19 DW_DLA_FRAME_OP */
203*f3e7f55eSRobert Mustacchi     {12, sizeof(struct Dwarf_Cie_s), BASE_ALLOC, 0, 0}, /* 20
204*f3e7f55eSRobert Mustacchi                                                            DW_DLA_CIE */
205*f3e7f55eSRobert Mustacchi     {13, sizeof(struct Dwarf_Fde_s), BASE_ALLOC, 0, 0}, /* 21 DW_DLA_FDE */
206*f3e7f55eSRobert Mustacchi     {0, 1, 1, 0, 0},            /* 22 DW_DLA_LOC_BLOCK */
207*f3e7f55eSRobert Mustacchi     {0, 1, 1, 0, 0},            /* 23 DW_DLA_FRAME_BLOCK */
208*f3e7f55eSRobert Mustacchi     {14, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0}, /* 24 DW_DLA_FUNC
209*f3e7f55eSRobert Mustacchi                                                               UNUSED */
210*f3e7f55eSRobert Mustacchi     {15, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0}, /* 25
211*f3e7f55eSRobert Mustacchi                                                               DW_DLA_TYPENAME
212*f3e7f55eSRobert Mustacchi                                                               UNUSED */
213*f3e7f55eSRobert Mustacchi     {16, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0}, /* 26 DW_DLA_VAR
214*f3e7f55eSRobert Mustacchi                                                               UNUSED */
215*f3e7f55eSRobert Mustacchi     {17, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0}, /* 27 DW_DLA_WEAK
216*f3e7f55eSRobert Mustacchi                                                               UNUSED */
217*f3e7f55eSRobert Mustacchi     {0, 1, 1, 0, 0},            /* 28 DW_DLA_ADDR */
218*f3e7f55eSRobert Mustacchi     {0, 1,1,0,0 },              /* 29 DW_DLA_RANGES */
219*f3e7f55eSRobert Mustacchi 
220*f3e7f55eSRobert Mustacchi     /* The following DW_DLA data types
221*f3e7f55eSRobert Mustacchi        are known only inside libdwarf.  */
222*f3e7f55eSRobert Mustacchi 
223*f3e7f55eSRobert Mustacchi     {18, sizeof(struct Dwarf_Abbrev_List_s), BIG_ALLOC, 0, 0},
224*f3e7f55eSRobert Mustacchi     /* 30 DW_DLA_ABBREV_LIST */
225*f3e7f55eSRobert Mustacchi 
226*f3e7f55eSRobert Mustacchi     {19, sizeof(struct Dwarf_Chain_s), BIG_ALLOC, 0, 0}, /* 31 DW_DLA_CHAIN */
227*f3e7f55eSRobert Mustacchi     {20, sizeof(struct Dwarf_CU_Context_s), BASE_ALLOC, 0, 0},
228*f3e7f55eSRobert Mustacchi     /* 32 DW_DLA_CU_CONTEXT */
229*f3e7f55eSRobert Mustacchi     {21, sizeof(struct Dwarf_Frame_s), BASE_ALLOC,
230*f3e7f55eSRobert Mustacchi      _dwarf_frame_constructor,
231*f3e7f55eSRobert Mustacchi      _dwarf_frame_destructor},  /* 33 DW_DLA_FRAME */
232*f3e7f55eSRobert Mustacchi     {22, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
233*f3e7f55eSRobert Mustacchi     /* 34 DW_DLA_GLOBAL_CONTEXT */
234*f3e7f55eSRobert Mustacchi     {23, sizeof(struct Dwarf_File_Entry_s), BASE_ALLOC, 0, 0},  /* 34 */
235*f3e7f55eSRobert Mustacchi     /* 35 DW_DLA_FILE_ENTRY */
236*f3e7f55eSRobert Mustacchi     {24, sizeof(struct Dwarf_Line_Context_s), BASE_ALLOC, 0, 0},
237*f3e7f55eSRobert Mustacchi     /* 36 DW_DLA_LINE_CONTEXT */
238*f3e7f55eSRobert Mustacchi     {25, sizeof(struct Dwarf_Loc_Chain_s), BASE_ALLOC, 0, 0},   /* 36 */
239*f3e7f55eSRobert Mustacchi     /* 37 DW_DLA_LOC_CHAIN */
240*f3e7f55eSRobert Mustacchi 
241*f3e7f55eSRobert Mustacchi     {26, sizeof(struct Dwarf_Hash_Table_s),BASE_ALLOC, 0, 0},   /* 37 */
242*f3e7f55eSRobert Mustacchi     /* 38 DW_DLA_HASH_TABLE */
243*f3e7f55eSRobert Mustacchi 
244*f3e7f55eSRobert Mustacchi /* The following really use Global struct: used to be unique struct
245*f3e7f55eSRobert Mustacchi    per type, but now merged (11/99).  The opaque types
246*f3e7f55eSRobert Mustacchi    are visible in the interface. The types  for
247*f3e7f55eSRobert Mustacchi    DW_DLA_FUNC,
248*f3e7f55eSRobert Mustacchi    DW_DLA_TYPENAME, DW_DLA_VAR, DW_DLA_WEAK also use
249*f3e7f55eSRobert Mustacchi    the global types.
250*f3e7f55eSRobert Mustacchi 
251*f3e7f55eSRobert Mustacchi */
252*f3e7f55eSRobert Mustacchi     {27, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
253*f3e7f55eSRobert Mustacchi     /* 39 DW_DLA_FUNC_CONTEXT */
254*f3e7f55eSRobert Mustacchi     {28, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
255*f3e7f55eSRobert Mustacchi     /* 40 DW_DLA_TYPENAME_CONTEXT */
256*f3e7f55eSRobert Mustacchi     {29, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
257*f3e7f55eSRobert Mustacchi     /* 41 DW_DLA_VAR_CONTEXT */
258*f3e7f55eSRobert Mustacchi     {30, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
259*f3e7f55eSRobert Mustacchi     /* 42 DW_DLA_WEAK_CONTEXT */
260*f3e7f55eSRobert Mustacchi     {31, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
261*f3e7f55eSRobert Mustacchi     /* 43 DW_DLA_PUBTYPES_CONTEXT DWARF3 */
262*f3e7f55eSRobert Mustacchi 
263*f3e7f55eSRobert Mustacchi     {0,1,1,0,0 },
264*f3e7f55eSRobert Mustacchi     /* 44 DW_DLA_HASH_TABLE_ENTRY */
265*f3e7f55eSRobert Mustacchi 
266*f3e7f55eSRobert Mustacchi 
267*f3e7f55eSRobert Mustacchi };
268*f3e7f55eSRobert Mustacchi 
269*f3e7f55eSRobert Mustacchi #ifndef DWARF_SIMPLE_MALLOC
270*f3e7f55eSRobert Mustacchi 
271*f3e7f55eSRobert Mustacchi /*
272*f3e7f55eSRobert Mustacchi     This function is given a pointer to the header
273*f3e7f55eSRobert Mustacchi     structure that is used to allocate 1 struct of
274*f3e7f55eSRobert Mustacchi     the type given by alloc_type.  It first checks
275*f3e7f55eSRobert Mustacchi     if a struct is available in its free list.  If
276*f3e7f55eSRobert Mustacchi     not, it checks if 1 is available in its blob,
277*f3e7f55eSRobert Mustacchi     which is a chunk of memory that is reserved for
278*f3e7f55eSRobert Mustacchi     its use.  If not, it malloc's a chunk.  The
279*f3e7f55eSRobert Mustacchi     initial part of it is used to store the end
280*f3e7f55eSRobert Mustacchi     address of the chunk, and also to keep track
281*f3e7f55eSRobert Mustacchi     of the number of free structs in that chunk.
282*f3e7f55eSRobert Mustacchi     This information is used for freeing the chunk
283*f3e7f55eSRobert Mustacchi     when all the structs in it are free.
284*f3e7f55eSRobert Mustacchi 
285*f3e7f55eSRobert Mustacchi     Assume all input arguments have been validated.
286*f3e7f55eSRobert Mustacchi 
287*f3e7f55eSRobert Mustacchi     This function can be used only to allocate 1
288*f3e7f55eSRobert Mustacchi     struct of the given type.
289*f3e7f55eSRobert Mustacchi 
290*f3e7f55eSRobert Mustacchi     It returns a pointer to the struct that the
291*f3e7f55eSRobert Mustacchi     user can use.  It returns NULL only when it
292*f3e7f55eSRobert Mustacchi     is out of free structs, and cannot malloc
293*f3e7f55eSRobert Mustacchi     any more.  The struct returned is zero-ed.
294*f3e7f55eSRobert Mustacchi 
295*f3e7f55eSRobert Mustacchi     A pointer to the chunk that the struct belongs
296*f3e7f55eSRobert Mustacchi     to is stored in the bytes preceding the
297*f3e7f55eSRobert Mustacchi     returned address.  Since this pointer it
298*f3e7f55eSRobert Mustacchi     never overwritten, when a struct is allocated
299*f3e7f55eSRobert Mustacchi     from the free_list this pointer does not
300*f3e7f55eSRobert Mustacchi     have to be written.  In the 2 other cases,
301*f3e7f55eSRobert Mustacchi     where the struct is allocated from a new
302*f3e7f55eSRobert Mustacchi     chunk, or the blob, a pointer to the chunk
303*f3e7f55eSRobert Mustacchi     is written.
304*f3e7f55eSRobert Mustacchi */
305*f3e7f55eSRobert Mustacchi static Dwarf_Ptr
_dwarf_find_memory(Dwarf_Alloc_Hdr alloc_hdr)306*f3e7f55eSRobert Mustacchi _dwarf_find_memory(Dwarf_Alloc_Hdr alloc_hdr)
307*f3e7f55eSRobert Mustacchi {
308*f3e7f55eSRobert Mustacchi     /* Pointer to the struct allocated. */
309*f3e7f55eSRobert Mustacchi     Dwarf_Small *ret_mem = 0;
310*f3e7f55eSRobert Mustacchi 
311*f3e7f55eSRobert Mustacchi     /* Pointer to info about chunks allocated. */
312*f3e7f55eSRobert Mustacchi     Dwarf_Alloc_Area alloc_area;
313*f3e7f55eSRobert Mustacchi 
314*f3e7f55eSRobert Mustacchi     /* Size of chunk malloc'ed when no free structs left. */
315*f3e7f55eSRobert Mustacchi     Dwarf_Signed mem_block_size;
316*f3e7f55eSRobert Mustacchi 
317*f3e7f55eSRobert Mustacchi     /* Pointer to block malloc'ed. */
318*f3e7f55eSRobert Mustacchi     Dwarf_Small *mem_block;
319*f3e7f55eSRobert Mustacchi 
320*f3e7f55eSRobert Mustacchi     /*
321*f3e7f55eSRobert Mustacchi        Check the alloc_area from which the last allocation was made
322*f3e7f55eSRobert Mustacchi        (most recent new block). If that is not successful, then search
323*f3e7f55eSRobert Mustacchi        the list of alloc_area's from alloc_header. */
324*f3e7f55eSRobert Mustacchi     alloc_area = alloc_hdr->ah_last_alloc_area;
325*f3e7f55eSRobert Mustacchi     if (alloc_area == NULL || alloc_area->aa_free_structs_in_chunk == 0)
326*f3e7f55eSRobert Mustacchi         for (alloc_area = alloc_hdr->ah_alloc_area_head;
327*f3e7f55eSRobert Mustacchi              alloc_area != NULL; alloc_area = alloc_area->aa_next) {
328*f3e7f55eSRobert Mustacchi 
329*f3e7f55eSRobert Mustacchi             if (alloc_area->aa_free_structs_in_chunk > 0) {
330*f3e7f55eSRobert Mustacchi                 break;          /* found a free entry! */
331*f3e7f55eSRobert Mustacchi             }
332*f3e7f55eSRobert Mustacchi 
333*f3e7f55eSRobert Mustacchi         }
334*f3e7f55eSRobert Mustacchi 
335*f3e7f55eSRobert Mustacchi     if (alloc_area != NULL) {
336*f3e7f55eSRobert Mustacchi         alloc_area->aa_free_structs_in_chunk--;
337*f3e7f55eSRobert Mustacchi 
338*f3e7f55eSRobert Mustacchi         if (alloc_area->aa_free_list != NULL) {
339*f3e7f55eSRobert Mustacchi             ret_mem = alloc_area->aa_free_list;
340*f3e7f55eSRobert Mustacchi 
341*f3e7f55eSRobert Mustacchi             /*
342*f3e7f55eSRobert Mustacchi                Update the free list.  The initial part of the struct is
343*f3e7f55eSRobert Mustacchi                used to hold a pointer to the next struct on the free
344*f3e7f55eSRobert Mustacchi                list.  In this way, the free list chain is maintained at
345*f3e7f55eSRobert Mustacchi                0 memory cost. */
346*f3e7f55eSRobert Mustacchi             alloc_area->aa_free_list =
347*f3e7f55eSRobert Mustacchi                 ((Dwarf_Free_List) ret_mem)->fl_next;
348*f3e7f55eSRobert Mustacchi         } else if (alloc_area->aa_blob_start < alloc_area->aa_blob_end) {
349*f3e7f55eSRobert Mustacchi             ret_mem = alloc_area->aa_blob_start;
350*f3e7f55eSRobert Mustacchi 
351*f3e7f55eSRobert Mustacchi             /*
352*f3e7f55eSRobert Mustacchi                Store pointer to chunk this struct belongs to in the
353*f3e7f55eSRobert Mustacchi                first few bytes.  Return pointer to bytes after this
354*f3e7f55eSRobert Mustacchi                pointer storage. */
355*f3e7f55eSRobert Mustacchi             *(Dwarf_Alloc_Area *) ret_mem = alloc_area;
356*f3e7f55eSRobert Mustacchi             ret_mem += DW_RESERVE;
357*f3e7f55eSRobert Mustacchi 
358*f3e7f55eSRobert Mustacchi             alloc_area->aa_blob_start += alloc_hdr->ah_bytes_one_struct;
359*f3e7f55eSRobert Mustacchi         } else {
360*f3e7f55eSRobert Mustacchi             /* else fall thru , though it should be impossible to fall
361*f3e7f55eSRobert Mustacchi                thru. And represents a disastrous programming error if
362*f3e7f55eSRobert Mustacchi                we get here. */
363*f3e7f55eSRobert Mustacchi #ifdef DEBUG
364*f3e7f55eSRobert Mustacchi             fprintf(stderr, "libdwarf Internal error start %x end %x\n",
365*f3e7f55eSRobert Mustacchi                     (int) alloc_area->aa_blob_start,
366*f3e7f55eSRobert Mustacchi                     (int) alloc_area->aa_blob_end);
367*f3e7f55eSRobert Mustacchi #endif
368*f3e7f55eSRobert Mustacchi         }
369*f3e7f55eSRobert Mustacchi     }
370*f3e7f55eSRobert Mustacchi 
371*f3e7f55eSRobert Mustacchi     /* New memory has to malloc'ed since there are no free structs. */
372*f3e7f55eSRobert Mustacchi     if (ret_mem == 0) {
373*f3e7f55eSRobert Mustacchi         Dwarf_Word rounded_area_hdr_size;
374*f3e7f55eSRobert Mustacchi 
375*f3e7f55eSRobert Mustacchi         alloc_hdr->ah_chunks_allocated++;
376*f3e7f55eSRobert Mustacchi 
377*f3e7f55eSRobert Mustacchi         {                       /* this nonsense avoids a warning */
378*f3e7f55eSRobert Mustacchi             /* CONSTCOND would be better */
379*f3e7f55eSRobert Mustacchi             unsigned long v = sizeof(struct Dwarf_Alloc_Area_s);
380*f3e7f55eSRobert Mustacchi 
381*f3e7f55eSRobert Mustacchi             rounded_area_hdr_size = ROUND_SIZE(v);
382*f3e7f55eSRobert Mustacchi         }
383*f3e7f55eSRobert Mustacchi 
384*f3e7f55eSRobert Mustacchi         /*
385*f3e7f55eSRobert Mustacchi            Allocate memory to contain the required number of structs
386*f3e7f55eSRobert Mustacchi            and the Dwarf_Alloc_Area_s to control it. */
387*f3e7f55eSRobert Mustacchi         mem_block_size = alloc_hdr->ah_bytes_malloc_per_chunk +
388*f3e7f55eSRobert Mustacchi             rounded_area_hdr_size;
389*f3e7f55eSRobert Mustacchi 
390*f3e7f55eSRobert Mustacchi         mem_block = malloc(mem_block_size);
391*f3e7f55eSRobert Mustacchi         if (mem_block == NULL) {
392*f3e7f55eSRobert Mustacchi             return (NULL);
393*f3e7f55eSRobert Mustacchi         }
394*f3e7f55eSRobert Mustacchi 
395*f3e7f55eSRobert Mustacchi 
396*f3e7f55eSRobert Mustacchi         /*
397*f3e7f55eSRobert Mustacchi            Attach the Dwarf_Alloc_Area_s struct to the list of chunks
398*f3e7f55eSRobert Mustacchi            malloc'ed for this struct type. Also initialize the fields
399*f3e7f55eSRobert Mustacchi            of the Dwarf_Alloc_Area_s. */
400*f3e7f55eSRobert Mustacchi         alloc_area = (Dwarf_Alloc_Area) mem_block;
401*f3e7f55eSRobert Mustacchi         alloc_area->aa_prev = 0;
402*f3e7f55eSRobert Mustacchi         if (alloc_hdr->ah_alloc_area_head != NULL) {
403*f3e7f55eSRobert Mustacchi             alloc_hdr->ah_alloc_area_head->aa_prev = alloc_area;
404*f3e7f55eSRobert Mustacchi         }
405*f3e7f55eSRobert Mustacchi         alloc_area->aa_free_list = 0;
406*f3e7f55eSRobert Mustacchi         alloc_area->aa_next = alloc_hdr->ah_alloc_area_head;
407*f3e7f55eSRobert Mustacchi         alloc_hdr->ah_alloc_area_head = alloc_area;
408*f3e7f55eSRobert Mustacchi 
409*f3e7f55eSRobert Mustacchi         alloc_area->aa_alloc_hdr = alloc_hdr;
410*f3e7f55eSRobert Mustacchi         alloc_area->aa_free_structs_in_chunk =
411*f3e7f55eSRobert Mustacchi             (Dwarf_Sword) alloc_hdr->ah_structs_per_chunk - 1;
412*f3e7f55eSRobert Mustacchi         if (alloc_area->aa_free_structs_in_chunk < 1) {
413*f3e7f55eSRobert Mustacchi             /* If we get here, there is a disastrous programming error
414*f3e7f55eSRobert Mustacchi                somewhere. */
415*f3e7f55eSRobert Mustacchi #ifdef DEBUG
416*f3e7f55eSRobert Mustacchi             fprintf(stderr,
417*f3e7f55eSRobert Mustacchi                     "libdwarf Internal error: free structs in chunk %d\n",
418*f3e7f55eSRobert Mustacchi                     (int) alloc_area->aa_free_structs_in_chunk);
419*f3e7f55eSRobert Mustacchi #endif
420*f3e7f55eSRobert Mustacchi             return NULL;
421*f3e7f55eSRobert Mustacchi         }
422*f3e7f55eSRobert Mustacchi 
423*f3e7f55eSRobert Mustacchi         /*
424*f3e7f55eSRobert Mustacchi            The struct returned begins immediately after the
425*f3e7f55eSRobert Mustacchi            Dwarf_Alloc_Area_s struct. */
426*f3e7f55eSRobert Mustacchi         ret_mem = mem_block + rounded_area_hdr_size;
427*f3e7f55eSRobert Mustacchi         alloc_area->aa_blob_start =
428*f3e7f55eSRobert Mustacchi             ret_mem + alloc_hdr->ah_bytes_one_struct;
429*f3e7f55eSRobert Mustacchi         alloc_area->aa_blob_end = mem_block + mem_block_size;
430*f3e7f55eSRobert Mustacchi 
431*f3e7f55eSRobert Mustacchi         /*
432*f3e7f55eSRobert Mustacchi            Store pointer to chunk this struct belongs to in the first
433*f3e7f55eSRobert Mustacchi            few bytes.  Return pointer to bytes after this pointer
434*f3e7f55eSRobert Mustacchi            storage. */
435*f3e7f55eSRobert Mustacchi         *(Dwarf_Alloc_Area *) ret_mem = alloc_area;
436*f3e7f55eSRobert Mustacchi         ret_mem += DW_RESERVE;
437*f3e7f55eSRobert Mustacchi     }
438*f3e7f55eSRobert Mustacchi 
439*f3e7f55eSRobert Mustacchi     alloc_hdr->ah_last_alloc_area = alloc_area;
440*f3e7f55eSRobert Mustacchi     alloc_hdr->ah_struct_user_holds++;
441*f3e7f55eSRobert Mustacchi     memset(ret_mem, 0, alloc_hdr->ah_bytes_one_struct - DW_RESERVE);
442*f3e7f55eSRobert Mustacchi     return (ret_mem);
443*f3e7f55eSRobert Mustacchi }
444*f3e7f55eSRobert Mustacchi 
445*f3e7f55eSRobert Mustacchi #endif /* ndef DWARF_SIMPLE_MALLOC */
446*f3e7f55eSRobert Mustacchi 
447*f3e7f55eSRobert Mustacchi /*
448*f3e7f55eSRobert Mustacchi     This function returns a pointer to a region
449*f3e7f55eSRobert Mustacchi     of memory.  For alloc_types that are not
450*f3e7f55eSRobert Mustacchi     strings or lists of pointers, only 1 struct
451*f3e7f55eSRobert Mustacchi     can be requested at a time.  This is indicated
452*f3e7f55eSRobert Mustacchi     by an input count of 1.  For strings, count
453*f3e7f55eSRobert Mustacchi     equals the length of the string it will
454*f3e7f55eSRobert Mustacchi     contain, i.e it the length of the string
455*f3e7f55eSRobert Mustacchi     plus 1 for the terminating null.  For lists
456*f3e7f55eSRobert Mustacchi     of pointers, count is equal to the number of
457*f3e7f55eSRobert Mustacchi     pointers.  For DW_DLA_FRAME_BLOCK, DW_DLA_RANGES, and
458*f3e7f55eSRobert Mustacchi     DW_DLA_LOC_BLOCK allocation types also, count
459*f3e7f55eSRobert Mustacchi     is the count of the number of structs needed.
460*f3e7f55eSRobert Mustacchi 
461*f3e7f55eSRobert Mustacchi     This function cannot be used to allocate a
462*f3e7f55eSRobert Mustacchi     Dwarf_Debug_s struct.
463*f3e7f55eSRobert Mustacchi 
464*f3e7f55eSRobert Mustacchi */
465*f3e7f55eSRobert Mustacchi Dwarf_Ptr
_dwarf_get_alloc(Dwarf_Debug dbg,Dwarf_Small alloc_type,Dwarf_Unsigned count)466*f3e7f55eSRobert Mustacchi _dwarf_get_alloc(Dwarf_Debug dbg,
467*f3e7f55eSRobert Mustacchi                  Dwarf_Small alloc_type, Dwarf_Unsigned count)
468*f3e7f55eSRobert Mustacchi {
469*f3e7f55eSRobert Mustacchi     Dwarf_Alloc_Hdr alloc_hdr;
470*f3e7f55eSRobert Mustacchi 
471*f3e7f55eSRobert Mustacchi     Dwarf_Ptr ret_mem;
472*f3e7f55eSRobert Mustacchi 
473*f3e7f55eSRobert Mustacchi     Dwarf_Signed size = 0;
474*f3e7f55eSRobert Mustacchi     unsigned int index;
475*f3e7f55eSRobert Mustacchi     unsigned int type = alloc_type;
476*f3e7f55eSRobert Mustacchi 
477*f3e7f55eSRobert Mustacchi     if (dbg == NULL) {
478*f3e7f55eSRobert Mustacchi         return (NULL);
479*f3e7f55eSRobert Mustacchi     }
480*f3e7f55eSRobert Mustacchi 
481*f3e7f55eSRobert Mustacchi     if (type >= ALLOC_AREA_INDEX_TABLE_MAX) {
482*f3e7f55eSRobert Mustacchi         /* internal error */
483*f3e7f55eSRobert Mustacchi         return NULL;
484*f3e7f55eSRobert Mustacchi     }
485*f3e7f55eSRobert Mustacchi     index = index_into_allocated[type].ia_al_num;
486*f3e7f55eSRobert Mustacchi     /* zero also illegal but not tested for */
487*f3e7f55eSRobert Mustacchi 
488*f3e7f55eSRobert Mustacchi     /* If the Dwarf_Debug is not fully set up, we will get index 0 for
489*f3e7f55eSRobert Mustacchi        any type and must do something.  'Not fully set up' can only
490*f3e7f55eSRobert Mustacchi        happen for DW_DLA_ERROR, I (davea) believe, and for that we call
491*f3e7f55eSRobert Mustacchi        special code here.. */
492*f3e7f55eSRobert Mustacchi 
493*f3e7f55eSRobert Mustacchi     if (index == 0) {
494*f3e7f55eSRobert Mustacchi         if (alloc_type == DW_DLA_STRING) {
495*f3e7f55eSRobert Mustacchi             size = count;
496*f3e7f55eSRobert Mustacchi         } else if (alloc_type == DW_DLA_LIST) {
497*f3e7f55eSRobert Mustacchi             size = count * sizeof(Dwarf_Ptr);
498*f3e7f55eSRobert Mustacchi         } else if (alloc_type == DW_DLA_FRAME_BLOCK) {
499*f3e7f55eSRobert Mustacchi             size = count * sizeof(Dwarf_Frame_Op);
500*f3e7f55eSRobert Mustacchi         } else if (alloc_type == DW_DLA_LOC_BLOCK) {
501*f3e7f55eSRobert Mustacchi             size = count * sizeof(Dwarf_Loc);
502*f3e7f55eSRobert Mustacchi         } else if (alloc_type == DW_DLA_HASH_TABLE_ENTRY) {
503*f3e7f55eSRobert Mustacchi             size = count * sizeof(struct Dwarf_Hash_Table_Entry_s);
504*f3e7f55eSRobert Mustacchi         } else if (alloc_type == DW_DLA_ADDR) {
505*f3e7f55eSRobert Mustacchi             size = count *
506*f3e7f55eSRobert Mustacchi                 (sizeof(Dwarf_Addr) > sizeof(Dwarf_Off) ?
507*f3e7f55eSRobert Mustacchi                  sizeof(Dwarf_Addr) : sizeof(Dwarf_Off));
508*f3e7f55eSRobert Mustacchi         } else if (alloc_type == DW_DLA_RANGES) {
509*f3e7f55eSRobert Mustacchi             size = count * sizeof(Dwarf_Ranges);
510*f3e7f55eSRobert Mustacchi         } else if (alloc_type == DW_DLA_ERROR) {
511*f3e7f55eSRobert Mustacchi             void *m = _dwarf_special_no_dbg_error_malloc();
512*f3e7f55eSRobert Mustacchi 
513*f3e7f55eSRobert Mustacchi             dwarf_malloc_check_alloc_data(m, DW_DLA_ERROR);
514*f3e7f55eSRobert Mustacchi             return m;
515*f3e7f55eSRobert Mustacchi 
516*f3e7f55eSRobert Mustacchi         } else {
517*f3e7f55eSRobert Mustacchi             /* If we get here, there is a disastrous programming error
518*f3e7f55eSRobert Mustacchi                somewhere. */
519*f3e7f55eSRobert Mustacchi #ifdef DEBUG
520*f3e7f55eSRobert Mustacchi             fprintf(stderr,
521*f3e7f55eSRobert Mustacchi                     "libdwarf Internal error: type %d  unexpected\n",
522*f3e7f55eSRobert Mustacchi                     (int) type);
523*f3e7f55eSRobert Mustacchi #endif
524*f3e7f55eSRobert Mustacchi         }
525*f3e7f55eSRobert Mustacchi     } else {
526*f3e7f55eSRobert Mustacchi         alloc_hdr = &dbg->de_alloc_hdr[index];
527*f3e7f55eSRobert Mustacchi         if (alloc_hdr->ah_bytes_one_struct > 0) {
528*f3e7f55eSRobert Mustacchi #ifdef DWARF_SIMPLE_MALLOC
529*f3e7f55eSRobert Mustacchi             size = alloc_hdr->ah_bytes_one_struct;
530*f3e7f55eSRobert Mustacchi #else
531*f3e7f55eSRobert Mustacchi             {
532*f3e7f55eSRobert Mustacchi                 void *m = _dwarf_find_memory(alloc_hdr);
533*f3e7f55eSRobert Mustacchi 
534*f3e7f55eSRobert Mustacchi                 dwarf_malloc_check_alloc_data(m, type);
535*f3e7f55eSRobert Mustacchi                 if (index_into_allocated[type].specialconstructor) {
536*f3e7f55eSRobert Mustacchi                     int res =
537*f3e7f55eSRobert Mustacchi                         index_into_allocated[type].
538*f3e7f55eSRobert Mustacchi                         specialconstructor(dbg, m);
539*f3e7f55eSRobert Mustacchi                     if (res != DW_DLV_OK) {
540*f3e7f55eSRobert Mustacchi                         /* We leak what we allocated in
541*f3e7f55eSRobert Mustacchi                            _dwarf_find_memory when constructor fails. */
542*f3e7f55eSRobert Mustacchi                         return NULL;
543*f3e7f55eSRobert Mustacchi                     }
544*f3e7f55eSRobert Mustacchi                 }
545*f3e7f55eSRobert Mustacchi                 return m;
546*f3e7f55eSRobert Mustacchi             }
547*f3e7f55eSRobert Mustacchi #endif
548*f3e7f55eSRobert Mustacchi 
549*f3e7f55eSRobert Mustacchi         } else {
550*f3e7f55eSRobert Mustacchi             /* Special case: should not really happen at all. */
551*f3e7f55eSRobert Mustacchi             if (type == DW_DLA_ERROR) {
552*f3e7f55eSRobert Mustacchi                 /* dwarf_init failure. Because dbg is incomplete we
553*f3e7f55eSRobert Mustacchi                    won't use it to record the malloc. */
554*f3e7f55eSRobert Mustacchi                 void *m = _dwarf_special_no_dbg_error_malloc();
555*f3e7f55eSRobert Mustacchi 
556*f3e7f55eSRobert Mustacchi                 dwarf_malloc_check_alloc_data(m, DW_DLA_ERROR);
557*f3e7f55eSRobert Mustacchi                 return m;
558*f3e7f55eSRobert Mustacchi             } else {
559*f3e7f55eSRobert Mustacchi                 /* If we get here, there is a disastrous programming
560*f3e7f55eSRobert Mustacchi                    error somewhere. */
561*f3e7f55eSRobert Mustacchi #ifdef DWARF_SIMPLE_MALLOC
562*f3e7f55eSRobert Mustacchi                 _dwarf_simple_malloc_botch(3);
563*f3e7f55eSRobert Mustacchi #endif
564*f3e7f55eSRobert Mustacchi #ifdef DEBUG
565*f3e7f55eSRobert Mustacchi                 fprintf(stderr,
566*f3e7f55eSRobert Mustacchi                         "libdwarf Internal error: Type %d  unexpected\n",
567*f3e7f55eSRobert Mustacchi                         (int) type);
568*f3e7f55eSRobert Mustacchi #endif
569*f3e7f55eSRobert Mustacchi             }
570*f3e7f55eSRobert Mustacchi         }
571*f3e7f55eSRobert Mustacchi     }
572*f3e7f55eSRobert Mustacchi 
573*f3e7f55eSRobert Mustacchi     ret_mem = malloc(size);
574*f3e7f55eSRobert Mustacchi #ifdef DWARF_SIMPLE_MALLOC
575*f3e7f55eSRobert Mustacchi     _dwarf_simple_malloc_add_to_list(dbg, ret_mem, (unsigned long) size,
576*f3e7f55eSRobert Mustacchi                                      type);
577*f3e7f55eSRobert Mustacchi #endif
578*f3e7f55eSRobert Mustacchi     if (ret_mem != NULL)
579*f3e7f55eSRobert Mustacchi         memset(ret_mem, 0, size);
580*f3e7f55eSRobert Mustacchi 
581*f3e7f55eSRobert Mustacchi     dwarf_malloc_check_alloc_data(ret_mem, type);
582*f3e7f55eSRobert Mustacchi     if (index_into_allocated[type].specialconstructor) {
583*f3e7f55eSRobert Mustacchi         int res =
584*f3e7f55eSRobert Mustacchi             index_into_allocated[type].specialconstructor(dbg, ret_mem);
585*f3e7f55eSRobert Mustacchi         if (res != DW_DLV_OK) {
586*f3e7f55eSRobert Mustacchi             /* We leak what we allocated in _dwarf_find_memory when
587*f3e7f55eSRobert Mustacchi                constructor fails. */
588*f3e7f55eSRobert Mustacchi             return NULL;
589*f3e7f55eSRobert Mustacchi         }
590*f3e7f55eSRobert Mustacchi     }
591*f3e7f55eSRobert Mustacchi 
592*f3e7f55eSRobert Mustacchi     return (ret_mem);
593*f3e7f55eSRobert Mustacchi }
594*f3e7f55eSRobert Mustacchi 
595*f3e7f55eSRobert Mustacchi 
596*f3e7f55eSRobert Mustacchi 
597*f3e7f55eSRobert Mustacchi /*
598*f3e7f55eSRobert Mustacchi     This function is used to deallocate a region of memory
599*f3e7f55eSRobert Mustacchi     that was obtained by a call to _dwarf_get_alloc.  Note
600*f3e7f55eSRobert Mustacchi     that though dwarf_dealloc() is a public function,
601*f3e7f55eSRobert Mustacchi     _dwarf_get_alloc() isn't.
602*f3e7f55eSRobert Mustacchi 
603*f3e7f55eSRobert Mustacchi     For lists, typically arrays of pointers, it is assumed
604*f3e7f55eSRobert Mustacchi     that the space was allocated by a direct call to malloc,
605*f3e7f55eSRobert Mustacchi     and so a straight free() is done.  This is also the case
606*f3e7f55eSRobert Mustacchi     for variable length blocks such as DW_DLA_FRAME_BLOCK
607*f3e7f55eSRobert Mustacchi     and DW_DLA_LOC_BLOCK and DW_DLA_RANGES.
608*f3e7f55eSRobert Mustacchi 
609*f3e7f55eSRobert Mustacchi     For strings, the pointer might point to a string in
610*f3e7f55eSRobert Mustacchi     .debug_info or .debug_string.  After this is checked,
611*f3e7f55eSRobert Mustacchi     and if found not to be the case, a free() is done,
612*f3e7f55eSRobert Mustacchi     again on the assumption that a malloc was used to
613*f3e7f55eSRobert Mustacchi     obtain the space.
614*f3e7f55eSRobert Mustacchi 
615*f3e7f55eSRobert Mustacchi     For other types of structs, a pointer to the chunk that
616*f3e7f55eSRobert Mustacchi     the struct was allocated out of, is present in the bytes
617*f3e7f55eSRobert Mustacchi     preceding the pointer passed in.  For this chunk it is
618*f3e7f55eSRobert Mustacchi     checked whether all the structs in that chunk are now free.
619*f3e7f55eSRobert Mustacchi     If so, the entire chunk is free_ed.  Otherwise, the space
620*f3e7f55eSRobert Mustacchi     is added to the free list for that chunk, and the free count
621*f3e7f55eSRobert Mustacchi     incremented.
622*f3e7f55eSRobert Mustacchi 
623*f3e7f55eSRobert Mustacchi     This function does not return anything.
624*f3e7f55eSRobert Mustacchi */
625*f3e7f55eSRobert Mustacchi void
dwarf_dealloc(Dwarf_Debug dbg,Dwarf_Ptr space,Dwarf_Unsigned alloc_type)626*f3e7f55eSRobert Mustacchi dwarf_dealloc(Dwarf_Debug dbg,
627*f3e7f55eSRobert Mustacchi               Dwarf_Ptr space, Dwarf_Unsigned alloc_type)
628*f3e7f55eSRobert Mustacchi {
629*f3e7f55eSRobert Mustacchi     Dwarf_Alloc_Hdr alloc_hdr;
630*f3e7f55eSRobert Mustacchi     Dwarf_Alloc_Area alloc_area;
631*f3e7f55eSRobert Mustacchi     unsigned int type = alloc_type;
632*f3e7f55eSRobert Mustacchi     unsigned int index;
633*f3e7f55eSRobert Mustacchi 
634*f3e7f55eSRobert Mustacchi     if (space == NULL) {
635*f3e7f55eSRobert Mustacchi         return;
636*f3e7f55eSRobert Mustacchi     }
637*f3e7f55eSRobert Mustacchi     if (type == DW_DLA_ERROR) {
638*f3e7f55eSRobert Mustacchi         /* Get pointer to Dwarf_Alloc_Area this struct came from. See
639*f3e7f55eSRobert Mustacchi            dwarf_alloc.h ROUND_SIZE_WITH_POINTER stuff */
640*f3e7f55eSRobert Mustacchi         alloc_area =
641*f3e7f55eSRobert Mustacchi             *(Dwarf_Alloc_Area *) ((char *) space - DW_RESERVE);
642*f3e7f55eSRobert Mustacchi         if (alloc_area == 0) {
643*f3e7f55eSRobert Mustacchi             /* This is the special case of a failed dwarf_init(). Also
644*f3e7f55eSRobert Mustacchi                (and more signficantly) there are a variety of other
645*f3e7f55eSRobert Mustacchi                situations where libdwarf does not *know* what dbg is
646*f3e7f55eSRobert Mustacchi                involved (because of a libdwarf-caller-error) so
647*f3e7f55eSRobert Mustacchi                libdwarf uses NULL as the dbg. Those too wind up here. */
648*f3e7f55eSRobert Mustacchi             _dwarf_free_special_error(space);
649*f3e7f55eSRobert Mustacchi             dwarf_malloc_check_dealloc_data(space, type);
650*f3e7f55eSRobert Mustacchi             return;
651*f3e7f55eSRobert Mustacchi         }
652*f3e7f55eSRobert Mustacchi 
653*f3e7f55eSRobert Mustacchi     }
654*f3e7f55eSRobert Mustacchi     if (dbg == NULL) {
655*f3e7f55eSRobert Mustacchi         /* App error, or an app that failed to succeed in a
656*f3e7f55eSRobert Mustacchi            dwarf_init() call. */
657*f3e7f55eSRobert Mustacchi         return;
658*f3e7f55eSRobert Mustacchi     }
659*f3e7f55eSRobert Mustacchi     if (type >= ALLOC_AREA_INDEX_TABLE_MAX) {
660*f3e7f55eSRobert Mustacchi         /* internal or user app error */
661*f3e7f55eSRobert Mustacchi         return;
662*f3e7f55eSRobert Mustacchi     }
663*f3e7f55eSRobert Mustacchi 
664*f3e7f55eSRobert Mustacchi     index = index_into_allocated[type].ia_al_num;
665*f3e7f55eSRobert Mustacchi     /*
666*f3e7f55eSRobert Mustacchi        A string pointer may point into .debug_info or .debug_string.
667*f3e7f55eSRobert Mustacchi        Otherwise, they are directly malloc'ed. */
668*f3e7f55eSRobert Mustacchi     dwarf_malloc_check_dealloc_data(space, type);
669*f3e7f55eSRobert Mustacchi     if (index == 0) {
670*f3e7f55eSRobert Mustacchi         if (type == DW_DLA_STRING) {
671*f3e7f55eSRobert Mustacchi             if ((Dwarf_Small *) space >= dbg->de_debug_info.dss_data &&
672*f3e7f55eSRobert Mustacchi                 (Dwarf_Small *) space <
673*f3e7f55eSRobert Mustacchi                 dbg->de_debug_info.dss_data + dbg->de_debug_info.dss_size)
674*f3e7f55eSRobert Mustacchi                 return;
675*f3e7f55eSRobert Mustacchi 
676*f3e7f55eSRobert Mustacchi             if (dbg->de_debug_line.dss_data != NULL &&
677*f3e7f55eSRobert Mustacchi                 (Dwarf_Small *) space >= dbg->de_debug_line.dss_data &&
678*f3e7f55eSRobert Mustacchi                 (Dwarf_Small *) space <
679*f3e7f55eSRobert Mustacchi                 dbg->de_debug_line.dss_data + dbg->de_debug_line.dss_size)
680*f3e7f55eSRobert Mustacchi                 return;
681*f3e7f55eSRobert Mustacchi 
682*f3e7f55eSRobert Mustacchi             if (dbg->de_debug_pubnames.dss_data != NULL &&
683*f3e7f55eSRobert Mustacchi                 (Dwarf_Small *) space >= dbg->de_debug_pubnames.dss_data &&
684*f3e7f55eSRobert Mustacchi                 (Dwarf_Small *) space <
685*f3e7f55eSRobert Mustacchi                 dbg->de_debug_pubnames.dss_data +
686*f3e7f55eSRobert Mustacchi                 dbg->de_debug_pubnames.dss_size)
687*f3e7f55eSRobert Mustacchi                 return;
688*f3e7f55eSRobert Mustacchi 
689*f3e7f55eSRobert Mustacchi             if (dbg->de_debug_frame.dss_data != NULL &&
690*f3e7f55eSRobert Mustacchi                 (Dwarf_Small *) space >= dbg->de_debug_frame.dss_data &&
691*f3e7f55eSRobert Mustacchi                 (Dwarf_Small *) space <
692*f3e7f55eSRobert Mustacchi                 dbg->de_debug_frame.dss_data + dbg->de_debug_frame.dss_size)
693*f3e7f55eSRobert Mustacchi                 return;
694*f3e7f55eSRobert Mustacchi 
695*f3e7f55eSRobert Mustacchi             if (dbg->de_debug_str.dss_data != NULL &&
696*f3e7f55eSRobert Mustacchi                 (Dwarf_Small *) space >= dbg->de_debug_str.dss_data &&
697*f3e7f55eSRobert Mustacchi                 (Dwarf_Small *) space <
698*f3e7f55eSRobert Mustacchi                 dbg->de_debug_str.dss_data + dbg->de_debug_str.dss_size)
699*f3e7f55eSRobert Mustacchi                 return;
700*f3e7f55eSRobert Mustacchi 
701*f3e7f55eSRobert Mustacchi             if (dbg->de_debug_funcnames.dss_data != NULL &&
702*f3e7f55eSRobert Mustacchi                 (Dwarf_Small *) space >= dbg->de_debug_funcnames.dss_data &&
703*f3e7f55eSRobert Mustacchi                 (Dwarf_Small *) space <
704*f3e7f55eSRobert Mustacchi                 dbg->de_debug_funcnames.dss_data +
705*f3e7f55eSRobert Mustacchi                 dbg->de_debug_funcnames.dss_size)
706*f3e7f55eSRobert Mustacchi                 return;
707*f3e7f55eSRobert Mustacchi 
708*f3e7f55eSRobert Mustacchi             if (dbg->de_debug_typenames.dss_data != NULL &&
709*f3e7f55eSRobert Mustacchi                 (Dwarf_Small *) space >= dbg->de_debug_typenames.dss_data &&
710*f3e7f55eSRobert Mustacchi                 (Dwarf_Small *) space <
711*f3e7f55eSRobert Mustacchi                 dbg->de_debug_typenames.dss_data +
712*f3e7f55eSRobert Mustacchi                 dbg->de_debug_typenames.dss_size)
713*f3e7f55eSRobert Mustacchi                 return;
714*f3e7f55eSRobert Mustacchi             if (dbg->de_debug_pubtypes.dss_data != NULL &&
715*f3e7f55eSRobert Mustacchi                 (Dwarf_Small *) space >= dbg->de_debug_pubtypes.dss_data &&
716*f3e7f55eSRobert Mustacchi                 (Dwarf_Small *) space <
717*f3e7f55eSRobert Mustacchi                     dbg->de_debug_pubtypes.dss_data +
718*f3e7f55eSRobert Mustacchi                     dbg->de_debug_pubtypes.dss_size)
719*f3e7f55eSRobert Mustacchi                 return;
720*f3e7f55eSRobert Mustacchi 
721*f3e7f55eSRobert Mustacchi             if (dbg->de_debug_varnames.dss_data != NULL &&
722*f3e7f55eSRobert Mustacchi                 (Dwarf_Small *) space >= dbg->de_debug_varnames.dss_data &&
723*f3e7f55eSRobert Mustacchi                 (Dwarf_Small *) space <
724*f3e7f55eSRobert Mustacchi                 dbg->de_debug_varnames.dss_data +
725*f3e7f55eSRobert Mustacchi                 dbg->de_debug_varnames.dss_size)
726*f3e7f55eSRobert Mustacchi                 return;
727*f3e7f55eSRobert Mustacchi 
728*f3e7f55eSRobert Mustacchi             if (dbg->de_debug_weaknames.dss_data != NULL &&
729*f3e7f55eSRobert Mustacchi                 (Dwarf_Small *) space >= dbg->de_debug_weaknames.dss_data &&
730*f3e7f55eSRobert Mustacchi                 (Dwarf_Small *) space <
731*f3e7f55eSRobert Mustacchi                 dbg->de_debug_weaknames.dss_data +
732*f3e7f55eSRobert Mustacchi                 dbg->de_debug_weaknames.dss_size)
733*f3e7f55eSRobert Mustacchi                 return;
734*f3e7f55eSRobert Mustacchi 
735*f3e7f55eSRobert Mustacchi #ifdef DWARF_SIMPLE_MALLOC
736*f3e7f55eSRobert Mustacchi             _dwarf_simple_malloc_delete_from_list(dbg, space, type);
737*f3e7f55eSRobert Mustacchi #endif
738*f3e7f55eSRobert Mustacchi             free(space);
739*f3e7f55eSRobert Mustacchi             return;
740*f3e7f55eSRobert Mustacchi         }
741*f3e7f55eSRobert Mustacchi 
742*f3e7f55eSRobert Mustacchi         if (type == DW_DLA_LIST ||
743*f3e7f55eSRobert Mustacchi             type == DW_DLA_FRAME_BLOCK ||
744*f3e7f55eSRobert Mustacchi             type == DW_DLA_LOC_BLOCK || type == DW_DLA_ADDR ||
745*f3e7f55eSRobert Mustacchi             type == DW_DLA_RANGES ||
746*f3e7f55eSRobert Mustacchi             type == DW_DLA_HASH_TABLE_ENTRY) {
747*f3e7f55eSRobert Mustacchi 
748*f3e7f55eSRobert Mustacchi #ifdef DWARF_SIMPLE_MALLOC
749*f3e7f55eSRobert Mustacchi             _dwarf_simple_malloc_delete_from_list(dbg, space, type);
750*f3e7f55eSRobert Mustacchi #endif
751*f3e7f55eSRobert Mustacchi             free(space);
752*f3e7f55eSRobert Mustacchi             return;
753*f3e7f55eSRobert Mustacchi         }
754*f3e7f55eSRobert Mustacchi         /* else is an alloc type that is not used */
755*f3e7f55eSRobert Mustacchi         /* app or internal error */
756*f3e7f55eSRobert Mustacchi #ifdef DWARF_SIMPLE_MALLOC
757*f3e7f55eSRobert Mustacchi         _dwarf_simple_malloc_botch(4);
758*f3e7f55eSRobert Mustacchi #endif
759*f3e7f55eSRobert Mustacchi         return;
760*f3e7f55eSRobert Mustacchi 
761*f3e7f55eSRobert Mustacchi     }
762*f3e7f55eSRobert Mustacchi     if (index_into_allocated[type].specialdestructor) {
763*f3e7f55eSRobert Mustacchi         index_into_allocated[type].specialdestructor(space);
764*f3e7f55eSRobert Mustacchi     }
765*f3e7f55eSRobert Mustacchi #ifdef DWARF_SIMPLE_MALLOC
766*f3e7f55eSRobert Mustacchi     _dwarf_simple_malloc_delete_from_list(dbg, space, type);
767*f3e7f55eSRobert Mustacchi     free(space);
768*f3e7f55eSRobert Mustacchi #else /* !DWARF_SIMPLE_MALLOC */
769*f3e7f55eSRobert Mustacchi     alloc_hdr = &dbg->de_alloc_hdr[index];
770*f3e7f55eSRobert Mustacchi 
771*f3e7f55eSRobert Mustacchi     /* Get pointer to Dwarf_Alloc_Area this struct came from. See
772*f3e7f55eSRobert Mustacchi        dwarf_alloc.h ROUND_SIZE_WITH_POINTER stuff */
773*f3e7f55eSRobert Mustacchi     alloc_area = *(Dwarf_Alloc_Area *) ((char *) space - DW_RESERVE);
774*f3e7f55eSRobert Mustacchi 
775*f3e7f55eSRobert Mustacchi     /* ASSERT: alloc_area != NULL If NULL we could abort, let it
776*f3e7f55eSRobert Mustacchi        coredump below, or return, pretending all is well. We go on,
777*f3e7f55eSRobert Mustacchi        letting program crash. Is caller error. */
778*f3e7f55eSRobert Mustacchi 
779*f3e7f55eSRobert Mustacchi     /*
780*f3e7f55eSRobert Mustacchi        Check that the alloc_hdr field of the alloc_area we have is
781*f3e7f55eSRobert Mustacchi        pointing to the right alloc_hdr.  This is used to catch use of
782*f3e7f55eSRobert Mustacchi        incorrect deallocation code by the user. */
783*f3e7f55eSRobert Mustacchi     if (alloc_area->aa_alloc_hdr != alloc_hdr) {
784*f3e7f55eSRobert Mustacchi         /* If we get here, the user has called dwarf_dealloc wrongly or
785*f3e7f55eSRobert Mustacchi            there is some other disastrous error. By leaking mem here we
786*f3e7f55eSRobert Mustacchi            try to be safe... */
787*f3e7f55eSRobert Mustacchi #ifdef DEBUG
788*f3e7f55eSRobert Mustacchi         fprintf(stderr,
789*f3e7f55eSRobert Mustacchi                 "libdwarf Internal error: type %d hdr mismatch %lx %lx "
790*f3e7f55eSRobert Mustacchi                 "area ptr %lx\n",
791*f3e7f55eSRobert Mustacchi                 (int) type,
792*f3e7f55eSRobert Mustacchi                 (long) alloc_area->aa_alloc_hdr,
793*f3e7f55eSRobert Mustacchi                 (long) alloc_hdr, (long) alloc_area);
794*f3e7f55eSRobert Mustacchi #endif
795*f3e7f55eSRobert Mustacchi         return;
796*f3e7f55eSRobert Mustacchi     }
797*f3e7f55eSRobert Mustacchi 
798*f3e7f55eSRobert Mustacchi     alloc_hdr->ah_struct_user_holds--;
799*f3e7f55eSRobert Mustacchi     alloc_area->aa_free_structs_in_chunk++;
800*f3e7f55eSRobert Mustacchi 
801*f3e7f55eSRobert Mustacchi     /*
802*f3e7f55eSRobert Mustacchi        Give chunk back to malloc only when every struct is freed */
803*f3e7f55eSRobert Mustacchi     if (alloc_area->aa_free_structs_in_chunk ==
804*f3e7f55eSRobert Mustacchi         alloc_hdr->ah_structs_per_chunk) {
805*f3e7f55eSRobert Mustacchi         if (alloc_area->aa_prev != NULL) {
806*f3e7f55eSRobert Mustacchi             alloc_area->aa_prev->aa_next = alloc_area->aa_next;
807*f3e7f55eSRobert Mustacchi         } else {
808*f3e7f55eSRobert Mustacchi             alloc_hdr->ah_alloc_area_head = alloc_area->aa_next;
809*f3e7f55eSRobert Mustacchi         }
810*f3e7f55eSRobert Mustacchi 
811*f3e7f55eSRobert Mustacchi         if (alloc_area->aa_next != NULL) {
812*f3e7f55eSRobert Mustacchi             alloc_area->aa_next->aa_prev = alloc_area->aa_prev;
813*f3e7f55eSRobert Mustacchi         }
814*f3e7f55eSRobert Mustacchi 
815*f3e7f55eSRobert Mustacchi         alloc_hdr->ah_chunks_allocated--;
816*f3e7f55eSRobert Mustacchi 
817*f3e7f55eSRobert Mustacchi         if (alloc_area == alloc_hdr->ah_last_alloc_area) {
818*f3e7f55eSRobert Mustacchi             alloc_hdr->ah_last_alloc_area = NULL;
819*f3e7f55eSRobert Mustacchi         }
820*f3e7f55eSRobert Mustacchi         memset(alloc_area, 0, sizeof(*alloc_area));
821*f3e7f55eSRobert Mustacchi         free(alloc_area);
822*f3e7f55eSRobert Mustacchi     }
823*f3e7f55eSRobert Mustacchi 
824*f3e7f55eSRobert Mustacchi     else {
825*f3e7f55eSRobert Mustacchi         ((Dwarf_Free_List) space)->fl_next = alloc_area->aa_free_list;
826*f3e7f55eSRobert Mustacchi         alloc_area->aa_free_list = space;
827*f3e7f55eSRobert Mustacchi     }
828*f3e7f55eSRobert Mustacchi #endif /* !DWARF_SIMPLE_MALLOC */
829*f3e7f55eSRobert Mustacchi }
830*f3e7f55eSRobert Mustacchi 
831*f3e7f55eSRobert Mustacchi 
832*f3e7f55eSRobert Mustacchi /*
833*f3e7f55eSRobert Mustacchi     Allocates space for a Dwarf_Debug_s struct,
834*f3e7f55eSRobert Mustacchi     since one does not exist.
835*f3e7f55eSRobert Mustacchi */
836*f3e7f55eSRobert Mustacchi Dwarf_Debug
_dwarf_get_debug(void)837*f3e7f55eSRobert Mustacchi _dwarf_get_debug(void
838*f3e7f55eSRobert Mustacchi     )
839*f3e7f55eSRobert Mustacchi {
840*f3e7f55eSRobert Mustacchi     Dwarf_Debug dbg;
841*f3e7f55eSRobert Mustacchi 
842*f3e7f55eSRobert Mustacchi     dbg = (Dwarf_Debug) malloc(sizeof(struct Dwarf_Debug_s));
843*f3e7f55eSRobert Mustacchi     if (dbg == NULL)
844*f3e7f55eSRobert Mustacchi         return (NULL);
845*f3e7f55eSRobert Mustacchi     else
846*f3e7f55eSRobert Mustacchi         memset(dbg, 0, sizeof(struct Dwarf_Debug_s));
847*f3e7f55eSRobert Mustacchi     return (dbg);
848*f3e7f55eSRobert Mustacchi }
849*f3e7f55eSRobert Mustacchi 
850*f3e7f55eSRobert Mustacchi 
851*f3e7f55eSRobert Mustacchi /*
852*f3e7f55eSRobert Mustacchi     Sets up the Dwarf_Debug_s struct for all the
853*f3e7f55eSRobert Mustacchi     allocation types currently defined.
854*f3e7f55eSRobert Mustacchi     Allocation types DW_DLA_STRING, DW_DLA_LIST,
855*f3e7f55eSRobert Mustacchi     DW_DLA_FRAME_BLOCK, DW_DLA_LOC_BLOCK, DW_DLA_RANGES are
856*f3e7f55eSRobert Mustacchi     malloc'ed directly.
857*f3e7f55eSRobert Mustacchi 
858*f3e7f55eSRobert Mustacchi     This routine should be called after _dwarf_setup(),
859*f3e7f55eSRobert Mustacchi     so that information about the sizes of the Dwarf
860*f3e7f55eSRobert Mustacchi     sections can be used to decide the number of
861*f3e7f55eSRobert Mustacchi     structs of each type malloc'ed.
862*f3e7f55eSRobert Mustacchi 
863*f3e7f55eSRobert Mustacchi     Also DW_DLA_ELLIST, DW_DLA_BOUNDS, DW_DLA_TYPE,
864*f3e7f55eSRobert Mustacchi     DW_DLA_SUBSCR, DW_DLA_LINEBUF allocation types
865*f3e7f55eSRobert Mustacchi     are currently not used.
866*f3e7f55eSRobert Mustacchi     The ah_bytes_one_struct and ah_structs_per_chunk fields for
867*f3e7f55eSRobert Mustacchi     these types have been set to 1 for efficiency
868*f3e7f55eSRobert Mustacchi     in dwarf_get_alloc().
869*f3e7f55eSRobert Mustacchi 
870*f3e7f55eSRobert Mustacchi     Ah_alloc_num should be greater than 1 for all
871*f3e7f55eSRobert Mustacchi     types that are currently being used.
872*f3e7f55eSRobert Mustacchi 
873*f3e7f55eSRobert Mustacchi     Therefore, for these allocation types the
874*f3e7f55eSRobert Mustacchi     ah_bytes_one_struct, and ah_structs_per_chunk fields do not
875*f3e7f55eSRobert Mustacchi     need to be initialized.
876*f3e7f55eSRobert Mustacchi 
877*f3e7f55eSRobert Mustacchi     Being an internal routine, assume proper dbg.
878*f3e7f55eSRobert Mustacchi */
879*f3e7f55eSRobert Mustacchi 
880*f3e7f55eSRobert Mustacchi Dwarf_Debug
_dwarf_setup_debug(Dwarf_Debug dbg)881*f3e7f55eSRobert Mustacchi _dwarf_setup_debug(Dwarf_Debug dbg)
882*f3e7f55eSRobert Mustacchi {
883*f3e7f55eSRobert Mustacchi     int i;
884*f3e7f55eSRobert Mustacchi 
885*f3e7f55eSRobert Mustacchi     for (i = 1; i <= MAX_DW_DLA; i++) {
886*f3e7f55eSRobert Mustacchi         const struct ial_s *ialp = &index_into_allocated[i];
887*f3e7f55eSRobert Mustacchi         unsigned int hdr_index = ialp->ia_al_num;
888*f3e7f55eSRobert Mustacchi         Dwarf_Word str_size = ialp->ia_struct_size;
889*f3e7f55eSRobert Mustacchi         Dwarf_Word str_count = ialp->ia_base_count;
890*f3e7f55eSRobert Mustacchi         Dwarf_Word rnded_size = ROUND_SIZE_WITH_POINTER(str_size);
891*f3e7f55eSRobert Mustacchi 
892*f3e7f55eSRobert Mustacchi         Dwarf_Alloc_Hdr alloc_hdr = &dbg->de_alloc_hdr[hdr_index];
893*f3e7f55eSRobert Mustacchi 
894*f3e7f55eSRobert Mustacchi         alloc_hdr->ah_bytes_one_struct = (Dwarf_Half) rnded_size;
895*f3e7f55eSRobert Mustacchi 
896*f3e7f55eSRobert Mustacchi         /* ah_structs_per_chunk must be >0 else we are in trouble */
897*f3e7f55eSRobert Mustacchi         alloc_hdr->ah_structs_per_chunk = str_count;
898*f3e7f55eSRobert Mustacchi         alloc_hdr->ah_bytes_malloc_per_chunk = rnded_size * str_count;
899*f3e7f55eSRobert Mustacchi     }
900*f3e7f55eSRobert Mustacchi     return (dbg);
901*f3e7f55eSRobert Mustacchi }
902*f3e7f55eSRobert Mustacchi 
903*f3e7f55eSRobert Mustacchi /*
904*f3e7f55eSRobert Mustacchi     This function prints out the statistics
905*f3e7f55eSRobert Mustacchi     collected on allocation of memory chunks.
906*f3e7f55eSRobert Mustacchi */
907*f3e7f55eSRobert Mustacchi void
dwarf_print_memory_stats(Dwarf_Debug dbg)908*f3e7f55eSRobert Mustacchi dwarf_print_memory_stats(Dwarf_Debug dbg)
909*f3e7f55eSRobert Mustacchi {
910*f3e7f55eSRobert Mustacchi     Dwarf_Alloc_Hdr alloc_hdr;
911*f3e7f55eSRobert Mustacchi     Dwarf_Shalf i;
912*f3e7f55eSRobert Mustacchi 
913*f3e7f55eSRobert Mustacchi     /*
914*f3e7f55eSRobert Mustacchi        Alloc types start at 1, not 0. Hence, the first NULL string, and
915*f3e7f55eSRobert Mustacchi        also a size of MAX_DW_DLA + 1. */
916*f3e7f55eSRobert Mustacchi     char *alloc_type_name[MAX_DW_DLA + 1] = {
917*f3e7f55eSRobert Mustacchi         "",
918*f3e7f55eSRobert Mustacchi         "DW_DLA_STRING",
919*f3e7f55eSRobert Mustacchi         "DW_DLA_LOC",
920*f3e7f55eSRobert Mustacchi         "DW_DLA_LOCDESC",
921*f3e7f55eSRobert Mustacchi         "DW_DLA_ELLIST",
922*f3e7f55eSRobert Mustacchi         "DW_DLA_BOUNDS",
923*f3e7f55eSRobert Mustacchi         "DW_DLA_BLOCK",
924*f3e7f55eSRobert Mustacchi         "DW_DLA_DEBUG",
925*f3e7f55eSRobert Mustacchi         "DW_DLA_DIE",
926*f3e7f55eSRobert Mustacchi         "DW_DLA_LINE",
927*f3e7f55eSRobert Mustacchi         "DW_DLA_ATTR",
928*f3e7f55eSRobert Mustacchi         "DW_DLA_TYPE",
929*f3e7f55eSRobert Mustacchi         "DW_DLA_SUBSCR",
930*f3e7f55eSRobert Mustacchi         "DW_DLA_GLOBAL",
931*f3e7f55eSRobert Mustacchi         "DW_DLA_ERROR",
932*f3e7f55eSRobert Mustacchi         "DW_DLA_LIST",
933*f3e7f55eSRobert Mustacchi         "DW_DLA_LINEBUF",
934*f3e7f55eSRobert Mustacchi         "DW_DLA_ARANGE",
935*f3e7f55eSRobert Mustacchi         "DW_DLA_ABBREV",
936*f3e7f55eSRobert Mustacchi         "DW_DLA_FRAME_OP",
937*f3e7f55eSRobert Mustacchi         "DW_DLA_CIE",
938*f3e7f55eSRobert Mustacchi         "DW_DLA_FDE",
939*f3e7f55eSRobert Mustacchi         "DW_DLA_LOC_BLOCK",
940*f3e7f55eSRobert Mustacchi         "DW_DLA_FRAME_BLOCK",
941*f3e7f55eSRobert Mustacchi         "DW_DLA_FUNC",
942*f3e7f55eSRobert Mustacchi         "DW_DLA_TYPENAME",
943*f3e7f55eSRobert Mustacchi         "DW_DLA_VAR",
944*f3e7f55eSRobert Mustacchi         "DW_DLA_WEAK",
945*f3e7f55eSRobert Mustacchi         "DW_DLA_ADDR",
946*f3e7f55eSRobert Mustacchi         "DW_DLA_RANGES",
947*f3e7f55eSRobert Mustacchi         "DW_DLA_ABBREV_LIST",
948*f3e7f55eSRobert Mustacchi         "DW_DLA_CHAIN",
949*f3e7f55eSRobert Mustacchi         "DW_DLA_CU_CONTEXT",
950*f3e7f55eSRobert Mustacchi         "DW_DLA_FRAME",
951*f3e7f55eSRobert Mustacchi         "DW_DLA_GLOBAL_CONTEXT",
952*f3e7f55eSRobert Mustacchi         "DW_DLA_FILE_ENTRY",
953*f3e7f55eSRobert Mustacchi         "DW_DLA_LINE_CONTEXT",
954*f3e7f55eSRobert Mustacchi         "DW_DLA_LOC_CHAIN",
955*f3e7f55eSRobert Mustacchi         "DW_DLA_HASH_TABLE",
956*f3e7f55eSRobert Mustacchi         "DW_DLA_FUNC_CONTEXT",
957*f3e7f55eSRobert Mustacchi         "DW_DLA_TYPENAME_CONTEXT",
958*f3e7f55eSRobert Mustacchi         "DW_DLA_VAR_CONTEXT",
959*f3e7f55eSRobert Mustacchi         "DW_DLA_WEAK_CONTEXT",
960*f3e7f55eSRobert Mustacchi         "DW_DLA_PUBTYPES_CONTEXT",
961*f3e7f55eSRobert Mustacchi         "DW_DLA_HASH_TABLE_ENTRY",
962*f3e7f55eSRobert Mustacchi     };
963*f3e7f55eSRobert Mustacchi 
964*f3e7f55eSRobert Mustacchi     if (dbg == NULL)
965*f3e7f55eSRobert Mustacchi         return;
966*f3e7f55eSRobert Mustacchi 
967*f3e7f55eSRobert Mustacchi     printf("Size of Dwarf_Debug        %4ld bytes\n",
968*f3e7f55eSRobert Mustacchi            (long) sizeof(*dbg));
969*f3e7f55eSRobert Mustacchi     printf("Size of Dwarf_Alloc_Hdr_s  %4ld bytes\n",
970*f3e7f55eSRobert Mustacchi            (long) sizeof(struct Dwarf_Alloc_Hdr_s));
971*f3e7f55eSRobert Mustacchi     printf("size of Dwarf_Alloc_Area_s %4ld bytes\n",
972*f3e7f55eSRobert Mustacchi            (long) sizeof(struct Dwarf_Alloc_Area_s));
973*f3e7f55eSRobert Mustacchi 
974*f3e7f55eSRobert Mustacchi     printf("   Alloc Type                   Curr  Structs byt   str\n");
975*f3e7f55eSRobert Mustacchi     printf("   ----------                   ----  ------- per   per\n");
976*f3e7f55eSRobert Mustacchi     for (i = 1; i <= MAX_DW_DLA; i++) {
977*f3e7f55eSRobert Mustacchi         int indx = index_into_allocated[i].ia_al_num;
978*f3e7f55eSRobert Mustacchi 
979*f3e7f55eSRobert Mustacchi         alloc_hdr = &dbg->de_alloc_hdr[indx];
980*f3e7f55eSRobert Mustacchi         if (alloc_hdr->ah_bytes_one_struct != 1) {
981*f3e7f55eSRobert Mustacchi             printf("%2d %-25s   %6d %8d %6d %6d\n",
982*f3e7f55eSRobert Mustacchi                    (int) i,
983*f3e7f55eSRobert Mustacchi                    alloc_type_name[i],
984*f3e7f55eSRobert Mustacchi                    (int) alloc_hdr->ah_chunks_allocated,
985*f3e7f55eSRobert Mustacchi                    (int) alloc_hdr->ah_struct_user_holds,
986*f3e7f55eSRobert Mustacchi                    (int) alloc_hdr->ah_bytes_malloc_per_chunk,
987*f3e7f55eSRobert Mustacchi                    (int) alloc_hdr->ah_structs_per_chunk);
988*f3e7f55eSRobert Mustacchi         }
989*f3e7f55eSRobert Mustacchi     }
990*f3e7f55eSRobert Mustacchi }
991*f3e7f55eSRobert Mustacchi 
992*f3e7f55eSRobert Mustacchi 
993*f3e7f55eSRobert Mustacchi #ifndef DWARF_SIMPLE_MALLOC
994*f3e7f55eSRobert Mustacchi /*
995*f3e7f55eSRobert Mustacchi     This recursively frees
996*f3e7f55eSRobert Mustacchi     the chunks still allocated, and
997*f3e7f55eSRobert Mustacchi     forward chained through the aa_next
998*f3e7f55eSRobert Mustacchi     pointer.
999*f3e7f55eSRobert Mustacchi */
1000*f3e7f55eSRobert Mustacchi static void
_dwarf_recursive_free(Dwarf_Alloc_Area alloc_area)1001*f3e7f55eSRobert Mustacchi _dwarf_recursive_free(Dwarf_Alloc_Area alloc_area)
1002*f3e7f55eSRobert Mustacchi {
1003*f3e7f55eSRobert Mustacchi     if (alloc_area->aa_next != NULL) {
1004*f3e7f55eSRobert Mustacchi         _dwarf_recursive_free(alloc_area->aa_next);
1005*f3e7f55eSRobert Mustacchi     }
1006*f3e7f55eSRobert Mustacchi 
1007*f3e7f55eSRobert Mustacchi     alloc_area->aa_next = 0;
1008*f3e7f55eSRobert Mustacchi     alloc_area->aa_prev = 0;
1009*f3e7f55eSRobert Mustacchi     free(alloc_area);
1010*f3e7f55eSRobert Mustacchi }
1011*f3e7f55eSRobert Mustacchi #endif
1012*f3e7f55eSRobert Mustacchi 
1013*f3e7f55eSRobert Mustacchi /* In the 'rela' relocation case we might have malloc'd
1014*f3e7f55eSRobert Mustacchi    space to ensure it is read-write. In that case, free the space.  */
1015*f3e7f55eSRobert Mustacchi static void
rela_free(struct Dwarf_Section_s * sec)1016*f3e7f55eSRobert Mustacchi rela_free(struct Dwarf_Section_s * sec)
1017*f3e7f55eSRobert Mustacchi {
1018*f3e7f55eSRobert Mustacchi     if (sec->dss_data_was_malloc) {
1019*f3e7f55eSRobert Mustacchi         free(sec->dss_data);
1020*f3e7f55eSRobert Mustacchi     }
1021*f3e7f55eSRobert Mustacchi     sec->dss_data = 0;
1022*f3e7f55eSRobert Mustacchi     sec->dss_data_was_malloc = 0;
1023*f3e7f55eSRobert Mustacchi }
1024*f3e7f55eSRobert Mustacchi 
1025*f3e7f55eSRobert Mustacchi /*
1026*f3e7f55eSRobert Mustacchi     Used to free all space allocated for this Dwarf_Debug.
1027*f3e7f55eSRobert Mustacchi     The caller should assume that the Dwarf_Debug pointer
1028*f3e7f55eSRobert Mustacchi     itself is no longer valid upon return from this function.
1029*f3e7f55eSRobert Mustacchi 
1030*f3e7f55eSRobert Mustacchi     In case of difficulty, this function simply returns quietly.
1031*f3e7f55eSRobert Mustacchi */
1032*f3e7f55eSRobert Mustacchi int
_dwarf_free_all_of_one_debug(Dwarf_Debug dbg)1033*f3e7f55eSRobert Mustacchi _dwarf_free_all_of_one_debug(Dwarf_Debug dbg)
1034*f3e7f55eSRobert Mustacchi {
1035*f3e7f55eSRobert Mustacchi     Dwarf_Alloc_Hdr alloc_hdr;
1036*f3e7f55eSRobert Mustacchi     Dwarf_Shalf i;
1037*f3e7f55eSRobert Mustacchi     Dwarf_CU_Context context = 0;
1038*f3e7f55eSRobert Mustacchi     Dwarf_CU_Context nextcontext = 0;
1039*f3e7f55eSRobert Mustacchi 
1040*f3e7f55eSRobert Mustacchi     if (dbg == NULL)
1041*f3e7f55eSRobert Mustacchi         return (DW_DLV_ERROR);
1042*f3e7f55eSRobert Mustacchi 
1043*f3e7f55eSRobert Mustacchi     /* To do complete validation that we have no surprising missing or
1044*f3e7f55eSRobert Mustacchi        erroneous deallocs it is advisable to do the dwarf_deallocs here
1045*f3e7f55eSRobert Mustacchi        that are not things the user can otherwise request.
1046*f3e7f55eSRobert Mustacchi        Housecleaning.  */
1047*f3e7f55eSRobert Mustacchi 
1048*f3e7f55eSRobert Mustacchi     for (context = dbg->de_cu_context_list;
1049*f3e7f55eSRobert Mustacchi          context; context = nextcontext) {
1050*f3e7f55eSRobert Mustacchi         Dwarf_Hash_Table hash_table = context->cc_abbrev_hash_table;
1051*f3e7f55eSRobert Mustacchi         _dwarf_free_abbrev_hash_table_contents(dbg,hash_table);
1052*f3e7f55eSRobert Mustacchi         nextcontext = context->cc_next;
1053*f3e7f55eSRobert Mustacchi         dwarf_dealloc(dbg, hash_table, DW_DLA_HASH_TABLE);
1054*f3e7f55eSRobert Mustacchi         dwarf_dealloc(dbg, context, DW_DLA_CU_CONTEXT);
1055*f3e7f55eSRobert Mustacchi     }
1056*f3e7f55eSRobert Mustacchi 
1057*f3e7f55eSRobert Mustacchi     /* Housecleaning done. Now really free all the space. */
1058*f3e7f55eSRobert Mustacchi #ifdef DWARF_SIMPLE_MALLOC
1059*f3e7f55eSRobert Mustacchi     if (dbg->de_simple_malloc_base) {
1060*f3e7f55eSRobert Mustacchi         struct simple_malloc_record_s *smp = dbg->de_simple_malloc_base;
1061*f3e7f55eSRobert Mustacchi 
1062*f3e7f55eSRobert Mustacchi         while (smp) {
1063*f3e7f55eSRobert Mustacchi             int i;
1064*f3e7f55eSRobert Mustacchi             struct simple_malloc_record_s *prev_smp = 0;
1065*f3e7f55eSRobert Mustacchi 
1066*f3e7f55eSRobert Mustacchi             for (i = 0; i < smp->sr_used; ++i) {
1067*f3e7f55eSRobert Mustacchi                 struct simple_malloc_entry_s *cur;
1068*f3e7f55eSRobert Mustacchi 
1069*f3e7f55eSRobert Mustacchi                 cur = &smp->sr_entry[i];
1070*f3e7f55eSRobert Mustacchi                 if (cur->se_addr != 0) {
1071*f3e7f55eSRobert Mustacchi                     free(cur->se_addr);
1072*f3e7f55eSRobert Mustacchi                     cur->se_addr = 0;
1073*f3e7f55eSRobert Mustacchi                 }
1074*f3e7f55eSRobert Mustacchi             }
1075*f3e7f55eSRobert Mustacchi             prev_smp = smp;
1076*f3e7f55eSRobert Mustacchi             smp = smp->sr_next;
1077*f3e7f55eSRobert Mustacchi             free(prev_smp);
1078*f3e7f55eSRobert Mustacchi         }
1079*f3e7f55eSRobert Mustacchi         dbg->de_simple_malloc_base = 0;
1080*f3e7f55eSRobert Mustacchi     }
1081*f3e7f55eSRobert Mustacchi #else
1082*f3e7f55eSRobert Mustacchi     for (i = 1; i < ALLOC_AREA_REAL_TABLE_MAX; i++) {
1083*f3e7f55eSRobert Mustacchi         int indx = i;
1084*f3e7f55eSRobert Mustacchi 
1085*f3e7f55eSRobert Mustacchi         alloc_hdr = &dbg->de_alloc_hdr[indx];
1086*f3e7f55eSRobert Mustacchi         if (alloc_hdr->ah_alloc_area_head != NULL) {
1087*f3e7f55eSRobert Mustacchi             _dwarf_recursive_free(alloc_hdr->ah_alloc_area_head);
1088*f3e7f55eSRobert Mustacchi         }
1089*f3e7f55eSRobert Mustacchi     }
1090*f3e7f55eSRobert Mustacchi 
1091*f3e7f55eSRobert Mustacchi #endif
1092*f3e7f55eSRobert Mustacchi     rela_free(&dbg->de_debug_info);
1093*f3e7f55eSRobert Mustacchi     rela_free(&dbg->de_debug_abbrev);
1094*f3e7f55eSRobert Mustacchi     rela_free(&dbg->de_debug_line);
1095*f3e7f55eSRobert Mustacchi     rela_free(&dbg->de_debug_loc);
1096*f3e7f55eSRobert Mustacchi     rela_free(&dbg->de_debug_aranges);
1097*f3e7f55eSRobert Mustacchi     rela_free(&dbg->de_debug_macinfo);
1098*f3e7f55eSRobert Mustacchi     rela_free(&dbg->de_debug_pubnames);
1099*f3e7f55eSRobert Mustacchi     rela_free(&dbg->de_debug_str);
1100*f3e7f55eSRobert Mustacchi     rela_free(&dbg->de_debug_frame);
1101*f3e7f55eSRobert Mustacchi     rela_free(&dbg->de_debug_frame_eh_gnu);
1102*f3e7f55eSRobert Mustacchi     rela_free(&dbg->de_debug_pubtypes);
1103*f3e7f55eSRobert Mustacchi     rela_free(&dbg->de_debug_funcnames);
1104*f3e7f55eSRobert Mustacchi     rela_free(&dbg->de_debug_typenames);
1105*f3e7f55eSRobert Mustacchi     rela_free(&dbg->de_debug_varnames);
1106*f3e7f55eSRobert Mustacchi     rela_free(&dbg->de_debug_weaknames);
1107*f3e7f55eSRobert Mustacchi     rela_free(&dbg->de_debug_ranges);
1108*f3e7f55eSRobert Mustacchi     dwarf_harmless_cleanout(&dbg->de_harmless_errors);
1109*f3e7f55eSRobert Mustacchi 
1110*f3e7f55eSRobert Mustacchi     memset(dbg, 0, sizeof(*dbg)); /* Prevent accidental use later. */
1111*f3e7f55eSRobert Mustacchi     free(dbg);
1112*f3e7f55eSRobert Mustacchi     return (DW_DLV_OK);
1113*f3e7f55eSRobert Mustacchi }
1114*f3e7f55eSRobert Mustacchi 
1115*f3e7f55eSRobert Mustacchi /* A special case: we have no dbg, no alloc header etc.
1116*f3e7f55eSRobert Mustacchi    So create something out of thin air that we can recognize
1117*f3e7f55eSRobert Mustacchi    in dwarf_dealloc.
1118*f3e7f55eSRobert Mustacchi    Something with the prefix (prefix space hidden from caller).
1119*f3e7f55eSRobert Mustacchi 
1120*f3e7f55eSRobert Mustacchi    Only applies to DW_DLA_ERROR, making up an error record.
1121*f3e7f55eSRobert Mustacchi */
1122*f3e7f55eSRobert Mustacchi 
1123*f3e7f55eSRobert Mustacchi struct Dwarf_Error_s *
_dwarf_special_no_dbg_error_malloc(void)1124*f3e7f55eSRobert Mustacchi _dwarf_special_no_dbg_error_malloc(void)
1125*f3e7f55eSRobert Mustacchi {
1126*f3e7f55eSRobert Mustacchi     /* the union unused things are to guarantee proper alignment */
1127*f3e7f55eSRobert Mustacchi     union u {
1128*f3e7f55eSRobert Mustacchi         Dwarf_Alloc_Area ptr_not_used;
1129*f3e7f55eSRobert Mustacchi         struct Dwarf_Error_s base_not_used;
1130*f3e7f55eSRobert Mustacchi         char data_space[sizeof(struct Dwarf_Error_s) +
1131*f3e7f55eSRobert Mustacchi                         (DW_RESERVE * 2)];
1132*f3e7f55eSRobert Mustacchi     };
1133*f3e7f55eSRobert Mustacchi     char *mem;
1134*f3e7f55eSRobert Mustacchi 
1135*f3e7f55eSRobert Mustacchi     mem = malloc(sizeof(union u));
1136*f3e7f55eSRobert Mustacchi 
1137*f3e7f55eSRobert Mustacchi     if (mem == 0) {
1138*f3e7f55eSRobert Mustacchi         return 0;
1139*f3e7f55eSRobert Mustacchi 
1140*f3e7f55eSRobert Mustacchi     }
1141*f3e7f55eSRobert Mustacchi     memset(mem, 0, sizeof(union u));
1142*f3e7f55eSRobert Mustacchi     mem += DW_RESERVE;
1143*f3e7f55eSRobert Mustacchi     return (struct Dwarf_Error_s *) mem;
1144*f3e7f55eSRobert Mustacchi }
1145*f3e7f55eSRobert Mustacchi 
1146*f3e7f55eSRobert Mustacchi /* The free side of  _dwarf_special_no_dbg_error_malloc()
1147*f3e7f55eSRobert Mustacchi */
1148*f3e7f55eSRobert Mustacchi static void
_dwarf_free_special_error(Dwarf_Ptr space)1149*f3e7f55eSRobert Mustacchi _dwarf_free_special_error(Dwarf_Ptr space)
1150*f3e7f55eSRobert Mustacchi {
1151*f3e7f55eSRobert Mustacchi     char *mem = (char *) space;
1152*f3e7f55eSRobert Mustacchi 
1153*f3e7f55eSRobert Mustacchi     mem -= DW_RESERVE;
1154*f3e7f55eSRobert Mustacchi     free(mem);
1155*f3e7f55eSRobert Mustacchi }
1156*f3e7f55eSRobert Mustacchi 
1157*f3e7f55eSRobert Mustacchi 
1158*f3e7f55eSRobert Mustacchi #ifdef DWARF_SIMPLE_MALLOC
1159*f3e7f55eSRobert Mustacchi /* here solely for planting a breakpoint. */
1160*f3e7f55eSRobert Mustacchi /* ARGSUSED */
1161*f3e7f55eSRobert Mustacchi void
_dwarf_simple_malloc_botch(int err)1162*f3e7f55eSRobert Mustacchi _dwarf_simple_malloc_botch(int err)
1163*f3e7f55eSRobert Mustacchi {
1164*f3e7f55eSRobert Mustacchi        fprintf(stderr,"simple malloc botch %d\n",err);
1165*f3e7f55eSRobert Mustacchi }
1166*f3e7f55eSRobert Mustacchi static void
_dwarf_simple_malloc_add_to_list(Dwarf_Debug dbg,Dwarf_Ptr addr,unsigned long size,short alloc_type)1167*f3e7f55eSRobert Mustacchi _dwarf_simple_malloc_add_to_list(Dwarf_Debug dbg,
1168*f3e7f55eSRobert Mustacchi                                  Dwarf_Ptr addr,
1169*f3e7f55eSRobert Mustacchi                                  unsigned long size, short alloc_type)
1170*f3e7f55eSRobert Mustacchi {
1171*f3e7f55eSRobert Mustacchi     struct simple_malloc_record_s *cur;
1172*f3e7f55eSRobert Mustacchi     struct simple_malloc_entry_s *newentry;
1173*f3e7f55eSRobert Mustacchi 
1174*f3e7f55eSRobert Mustacchi     if (!dbg->de_simple_malloc_base) {
1175*f3e7f55eSRobert Mustacchi         /* First entry to this routine. */
1176*f3e7f55eSRobert Mustacchi         dbg->de_simple_malloc_base =
1177*f3e7f55eSRobert Mustacchi             malloc(sizeof(struct simple_malloc_record_s));
1178*f3e7f55eSRobert Mustacchi         if (!dbg->de_simple_malloc_base) {
1179*f3e7f55eSRobert Mustacchi             _dwarf_simple_malloc_botch(7);
1180*f3e7f55eSRobert Mustacchi             return;             /* no memory, give up */
1181*f3e7f55eSRobert Mustacchi         }
1182*f3e7f55eSRobert Mustacchi         memset(dbg->de_simple_malloc_base,
1183*f3e7f55eSRobert Mustacchi                0, sizeof(struct simple_malloc_record_s));
1184*f3e7f55eSRobert Mustacchi     }
1185*f3e7f55eSRobert Mustacchi     cur = dbg->de_simple_malloc_base;
1186*f3e7f55eSRobert Mustacchi 
1187*f3e7f55eSRobert Mustacchi     if (cur->sr_used >= DSM_BLOCK_COUNT) {
1188*f3e7f55eSRobert Mustacchi         /* Better not be > than as that means chaos */
1189*f3e7f55eSRobert Mustacchi 
1190*f3e7f55eSRobert Mustacchi         /* Create a new block to link at the head. */
1191*f3e7f55eSRobert Mustacchi 
1192*f3e7f55eSRobert Mustacchi         struct simple_malloc_record_s *newblock =
1193*f3e7f55eSRobert Mustacchi             malloc(sizeof(struct simple_malloc_record_s));
1194*f3e7f55eSRobert Mustacchi         if (!newblock) {
1195*f3e7f55eSRobert Mustacchi             _dwarf_simple_malloc_botch(8);
1196*f3e7f55eSRobert Mustacchi             return;             /* Can do nothing, out of memory */
1197*f3e7f55eSRobert Mustacchi         }
1198*f3e7f55eSRobert Mustacchi         memset(newblock, 0, sizeof(struct simple_malloc_record_s));
1199*f3e7f55eSRobert Mustacchi         /* Link the new block at the head of the chain, and make it
1200*f3e7f55eSRobert Mustacchi            'current' */
1201*f3e7f55eSRobert Mustacchi         dbg->de_simple_malloc_base = newblock;
1202*f3e7f55eSRobert Mustacchi         newblock->sr_next = cur;
1203*f3e7f55eSRobert Mustacchi         cur = newblock;
1204*f3e7f55eSRobert Mustacchi     }
1205*f3e7f55eSRobert Mustacchi     newentry = &cur->sr_entry[cur->sr_used];
1206*f3e7f55eSRobert Mustacchi     newentry->se_addr = addr;
1207*f3e7f55eSRobert Mustacchi     newentry->se_size = size;
1208*f3e7f55eSRobert Mustacchi     newentry->se_type = alloc_type;
1209*f3e7f55eSRobert Mustacchi     ++cur->sr_used;
1210*f3e7f55eSRobert Mustacchi }
1211*f3e7f55eSRobert Mustacchi 
1212*f3e7f55eSRobert Mustacchi /*
1213*f3e7f55eSRobert Mustacchi    DWARF_SIMPLE_MALLOC: testing the hypothesis that the existing
1214*f3e7f55eSRobert Mustacchi    malloc scheme here (see _dwarf_get_alloc()) is pointless complexity.
1215*f3e7f55eSRobert Mustacchi 
1216*f3e7f55eSRobert Mustacchi    DWARF_SIMPLE_MALLOC also makes it easy for a malloc-tracing
1217*f3e7f55eSRobert Mustacchi    tool to verify libdwarf malloc has no botches (though of course
1218*f3e7f55eSRobert Mustacchi    such does not test the complicated standard-libdwarf-alloc code).
1219*f3e7f55eSRobert Mustacchi 
1220*f3e7f55eSRobert Mustacchi    To properly answer the question, the simple-malloc allocate
1221*f3e7f55eSRobert Mustacchi    and delete should be something other than a simple list.
1222*f3e7f55eSRobert Mustacchi    Perhaps a heap, or perhaps a red-black tree.
1223*f3e7f55eSRobert Mustacchi 
1224*f3e7f55eSRobert Mustacchi */
1225*f3e7f55eSRobert Mustacchi static void
_dwarf_simple_malloc_delete_from_list(Dwarf_Debug dbg,Dwarf_Ptr space,short alloc_type)1226*f3e7f55eSRobert Mustacchi _dwarf_simple_malloc_delete_from_list(Dwarf_Debug dbg,
1227*f3e7f55eSRobert Mustacchi                                       Dwarf_Ptr space, short alloc_type)
1228*f3e7f55eSRobert Mustacchi {
1229*f3e7f55eSRobert Mustacchi     if (space == 0) {
1230*f3e7f55eSRobert Mustacchi         _dwarf_simple_malloc_botch(6);
1231*f3e7f55eSRobert Mustacchi     }
1232*f3e7f55eSRobert Mustacchi     if (dbg->de_simple_malloc_base) {
1233*f3e7f55eSRobert Mustacchi         struct simple_malloc_record_s *smp = dbg->de_simple_malloc_base;
1234*f3e7f55eSRobert Mustacchi 
1235*f3e7f55eSRobert Mustacchi         while (smp) {
1236*f3e7f55eSRobert Mustacchi             int i;
1237*f3e7f55eSRobert Mustacchi 
1238*f3e7f55eSRobert Mustacchi             for (i = 0; i < smp->sr_used; ++i) {
1239*f3e7f55eSRobert Mustacchi                 struct simple_malloc_entry_s *cur;
1240*f3e7f55eSRobert Mustacchi 
1241*f3e7f55eSRobert Mustacchi                 cur = &smp->sr_entry[i];
1242*f3e7f55eSRobert Mustacchi                 if (cur->se_addr == space) {
1243*f3e7f55eSRobert Mustacchi                     if (cur->se_type != alloc_type) {
1244*f3e7f55eSRobert Mustacchi                         _dwarf_simple_malloc_botch(0);
1245*f3e7f55eSRobert Mustacchi                     }
1246*f3e7f55eSRobert Mustacchi                     cur->se_addr = 0;
1247*f3e7f55eSRobert Mustacchi                     return;
1248*f3e7f55eSRobert Mustacchi                 }
1249*f3e7f55eSRobert Mustacchi             }
1250*f3e7f55eSRobert Mustacchi             smp = smp->sr_next;
1251*f3e7f55eSRobert Mustacchi         }
1252*f3e7f55eSRobert Mustacchi     }
1253*f3e7f55eSRobert Mustacchi     /* Never found the space. */
1254*f3e7f55eSRobert Mustacchi     _dwarf_simple_malloc_botch(1);
1255*f3e7f55eSRobert Mustacchi     return;
1256*f3e7f55eSRobert Mustacchi 
1257*f3e7f55eSRobert Mustacchi }
1258*f3e7f55eSRobert Mustacchi #endif
1259