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