|
Packit |
cdaae3 |
/*
|
|
Packit |
cdaae3 |
Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
|
|
Packit |
cdaae3 |
Portions Copyright (C) 2007-2011 David Anderson. All Rights Reserved.
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
This program is free software; you can redistribute it and/or modify it
|
|
Packit |
cdaae3 |
under the terms of version 2.1 of the GNU Lesser General Public License
|
|
Packit |
cdaae3 |
as published by the Free Software Foundation.
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
This program is distributed in the hope that it would be useful, but
|
|
Packit |
cdaae3 |
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
cdaae3 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
Further, this software is distributed without any warranty that it is
|
|
Packit |
cdaae3 |
free of the rightful claim of any third person regarding infringement
|
|
Packit |
cdaae3 |
or the like. Any license provided herein, whether implied or
|
|
Packit |
cdaae3 |
otherwise, applies only to this software file. Patent licenses, if
|
|
Packit |
cdaae3 |
any, provided herein do not apply to combinations of this program with
|
|
Packit |
cdaae3 |
other software, or any other product whatsoever.
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
You should have received a copy of the GNU Lesser General Public
|
|
Packit |
cdaae3 |
License along with this program; if not, write the Free Software
|
|
Packit |
cdaae3 |
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
|
|
Packit |
cdaae3 |
USA.
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
*/
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
#undef DEBUG
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
#include "config.h"
|
|
Packit |
cdaae3 |
#include "dwarf_incl.h"
|
|
Packit |
cdaae3 |
#include <sys/types.h>
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
#include <stdlib.h>
|
|
Packit |
cdaae3 |
#include <stdio.h>
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* These files are included to get the sizes
|
|
Packit |
cdaae3 |
of structs for malloc.
|
|
Packit |
cdaae3 |
*/
|
|
Packit |
cdaae3 |
#include "dwarf_line.h"
|
|
Packit |
cdaae3 |
#include "dwarf_global.h"
|
|
Packit |
cdaae3 |
#include "dwarf_arange.h"
|
|
Packit |
cdaae3 |
#include "dwarf_abbrev.h"
|
|
Packit |
cdaae3 |
#include "dwarf_die_deliv.h"
|
|
Packit |
cdaae3 |
#include "dwarf_frame.h"
|
|
Packit |
cdaae3 |
#include "dwarf_loc.h"
|
|
Packit |
cdaae3 |
#include "dwarf_funcs.h"
|
|
Packit |
cdaae3 |
#include "dwarf_types.h"
|
|
Packit |
cdaae3 |
#include "dwarf_vars.h"
|
|
Packit |
cdaae3 |
#include "dwarf_weaks.h"
|
|
Packit |
cdaae3 |
#include "dwarf_harmless.h"
|
|
Packit |
cdaae3 |
#include "dwarf_tsearch.h"
|
|
Packit |
cdaae3 |
#include "dwarf_gdbindex.h"
|
|
Packit |
cdaae3 |
#include "dwarf_xu_index.h"
|
|
Packit |
cdaae3 |
#include "dwarf_macro5.h"
|
|
Packit |
cdaae3 |
#include "dwarf_dnames.h"
|
|
Packit |
cdaae3 |
#include "dwarf_dsc.h"
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
#define TRUE 1
|
|
Packit |
cdaae3 |
#define FALSE 0
|
|
Packit |
cdaae3 |
/* Some allocations are simple some not. These reduce
|
|
Packit |
cdaae3 |
the issue of determining which sort of thing to a simple
|
|
Packit |
cdaae3 |
test. See ia_multiply_count
|
|
Packit |
cdaae3 |
Usually when MULTIPLY_NO is set the count
|
|
Packit |
cdaae3 |
is 1, so MULTIPY_CT would work as well. */
|
|
Packit |
cdaae3 |
#define MULTIPLY_NO 0
|
|
Packit |
cdaae3 |
#define MULTIPLY_CT 1
|
|
Packit |
cdaae3 |
#define MULTIPLY_SP 2
|
|
Packit |
cdaae3 |
/* This translates into de_alloc_hdr into a per-instance size
|
|
Packit |
cdaae3 |
and allows room for a constructor/destructor pointer.
|
|
Packit |
cdaae3 |
Rearranging the DW_DLA values would break binary compatibility
|
|
Packit |
cdaae3 |
so that is not an option.
|
|
Packit |
cdaae3 |
*/
|
|
Packit |
cdaae3 |
struct ial_s {
|
|
Packit |
cdaae3 |
/* In bytes, one struct instance. */
|
|
Packit |
cdaae3 |
short ia_struct_size;
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* Not a count, but a MULTIPLY{_NO,_CT,_SP} value. */
|
|
Packit |
cdaae3 |
short ia_multiply_count;
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* When we really need a constructor/destructor
|
|
Packit |
cdaae3 |
these make applying such quite simple. */
|
|
Packit |
cdaae3 |
int (*specialconstructor) (Dwarf_Debug, void *);
|
|
Packit |
cdaae3 |
void (*specialdestructor) (void *);
|
|
Packit |
cdaae3 |
};
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* Used as a way to return meaningful errors when
|
|
Packit |
cdaae3 |
the malloc arena is exhausted (when malloc returns NULL).
|
|
Packit |
cdaae3 |
Not normally used.
|
|
Packit |
cdaae3 |
New in December 2014.*/
|
|
Packit |
cdaae3 |
struct Dwarf_Error_s _dwarf_failsafe_error = {
|
|
Packit |
cdaae3 |
DW_DLE_FAILSAFE_ERRVAL,
|
|
Packit |
cdaae3 |
1
|
|
Packit |
cdaae3 |
};
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* To do destructors we need some extra data in every
|
|
Packit |
cdaae3 |
_dwarf_get_alloc situation. */
|
|
Packit |
cdaae3 |
/* Here is the extra we malloc for a prefix. */
|
|
Packit |
cdaae3 |
struct reserve_size_s {
|
|
Packit |
cdaae3 |
void *dummy_rsv1;
|
|
Packit |
cdaae3 |
void *dummy_rsv2;
|
|
Packit |
cdaae3 |
};
|
|
Packit |
cdaae3 |
/* Here is how we use the extra prefix area. */
|
|
Packit |
cdaae3 |
struct reserve_data_s {
|
|
Packit |
cdaae3 |
void *rd_dbg;
|
|
Packit |
cdaae3 |
unsigned short rd_length;
|
|
Packit |
cdaae3 |
unsigned short rd_type;
|
|
Packit |
cdaae3 |
};
|
|
Packit |
cdaae3 |
#define DW_RESERVE sizeof(struct reserve_size_s)
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
static const
|
|
Packit |
cdaae3 |
struct ial_s alloc_instance_basics[ALLOC_AREA_INDEX_TABLE_MAX] = {
|
|
Packit |
cdaae3 |
{ 1,MULTIPLY_NO, 0, 0}, /* 0 none */
|
|
Packit |
cdaae3 |
{ 1,MULTIPLY_CT, 0, 0}, /* 1 DW_DLA_STRING */
|
|
Packit |
cdaae3 |
{ sizeof(Dwarf_Loc),MULTIPLY_NO, 0, 0} ,/* 2 DW_DLA_LOC */
|
|
Packit |
cdaae3 |
{ sizeof(Dwarf_Locdesc),MULTIPLY_NO, 0, 0} , /* 3 DW_DLA_LOCDESC */
|
|
Packit |
cdaae3 |
{ 1,MULTIPLY_NO, 0, 0} , /* not used *//* 4 DW_DLA_ELLIST */
|
|
Packit |
cdaae3 |
{ 1,MULTIPLY_NO, 0, 0} , /* not used *//* 5 DW_DLA_BOUNDS */
|
|
Packit |
cdaae3 |
{ sizeof(Dwarf_Block),MULTIPLY_NO, 0, 0} , /* 6 DW_DLA_BLOCK */
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* the actual dwarf_debug structure */ /* 7 DW_DLA_DEBUG */
|
|
Packit |
cdaae3 |
{ 1,MULTIPLY_NO, 0, 0} ,
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Die_s),MULTIPLY_NO, 0, 0},/* 8 DW_DLA_DIE */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Line_s),MULTIPLY_NO, 0, 0},/* 9 DW_DLA_LINE */
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 10 DW_DLA_ATTR */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Attribute_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
{1,MULTIPLY_NO, 0, 0}, /* not used */ /* 11 DW_DLA_TYPE */
|
|
Packit |
cdaae3 |
{1,MULTIPLY_NO, 0, 0}, /* not used */ /* 12 DW_DLA_SUBSCR */
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 13 DW_DLA_GLOBAL */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Global_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 14 DW_DLA_ERROR */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Error_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
{sizeof(Dwarf_Ptr),MULTIPLY_CT, 0, 0}, /* 15 DW_DLA_LIST */
|
|
Packit |
cdaae3 |
{1,MULTIPLY_NO, 0, 0}, /* not used *//* 16 DW_DLA_LINEBUF */
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 17 DW_DLA_ARANGE */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Arange_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 18 DW_DLA_ABBREV */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Abbrev_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 19 DW_DLA_FRAME_OP */
|
|
Packit |
cdaae3 |
{sizeof(Dwarf_Frame_Op),MULTIPLY_NO, 0, 0} ,
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 20 DW_DLA_CIE */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Cie_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Fde_s),MULTIPLY_NO, 0,
|
|
Packit |
cdaae3 |
_dwarf_fde_destructor},/* 21 DW_DLA_FDE */
|
|
Packit |
cdaae3 |
{sizeof(Dwarf_Loc),MULTIPLY_CT, 0, 0}, /* 22 DW_DLA_LOC_BLOCK */
|
|
Packit |
cdaae3 |
{sizeof(Dwarf_Frame_Op),MULTIPLY_CT, 0, 0}, /* 23 DW_DLA_FRAME_BLOCK */
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 24 DW_DLA_FUNC UNUSED */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Global_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 25 DW_DLA_TYPENAME UNUSED */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Global_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 26 DW_DLA_VAR UNUSED */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Global_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 27 DW_DLA_WEAK UNUSED */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Global_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
{1,MULTIPLY_SP, 0, 0}, /* 28 DW_DLA_ADDR */
|
|
Packit |
cdaae3 |
{sizeof(Dwarf_Ranges),MULTIPLY_CT, 0,0 }, /* 29 DW_DLA_RANGES */
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* The following DW_DLA data types
|
|
Packit |
cdaae3 |
are known only inside libdwarf. */
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 30 DW_DLA_ABBREV_LIST */
|
|
Packit |
cdaae3 |
{ sizeof(struct Dwarf_Abbrev_List_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 31 DW_DLA_CHAIN */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Chain_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 32 DW_DLA_CU_CONTEXT */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_CU_Context_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Frame_s),MULTIPLY_NO,
|
|
Packit |
cdaae3 |
_dwarf_frame_constructor,
|
|
Packit |
cdaae3 |
_dwarf_frame_destructor}, /* 33 DW_DLA_FRAME */
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 34 DW_DLA_GLOBAL_CONTEXT */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Global_Context_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 35 DW_DLA_FILE_ENTRY */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_File_Entry_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 36 DW_DLA_LINE_CONTEXT */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Line_Context_s),MULTIPLY_NO,
|
|
Packit |
cdaae3 |
_dwarf_line_context_constructor,
|
|
Packit |
cdaae3 |
_dwarf_line_context_destructor},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 37 DW_DLA_LOC_CHAIN */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Loc_Chain_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 38 0x26 DW_DLA_HASH_TABLE */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Hash_Table_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* The following really use Global struct: used to be unique struct
|
|
Packit |
cdaae3 |
per type, but now merged (11/99). The opaque types
|
|
Packit |
cdaae3 |
are visible in the interface. The types for
|
|
Packit |
cdaae3 |
DW_DLA_FUNC, DW_DLA_TYPENAME, DW_DLA_VAR, DW_DLA_WEAK also use
|
|
Packit |
cdaae3 |
the global types. */
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 39 0x27 DW_DLA_FUNC_CONTEXT */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Global_Context_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 40 0x28 DW_DLA_TYPENAME_CONTEXT */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Global_Context_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 41 0x29 DW_DLA_VAR_CONTEXT */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Global_Context_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 42 0x2a DW_DLA_WEAK_CONTEXT */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Global_Context_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 43 0x2b DW_DLA_PUBTYPES_CONTEXT DWARF3 */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Global_Context_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 44 0x2c DW_DLA_HASH_TABLE_ENTRY */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Hash_Table_Entry_s),MULTIPLY_CT,0,0 },
|
|
Packit |
cdaae3 |
/* 0x2d - 0x2f, reserved for future internal use. */
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 45 0x2d DW_DLA_FISSION_PERCU */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Fission_Per_CU_s),MULTIPLY_CT, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
{sizeof(int),MULTIPLY_NO, 0, 0}, /* reserved for future internal types*/
|
|
Packit |
cdaae3 |
{sizeof(int),MULTIPLY_NO, 0, 0}, /* reserved for future internal types*/
|
|
Packit |
cdaae3 |
/* 0x30-0x36 reserved for future internal use. */
|
|
Packit |
cdaae3 |
{sizeof(int),MULTIPLY_NO, 0, 0}, /* reserved for future internal types*/
|
|
Packit |
cdaae3 |
{sizeof(int),MULTIPLY_NO, 0, 0}, /* reserved for future internal types*/
|
|
Packit |
cdaae3 |
{sizeof(int),MULTIPLY_NO, 0, 0}, /* reserved for future internal types*/
|
|
Packit |
cdaae3 |
{sizeof(int),MULTIPLY_NO, 0, 0}, /* reserved for future internal types*/
|
|
Packit |
cdaae3 |
{sizeof(int),MULTIPLY_NO, 0, 0}, /* reserved for future internal types*/
|
|
Packit |
cdaae3 |
{sizeof(int),MULTIPLY_NO, 0, 0}, /* reserved for future internal types*/
|
|
Packit |
cdaae3 |
{sizeof(int),MULTIPLY_NO, 0, 0}, /* reserved for future internal types*/
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* now, we have types that are public. */
|
|
Packit |
cdaae3 |
/* 0x37 55. New in June 2014. Gdb. */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Gdbindex_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 0x38 56. New in July 2014. DWARF5 DebugFission dwp file sections
|
|
Packit |
cdaae3 |
.debug_cu_index and .debug_tu_index . */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Xu_Index_Header_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* These required by new features in DWARF5. Also usable
|
|
Packit |
cdaae3 |
for DWARF2,3,4. */
|
|
Packit |
cdaae3 |
/* 57 DW_DLA_LOC_BLOCK_C */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Loc_c_s),MULTIPLY_CT, 0, 0},
|
|
Packit |
cdaae3 |
/* 58 DW_DLA_LOCDESC_C */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Locdesc_c_s),MULTIPLY_CT, 0, 0},
|
|
Packit |
cdaae3 |
/* 59 DW_DLA_LOC_HEAD_C */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Loc_Head_c_s),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
/* 60 DW_DLA_MACRO_CONTEXT */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Macro_Context_s),MULTIPLY_NO,
|
|
Packit |
cdaae3 |
_dwarf_macro_constructor,
|
|
Packit |
cdaae3 |
_dwarf_macro_destructor},
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* 61 DW_DLA_CHAIN_2 */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Chain_o),MULTIPLY_NO, 0, 0},
|
|
Packit |
cdaae3 |
/* 62 DW_DLA_DSC_HEAD 0x3e */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Dsc_Head_s),MULTIPLY_NO, 0,
|
|
Packit |
cdaae3 |
_dwarf_dsc_destructor},
|
|
Packit |
cdaae3 |
/* 63 DW_DLA_DNAMES_HEAD 0x3f */
|
|
Packit |
cdaae3 |
{sizeof(struct Dwarf_Dnames_Head_s),MULTIPLY_NO, 0,
|
|
Packit |
cdaae3 |
_dwarf_debugnames_destructor},
|
|
Packit |
cdaae3 |
};
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* We are simply using the incoming pointer as the key-pointer.
|
|
Packit |
cdaae3 |
*/
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
static DW_TSHASHTYPE
|
|
Packit |
cdaae3 |
simple_value_hashfunc(const void *keyp)
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
DW_TSHASHTYPE up = (DW_TSHASHTYPE)keyp;
|
|
Packit |
cdaae3 |
return up;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
/* We did alloc something but not a fixed-length thing.
|
|
Packit |
cdaae3 |
Instead, it starts with some special data we noted.
|
|
Packit |
cdaae3 |
The incoming pointer is to the caller data, we
|
|
Packit |
cdaae3 |
destruct based on caller, but find the special
|
|
Packit |
cdaae3 |
extra data in a prefix area. */
|
|
Packit |
cdaae3 |
static void
|
|
Packit |
cdaae3 |
tdestroy_free_node(void *nodep)
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
char * m = (char *)nodep;
|
|
Packit |
cdaae3 |
char * malloc_addr = m - DW_RESERVE;
|
|
Packit |
cdaae3 |
struct reserve_data_s * reserve =(struct reserve_data_s *)malloc_addr;
|
|
Packit |
cdaae3 |
unsigned type = reserve->rd_type;
|
|
Packit |
cdaae3 |
if (type >= ALLOC_AREA_INDEX_TABLE_MAX) {
|
|
Packit |
cdaae3 |
/* Internal error, corrupted data. */
|
|
Packit |
cdaae3 |
return;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
if(!reserve->rd_dbg) {
|
|
Packit |
cdaae3 |
/* Unused (corrupted?) node in the tree.
|
|
Packit |
cdaae3 |
Should never happen. */
|
|
Packit |
cdaae3 |
return;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
if(!reserve->rd_type) {
|
|
Packit |
cdaae3 |
/* Unused (corrupted?) node in the tree.
|
|
Packit |
cdaae3 |
Should never happen. */
|
|
Packit |
cdaae3 |
return;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
if (alloc_instance_basics[type].specialdestructor) {
|
|
Packit |
cdaae3 |
alloc_instance_basics[type].specialdestructor(m);
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
free(malloc_addr);
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* The sort of hash table entries result in very simple helper functions. */
|
|
Packit |
cdaae3 |
static int
|
|
Packit |
cdaae3 |
simple_compare_function(const void *l, const void *r)
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
DW_TSHASHTYPE lp = (DW_TSHASHTYPE)l;
|
|
Packit |
cdaae3 |
DW_TSHASHTYPE rp = (DW_TSHASHTYPE)r;
|
|
Packit |
cdaae3 |
if(lp < rp) {
|
|
Packit |
cdaae3 |
return -1;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
if(lp > rp) {
|
|
Packit |
cdaae3 |
return 1;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
return 0;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* This function returns a pointer to a region
|
|
Packit |
cdaae3 |
of memory. For alloc_types that are not
|
|
Packit |
cdaae3 |
strings or lists of pointers, only 1 struct
|
|
Packit |
cdaae3 |
can be requested at a time. This is indicated
|
|
Packit |
cdaae3 |
by an input count of 1. For strings, count
|
|
Packit |
cdaae3 |
equals the length of the string it will
|
|
Packit |
cdaae3 |
contain, i.e it the length of the string
|
|
Packit |
cdaae3 |
plus 1 for the terminating null. For lists
|
|
Packit |
cdaae3 |
of pointers, count is equal to the number of
|
|
Packit |
cdaae3 |
pointers. For DW_DLA_FRAME_BLOCK, DW_DLA_RANGES, and
|
|
Packit |
cdaae3 |
DW_DLA_LOC_BLOCK allocation types also, count
|
|
Packit |
cdaae3 |
is the count of the number of structs needed.
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
This function cannot be used to allocate a
|
|
Packit |
cdaae3 |
Dwarf_Debug_s struct. */
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
char *
|
|
Packit |
cdaae3 |
_dwarf_get_alloc(Dwarf_Debug dbg,
|
|
Packit |
cdaae3 |
Dwarf_Small alloc_type, Dwarf_Unsigned count)
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
char * alloc_mem = 0;
|
|
Packit |
cdaae3 |
Dwarf_Signed basesize = 0;
|
|
Packit |
cdaae3 |
Dwarf_Signed size = 0;
|
|
Packit |
cdaae3 |
unsigned int type = alloc_type;
|
|
Packit |
cdaae3 |
short action = 0;
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
if (dbg == NULL) {
|
|
Packit |
cdaae3 |
return NULL;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
if (type >= ALLOC_AREA_INDEX_TABLE_MAX) {
|
|
Packit |
cdaae3 |
/* internal error */
|
|
Packit |
cdaae3 |
return NULL;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
basesize = alloc_instance_basics[alloc_type].ia_struct_size;
|
|
Packit |
cdaae3 |
action = alloc_instance_basics[alloc_type].ia_multiply_count;
|
|
Packit |
cdaae3 |
if(action == MULTIPLY_NO) {
|
|
Packit |
cdaae3 |
/* Usually count is 1, but do not assume it. */
|
|
Packit |
cdaae3 |
size = basesize;
|
|
Packit |
cdaae3 |
} else if (action == MULTIPLY_CT) {
|
|
Packit |
cdaae3 |
size = basesize * count;
|
|
Packit |
cdaae3 |
} else {
|
|
Packit |
cdaae3 |
/* MULTIPLY_SP */
|
|
Packit |
cdaae3 |
/* DW_DLA_ADDR.. count * largest size */
|
|
Packit |
cdaae3 |
size = count *
|
|
Packit |
cdaae3 |
(sizeof(Dwarf_Addr) > sizeof(Dwarf_Off) ?
|
|
Packit |
cdaae3 |
sizeof(Dwarf_Addr) : sizeof(Dwarf_Off));
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
size += DW_RESERVE;
|
|
Packit |
cdaae3 |
alloc_mem = malloc(size);
|
|
Packit |
cdaae3 |
if (!alloc_mem) {
|
|
Packit |
cdaae3 |
return NULL;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
char * ret_mem = alloc_mem + DW_RESERVE;
|
|
Packit |
cdaae3 |
void *key = ret_mem;
|
|
Packit |
cdaae3 |
struct reserve_data_s *r = (struct reserve_data_s*)alloc_mem;
|
|
Packit |
cdaae3 |
void *result = 0;
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
memset(alloc_mem, 0, size);
|
|
Packit |
cdaae3 |
/* We are not actually using rd_dbg, we are using rd_type. */
|
|
Packit |
cdaae3 |
r->rd_dbg = dbg;
|
|
Packit |
cdaae3 |
r->rd_type = alloc_type;
|
|
Packit |
cdaae3 |
r->rd_length = size;
|
|
Packit |
cdaae3 |
if (alloc_instance_basics[type].specialconstructor) {
|
|
Packit |
cdaae3 |
int res =
|
|
Packit |
cdaae3 |
alloc_instance_basics[type].specialconstructor(dbg, ret_mem);
|
|
Packit |
cdaae3 |
if (res != DW_DLV_OK) {
|
|
Packit |
cdaae3 |
/* We leak what we allocated in _dwarf_find_memory when
|
|
Packit |
cdaae3 |
constructor fails. */
|
|
Packit |
cdaae3 |
return NULL;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
result = dwarf_tsearch((void *)key,
|
|
Packit |
cdaae3 |
&dbg->de_alloc_tree,simple_compare_function);
|
|
Packit |
cdaae3 |
if(!result) {
|
|
Packit |
cdaae3 |
/* Something badly wrong. Out of memory.
|
|
Packit |
cdaae3 |
pretend all is well. */
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
return (ret_mem);
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* This was once a long list of tests using dss_data
|
|
Packit |
cdaae3 |
and dss_size to see if 'space' was inside a debug section.
|
|
Packit |
cdaae3 |
This tfind approach removes that maintenance headache. */
|
|
Packit |
cdaae3 |
static int
|
|
Packit |
cdaae3 |
string_is_in_debug_section(Dwarf_Debug dbg,void * space)
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
/* See dwarf_line.c dwarf_srcfiles()
|
|
Packit |
cdaae3 |
for one way we can wind up with
|
|
Packit |
cdaae3 |
a DW_DLA_STRING string that may or may not be malloc-ed
|
|
Packit |
cdaae3 |
by _dwarf_get_alloc().
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
dwarf_formstring(), for example, returns strings
|
|
Packit |
cdaae3 |
which point into .debug_info or .debug_types but
|
|
Packit |
cdaae3 |
dwarf_dealloc is never supposed to be applied
|
|
Packit |
cdaae3 |
to strings dwarf_formstring() returns!
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
Lots of calls returning strings
|
|
Packit |
cdaae3 |
have always been documented as requiring
|
|
Packit |
cdaae3 |
dwarf_dealloc(...DW_DLA_STRING) when the code
|
|
Packit |
cdaae3 |
just returns a pointer to a portion of a loaded section!
|
|
Packit |
cdaae3 |
It is too late to change the documentation. */
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
void *result = 0;
|
|
Packit |
cdaae3 |
result = dwarf_tfind((void *)space,
|
|
Packit |
cdaae3 |
&dbg->de_alloc_tree,simple_compare_function);
|
|
Packit |
cdaae3 |
if(!result) {
|
|
Packit |
cdaae3 |
/* Not in the tree, so not malloc-ed
|
|
Packit |
cdaae3 |
Nothing to delete. */
|
|
Packit |
cdaae3 |
return TRUE;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
/* We found the address in the tree, so it is NOT
|
|
Packit |
cdaae3 |
part of .debug_info or any other dwarf section,
|
|
Packit |
cdaae3 |
but is space malloc-d in _dwarf_get_alloc(). */
|
|
Packit |
cdaae3 |
return FALSE;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/*
|
|
Packit |
cdaae3 |
This function is used to deallocate a region of memory
|
|
Packit |
cdaae3 |
that was obtained by a call to _dwarf_get_alloc. Note
|
|
Packit |
cdaae3 |
that though dwarf_dealloc() is a public function,
|
|
Packit |
cdaae3 |
_dwarf_get_alloc() isn't.
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
For lists, typically arrays of pointers, it is assumed
|
|
Packit |
cdaae3 |
that the space was allocated by a direct call to malloc,
|
|
Packit |
cdaae3 |
and so a straight free() is done. This is also the case
|
|
Packit |
cdaae3 |
for variable length blocks such as DW_DLA_FRAME_BLOCK
|
|
Packit |
cdaae3 |
and DW_DLA_LOC_BLOCK and DW_DLA_RANGES.
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
For strings, the pointer might point to a string in
|
|
Packit |
cdaae3 |
.debug_info or .debug_string. After this is checked,
|
|
Packit |
cdaae3 |
and if found not to be the case, a free() is done,
|
|
Packit |
cdaae3 |
again on the assumption that a malloc was used to
|
|
Packit |
cdaae3 |
obtain the space.
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
This function does not return anything.
|
|
Packit |
cdaae3 |
*/
|
|
Packit |
cdaae3 |
void
|
|
Packit |
cdaae3 |
dwarf_dealloc(Dwarf_Debug dbg,
|
|
Packit |
cdaae3 |
Dwarf_Ptr space, Dwarf_Unsigned alloc_type)
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
unsigned int type = 0;
|
|
Packit |
cdaae3 |
char * malloc_addr = 0;
|
|
Packit |
cdaae3 |
struct reserve_data_s * r = 0;
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
if (space == NULL) {
|
|
Packit |
cdaae3 |
return;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
if (dbg) {
|
|
Packit |
cdaae3 |
/* If it's a string in debug_info etc doing
|
|
Packit |
cdaae3 |
(char *)space - DW_RESERVE is totally bogus. */
|
|
Packit |
cdaae3 |
if (alloc_type == DW_DLA_STRING &&
|
|
Packit |
cdaae3 |
string_is_in_debug_section(dbg,space)) {
|
|
Packit |
cdaae3 |
/* A string pointer may point into .debug_info or
|
|
Packit |
cdaae3 |
.debug_string etc.
|
|
Packit |
cdaae3 |
So must not be freed. And strings have no need of a
|
|
Packit |
cdaae3 |
specialdestructor().
|
|
Packit |
cdaae3 |
Mostly a historical mistake here. */
|
|
Packit |
cdaae3 |
return;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
/* Otherwise it might be allocated string so it is ok
|
|
Packit |
cdaae3 |
do the (char *)space - DW_RESERVE */
|
|
Packit |
cdaae3 |
} else {
|
|
Packit |
cdaae3 |
/* App error, or an app that failed to succeed in a
|
|
Packit |
cdaae3 |
dwarf_init() call. */
|
|
Packit |
cdaae3 |
return;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
if (alloc_type == DW_DLA_ERROR) {
|
|
Packit |
cdaae3 |
Dwarf_Error ep = (Dwarf_Error)space;
|
|
Packit |
cdaae3 |
if (ep->er_static_alloc == DE_STATIC) {
|
|
Packit |
cdaae3 |
/* This is special, malloc arena
|
|
Packit |
cdaae3 |
was exhausted or a NULL dbg
|
|
Packit |
cdaae3 |
was used for the error because the real
|
|
Packit |
cdaae3 |
dbg was unavailable. There is nothing to delete, really.
|
|
Packit |
cdaae3 |
Set er_errval to signal that the space was dealloc'd. */
|
|
Packit |
cdaae3 |
_dwarf_failsafe_error.er_errval = DW_DLE_FAILSAFE_ERRVAL;
|
|
Packit |
cdaae3 |
return;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
if (ep->er_static_alloc == DE_MALLOC) {
|
|
Packit |
cdaae3 |
/* This is special, we had no arena
|
|
Packit |
cdaae3 |
so just malloc'd a Dwarf_Error_s. */
|
|
Packit |
cdaae3 |
free(space);
|
|
Packit |
cdaae3 |
return;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
/* Was normal alloc, use normal dealloc. */
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
type = alloc_type;
|
|
Packit |
cdaae3 |
malloc_addr = (char *)space - DW_RESERVE;
|
|
Packit |
cdaae3 |
r =(struct reserve_data_s *)malloc_addr;
|
|
Packit |
cdaae3 |
if(dbg != r->rd_dbg) {
|
|
Packit |
cdaae3 |
/* Something is badly wrong. Better to leak than
|
|
Packit |
cdaae3 |
to crash. */
|
|
Packit |
cdaae3 |
return;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
if (type >= ALLOC_AREA_INDEX_TABLE_MAX) {
|
|
Packit |
cdaae3 |
/* internal or user app error */
|
|
Packit |
cdaae3 |
return;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
if (alloc_instance_basics[type].specialdestructor) {
|
|
Packit |
cdaae3 |
alloc_instance_basics[type].specialdestructor(space);
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
/* The 'space' pointer we get points after the reserve space.
|
|
Packit |
cdaae3 |
The key and address to free are just a few bytes before
|
|
Packit |
cdaae3 |
'space'. */
|
|
Packit |
cdaae3 |
void *key = space;
|
|
Packit |
cdaae3 |
dwarf_tdelete(key,&dbg->de_alloc_tree,simple_compare_function);
|
|
Packit |
cdaae3 |
/* If dwarf_tdelete returns NULL it might mean
|
|
Packit |
cdaae3 |
a) tree is empty.
|
|
Packit |
cdaae3 |
b) If hashsearch, then a single chain might now be empty,
|
|
Packit |
cdaae3 |
so we do not know of a 'parent node'.
|
|
Packit |
cdaae3 |
c) We did not find that key, we did nothing.
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
In any case, we simply don't worry about it.
|
|
Packit |
cdaae3 |
Not Supposed To Happen. */
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
free(malloc_addr);
|
|
Packit |
cdaae3 |
return;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/*
|
|
Packit |
cdaae3 |
Allocates space for a Dwarf_Debug_s struct,
|
|
Packit |
cdaae3 |
since one does not exist.
|
|
Packit |
cdaae3 |
*/
|
|
Packit |
cdaae3 |
Dwarf_Debug
|
|
Packit |
cdaae3 |
_dwarf_get_debug(void)
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
Dwarf_Debug dbg;
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
dbg = (Dwarf_Debug) malloc(sizeof(struct Dwarf_Debug_s));
|
|
Packit |
cdaae3 |
if (dbg == NULL) {
|
|
Packit |
cdaae3 |
return (NULL);
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
memset(dbg, 0, sizeof(struct Dwarf_Debug_s));
|
|
Packit |
cdaae3 |
/* Set up for a dwarf_tsearch hash table */
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
dwarf_initialize_search_hash(&dbg->de_alloc_tree,simple_value_hashfunc,0);
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
return (dbg);
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/*
|
|
Packit |
cdaae3 |
This function prints out the statistics
|
|
Packit |
cdaae3 |
collected on allocation of memory chunks.
|
|
Packit |
cdaae3 |
No longer used.
|
|
Packit |
cdaae3 |
*/
|
|
Packit |
cdaae3 |
void
|
|
Packit |
cdaae3 |
dwarf_print_memory_stats(UNUSEDARG Dwarf_Debug dbg)
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* In the 'rela' relocation case we might have malloc'd
|
|
Packit |
cdaae3 |
space to ensure it is read-write. In that case, free the space. */
|
|
Packit |
cdaae3 |
static void
|
|
Packit |
cdaae3 |
rela_free(struct Dwarf_Section_s * sec)
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
if (sec->dss_data_was_malloc) {
|
|
Packit |
cdaae3 |
free(sec->dss_data);
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
sec->dss_data = 0;
|
|
Packit |
cdaae3 |
sec->dss_data_was_malloc = 0;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
static void
|
|
Packit |
cdaae3 |
freecontextlist(Dwarf_Debug dbg, Dwarf_Debug_InfoTypes dis)
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
Dwarf_CU_Context context = 0;
|
|
Packit |
cdaae3 |
Dwarf_CU_Context nextcontext = 0;
|
|
Packit |
cdaae3 |
for (context = dis->de_cu_context_list;
|
|
Packit |
cdaae3 |
context; context = nextcontext) {
|
|
Packit |
cdaae3 |
Dwarf_Hash_Table hash_table = context->cc_abbrev_hash_table;
|
|
Packit |
cdaae3 |
_dwarf_free_abbrev_hash_table_contents(dbg,hash_table);
|
|
Packit |
cdaae3 |
nextcontext = context->cc_next;
|
|
Packit |
cdaae3 |
dwarf_dealloc(dbg, hash_table, DW_DLA_HASH_TABLE);
|
|
Packit |
cdaae3 |
context->cc_abbrev_hash_table = 0;
|
|
Packit |
cdaae3 |
dwarf_dealloc(dbg, context, DW_DLA_CU_CONTEXT);
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
dis->de_cu_context_list = 0;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/*
|
|
Packit |
cdaae3 |
Used to free all space allocated for this Dwarf_Debug.
|
|
Packit |
cdaae3 |
The caller should assume that the Dwarf_Debug pointer
|
|
Packit |
cdaae3 |
itself is no longer valid upon return from this function.
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
In case of difficulty, this function simply returns quietly.
|
|
Packit |
cdaae3 |
*/
|
|
Packit |
cdaae3 |
int
|
|
Packit |
cdaae3 |
_dwarf_free_all_of_one_debug(Dwarf_Debug dbg)
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
if (dbg == NULL) {
|
|
Packit |
cdaae3 |
return (DW_DLV_ERROR);
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* To do complete validation that we have no surprising missing or
|
|
Packit |
cdaae3 |
erroneous deallocs it is advisable to do the dwarf_deallocs here
|
|
Packit |
cdaae3 |
that are not things the user can otherwise request.
|
|
Packit |
cdaae3 |
Housecleaning. */
|
|
Packit |
cdaae3 |
if (dbg->de_cu_hashindex_data) {
|
|
Packit |
cdaae3 |
dwarf_xu_header_free(dbg->de_cu_hashindex_data);
|
|
Packit |
cdaae3 |
dbg->de_cu_hashindex_data = 0;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
if (dbg->de_tu_hashindex_data) {
|
|
Packit |
cdaae3 |
dwarf_xu_header_free(dbg->de_tu_hashindex_data);
|
|
Packit |
cdaae3 |
dbg->de_tu_hashindex_data = 0;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
freecontextlist(dbg,&dbg->de_info_reading);
|
|
Packit |
cdaae3 |
freecontextlist(dbg,&dbg->de_types_reading);
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* Housecleaning done. Now really free all the space. */
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_info);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_types);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_abbrev);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_line);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_line_str);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_loc);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_aranges);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_macinfo);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_macro);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_names);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_pubnames);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_str);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_sup);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_frame);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_frame_eh_gnu);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_pubtypes);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_funcnames);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_typenames);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_varnames);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_weaknames);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_ranges);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_str_offsets);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_addr);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_gdbindex);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_cu_index);
|
|
Packit |
cdaae3 |
rela_free(&dbg->de_debug_tu_index);
|
|
Packit |
cdaae3 |
dwarf_harmless_cleanout(&dbg->de_harmless_errors);
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
if (dbg->de_printf_callback.dp_buffer &&
|
|
Packit |
cdaae3 |
!dbg->de_printf_callback.dp_buffer_user_provided ) {
|
|
Packit |
cdaae3 |
free(dbg->de_printf_callback.dp_buffer);
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
_dwarf_destroy_group_map(dbg);
|
|
Packit |
cdaae3 |
dwarf_tdestroy(dbg->de_alloc_tree,tdestroy_free_node);
|
|
Packit |
cdaae3 |
dbg->de_alloc_tree = 0;
|
|
Packit |
cdaae3 |
if (dbg->de_tied_data.td_tied_search) {
|
|
Packit |
cdaae3 |
dwarf_tdestroy(dbg->de_tied_data.td_tied_search,
|
|
Packit |
cdaae3 |
_dwarf_tied_destroy_free_node);
|
|
Packit |
cdaae3 |
dbg->de_tied_data.td_tied_search = 0;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
memset(dbg, 0, sizeof(*dbg)); /* Prevent accidental use later. */
|
|
Packit |
cdaae3 |
free(dbg);
|
|
Packit |
cdaae3 |
return (DW_DLV_OK);
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
/* A special case: we have no dbg, no alloc header etc.
|
|
Packit |
cdaae3 |
So create something out of thin air that we can recognize
|
|
Packit |
cdaae3 |
in dwarf_dealloc.
|
|
Packit |
cdaae3 |
Something with the prefix (prefix space hidden from caller).
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
Only applies to DW_DLA_ERROR, and making up an error record.
|
|
Packit |
cdaae3 |
The allocated space simply leaks.
|
|
Packit |
cdaae3 |
*/
|
|
Packit |
cdaae3 |
struct Dwarf_Error_s *
|
|
Packit |
cdaae3 |
_dwarf_special_no_dbg_error_malloc(void)
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
Dwarf_Error e = 0;
|
|
Packit |
cdaae3 |
/* The union unused things are to guarantee proper alignment */
|
|
Packit |
cdaae3 |
char *mem = malloc(sizeof(struct Dwarf_Error_s));
|
|
Packit |
cdaae3 |
if (mem == 0) {
|
|
Packit |
cdaae3 |
return 0;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
memset(mem, 0, sizeof(struct Dwarf_Error_s));
|
|
Packit |
cdaae3 |
e = (Dwarf_Error)mem;
|
|
Packit |
cdaae3 |
e->er_static_alloc = DE_MALLOC;
|
|
Packit |
cdaae3 |
return e;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
|