#undef DEBUG
#include "config.h"
#include "dwarf_incl.h"
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include "malloc_check.h"
#include "dwarf_line.h"
#include "dwarf_global.h"
#include "dwarf_arange.h"
#include "dwarf_abbrev.h"
#include "dwarf_die_deliv.h"
#include "dwarf_frame.h"
#include "dwarf_loc.h"
#include "dwarf_funcs.h"
#include "dwarf_types.h"
#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);
void _dwarf_simple_malloc_botch(int err);
#endif
#define DW_RESERVE 8
#define ROUND_SIZE(inputsize) \
(((inputsize) % (DW_RESERVE)) == 0 ? \
(inputsize): \
((inputsize) + \
(DW_RESERVE) - ((inputsize) % (DW_RESERVE)) ))
#define ROUND_SIZE_WITH_POINTER(i_size) (ROUND_SIZE(i_size) + DW_RESERVE)
#define SMALL_ALLOC 2
#define BASE_ALLOC 64
#define BIG_ALLOC 128
struct ial_s {
int ia_al_num;
int ia_struct_size;
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, 0, 0},
{0, 1, 1, 0, 0},
{1, sizeof(Dwarf_Loc), BASE_ALLOC, 0, 0}
,
{2, sizeof(Dwarf_Locdesc), BASE_ALLOC, 0, 0}
,
{0, 1, 1, 0, 0}
,
{0, 1, 1, 0, 0}
,
{3, sizeof(Dwarf_Block), BASE_ALLOC, 0, 0}
,
{0, 1, 1, 0, 0}
,
{4, sizeof(struct Dwarf_Die_s), BIG_ALLOC, 0, 0},
{5, sizeof(struct Dwarf_Line_s), BIG_ALLOC, 0, 0},
{6, sizeof(struct Dwarf_Attribute_s), BIG_ALLOC * 2, 0, 0},
{0, 1, 1, 0, 0},
{0, 1, 1, 0, 0},
{7, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0},
{8, sizeof(struct Dwarf_Error_s), BASE_ALLOC, 0, 0},
{0, 1, 1, 0, 0},
{0, 1, 1, 0, 0},
{9, sizeof(struct Dwarf_Arange_s), BASE_ALLOC, 0, 0},
{10, sizeof(struct Dwarf_Abbrev_s), BIG_ALLOC, 0, 0},
{11, sizeof(Dwarf_Frame_Op), BIG_ALLOC, 0, 0}
,
{12, sizeof(struct Dwarf_Cie_s), BASE_ALLOC, 0, 0},
{13, sizeof(struct Dwarf_Fde_s), BASE_ALLOC, 0, 0},
{0, 1, 1, 0, 0},
{0, 1, 1, 0, 0},
{14, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0},
{15, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0},
{16, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0},
{17, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0},
{0, 1, 1, 0, 0},
{18, sizeof(struct Dwarf_Abbrev_List_s), BIG_ALLOC, 0, 0},
{19, sizeof(struct Dwarf_Chain_s), BIG_ALLOC, 0, 0},
{20, sizeof(struct Dwarf_CU_Context_s), BASE_ALLOC, 0, 0},
{21, sizeof(struct Dwarf_Frame_s), BASE_ALLOC,
_dwarf_frame_constructor,
_dwarf_frame_destructor},
{22, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
{23, sizeof(struct Dwarf_File_Entry_s), BASE_ALLOC, 0, 0},
{24, sizeof(struct Dwarf_Line_Context_s), BASE_ALLOC, 0, 0},
{25, sizeof(struct Dwarf_Loc_Chain_s), BASE_ALLOC, 0, 0},
{26, ABBREV_HASH_TABLE_SIZE * sizeof(struct Dwarf_Hash_Table_s),
BASE_ALLOC, 0, 0},
{27, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
{28, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
{29, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
{30, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
{31, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
};
#ifndef DWARF_SIMPLE_MALLOC
static Dwarf_Ptr
_dwarf_find_memory(Dwarf_Alloc_Hdr alloc_hdr)
{
Dwarf_Small *ret_mem = 0;
Dwarf_Alloc_Area alloc_area;
Dwarf_Signed mem_block_size;
Dwarf_Small *mem_block;
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) {
if (alloc_area->aa_free_structs_in_chunk > 0) {
break;
}
}
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;
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;
*(Dwarf_Alloc_Area *) ret_mem = alloc_area;
ret_mem += DW_RESERVE;
alloc_area->aa_blob_start += alloc_hdr->ah_bytes_one_struct;
} else {
#ifdef DEBUG
fprintf(stderr, "libdwarf Internal error start %x end %x\n",
(int) alloc_area->aa_blob_start,
(int) alloc_area->aa_blob_end);
#endif
}
}
if (ret_mem == 0) {
Dwarf_Word rounded_area_hdr_size;
alloc_hdr->ah_chunks_allocated++;
{
unsigned long v = sizeof(struct Dwarf_Alloc_Area_s);
rounded_area_hdr_size = ROUND_SIZE(v);
}
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);
}
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) {
#ifdef DEBUG
fprintf(stderr,
"libdwarf Internal error: free structs in chunk %d\n",
(int) alloc_area->aa_free_structs_in_chunk);
#endif
return NULL;
}
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;
*(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);
return (ret_mem);
}
#endif
Dwarf_Ptr
_dwarf_get_alloc(Dwarf_Debug dbg,
Dwarf_Small alloc_type, Dwarf_Unsigned count)
{
Dwarf_Alloc_Hdr alloc_hdr;
Dwarf_Ptr ret_mem;
Dwarf_Signed size = 0;
unsigned int index;
unsigned int type = alloc_type;
if (dbg == NULL) {
return (NULL);
}
if (type >= ALLOC_AREA_INDEX_TABLE_MAX) {
return NULL;
}
index = index_into_allocated[type].ia_al_num;
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) {
void *m = _dwarf_special_no_dbg_error_malloc();
dwarf_malloc_check_alloc_data(m, DW_DLA_ERROR);
return m;
} else {
#ifdef DEBUG
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) {
#ifdef DWARF_SIMPLE_MALLOC
size = alloc_hdr->ah_bytes_one_struct;
#else
{
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) {
return NULL;
}
}
return m;
}
#endif
} else {
if (type == DW_DLA_ERROR) {
void *m = _dwarf_special_no_dbg_error_malloc();
dwarf_malloc_check_alloc_data(m, DW_DLA_ERROR);
return m;
} else {
#ifdef DWARF_SIMPLE_MALLOC
_dwarf_simple_malloc_botch(3);
#endif
#ifdef DEBUG
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,
type);
#endif
if (ret_mem != NULL)
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) {
return NULL;
}
}
return (ret_mem);
}
void
dwarf_dealloc(Dwarf_Debug dbg,
Dwarf_Ptr space, Dwarf_Unsigned alloc_type)
{
Dwarf_Alloc_Hdr alloc_hdr;
Dwarf_Alloc_Area alloc_area;
unsigned int type = alloc_type;
unsigned int index;
if (space == NULL) {
return;
}
if (type == DW_DLA_ERROR) {
alloc_area =
*(Dwarf_Alloc_Area *) ((char *) space - DW_RESERVE);
if (alloc_area == 0) {
_dwarf_free_special_error(space);
dwarf_malloc_check_dealloc_data(space, type);
return;
}
}
if (dbg == NULL) {
return;
}
if (type >= ALLOC_AREA_INDEX_TABLE_MAX) {
return;
}
index = index_into_allocated[type].ia_al_num;
dwarf_malloc_check_dealloc_data(space, type);
if (index == 0) {
if (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_pubtypes != NULL &&
(Dwarf_Small *) space >= dbg->de_debug_pubtypes &&
(Dwarf_Small *) space <
dbg->de_debug_pubtypes + dbg->de_debug_pubtypes_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 (type == DW_DLA_LIST ||
type == DW_DLA_FRAME_BLOCK ||
type == DW_DLA_LOC_BLOCK || type == DW_DLA_ADDR) {
free(space);
return;
}
#ifdef DWARF_SIMPLE_MALLOC
_dwarf_simple_malloc_botch(4);
#endif
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, type);
free(space);
#else
alloc_hdr = &dbg->de_alloc_hdr[index];
alloc_area = *(Dwarf_Alloc_Area *) ((char *) space - DW_RESERVE);
if (alloc_area->aa_alloc_hdr != alloc_hdr) {
#ifdef DEBUG
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;
}
alloc_hdr->ah_struct_user_holds--;
alloc_area->aa_free_structs_in_chunk++;
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);
}
else {
((Dwarf_Free_List) space)->fl_next = alloc_area->aa_free_list;
alloc_area->aa_free_list = space;
}
#endif
}
Dwarf_Debug
_dwarf_get_debug(void
)
{
Dwarf_Debug dbg;
dbg = (Dwarf_Debug) malloc(sizeof(struct Dwarf_Debug_s));
if (dbg == NULL)
return (NULL);
else
memset(dbg, 0, sizeof(struct Dwarf_Debug_s));
return (dbg);
}
Dwarf_Debug
_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);
Dwarf_Alloc_Hdr alloc_hdr = &dbg->de_alloc_hdr[hdr_index];
alloc_hdr->ah_bytes_one_struct = (Dwarf_Half) rnded_size;
alloc_hdr->ah_structs_per_chunk = str_count;
alloc_hdr->ah_bytes_malloc_per_chunk = rnded_size * str_count;
}
return (dbg);
}
void
dwarf_print_memory_stats(Dwarf_Debug dbg)
{
Dwarf_Alloc_Hdr alloc_hdr;
Dwarf_Shalf i;
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_PUBTYPES_CONTEXT"
};
if (dbg == NULL)
return;
printf("Size of Dwarf_Debug %4ld bytes\n",
(long) sizeof(*dbg));
printf("Size of Dwarf_Alloc_Hdr_s %4ld bytes\n",
(long) sizeof(struct Dwarf_Alloc_Hdr_s));
printf("size of Dwarf_Alloc_Area_s %4ld bytes\n",
(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);
}
}
}
#ifndef DWARF_SIMPLE_MALLOC
static void
_dwarf_recursive_free(Dwarf_Alloc_Area alloc_area)
{
if (alloc_area->aa_next != NULL) {
_dwarf_recursive_free(alloc_area->aa_next);
}
alloc_area->aa_next = 0;
alloc_area->aa_prev = 0;
free(alloc_area);
}
#endif
int
_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);
for (context = dbg->de_cu_context_list;
context; context = nextcontext) {
Dwarf_Hash_Table hash_table = context->cc_abbrev_hash_table;
int hashnum = 0;
for (; hashnum < ABBREV_HASH_TABLE_SIZE; ++hashnum) {
struct Dwarf_Abbrev_List_s *abbrev = 0;
struct Dwarf_Abbrev_List_s *nextabbrev = 0;
abbrev = hash_table[hashnum].at_head;
for (; abbrev; abbrev = nextabbrev) {
nextabbrev = abbrev->ab_next;
dwarf_dealloc(dbg, abbrev, DW_DLA_ABBREV_LIST);
}
}
nextcontext = context->cc_next;
dwarf_dealloc(dbg, hash_table, DW_DLA_HASH_TABLE);
dwarf_dealloc(dbg, context, DW_DLA_CU_CONTEXT);
}
#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;
}
#else
for (i = 1; i < ALLOC_AREA_REAL_TABLE_MAX; 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);
}
}
#endif
memset(dbg, 0, sizeof(*dbg));
free(dbg);
return (DW_DLV_OK);
}
struct Dwarf_Error_s *
_dwarf_special_no_dbg_error_malloc(void)
{
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)];
};
char *mem;
mem = malloc(sizeof(union u));
if (mem == 0) {
return 0;
}
memset(mem, 0, sizeof(union u));
mem += DW_RESERVE;
return (struct Dwarf_Error_s *) mem;
}
static void
_dwarf_free_special_error(Dwarf_Ptr space)
{
char *mem = (char *) space;
mem -= DW_RESERVE;
free(mem);
}
#ifdef DWARF_SIMPLE_MALLOC
void
_dwarf_simple_malloc_botch(int err)
{
}
static void
_dwarf_simple_malloc_add_to_list(Dwarf_Debug dbg,
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) {
dbg->de_simple_malloc_current =
malloc(sizeof(struct simple_malloc_record_s));
if (!dbg->de_simple_malloc_current) {
return;
}
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) {
struct simple_malloc_record_s *newblock =
malloc(sizeof(struct simple_malloc_record_s));
if (!newblock) {
return;
}
memset(newblock, 0, sizeof(struct simple_malloc_record_s));
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;
}
static void
_dwarf_simple_malloc_delete_from_list(Dwarf_Debug dbg,
Dwarf_Ptr space, short alloc_type)
{
if (space == 0) {
_dwarf_simple_malloc_botch(6);
}
if (dbg->de_simple_malloc_base) {
struct simple_malloc_record_s *smp = dbg->de_simple_malloc_base;
while (smp) {
int 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;
}
}
smp = smp->sr_next;
}
}
_dwarf_simple_malloc_botch(1);
return;
}
#endif