summaryrefslogtreecommitdiff
path: root/usr/src/tools/ctf/dwarf/common/dwarf_alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/tools/ctf/dwarf/common/dwarf_alloc.c')
-rw-r--r--usr/src/tools/ctf/dwarf/common/dwarf_alloc.c1292
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
-