diff options
author | Richard Lowe <richlowe@richlowe.net> | 2011-05-22 03:13:22 +0100 |
---|---|---|
committer | Richard Lowe <richlowe@richlowe.net> | 2011-06-29 19:12:22 -0400 |
commit | 77b6d4a80fc05587b08370de690c979abe2667d5 (patch) | |
tree | f00c511c215afecbbe09aac179e10839099358a6 /usr/src/tools/ctf/dwarf/common/dwarf_alloc.c | |
parent | 9ecc7612020c1993e4dbadd3422a74b210279739 (diff) | |
download | illumos-joyent-77b6d4a80fc05587b08370de690c979abe2667d5.tar.gz |
dwarf: Upgrade to libdwarf-20110113
Diffstat (limited to 'usr/src/tools/ctf/dwarf/common/dwarf_alloc.c')
-rw-r--r-- | usr/src/tools/ctf/dwarf/common/dwarf_alloc.c | 1292 |
1 files changed, 714 insertions, 578 deletions
diff --git a/usr/src/tools/ctf/dwarf/common/dwarf_alloc.c b/usr/src/tools/ctf/dwarf/common/dwarf_alloc.c index ae94c8b355..ddb423e841 100644 --- a/usr/src/tools/ctf/dwarf/common/dwarf_alloc.c +++ b/usr/src/tools/ctf/dwarf/common/dwarf_alloc.c @@ -1,6 +1,7 @@ /* - Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved. + Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License @@ -19,10 +20,10 @@ You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. - Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, Mountain View, CA 94043, or: http://www.sgi.com @@ -32,8 +33,14 @@ http://oss.sgi.com/projects/GenInfo/NoticeExplan */ +/* The address of the Free Software Foundation is + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + SGI has moved from the Crittenden Lane address. +*/ +#undef DEBUG #include "config.h" #include "dwarf_incl.h" @@ -41,7 +48,7 @@ #include <stdlib.h> #include <stdio.h> -#include <malloc.h> +#include "malloc_check.h" /* These files are included to get the sizes @@ -61,15 +68,17 @@ #include "dwarf_vars.h" #include "dwarf_weaks.h" + static void _dwarf_free_special_error(Dwarf_Ptr space); + #ifdef DWARF_SIMPLE_MALLOC static void _dwarf_simple_malloc_add_to_list(Dwarf_Debug dbg, - Dwarf_Ptr addr, - unsigned long size, - short alloc_type); -static void _dwarf_simple_malloc_delete_from_list(Dwarf_Debug dbg, - Dwarf_Ptr space, - short alloc_type); + Dwarf_Ptr addr, + unsigned long size, + short alloc_type); +static void _dwarf_simple_malloc_delete_from_list(Dwarf_Debug dbg, + Dwarf_Ptr space, + short alloc_type); void _dwarf_simple_malloc_botch(int err); #endif /* DWARF_SIMPLE_MALLOC */ @@ -83,40 +92,49 @@ void _dwarf_simple_malloc_botch(int err); be a multiple of the size of a pointer. This is done so that every struct returned by _dwarf_get_alloc() can be preceded by a pointer to the chunk it came from. - Before, it checks if the size of struct is less than + Before allocating, it checks if the size of struct is less than the size of a pointer. If yes, it returns the size of 2 pointers. The returned size should be at least the size of 2 pointers, since the first points to the chunk the struct was allocated from, and the second is used to link the free list. - If this is n32, we want the sizes to be 64-bit aligned - so that longlong in the structure we return to user - is aligned properly. Thus the _dw_fac of 2 + We want DW_RESERVE to be at least the size of + a long long and at least the size of a pointer because + our struct has a long long and we want that aligned right. + Now Standard C defines long long as 8 bytes, so lets + make that standard. It will become unworkable when + long long or pointer grows beyound 8 bytes. + Unclear what to do with wierd requirements, like + 36 bit pointers. - Only long longs need to be properly aligned: we don't - have long double and don't align for that. */ -#if _MIPS_SIM == _MIPS_SIM_NABI32 -#define _DW_FAC 2 -#define _DW_PS sizeof(void *) -#else -#define _DW_FAC 1 -#define _DW_PS sizeof(void *) -#endif -#define _DW_RESERVE (_DW_FAC * _DW_PS) +#define DW_RESERVE 8 -/* Round size up to the next multiple of _DW_RESERVE bytes +/* Round size up to the next multiple of DW_RESERVE bytes */ #define ROUND_SIZE(inputsize) \ - (((inputsize) % (_DW_RESERVE)) == 0 ? \ + (((inputsize) % (DW_RESERVE)) == 0 ? \ (inputsize): \ ((inputsize) + \ - (_DW_RESERVE) - ((inputsize) % (_DW_RESERVE)) )) + (DW_RESERVE) - ((inputsize) % (DW_RESERVE)) )) + +#define ROUND_SIZE_WITH_POINTER(i_size) (ROUND_SIZE(i_size) + DW_RESERVE) -#define ROUND_SIZE_WITH_POINTER(i_size) (ROUND_SIZE(i_size) + _DW_RESERVE) +/* SMALL_ALLOC is for trivia where allocation is a waste. + Things that should be removed, really. */ +#define SMALL_ALLOC 2 + +/* BASE_ALLOC is where a basic allocation makes sense, but 'not too large'. + No thorough evaluation of this value has been done, though + it was found wasteful of memory to have BASE_ALLOC be as large as + BIG_ALLOC. */ #define BASE_ALLOC 64 + +/* BIG_ALLOC is where a larger-than-BASE_ALLOC + allocation makes sense, but still 'not too large'. + No thorough evaluation of this value has been done. */ #define BIG_ALLOC 128 /* This translates into de_alloc_hdr index @@ -126,110 +144,126 @@ void _dwarf_simple_malloc_botch(int err); ** so that is not an option. */ struct ial_s { - int ia_al_num; /* Index into de_alloc_hdr table. */ + int ia_al_num; /* Index into de_alloc_hdr table. */ /* In bytes, one struct instance. This does not account for extra - space needed per block, but that (_DW_RESERVE) will be added in - later where it is needed (_DW_RESERVE space never added in - here). */ + space needed per block, but that (DW_RESERVE) will be added in + later where it is needed (DW_RESERVE space never added in here). + */ int ia_struct_size; /* Number of instances per alloc block. MUST be > 0. */ int ia_base_count; + + int (*specialconstructor) (Dwarf_Debug, void *); + void (*specialdestructor) (void *); }; static const struct ial_s index_into_allocated[ALLOC_AREA_INDEX_TABLE_MAX] = { - {0, 1, 1}, /* none */ - {0, 1, 1,}, /* 1 DW_DLA_STRING */ - {1, sizeof(Dwarf_Loc), BASE_ALLOC} - , /* 2 DW_DLA_LOC */ - {2, sizeof(Dwarf_Locdesc), BASE_ALLOC} - , /* 3 DW_DLA_LOCDESC */ - {0, 1, 1} - , /* not used *//* 4 DW_DLA_ELLIST */ - {0, 1, 1} - , /* not used *//* 5 DW_DLA_BOUNDS */ - {3, sizeof(Dwarf_Block), BASE_ALLOC} - , /* 6 DW_DLA_BLOCK */ - {0, 1, 1} - , /* the actual dwarf_debug structure *//* 7 DW_DLA_DEBUG */ - {4, sizeof(struct Dwarf_Die_s), BIG_ALLOC}, /* 8 DW_DLA_DIE */ - {5, sizeof(struct Dwarf_Line_s), BIG_ALLOC}, /* 9 - DW_DLA_LINE */ - {6, sizeof(struct Dwarf_Attribute_s), BIG_ALLOC * 2}, + {0, 1, 1, 0, 0}, /* none */ + {0, 1, 1, 0, 0}, /* 1 DW_DLA_STRING */ + {1, sizeof(Dwarf_Loc), BASE_ALLOC, 0, 0} + , /* 2 DW_DLA_LOC */ + {2, sizeof(Dwarf_Locdesc), BASE_ALLOC, 0, 0} + , /* 3 DW_DLA_LOCDESC */ + {0, 1, 1, 0, 0} + , /* not used *//* 4 DW_DLA_ELLIST */ + {0, 1, 1, 0, 0} + , /* not used *//* 5 DW_DLA_BOUNDS */ + {3, sizeof(Dwarf_Block), BASE_ALLOC, 0, 0} + , /* 6 DW_DLA_BLOCK */ + {0, 1, 1, 0, 0} + , /* the actual dwarf_debug structure *//* 7 DW_DLA_DEBUG */ + {4, sizeof(struct Dwarf_Die_s), BIG_ALLOC, 0, 0}, /* 8 DW_DLA_DIE + */ + {5, sizeof(struct Dwarf_Line_s), BIG_ALLOC, 0, 0}, /* 9 + DW_DLA_LINE */ + {6, sizeof(struct Dwarf_Attribute_s), BIG_ALLOC * 2, 0, 0}, /* 10 DW_DLA_ATTR */ - {0, 1, 1}, /* not used *//* 11 DW_DLA_TYPE */ - {0, 1, 1}, /* not used *//* 12 DW_DLA_SUBSCR */ - {7, sizeof(struct Dwarf_Global_s), BIG_ALLOC}, /* 13 - DW_DLA_GLOBAL - */ - {8, sizeof(struct Dwarf_Error_s), BASE_ALLOC}, /* 14 - DW_DLA_ERROR - */ - {0, 1, 1}, /* 15 DW_DLA_LIST */ - {0, 1, 1}, /* not used *//* 16 DW_DLA_LINEBUF */ - {9, sizeof(struct Dwarf_Arange_s), BASE_ALLOC}, /* 17 - DW_DLA_ARANGE - */ - {10, sizeof(struct Dwarf_Abbrev_s), BIG_ALLOC}, /* 18 - DW_DLA_ABBREV - */ - {11, sizeof(Dwarf_Frame_Op), BIG_ALLOC} - , /* 19 DW_DLA_FRAME_OP */ - {12, sizeof(struct Dwarf_Cie_s), BASE_ALLOC}, /* 20 - DW_DLA_CIE */ - {13, sizeof(struct Dwarf_Fde_s), BASE_ALLOC}, /* 21 - DW_DLA_FDE */ - {0, 1, 1}, /* 22 DW_DLA_LOC_BLOCK */ - {0, 1, 1}, /* 23 DW_DLA_FRAME_BLOCK */ - {14, sizeof(struct Dwarf_Global_s), BIG_ALLOC}, /* 24 - DW_DLA_FUNC */ - {15, sizeof(struct Dwarf_Global_s), BIG_ALLOC}, /* 25 - DW_DLA_TYPENAME - */ - {16, sizeof(struct Dwarf_Global_s), BIG_ALLOC}, /* 26 - DW_DLA_VAR */ - {17, sizeof(struct Dwarf_Global_s), BASE_ALLOC}, /* 27 - DW_DLA_WEAK */ - {0, 1, 1}, /* 28 DW_DLA_ADDR */ - {18, sizeof(struct Dwarf_Abbrev_List_s), BIG_ALLOC}, - /* 29 DW_DLA_ABBREV_LIST */ - {19, sizeof(struct Dwarf_Chain_s), BIG_ALLOC}, /* 30 - DW_DLA_CHAIN - */ - {20, sizeof(struct Dwarf_CU_Context_s), BASE_ALLOC}, - /* 31 DW_DLA_CU_CONTEXT */ - {21, sizeof(struct Dwarf_Frame_s), BASE_ALLOC}, /* 32 - DW_DLA_FRAME - */ - {22, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC}, - /* 33 DW_DLA_GLOBAL_CONTEXT */ - {23, sizeof(struct Dwarf_File_Entry_s), BASE_ALLOC}, - /* 34 DW_DLA_FILE_ENTRY */ - {24, sizeof(struct Dwarf_Line_Context_s), BASE_ALLOC}, - /* 35 DW_DLA_LINE_CONTEXT */ - {25, sizeof(struct Dwarf_Loc_Chain_s), BASE_ALLOC}, - /* 36 DW_DLA_LOC_CHAIN */ - {26, ABBREV_HASH_TABLE_SIZE * 2 * sizeof(Dwarf_Abbrev_List), - BASE_ALLOC} - , - /* 37 DW_DLA_HASH_TABLE */ + {0, 1, 1, 0, 0}, /* not used *//* 11 DW_DLA_TYPE */ + {0, 1, 1, 0, 0}, /* not used *//* 12 DW_DLA_SUBSCR */ + {7, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0}, /* 13 + DW_DLA_GLOBAL + */ + {8, sizeof(struct Dwarf_Error_s), BASE_ALLOC, 0, 0}, /* 14 + DW_DLA_ERROR + */ + {0, 1, 1, 0, 0}, /* 15 DW_DLA_LIST */ + {0, 1, 1, 0, 0}, /* not used *//* 16 DW_DLA_LINEBUF */ + {9, sizeof(struct Dwarf_Arange_s), BASE_ALLOC, 0, 0}, /* 17 + DW_DLA_ARANGE + */ + {10, sizeof(struct Dwarf_Abbrev_s), BIG_ALLOC, 0, 0}, /* 18 + DW_DLA_ABBREV + */ + {11, sizeof(Dwarf_Frame_Op), BIG_ALLOC, 0, 0} + , /* 19 DW_DLA_FRAME_OP */ + {12, sizeof(struct Dwarf_Cie_s), BASE_ALLOC, 0, 0}, /* 20 + DW_DLA_CIE */ + {13, sizeof(struct Dwarf_Fde_s), BASE_ALLOC, 0, 0}, /* 21 DW_DLA_FDE */ + {0, 1, 1, 0, 0}, /* 22 DW_DLA_LOC_BLOCK */ + {0, 1, 1, 0, 0}, /* 23 DW_DLA_FRAME_BLOCK */ + {14, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0}, /* 24 DW_DLA_FUNC + UNUSED */ + {15, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0}, /* 25 + DW_DLA_TYPENAME + UNUSED */ + {16, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0}, /* 26 DW_DLA_VAR + UNUSED */ + {17, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0}, /* 27 DW_DLA_WEAK + UNUSED */ + {0, 1, 1, 0, 0}, /* 28 DW_DLA_ADDR */ + {0, 1,1,0,0 }, /* 29 DW_DLA_RANGES */ + + /* The following DW_DLA data types + are known only inside libdwarf. */ + + {18, sizeof(struct Dwarf_Abbrev_List_s), BIG_ALLOC, 0, 0}, + /* 30 DW_DLA_ABBREV_LIST */ + + {19, sizeof(struct Dwarf_Chain_s), BIG_ALLOC, 0, 0}, /* 31 DW_DLA_CHAIN */ + {20, sizeof(struct Dwarf_CU_Context_s), BASE_ALLOC, 0, 0}, + /* 32 DW_DLA_CU_CONTEXT */ + {21, sizeof(struct Dwarf_Frame_s), BASE_ALLOC, + _dwarf_frame_constructor, + _dwarf_frame_destructor}, /* 33 DW_DLA_FRAME */ + {22, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0}, + /* 34 DW_DLA_GLOBAL_CONTEXT */ + {23, sizeof(struct Dwarf_File_Entry_s), BASE_ALLOC, 0, 0}, /* 34 */ + /* 35 DW_DLA_FILE_ENTRY */ + {24, sizeof(struct Dwarf_Line_Context_s), BASE_ALLOC, 0, 0}, + /* 36 DW_DLA_LINE_CONTEXT */ + {25, sizeof(struct Dwarf_Loc_Chain_s), BASE_ALLOC, 0, 0}, /* 36 */ + /* 37 DW_DLA_LOC_CHAIN */ + + {26, sizeof(struct Dwarf_Hash_Table_s),BASE_ALLOC, 0, 0}, /* 37 */ + /* 38 DW_DLA_HASH_TABLE */ /* The following really use Global struct: used to be unique struct per type, but now merged (11/99). The opaque types - are visible in the interface. The types are left in existence, - with unchanged numbers. + are visible in the interface. The types for + DW_DLA_FUNC, + DW_DLA_TYPENAME, DW_DLA_VAR, DW_DLA_WEAK also use + the global types. + */ - {27, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC}, - /* 38 DW_DLA_FUNC_CONTEXT */ - {28, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC}, - /* 39 DW_DLA_TYPENAME_CONTEXT */ - {29, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC}, - /* 40 DW_DLA_VAR_CONTEXT */ - {30, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC}, - /* 41 DW_DLA_WEAK_CONTEXT */ + {27, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0}, + /* 39 DW_DLA_FUNC_CONTEXT */ + {28, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0}, + /* 40 DW_DLA_TYPENAME_CONTEXT */ + {29, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0}, + /* 41 DW_DLA_VAR_CONTEXT */ + {30, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0}, + /* 42 DW_DLA_WEAK_CONTEXT */ + {31, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0}, + /* 43 DW_DLA_PUBTYPES_CONTEXT DWARF3 */ + + {0,1,1,0,0 }, + /* 44 DW_DLA_HASH_TABLE_ENTRY */ + + }; #ifndef DWARF_SIMPLE_MALLOC @@ -285,126 +319,126 @@ _dwarf_find_memory(Dwarf_Alloc_Hdr alloc_hdr) /* Check the alloc_area from which the last allocation was made - (most recent new block). If that is not successful, then - search the list of alloc_area's from alloc_header. */ + (most recent new block). If that is not successful, then search + the list of alloc_area's from alloc_header. */ alloc_area = alloc_hdr->ah_last_alloc_area; if (alloc_area == NULL || alloc_area->aa_free_structs_in_chunk == 0) - for (alloc_area = alloc_hdr->ah_alloc_area_head; - alloc_area != NULL; alloc_area = alloc_area->aa_next) { + for (alloc_area = alloc_hdr->ah_alloc_area_head; + alloc_area != NULL; alloc_area = alloc_area->aa_next) { - if (alloc_area->aa_free_structs_in_chunk > 0) { - break; /* found a free entry! */ - } + if (alloc_area->aa_free_structs_in_chunk > 0) { + break; /* found a free entry! */ + } - } + } if (alloc_area != NULL) { - alloc_area->aa_free_structs_in_chunk--; - - if (alloc_area->aa_free_list != NULL) { - ret_mem = alloc_area->aa_free_list; - - /* - Update the free list. The initial part of the struct is - used to hold a pointer to the next struct on the free - list. In this way, the free list chain is maintained at - 0 memory cost. */ - alloc_area->aa_free_list = - ((Dwarf_Free_List) ret_mem)->fl_next; - } else if (alloc_area->aa_blob_start < alloc_area->aa_blob_end) { - ret_mem = alloc_area->aa_blob_start; - - /* - Store pointer to chunk this struct belongs to in the - first few bytes. Return pointer to bytes after this - pointer storage. */ - *(Dwarf_Alloc_Area *) ret_mem = alloc_area; - ret_mem += _DW_RESERVE; - - alloc_area->aa_blob_start += alloc_hdr->ah_bytes_one_struct; - } else { - /* else fall thru , though it should be impossible to fall - thru. And represents a disastrous programming error if - we get here. */ + alloc_area->aa_free_structs_in_chunk--; + + if (alloc_area->aa_free_list != NULL) { + ret_mem = alloc_area->aa_free_list; + + /* + Update the free list. The initial part of the struct is + used to hold a pointer to the next struct on the free + list. In this way, the free list chain is maintained at + 0 memory cost. */ + alloc_area->aa_free_list = + ((Dwarf_Free_List) ret_mem)->fl_next; + } else if (alloc_area->aa_blob_start < alloc_area->aa_blob_end) { + ret_mem = alloc_area->aa_blob_start; + + /* + Store pointer to chunk this struct belongs to in the + first few bytes. Return pointer to bytes after this + pointer storage. */ + *(Dwarf_Alloc_Area *) ret_mem = alloc_area; + ret_mem += DW_RESERVE; + + alloc_area->aa_blob_start += alloc_hdr->ah_bytes_one_struct; + } else { + /* else fall thru , though it should be impossible to fall + thru. And represents a disastrous programming error if + we get here. */ #ifdef DEBUG - fprintf(stderr, "libdwarf Internal error start %x end %x\n", - (int) alloc_area->aa_blob_start, - (int) alloc_area->aa_blob_end); + fprintf(stderr, "libdwarf Internal error start %x end %x\n", + (int) alloc_area->aa_blob_start, + (int) alloc_area->aa_blob_end); #endif - } + } } /* New memory has to malloc'ed since there are no free structs. */ if (ret_mem == 0) { - Dwarf_Word rounded_area_hdr_size; - - alloc_hdr->ah_chunks_allocated++; - - { /* this nonsense avoids a warning */ - /* CONSTCOND would be better */ - unsigned long v = sizeof(struct Dwarf_Alloc_Area_s); - - rounded_area_hdr_size = ROUND_SIZE(v); - } - - /* - Allocate memory to contain the required number of structs - and the Dwarf_Alloc_Area_s to control it. */ - mem_block_size = alloc_hdr->ah_bytes_malloc_per_chunk + - rounded_area_hdr_size; - - mem_block = malloc(mem_block_size); - if (mem_block == NULL) { - return (NULL); - } - - - /* - Attach the Dwarf_Alloc_Area_s struct to the list of chunks - malloc'ed for this struct type. Also initialize the fields - of the Dwarf_Alloc_Area_s. */ - alloc_area = (Dwarf_Alloc_Area) mem_block; - alloc_area->aa_prev = 0; - if (alloc_hdr->ah_alloc_area_head != NULL) { - alloc_hdr->ah_alloc_area_head->aa_prev = alloc_area; - } - alloc_area->aa_free_list = 0; - alloc_area->aa_next = alloc_hdr->ah_alloc_area_head; - alloc_hdr->ah_alloc_area_head = alloc_area; - - alloc_area->aa_alloc_hdr = alloc_hdr; - alloc_area->aa_free_structs_in_chunk = - (Dwarf_Sword) alloc_hdr->ah_structs_per_chunk - 1; - if (alloc_area->aa_free_structs_in_chunk < 1) { - /* If we get here, there is a disastrous programming error - somewhere. */ + Dwarf_Word rounded_area_hdr_size; + + alloc_hdr->ah_chunks_allocated++; + + { /* this nonsense avoids a warning */ + /* CONSTCOND would be better */ + unsigned long v = sizeof(struct Dwarf_Alloc_Area_s); + + rounded_area_hdr_size = ROUND_SIZE(v); + } + + /* + Allocate memory to contain the required number of structs + and the Dwarf_Alloc_Area_s to control it. */ + mem_block_size = alloc_hdr->ah_bytes_malloc_per_chunk + + rounded_area_hdr_size; + + mem_block = malloc(mem_block_size); + if (mem_block == NULL) { + return (NULL); + } + + + /* + Attach the Dwarf_Alloc_Area_s struct to the list of chunks + malloc'ed for this struct type. Also initialize the fields + of the Dwarf_Alloc_Area_s. */ + alloc_area = (Dwarf_Alloc_Area) mem_block; + alloc_area->aa_prev = 0; + if (alloc_hdr->ah_alloc_area_head != NULL) { + alloc_hdr->ah_alloc_area_head->aa_prev = alloc_area; + } + alloc_area->aa_free_list = 0; + alloc_area->aa_next = alloc_hdr->ah_alloc_area_head; + alloc_hdr->ah_alloc_area_head = alloc_area; + + alloc_area->aa_alloc_hdr = alloc_hdr; + alloc_area->aa_free_structs_in_chunk = + (Dwarf_Sword) alloc_hdr->ah_structs_per_chunk - 1; + if (alloc_area->aa_free_structs_in_chunk < 1) { + /* If we get here, there is a disastrous programming error + somewhere. */ #ifdef DEBUG - fprintf(stderr, - "libdwarf Internal error: free structs in chunk %d\n", - (int) alloc_area->aa_free_structs_in_chunk); + fprintf(stderr, + "libdwarf Internal error: free structs in chunk %d\n", + (int) alloc_area->aa_free_structs_in_chunk); #endif - return NULL; - } - - /* - The struct returned begins immediately after the - Dwarf_Alloc_Area_s struct. */ - ret_mem = mem_block + rounded_area_hdr_size; - alloc_area->aa_blob_start = - ret_mem + alloc_hdr->ah_bytes_one_struct; - alloc_area->aa_blob_end = mem_block + mem_block_size; - - /* - Store pointer to chunk this struct belongs to in the first - few bytes. Return pointer to bytes after this pointer - storage. */ - *(Dwarf_Alloc_Area *) ret_mem = alloc_area; - ret_mem += _DW_RESERVE; + return NULL; + } + + /* + The struct returned begins immediately after the + Dwarf_Alloc_Area_s struct. */ + ret_mem = mem_block + rounded_area_hdr_size; + alloc_area->aa_blob_start = + ret_mem + alloc_hdr->ah_bytes_one_struct; + alloc_area->aa_blob_end = mem_block + mem_block_size; + + /* + Store pointer to chunk this struct belongs to in the first + few bytes. Return pointer to bytes after this pointer + storage. */ + *(Dwarf_Alloc_Area *) ret_mem = alloc_area; + ret_mem += DW_RESERVE; } alloc_hdr->ah_last_alloc_area = alloc_area; alloc_hdr->ah_struct_user_holds++; - memset(ret_mem,0, alloc_hdr->ah_bytes_one_struct - _DW_RESERVE); + memset(ret_mem, 0, alloc_hdr->ah_bytes_one_struct - DW_RESERVE); return (ret_mem); } @@ -420,16 +454,17 @@ _dwarf_find_memory(Dwarf_Alloc_Hdr alloc_hdr) contain, i.e it the length of the string plus 1 for the terminating null. For lists of pointers, count is equal to the number of - pointers. For DW_DLA_FRAME_BLOCK, and + pointers. For DW_DLA_FRAME_BLOCK, DW_DLA_RANGES, and DW_DLA_LOC_BLOCK allocation types also, count is the count of the number of structs needed. This function cannot be used to allocate a Dwarf_Debug_s struct. + */ Dwarf_Ptr _dwarf_get_alloc(Dwarf_Debug dbg, - Dwarf_Small alloc_type, Dwarf_Unsigned count) + Dwarf_Small alloc_type, Dwarf_Unsigned count) { Dwarf_Alloc_Hdr alloc_hdr; @@ -440,12 +475,12 @@ _dwarf_get_alloc(Dwarf_Debug dbg, unsigned int type = alloc_type; if (dbg == NULL) { - return (NULL); + return (NULL); } if (type >= ALLOC_AREA_INDEX_TABLE_MAX) { - /* internal error */ - return NULL; + /* internal error */ + return NULL; } index = index_into_allocated[type].ia_al_num; /* zero also illegal but not tested for */ @@ -456,71 +491,109 @@ _dwarf_get_alloc(Dwarf_Debug dbg, special code here.. */ if (index == 0) { - if (alloc_type == DW_DLA_STRING) { - size = count; - } else if (alloc_type == DW_DLA_LIST) { - size = count * sizeof(Dwarf_Ptr); - } else if (alloc_type == DW_DLA_FRAME_BLOCK) { - size = count * sizeof(Dwarf_Frame_Op); - } else if (alloc_type == DW_DLA_LOC_BLOCK) { - size = count * sizeof(Dwarf_Loc); - } else if (alloc_type == DW_DLA_ADDR) { - size = count * - (sizeof(Dwarf_Addr) > sizeof(Dwarf_Off) ? - sizeof(Dwarf_Addr) : sizeof(Dwarf_Off)); - } else if (alloc_type == DW_DLA_ERROR) { - return _dwarf_special_no_dbg_error_malloc(); - } else { - /* If we get here, there is a disastrous programming error - somewhere. */ + if (alloc_type == DW_DLA_STRING) { + size = count; + } else if (alloc_type == DW_DLA_LIST) { + size = count * sizeof(Dwarf_Ptr); + } else if (alloc_type == DW_DLA_FRAME_BLOCK) { + size = count * sizeof(Dwarf_Frame_Op); + } else if (alloc_type == DW_DLA_LOC_BLOCK) { + size = count * sizeof(Dwarf_Loc); + } else if (alloc_type == DW_DLA_HASH_TABLE_ENTRY) { + size = count * sizeof(struct Dwarf_Hash_Table_Entry_s); + } else if (alloc_type == DW_DLA_ADDR) { + size = count * + (sizeof(Dwarf_Addr) > sizeof(Dwarf_Off) ? + sizeof(Dwarf_Addr) : sizeof(Dwarf_Off)); + } else if (alloc_type == DW_DLA_RANGES) { + size = count * sizeof(Dwarf_Ranges); + } else if (alloc_type == DW_DLA_ERROR) { + void *m = _dwarf_special_no_dbg_error_malloc(); + + dwarf_malloc_check_alloc_data(m, DW_DLA_ERROR); + return m; + + } else { + /* If we get here, there is a disastrous programming error + somewhere. */ #ifdef DEBUG - fprintf(stderr, - "libdwarf Internal error: type %d unexpected\n", - (int) type); + fprintf(stderr, + "libdwarf Internal error: type %d unexpected\n", + (int) type); #endif - } + } } else { - alloc_hdr = &dbg->de_alloc_hdr[index]; - if (alloc_hdr->ah_bytes_one_struct > 0) { + alloc_hdr = &dbg->de_alloc_hdr[index]; + if (alloc_hdr->ah_bytes_one_struct > 0) { #ifdef DWARF_SIMPLE_MALLOC - size = alloc_hdr->ah_bytes_one_struct; + size = alloc_hdr->ah_bytes_one_struct; #else - return (_dwarf_find_memory(alloc_hdr)); + { + void *m = _dwarf_find_memory(alloc_hdr); + + dwarf_malloc_check_alloc_data(m, type); + if (index_into_allocated[type].specialconstructor) { + int res = + index_into_allocated[type]. + specialconstructor(dbg, m); + if (res != DW_DLV_OK) { + /* We leak what we allocated in + _dwarf_find_memory when constructor fails. */ + return NULL; + } + } + return m; + } #endif - } else { - /* Special case: should not really happen at all. */ - if (type == DW_DLA_ERROR) { - /* dwarf_init failure. Because dbg is incomplete we - won't use it to record the malloc. */ - return _dwarf_special_no_dbg_error_malloc(); - } else { - /* If we get here, there is a disastrous programming - error somewhere. */ + } else { + /* Special case: should not really happen at all. */ + if (type == DW_DLA_ERROR) { + /* dwarf_init failure. Because dbg is incomplete we + won't use it to record the malloc. */ + void *m = _dwarf_special_no_dbg_error_malloc(); + + dwarf_malloc_check_alloc_data(m, DW_DLA_ERROR); + return m; + } else { + /* If we get here, there is a disastrous programming + error somewhere. */ #ifdef DWARF_SIMPLE_MALLOC - _dwarf_simple_malloc_botch(3); + _dwarf_simple_malloc_botch(3); #endif #ifdef DEBUG - fprintf(stderr, - "libdwarf Internal error: Type %d unexpected\n", - (int) type); + fprintf(stderr, + "libdwarf Internal error: Type %d unexpected\n", + (int) type); #endif - } - } + } + } } ret_mem = malloc(size); #ifdef DWARF_SIMPLE_MALLOC - _dwarf_simple_malloc_add_to_list(dbg,ret_mem,(unsigned long)size, - alloc_type); + _dwarf_simple_malloc_add_to_list(dbg, ret_mem, (unsigned long) size, + type); #endif if (ret_mem != NULL) - memset(ret_mem,0, size); + memset(ret_mem, 0, size); + + dwarf_malloc_check_alloc_data(ret_mem, type); + if (index_into_allocated[type].specialconstructor) { + int res = + index_into_allocated[type].specialconstructor(dbg, ret_mem); + if (res != DW_DLV_OK) { + /* We leak what we allocated in _dwarf_find_memory when + constructor fails. */ + return NULL; + } + } return (ret_mem); } + /* This function is used to deallocate a region of memory that was obtained by a call to _dwarf_get_alloc. Note @@ -531,7 +604,7 @@ _dwarf_get_alloc(Dwarf_Debug dbg, that the space was allocated by a direct call to malloc, and so a straight free() is done. This is also the case for variable length blocks such as DW_DLA_FRAME_BLOCK - and DW_DLA_LOC_BLOCK. + and DW_DLA_LOC_BLOCK and DW_DLA_RANGES. For strings, the pointer might point to a string in .debug_info or .debug_string. After this is checked, @@ -551,7 +624,7 @@ _dwarf_get_alloc(Dwarf_Debug dbg, */ void dwarf_dealloc(Dwarf_Debug dbg, - Dwarf_Ptr space, Dwarf_Unsigned alloc_type) + Dwarf_Ptr space, Dwarf_Unsigned alloc_type) { Dwarf_Alloc_Hdr alloc_hdr; Dwarf_Alloc_Area alloc_area; @@ -559,145 +632,167 @@ dwarf_dealloc(Dwarf_Debug dbg, unsigned int index; if (space == NULL) { - return; + return; } - if (alloc_type == DW_DLA_ERROR) { - /* Get pointer to Dwarf_Alloc_Area this struct came from. See - dwarf_alloc.h ROUND_SIZE_WITH_POINTER stuff */ - alloc_area = - *(Dwarf_Alloc_Area *) ((char *) space - _DW_RESERVE); - if (alloc_area == 0) { - /* This is the special case of a failed dwarf_init(). Also - (and more signficantly) there are a variety of other - situations where libdwarf does not *know* what dbg is - involved (because of a libdwarf-caller-error) so - libdwarf uses NULL as the dbg. Those too wind up here. */ - _dwarf_free_special_error(space); - return; - } + if (type == DW_DLA_ERROR) { + /* Get pointer to Dwarf_Alloc_Area this struct came from. See + dwarf_alloc.h ROUND_SIZE_WITH_POINTER stuff */ + alloc_area = + *(Dwarf_Alloc_Area *) ((char *) space - DW_RESERVE); + if (alloc_area == 0) { + /* This is the special case of a failed dwarf_init(). Also + (and more signficantly) there are a variety of other + situations where libdwarf does not *know* what dbg is + involved (because of a libdwarf-caller-error) so + libdwarf uses NULL as the dbg. Those too wind up here. */ + _dwarf_free_special_error(space); + dwarf_malloc_check_dealloc_data(space, type); + return; + } } if (dbg == NULL) { - /* App error, or an app that failed to succeed in a - dwarf_init() call. */ - return; + /* App error, or an app that failed to succeed in a + dwarf_init() call. */ + return; } if (type >= ALLOC_AREA_INDEX_TABLE_MAX) { - /* internal or user app error */ - return; + /* internal or user app error */ + return; } - index = index_into_allocated[alloc_type].ia_al_num; + index = index_into_allocated[type].ia_al_num; /* A string pointer may point into .debug_info or .debug_string. Otherwise, they are directly malloc'ed. */ + dwarf_malloc_check_dealloc_data(space, type); if (index == 0) { - if (alloc_type == DW_DLA_STRING) { - if ((Dwarf_Small *) space >= dbg->de_debug_info && - (Dwarf_Small *) space < - dbg->de_debug_info + dbg->de_debug_info_size) - return; - - if (dbg->de_debug_line != NULL && - (Dwarf_Small *) space >= dbg->de_debug_line && - (Dwarf_Small *) space < - dbg->de_debug_line + dbg->de_debug_line_size) - return; - - if (dbg->de_debug_pubnames != NULL && - (Dwarf_Small *) space >= dbg->de_debug_pubnames && - (Dwarf_Small *) space < - dbg->de_debug_pubnames + dbg->de_debug_pubnames_size) - return; - - if (dbg->de_debug_frame != NULL && - (Dwarf_Small *) space >= dbg->de_debug_frame && - (Dwarf_Small *) space < - dbg->de_debug_frame + dbg->de_debug_frame_size) - return; - - if (dbg->de_debug_str != NULL && - (Dwarf_Small *) space >= dbg->de_debug_str && - (Dwarf_Small *) space < - dbg->de_debug_str + dbg->de_debug_str_size) - return; - - if (dbg->de_debug_funcnames != NULL && - (Dwarf_Small *) space >= dbg->de_debug_funcnames && - (Dwarf_Small *) space < - dbg->de_debug_funcnames + dbg->de_debug_funcnames_size) - return; - - if (dbg->de_debug_typenames != NULL && - (Dwarf_Small *) space >= dbg->de_debug_typenames && - (Dwarf_Small *) space < - dbg->de_debug_typenames + dbg->de_debug_typenames_size) - return; - - if (dbg->de_debug_varnames != NULL && - (Dwarf_Small *) space >= dbg->de_debug_varnames && - (Dwarf_Small *) space < - dbg->de_debug_varnames + dbg->de_debug_varnames_size) - return; - - if (dbg->de_debug_weaknames != NULL && - (Dwarf_Small *) space >= dbg->de_debug_weaknames && - (Dwarf_Small *) space < - dbg->de_debug_weaknames + dbg->de_debug_weaknames_size) - return; - - free(space); - return; - } - - if (alloc_type == DW_DLA_LIST || - alloc_type == DW_DLA_FRAME_BLOCK || - alloc_type == DW_DLA_LOC_BLOCK || - alloc_type == DW_DLA_ADDR) { - - free(space); - return; - } - /* else is an alloc type that is not used */ - /* app or internal error */ + if (type == DW_DLA_STRING) { + if ((Dwarf_Small *) space >= dbg->de_debug_info.dss_data && + (Dwarf_Small *) space < + dbg->de_debug_info.dss_data + dbg->de_debug_info.dss_size) + return; + + if (dbg->de_debug_line.dss_data != NULL && + (Dwarf_Small *) space >= dbg->de_debug_line.dss_data && + (Dwarf_Small *) space < + dbg->de_debug_line.dss_data + dbg->de_debug_line.dss_size) + return; + + if (dbg->de_debug_pubnames.dss_data != NULL && + (Dwarf_Small *) space >= dbg->de_debug_pubnames.dss_data && + (Dwarf_Small *) space < + dbg->de_debug_pubnames.dss_data + + dbg->de_debug_pubnames.dss_size) + return; + + if (dbg->de_debug_frame.dss_data != NULL && + (Dwarf_Small *) space >= dbg->de_debug_frame.dss_data && + (Dwarf_Small *) space < + dbg->de_debug_frame.dss_data + dbg->de_debug_frame.dss_size) + return; + + if (dbg->de_debug_str.dss_data != NULL && + (Dwarf_Small *) space >= dbg->de_debug_str.dss_data && + (Dwarf_Small *) space < + dbg->de_debug_str.dss_data + dbg->de_debug_str.dss_size) + return; + + if (dbg->de_debug_funcnames.dss_data != NULL && + (Dwarf_Small *) space >= dbg->de_debug_funcnames.dss_data && + (Dwarf_Small *) space < + dbg->de_debug_funcnames.dss_data + + dbg->de_debug_funcnames.dss_size) + return; + + if (dbg->de_debug_typenames.dss_data != NULL && + (Dwarf_Small *) space >= dbg->de_debug_typenames.dss_data && + (Dwarf_Small *) space < + dbg->de_debug_typenames.dss_data + + dbg->de_debug_typenames.dss_size) + return; + if (dbg->de_debug_pubtypes.dss_data != NULL && + (Dwarf_Small *) space >= dbg->de_debug_pubtypes.dss_data && + (Dwarf_Small *) space < + dbg->de_debug_pubtypes.dss_data + + dbg->de_debug_pubtypes.dss_size) + return; + + if (dbg->de_debug_varnames.dss_data != NULL && + (Dwarf_Small *) space >= dbg->de_debug_varnames.dss_data && + (Dwarf_Small *) space < + dbg->de_debug_varnames.dss_data + + dbg->de_debug_varnames.dss_size) + return; + + if (dbg->de_debug_weaknames.dss_data != NULL && + (Dwarf_Small *) space >= dbg->de_debug_weaknames.dss_data && + (Dwarf_Small *) space < + dbg->de_debug_weaknames.dss_data + + dbg->de_debug_weaknames.dss_size) + return; + +#ifdef DWARF_SIMPLE_MALLOC + _dwarf_simple_malloc_delete_from_list(dbg, space, type); +#endif + free(space); + return; + } + + if (type == DW_DLA_LIST || + type == DW_DLA_FRAME_BLOCK || + type == DW_DLA_LOC_BLOCK || type == DW_DLA_ADDR || + type == DW_DLA_RANGES || + type == DW_DLA_HASH_TABLE_ENTRY) { + +#ifdef DWARF_SIMPLE_MALLOC + _dwarf_simple_malloc_delete_from_list(dbg, space, type); +#endif + free(space); + return; + } + /* else is an alloc type that is not used */ + /* app or internal error */ #ifdef DWARF_SIMPLE_MALLOC _dwarf_simple_malloc_botch(4); #endif - return; + return; } - + if (index_into_allocated[type].specialdestructor) { + index_into_allocated[type].specialdestructor(space); + } #ifdef DWARF_SIMPLE_MALLOC - _dwarf_simple_malloc_delete_from_list(dbg, space, alloc_type); + _dwarf_simple_malloc_delete_from_list(dbg, space, type); free(space); -#else /* !DWARF_SIMPLE_MALLOC */ +#else /* !DWARF_SIMPLE_MALLOC */ alloc_hdr = &dbg->de_alloc_hdr[index]; /* Get pointer to Dwarf_Alloc_Area this struct came from. See dwarf_alloc.h ROUND_SIZE_WITH_POINTER stuff */ - alloc_area = *(Dwarf_Alloc_Area *) ((char *) space - _DW_RESERVE); + alloc_area = *(Dwarf_Alloc_Area *) ((char *) space - DW_RESERVE); - /* ASSERT: alloc_area != NULL - If NULL we could abort, let it coredump below, - or return, pretending all is well. We go - on, letting program crash. Is caller error. */ + /* ASSERT: alloc_area != NULL If NULL we could abort, let it + coredump below, or return, pretending all is well. We go on, + letting program crash. Is caller error. */ /* Check that the alloc_hdr field of the alloc_area we have is pointing to the right alloc_hdr. This is used to catch use of incorrect deallocation code by the user. */ if (alloc_area->aa_alloc_hdr != alloc_hdr) { - /* If we get here, the user has called dwarf_dealloc wrongly or - there is some other disastrous error. By leaking mem here we - try to be safe... */ + /* If we get here, the user has called dwarf_dealloc wrongly or + there is some other disastrous error. By leaking mem here we + try to be safe... */ #ifdef DEBUG - fprintf(stderr, - "libdwarf Internal error: type %d hdr mismatch %x %x area ptr %x\n", - (int) alloc_type, - (int) alloc_area->aa_alloc_hdr, - (int) alloc_hdr, (int) alloc_area); + fprintf(stderr, + "libdwarf Internal error: type %d hdr mismatch %lx %lx " + "area ptr %lx\n", + (int) type, + (long) alloc_area->aa_alloc_hdr, + (long) alloc_hdr, (long) alloc_area); #endif - return; + return; } alloc_hdr->ah_struct_user_holds--; @@ -706,29 +801,29 @@ dwarf_dealloc(Dwarf_Debug dbg, /* Give chunk back to malloc only when every struct is freed */ if (alloc_area->aa_free_structs_in_chunk == - alloc_hdr->ah_structs_per_chunk) { - if (alloc_area->aa_prev != NULL) { - alloc_area->aa_prev->aa_next = alloc_area->aa_next; - } else { - alloc_hdr->ah_alloc_area_head = alloc_area->aa_next; - } - - if (alloc_area->aa_next != NULL) { - alloc_area->aa_next->aa_prev = alloc_area->aa_prev; - } - - alloc_hdr->ah_chunks_allocated--; - - if (alloc_area == alloc_hdr->ah_last_alloc_area) { - alloc_hdr->ah_last_alloc_area = NULL; - } - memset(alloc_area,0, sizeof(*alloc_area)); - free(alloc_area); + alloc_hdr->ah_structs_per_chunk) { + if (alloc_area->aa_prev != NULL) { + alloc_area->aa_prev->aa_next = alloc_area->aa_next; + } else { + alloc_hdr->ah_alloc_area_head = alloc_area->aa_next; + } + + if (alloc_area->aa_next != NULL) { + alloc_area->aa_next->aa_prev = alloc_area->aa_prev; + } + + alloc_hdr->ah_chunks_allocated--; + + if (alloc_area == alloc_hdr->ah_last_alloc_area) { + alloc_hdr->ah_last_alloc_area = NULL; + } + memset(alloc_area, 0, sizeof(*alloc_area)); + free(alloc_area); } else { - ((Dwarf_Free_List) space)->fl_next = alloc_area->aa_free_list; - alloc_area->aa_free_list = space; + ((Dwarf_Free_List) space)->fl_next = alloc_area->aa_free_list; + alloc_area->aa_free_list = space; } #endif /* !DWARF_SIMPLE_MALLOC */ } @@ -746,10 +841,9 @@ _dwarf_get_debug(void dbg = (Dwarf_Debug) malloc(sizeof(struct Dwarf_Debug_s)); if (dbg == NULL) - return (NULL); + return (NULL); else - memset(dbg,0, sizeof(struct Dwarf_Debug_s)); - + memset(dbg, 0, sizeof(struct Dwarf_Debug_s)); return (dbg); } @@ -758,7 +852,7 @@ _dwarf_get_debug(void Sets up the Dwarf_Debug_s struct for all the allocation types currently defined. Allocation types DW_DLA_STRING, DW_DLA_LIST, - DW_DLA_FRAME_BLOCK, DW_DLA_LOC_BLOCK are + DW_DLA_FRAME_BLOCK, DW_DLA_LOC_BLOCK, DW_DLA_RANGES are malloc'ed directly. This routine should be called after _dwarf_setup(), @@ -781,13 +875,6 @@ _dwarf_get_debug(void need to be initialized. Being an internal routine, assume proper dbg. - - - - -*/ -/* -** Set up all the Dwarf_Alloc_Hdr records. */ Dwarf_Debug @@ -796,19 +883,19 @@ _dwarf_setup_debug(Dwarf_Debug dbg) int i; for (i = 1; i <= MAX_DW_DLA; i++) { - const struct ial_s *ialp = &index_into_allocated[i]; - unsigned int hdr_index = ialp->ia_al_num; - Dwarf_Word str_size = ialp->ia_struct_size; - Dwarf_Word str_count = ialp->ia_base_count; - Dwarf_Word rnded_size = ROUND_SIZE_WITH_POINTER(str_size); + const struct ial_s *ialp = &index_into_allocated[i]; + unsigned int hdr_index = ialp->ia_al_num; + Dwarf_Word str_size = ialp->ia_struct_size; + Dwarf_Word str_count = ialp->ia_base_count; + Dwarf_Word rnded_size = ROUND_SIZE_WITH_POINTER(str_size); - Dwarf_Alloc_Hdr alloc_hdr = &dbg->de_alloc_hdr[hdr_index]; + Dwarf_Alloc_Hdr alloc_hdr = &dbg->de_alloc_hdr[hdr_index]; - alloc_hdr->ah_bytes_one_struct = (Dwarf_Half) rnded_size; + alloc_hdr->ah_bytes_one_struct = (Dwarf_Half) rnded_size; - /* ah_structs_per_chunk must be >0 else we are in trouble */ - alloc_hdr->ah_structs_per_chunk = str_count; - alloc_hdr->ah_bytes_malloc_per_chunk = rnded_size * str_count; + /* ah_structs_per_chunk must be >0 else we are in trouble */ + alloc_hdr->ah_structs_per_chunk = str_count; + alloc_hdr->ah_bytes_malloc_per_chunk = rnded_size * str_count; } return (dbg); } @@ -824,86 +911,89 @@ dwarf_print_memory_stats(Dwarf_Debug dbg) Dwarf_Shalf i; /* - Alloc types start at 1, not 0. Hence, the first NULL string, - and also a size of MAX_DW_DLA + 1. */ + Alloc types start at 1, not 0. Hence, the first NULL string, and + also a size of MAX_DW_DLA + 1. */ char *alloc_type_name[MAX_DW_DLA + 1] = { - "", - "DW_DLA_STRING", - "DW_DLA_LOC", - "DW_DLA_LOCDESC", - "DW_DLA_ELLIST", - "DW_DLA_BOUNDS", - "DW_DLA_BLOCK", - "DW_DLA_DEBUG", - "DW_DLA_DIE", - "DW_DLA_LINE", - "DW_DLA_ATTR", - "DW_DLA_TYPE", - "DW_DLA_SUBSCR", - "DW_DLA_GLOBAL", - "DW_DLA_ERROR", - "DW_DLA_LIST", - "DW_DLA_LINEBUF", - "DW_DLA_ARANGE", - "DW_DLA_ABBREV", - "DW_DLA_FRAME_OP", - "DW_DLA_CIE", - "DW_DLA_FDE", - "DW_DLA_LOC_BLOCK", - "DW_DLA_FRAME_BLOCK", - "DW_DLA_FUNC", - "DW_DLA_TYPENAME", - "DW_DLA_VAR", - "DW_DLA_WEAK", - "DW_DLA_ADDR", - "DW_DLA_ABBREV_LIST", - "DW_DLA_CHAIN", - "DW_DLA_CU_CONTEXT", - "DW_DLA_FRAME", - "DW_DLA_GLOBAL_CONTEXT", - "DW_DLA_FILE_ENTRY", - "DW_DLA_LINE_CONTEXT", - "DW_DLA_LOC_CHAIN", - "DW_DLA_HASH_TABLE", - "DW_DLA_FUNC_CONTEXT", - "DW_DLA_TYPENAME_CONTEXT", - "DW_DLA_VAR_CONTEXT", - "DW_DLA_WEAK_CONTEXT" + "", + "DW_DLA_STRING", + "DW_DLA_LOC", + "DW_DLA_LOCDESC", + "DW_DLA_ELLIST", + "DW_DLA_BOUNDS", + "DW_DLA_BLOCK", + "DW_DLA_DEBUG", + "DW_DLA_DIE", + "DW_DLA_LINE", + "DW_DLA_ATTR", + "DW_DLA_TYPE", + "DW_DLA_SUBSCR", + "DW_DLA_GLOBAL", + "DW_DLA_ERROR", + "DW_DLA_LIST", + "DW_DLA_LINEBUF", + "DW_DLA_ARANGE", + "DW_DLA_ABBREV", + "DW_DLA_FRAME_OP", + "DW_DLA_CIE", + "DW_DLA_FDE", + "DW_DLA_LOC_BLOCK", + "DW_DLA_FRAME_BLOCK", + "DW_DLA_FUNC", + "DW_DLA_TYPENAME", + "DW_DLA_VAR", + "DW_DLA_WEAK", + "DW_DLA_ADDR", + "DW_DLA_RANGES", + "DW_DLA_ABBREV_LIST", + "DW_DLA_CHAIN", + "DW_DLA_CU_CONTEXT", + "DW_DLA_FRAME", + "DW_DLA_GLOBAL_CONTEXT", + "DW_DLA_FILE_ENTRY", + "DW_DLA_LINE_CONTEXT", + "DW_DLA_LOC_CHAIN", + "DW_DLA_HASH_TABLE", + "DW_DLA_FUNC_CONTEXT", + "DW_DLA_TYPENAME_CONTEXT", + "DW_DLA_VAR_CONTEXT", + "DW_DLA_WEAK_CONTEXT", + "DW_DLA_PUBTYPES_CONTEXT", + "DW_DLA_HASH_TABLE_ENTRY", }; if (dbg == NULL) - return; + return; printf("Size of Dwarf_Debug %4ld bytes\n", - (long) sizeof(*dbg)); + (long) sizeof(*dbg)); printf("Size of Dwarf_Alloc_Hdr_s %4ld bytes\n", - (long) sizeof(struct Dwarf_Alloc_Hdr_s)); + (long) sizeof(struct Dwarf_Alloc_Hdr_s)); printf("size of Dwarf_Alloc_Area_s %4ld bytes\n", - (long) sizeof(struct Dwarf_Alloc_Area_s)); + (long) sizeof(struct Dwarf_Alloc_Area_s)); printf(" Alloc Type Curr Structs byt str\n"); printf(" ---------- ---- ------- per per\n"); for (i = 1; i <= MAX_DW_DLA; i++) { - int indx = index_into_allocated[i].ia_al_num; - - alloc_hdr = &dbg->de_alloc_hdr[indx]; - if (alloc_hdr->ah_bytes_one_struct != 1) { - printf("%2d %-25s %6d %8d %6d %6d\n", - (int) i, - alloc_type_name[i], - (int) alloc_hdr->ah_chunks_allocated, - (int) alloc_hdr->ah_struct_user_holds, - (int) alloc_hdr->ah_bytes_malloc_per_chunk, - (int) alloc_hdr->ah_structs_per_chunk); - } + int indx = index_into_allocated[i].ia_al_num; + + alloc_hdr = &dbg->de_alloc_hdr[indx]; + if (alloc_hdr->ah_bytes_one_struct != 1) { + printf("%2d %-25s %6d %8d %6d %6d\n", + (int) i, + alloc_type_name[i], + (int) alloc_hdr->ah_chunks_allocated, + (int) alloc_hdr->ah_struct_user_holds, + (int) alloc_hdr->ah_bytes_malloc_per_chunk, + (int) alloc_hdr->ah_structs_per_chunk); + } } } #ifndef DWARF_SIMPLE_MALLOC /* - This function is used to recursively - free the chunks still allocated, and + This recursively frees + the chunks still allocated, and forward chained through the aa_next pointer. */ @@ -911,7 +1001,7 @@ static void _dwarf_recursive_free(Dwarf_Alloc_Area alloc_area) { if (alloc_area->aa_next != NULL) { - _dwarf_recursive_free(alloc_area->aa_next); + _dwarf_recursive_free(alloc_area->aa_next); } alloc_area->aa_next = 0; @@ -920,6 +1010,18 @@ _dwarf_recursive_free(Dwarf_Alloc_Area alloc_area) } #endif +/* In the 'rela' relocation case we might have malloc'd + space to ensure it is read-write. In that case, free the space. */ +static void +rela_free(struct Dwarf_Section_s * sec) +{ + if (sec->dss_data_was_malloc) { + free(sec->dss_data); + } + sec->dss_data = 0; + sec->dss_data_was_malloc = 0; +} + /* Used to free all space allocated for this Dwarf_Debug. The caller should assume that the Dwarf_Debug pointer @@ -932,46 +1034,80 @@ _dwarf_free_all_of_one_debug(Dwarf_Debug dbg) { Dwarf_Alloc_Hdr alloc_hdr; Dwarf_Shalf i; + Dwarf_CU_Context context = 0; + Dwarf_CU_Context nextcontext = 0; if (dbg == NULL) - return (DW_DLV_ERROR); + return (DW_DLV_ERROR); + + /* To do complete validation that we have no surprising missing or + erroneous deallocs it is advisable to do the dwarf_deallocs here + that are not things the user can otherwise request. + Housecleaning. */ + + for (context = dbg->de_cu_context_list; + context; context = nextcontext) { + Dwarf_Hash_Table hash_table = context->cc_abbrev_hash_table; + _dwarf_free_abbrev_hash_table_contents(dbg,hash_table); + nextcontext = context->cc_next; + dwarf_dealloc(dbg, hash_table, DW_DLA_HASH_TABLE); + dwarf_dealloc(dbg, context, DW_DLA_CU_CONTEXT); + } + /* Housecleaning done. Now really free all the space. */ #ifdef DWARF_SIMPLE_MALLOC - if(dbg->de_simple_malloc_base) { - struct simple_malloc_record_s *smp = dbg->de_simple_malloc_base; - while( smp) - { - int i; - struct simple_malloc_record_s *prev_smp = 0; - - for(i = 0; i < smp->sr_used; ++i) { - struct simple_malloc_entry_s *cur; - cur = &smp->sr_entry[i]; - if(cur->se_addr != 0) { - free(cur->se_addr); - cur->se_addr = 0; - } - } - prev_smp = smp; - smp = smp->sr_next; - free(prev_smp); - } - dbg->de_simple_malloc_base = 0; - dbg->de_simple_malloc_current = 0; + if (dbg->de_simple_malloc_base) { + struct simple_malloc_record_s *smp = dbg->de_simple_malloc_base; + + while (smp) { + int i; + struct simple_malloc_record_s *prev_smp = 0; + + for (i = 0; i < smp->sr_used; ++i) { + struct simple_malloc_entry_s *cur; + + cur = &smp->sr_entry[i]; + if (cur->se_addr != 0) { + free(cur->se_addr); + cur->se_addr = 0; + } + } + prev_smp = smp; + smp = smp->sr_next; + free(prev_smp); + } + dbg->de_simple_malloc_base = 0; } #else for (i = 1; i < ALLOC_AREA_REAL_TABLE_MAX; i++) { - int indx = i; + int indx = i; - alloc_hdr = &dbg->de_alloc_hdr[indx]; - if (alloc_hdr->ah_alloc_area_head != NULL) { - _dwarf_recursive_free(alloc_hdr->ah_alloc_area_head); - } + alloc_hdr = &dbg->de_alloc_hdr[indx]; + if (alloc_hdr->ah_alloc_area_head != NULL) { + _dwarf_recursive_free(alloc_hdr->ah_alloc_area_head); + } } #endif - - memset(dbg,0, sizeof(*dbg)); /* prevent accidental use later */ + rela_free(&dbg->de_debug_info); + rela_free(&dbg->de_debug_abbrev); + rela_free(&dbg->de_debug_line); + rela_free(&dbg->de_debug_loc); + rela_free(&dbg->de_debug_aranges); + rela_free(&dbg->de_debug_macinfo); + rela_free(&dbg->de_debug_pubnames); + rela_free(&dbg->de_debug_str); + rela_free(&dbg->de_debug_frame); + rela_free(&dbg->de_debug_frame_eh_gnu); + rela_free(&dbg->de_debug_pubtypes); + rela_free(&dbg->de_debug_funcnames); + rela_free(&dbg->de_debug_typenames); + rela_free(&dbg->de_debug_varnames); + rela_free(&dbg->de_debug_weaknames); + rela_free(&dbg->de_debug_ranges); + dwarf_harmless_cleanout(&dbg->de_harmless_errors); + + memset(dbg, 0, sizeof(*dbg)); /* Prevent accidental use later. */ free(dbg); return (DW_DLV_OK); } @@ -989,21 +1125,21 @@ _dwarf_special_no_dbg_error_malloc(void) { /* the union unused things are to guarantee proper alignment */ union u { - Dwarf_Alloc_Area ptr_not_used; - struct Dwarf_Error_s base_not_used; - char data_space[sizeof(struct Dwarf_Error_s) + - (_DW_RESERVE * 2)]; + Dwarf_Alloc_Area ptr_not_used; + struct Dwarf_Error_s base_not_used; + char data_space[sizeof(struct Dwarf_Error_s) + + (DW_RESERVE * 2)]; }; char *mem; mem = malloc(sizeof(union u)); if (mem == 0) { - return 0; + return 0; } - memset(mem,0, sizeof(union u)); - mem += _DW_RESERVE; + memset(mem, 0, sizeof(union u)); + mem += DW_RESERVE; return (struct Dwarf_Error_s *) mem; } @@ -1014,7 +1150,7 @@ _dwarf_free_special_error(Dwarf_Ptr space) { char *mem = (char *) space; - mem -= _DW_RESERVE; + mem -= DW_RESERVE; free(mem); } @@ -1025,56 +1161,57 @@ _dwarf_free_special_error(Dwarf_Ptr space) void _dwarf_simple_malloc_botch(int err) { + fprintf(stderr,"simple malloc botch %d\n",err); } -static void +static void _dwarf_simple_malloc_add_to_list(Dwarf_Debug dbg, - Dwarf_Ptr addr, - unsigned long size, - short alloc_type) + Dwarf_Ptr addr, + unsigned long size, short alloc_type) { - struct simple_malloc_record_s *cur; - struct simple_malloc_entry_s *newentry; - if (!dbg->de_simple_malloc_current) { - /* First entry to this routine. */ - dbg->de_simple_malloc_current = - malloc(sizeof(struct simple_malloc_record_s)); - if(!dbg->de_simple_malloc_current) { - return; /* no memory, give up */ - } - memset(dbg->de_simple_malloc_current, - 0, - sizeof(struct simple_malloc_record_s)); - dbg->de_simple_malloc_base = dbg->de_simple_malloc_current; - } - cur = dbg->de_simple_malloc_current; - - if(cur->sr_used >= DSM_BLOCK_COUNT) { - /* better not be > than as that means chaos */ - - /* Create a new block to link at the head. */ - - struct simple_malloc_record_s *newblock = - malloc(sizeof(struct simple_malloc_record_s)); - if(!newblock) { - return; /* Can do nothing, out of memory */ - } - memset(newblock,0, sizeof(struct simple_malloc_record_s)); - /* Link the new block at the head of the chain, - and make it 'current' - */ - dbg->de_simple_malloc_current = newblock; - newblock->sr_next = cur; - cur = newblock; - } - newentry = &cur->sr_entry[cur->sr_used]; - newentry->se_addr = addr; - newentry->se_size = size; - newentry->se_type = alloc_type; - ++cur->sr_used; + struct simple_malloc_record_s *cur; + struct simple_malloc_entry_s *newentry; + + if (!dbg->de_simple_malloc_base) { + /* First entry to this routine. */ + dbg->de_simple_malloc_base = + malloc(sizeof(struct simple_malloc_record_s)); + if (!dbg->de_simple_malloc_base) { + _dwarf_simple_malloc_botch(7); + return; /* no memory, give up */ + } + memset(dbg->de_simple_malloc_base, + 0, sizeof(struct simple_malloc_record_s)); + } + cur = dbg->de_simple_malloc_base; + + if (cur->sr_used >= DSM_BLOCK_COUNT) { + /* Better not be > than as that means chaos */ + + /* Create a new block to link at the head. */ + + struct simple_malloc_record_s *newblock = + malloc(sizeof(struct simple_malloc_record_s)); + if (!newblock) { + _dwarf_simple_malloc_botch(8); + return; /* Can do nothing, out of memory */ + } + memset(newblock, 0, sizeof(struct simple_malloc_record_s)); + /* Link the new block at the head of the chain, and make it + 'current' */ + dbg->de_simple_malloc_base = newblock; + newblock->sr_next = cur; + cur = newblock; + } + newentry = &cur->sr_entry[cur->sr_used]; + newentry->se_addr = addr; + newentry->se_size = size; + newentry->se_type = alloc_type; + ++cur->sr_used; } + /* - DWARF_SIMPLE_MALLOC is for testing the hypothesis that the existing - complex malloc scheme in libdwarf is pointless complexity. + DWARF_SIMPLE_MALLOC: testing the hypothesis that the existing + malloc scheme here (see _dwarf_get_alloc()) is pointless complexity. DWARF_SIMPLE_MALLOC also makes it easy for a malloc-tracing tool to verify libdwarf malloc has no botches (though of course @@ -1086,37 +1223,36 @@ _dwarf_simple_malloc_add_to_list(Dwarf_Debug dbg, */ static void -_dwarf_simple_malloc_delete_from_list(Dwarf_Debug dbg, - Dwarf_Ptr space, - short alloc_type) +_dwarf_simple_malloc_delete_from_list(Dwarf_Debug dbg, + Dwarf_Ptr space, short alloc_type) { - if(space == 0) { - _dwarf_simple_malloc_botch(6); + if (space == 0) { + _dwarf_simple_malloc_botch(6); } - if(dbg->de_simple_malloc_base) { + if (dbg->de_simple_malloc_base) { struct simple_malloc_record_s *smp = dbg->de_simple_malloc_base; - while( smp) - { + + while (smp) { int i; - for(i = 0; i < smp->sr_used; ++i) { + for (i = 0; i < smp->sr_used; ++i) { struct simple_malloc_entry_s *cur; + cur = &smp->sr_entry[i]; - if(cur->se_addr == space) { - if(cur->se_type != alloc_type ) { - _dwarf_simple_malloc_botch(0); - } - cur->se_addr = 0; - return; + if (cur->se_addr == space) { + if (cur->se_type != alloc_type) { + _dwarf_simple_malloc_botch(0); + } + cur->se_addr = 0; + return; } } smp = smp->sr_next; } } - /* Never found the space */ + /* Never found the space. */ _dwarf_simple_malloc_botch(1); return; } #endif - |