149d3bc9Richard Lowe/*
249d3bc9Richard Lowe
307dc194Richard Lowe  Copyright (C) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
407dc194Richard Lowe  Portions Copyright (C) 2007-2010  David Anderson. All Rights Reserved.
549d3bc9Richard Lowe
649d3bc9Richard Lowe  This program is free software; you can redistribute it and/or modify it
749d3bc9Richard Lowe  under the terms of version 2.1 of the GNU Lesser General Public License
849d3bc9Richard Lowe  as published by the Free Software Foundation.
949d3bc9Richard Lowe
1049d3bc9Richard Lowe  This program is distributed in the hope that it would be useful, but
1149d3bc9Richard Lowe  WITHOUT ANY WARRANTY; without even the implied warranty of
1249d3bc9Richard Lowe  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1349d3bc9Richard Lowe
1449d3bc9Richard Lowe  Further, this software is distributed without any warranty that it is
1549d3bc9Richard Lowe  free of the rightful claim of any third person regarding infringement
1649d3bc9Richard Lowe  or the like.  Any license provided herein, whether implied or
1749d3bc9Richard Lowe  otherwise, applies only to this software file.  Patent licenses, if
1849d3bc9Richard Lowe  any, provided herein do not apply to combinations of this program with
1949d3bc9Richard Lowe  other software, or any other product whatsoever.
2049d3bc9Richard Lowe
2149d3bc9Richard Lowe  You should have received a copy of the GNU Lesser General Public
2249d3bc9Richard Lowe  License along with this program; if not, write the Free Software
2307dc194Richard Lowe  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
2449d3bc9Richard Lowe  USA.
2549d3bc9Richard Lowe
2607dc194Richard Lowe  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
2749d3bc9Richard Lowe  Mountain View, CA 94043, or:
2849d3bc9Richard Lowe
2949d3bc9Richard Lowe  http://www.sgi.com
3049d3bc9Richard Lowe
3149d3bc9Richard Lowe  For further information regarding this notice, see:
3249d3bc9Richard Lowe
3349d3bc9Richard Lowe  http://oss.sgi.com/projects/GenInfo/NoticeExplan
3449d3bc9Richard Lowe
3549d3bc9Richard Lowe*/
3607dc194Richard Lowe/* The address of the Free Software Foundation is
3707dc194Richard Lowe   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
3807dc194Richard Lowe   Boston, MA 02110-1301, USA.
3907dc194Richard Lowe   SGI has moved from the Crittenden Lane address.
4007dc194Richard Lowe*/
4149d3bc9Richard Lowe
4249d3bc9Richard Lowe
4307dc194Richard Lowe#undef  DEBUG
4449d3bc9Richard Lowe
4549d3bc9Richard Lowe#include "config.h"
4649d3bc9Richard Lowe#include "dwarf_incl.h"
4749d3bc9Richard Lowe#include <sys/types.h>
4849d3bc9Richard Lowe
4949d3bc9Richard Lowe#include <stdlib.h>
5049d3bc9Richard Lowe#include <stdio.h>
5107dc194Richard Lowe#include "malloc_check.h"
5249d3bc9Richard Lowe
5349d3bc9Richard Lowe/*
5449d3bc9Richard Lowe    These files are included to get the sizes
5549d3bc9Richard Lowe    of structs to set the ah_bytes_one_struct field
5649d3bc9Richard Lowe    of the Dwarf_Alloc_Hdr_s structs for each
5749d3bc9Richard Lowe    allocation type.
5849d3bc9Richard Lowe*/
5949d3bc9Richard Lowe#include "dwarf_line.h"
6049d3bc9Richard Lowe#include "dwarf_global.h"
6149d3bc9Richard Lowe#include "dwarf_arange.h"
6249d3bc9Richard Lowe#include "dwarf_abbrev.h"
6349d3bc9Richard Lowe#include "dwarf_die_deliv.h"
6449d3bc9Richard Lowe#include "dwarf_frame.h"
6549d3bc9Richard Lowe#include "dwarf_loc.h"
6649d3bc9Richard Lowe#include "dwarf_funcs.h"
6749d3bc9Richard Lowe#include "dwarf_types.h"
6849d3bc9Richard Lowe#include "dwarf_vars.h"
6949d3bc9Richard Lowe#include "dwarf_weaks.h"
7049d3bc9Richard Lowe
7107dc194Richard Lowe
7249d3bc9Richard Lowestatic void _dwarf_free_special_error(Dwarf_Ptr space);
7307dc194Richard Lowe
7449d3bc9Richard Lowe#ifdef DWARF_SIMPLE_MALLOC
7549d3bc9Richard Lowestatic void _dwarf_simple_malloc_add_to_list(Dwarf_Debug dbg,
7607dc194Richard Lowe    Dwarf_Ptr addr,
7707dc194Richard Lowe    unsigned long size,
7807dc194Richard Lowe    short alloc_type);
7907dc194Richard Lowestatic void _dwarf_simple_malloc_delete_from_list(Dwarf_Debug dbg,
8007dc194Richard Lowe    Dwarf_Ptr space,
8107dc194Richard Lowe    short alloc_type);
8249d3bc9Richard Lowevoid _dwarf_simple_malloc_botch(int err);
8349d3bc9Richard Lowe
8449d3bc9Richard Lowe#endif /* DWARF_SIMPLE_MALLOC */
8549d3bc9Richard Lowe
8649d3bc9Richard Lowe
8749d3bc9Richard Lowe
8849d3bc9Richard Lowe
8949d3bc9Richard Lowe/*
9049d3bc9Richard Lowe    This macro adds the size of a pointer to the size of a
9149d3bc9Richard Lowe    struct that is given to it.  It rounds up the size to
9249d3bc9Richard Lowe    be a multiple of the size of a pointer.  This is done
9349d3bc9Richard Lowe    so that every struct returned by _dwarf_get_alloc()
9449d3bc9Richard Lowe    can be preceded by a pointer to the chunk it came from.
9507dc194Richard Lowe    Before allocating, it checks if the size of struct is less than
9649d3bc9Richard Lowe    the size of a pointer.  If yes, it returns the size
9749d3bc9Richard Lowe    of 2 pointers.  The returned size should be at least
9849d3bc9Richard Lowe    the size of 2 pointers, since the first points to the
9949d3bc9Richard Lowe    chunk the struct was allocated from, and the second
10049d3bc9Richard Lowe    is used to link the free list.
10149d3bc9Richard Lowe
10207dc194Richard Lowe    We want DW_RESERVE to be at least the size of
10307dc194Richard Lowe    a long long and at least the size of a pointer because
10407dc194Richard Lowe    our struct has a long long and we want that aligned right.
10507dc194Richard Lowe    Now Standard C defines long long as 8 bytes, so lets
10607dc194Richard Lowe    make that standard. It will become unworkable when
10707dc194Richard Lowe    long long or pointer grows beyound 8 bytes.
10807dc194Richard Lowe    Unclear what to do with wierd requirements, like
10907dc194Richard Lowe    36 bit pointers.
11049d3bc9Richard Lowe
11149d3bc9Richard Lowe
11249d3bc9Richard Lowe*/
11307dc194Richard Lowe#define DW_RESERVE 8
11449d3bc9Richard Lowe
11507dc194Richard Lowe/* Round size up to the next multiple of DW_RESERVE bytes
11649d3bc9Richard Lowe*/
11749d3bc9Richard Lowe#define ROUND_SIZE(inputsize)                 \
11807dc194Richard Lowe        (((inputsize) % (DW_RESERVE)) == 0 ? \
11949d3bc9Richard Lowe            (inputsize):                      \
12049d3bc9Richard Lowe            ((inputsize)  +                   \
12107dc194Richard Lowe               (DW_RESERVE) - ((inputsize) % (DW_RESERVE)) ))
12207dc194Richard Lowe
12307dc194Richard Lowe#define ROUND_SIZE_WITH_POINTER(i_size) (ROUND_SIZE(i_size) + DW_RESERVE)
12449d3bc9Richard Lowe
12507dc194Richard Lowe/* SMALL_ALLOC is for trivia where allocation is a waste.
12607dc194Richard Lowe   Things that should be removed, really. */
12707dc194Richard Lowe#define SMALL_ALLOC 2
12807dc194Richard Lowe
12907dc194Richard Lowe/* BASE_ALLOC is where a basic allocation makes sense, but 'not too large'.
13007dc194Richard Lowe   No thorough evaluation of this value has been done, though
13107dc194Richard Lowe   it was found wasteful of memory to have BASE_ALLOC be as large as
13207dc194Richard Lowe   BIG_ALLOC. */
13349d3bc9Richard Lowe#define BASE_ALLOC 64
13407dc194Richard Lowe
13507dc194Richard Lowe/* BIG_ALLOC is where a larger-than-BASE_ALLOC
13607dc194Richard Lowe   allocation makes sense, but still 'not too large'.
13707dc194Richard Lowe   No thorough evaluation of this value has been done. */
13849d3bc9Richard Lowe#define BIG_ALLOC  128
13949d3bc9Richard Lowe
14049d3bc9Richard Lowe/* This translates into de_alloc_hdr index
14149d3bc9Richard Lowe** the 0,1,1 entries are special: they don't use the
14249d3bc9Richard Lowe** table values at all.
14349d3bc9Richard Lowe** Rearranging the DW_DLA values would break binary compatibility
14449d3bc9Richard Lowe** so that is not an option.
14549d3bc9Richard Lowe*/
14649d3bc9Richard Lowestruct ial_s {
14707dc194Richard Lowe    int ia_al_num;              /* Index into de_alloc_hdr table. */
14849d3bc9Richard Lowe
14949d3bc9Richard Lowe    /* In bytes, one struct instance. This does not account for extra
15007dc194Richard Lowe       space needed per block, but that (DW_RESERVE) will be added in
15107dc194Richard Lowe       later where it is needed (DW_RESERVE space never added in here).
15207dc194Richard Lowe     */
15349d3bc9Richard Lowe    int ia_struct_size;
15449d3bc9Richard Lowe
15549d3bc9Richard Lowe
15649d3bc9Richard Lowe    /* Number of instances per alloc block. MUST be > 0. */
15749d3bc9Richard Lowe    int ia_base_count;
15807dc194Richard Lowe
15907dc194Richard Lowe    int (*specialconstructor) (Dwarf_Debug, void *);
16007dc194Richard Lowe    void (*specialdestructor) (void *);
16149d3bc9Richard Lowe};
16249d3bc9Richard Lowe
16349d3bc9Richard Lowestatic const
16449d3bc9Richard Lowestruct ial_s index_into_allocated[ALLOC_AREA_INDEX_TABLE_MAX] = {
16507dc194Richard Lowe    {0, 1, 1, 0, 0},            /* none */
16607dc194Richard Lowe    {0, 1, 1, 0, 0},            /* 1 DW_DLA_STRING */
16707dc194Richard Lowe    {1, sizeof(Dwarf_Loc), BASE_ALLOC, 0, 0}
16807dc194Richard Lowe    ,                           /* 2 DW_DLA_LOC */
16907dc194Richard Lowe    {2, sizeof(Dwarf_Locdesc), BASE_ALLOC, 0, 0}
17007dc194Richard Lowe    ,                           /* 3 DW_DLA_LOCDESC */
17107dc194Richard Lowe    {0, 1, 1, 0, 0}
17207dc194Richard Lowe    ,                           /* not used *//* 4 DW_DLA_ELLIST */
17307dc194Richard Lowe    {0, 1, 1, 0, 0}
17407dc194Richard Lowe    ,                           /* not used *//* 5 DW_DLA_BOUNDS */
17507dc194Richard Lowe    {3, sizeof(Dwarf_Block), BASE_ALLOC, 0, 0}
17607dc194Richard Lowe    ,                           /* 6 DW_DLA_BLOCK */
17707dc194Richard Lowe    {0, 1, 1, 0, 0}
17807dc194Richard Lowe    ,                           /* the actual dwarf_debug structure *//* 7 DW_DLA_DEBUG */
17907dc194Richard Lowe    {4, sizeof(struct Dwarf_Die_s), BIG_ALLOC, 0, 0},   /* 8 DW_DLA_DIE
18007dc194Richard Lowe                                                         */
18107dc194Richard Lowe    {5, sizeof(struct Dwarf_Line_s), BIG_ALLOC, 0, 0},  /* 9
18207dc194Richard Lowe                                                           DW_DLA_LINE */
18307dc194Richard Lowe    {6, sizeof(struct Dwarf_Attribute_s), BIG_ALLOC * 2, 0, 0},
18449d3bc9Richard Lowe    /* 10 DW_DLA_ATTR */
18507dc194Richard Lowe    {0, 1, 1, 0, 0},            /* not used *//* 11 DW_DLA_TYPE */
18607dc194Richard Lowe    {0, 1, 1, 0, 0},            /* not used *//* 12 DW_DLA_SUBSCR */
18707dc194Richard Lowe    {7, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0},       /* 13
18807dc194Richard Lowe                                                                   DW_DLA_GLOBAL
18907dc194Richard Lowe                                                                 */
19007dc194Richard Lowe    {8, sizeof(struct Dwarf_Error_s), BASE_ALLOC, 0, 0},        /* 14
19107dc194Richard Lowe                                                                   DW_DLA_ERROR
19207dc194Richard Lowe                                                                 */
19307dc194Richard Lowe    {0, 1, 1, 0, 0},            /* 15 DW_DLA_LIST */
19407dc194Richard Lowe    {0, 1, 1, 0, 0},            /* not used *//* 16 DW_DLA_LINEBUF */
19507dc194Richard Lowe    {9, sizeof(struct Dwarf_Arange_s), BASE_ALLOC, 0, 0},       /* 17
19607dc194Richard Lowe                                                                   DW_DLA_ARANGE
19707dc194Richard Lowe                                                                 */
19807dc194Richard Lowe    {10, sizeof(struct Dwarf_Abbrev_s), BIG_ALLOC, 0, 0},       /* 18
19907dc194Richard Lowe                                                                   DW_DLA_ABBREV
20007dc194Richard Lowe                                                                 */
20107dc194Richard Lowe    {11, sizeof(Dwarf_Frame_Op), BIG_ALLOC, 0, 0}
20207dc194Richard Lowe    ,                           /* 19 DW_DLA_FRAME_OP */
20307dc194Richard Lowe    {12, sizeof(struct Dwarf_Cie_s), BASE_ALLOC, 0, 0}, /* 20
20407dc194Richard Lowe                                                           DW_DLA_CIE */
20507dc194Richard Lowe    {13, sizeof(struct Dwarf_Fde_s), BASE_ALLOC, 0, 0}, /* 21 DW_DLA_FDE */
20607dc194Richard Lowe    {0, 1, 1, 0, 0},            /* 22 DW_DLA_LOC_BLOCK */
20707dc194Richard Lowe    {0, 1, 1, 0, 0},            /* 23 DW_DLA_FRAME_BLOCK */
20807dc194Richard Lowe    {14, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0}, /* 24 DW_DLA_FUNC
20907dc194Richard Lowe                                                              UNUSED */
21007dc194Richard Lowe    {15, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0}, /* 25
21107dc194Richard Lowe                                                              DW_DLA_TYPENAME
21207dc194Richard Lowe                                                              UNUSED */
21307dc194Richard Lowe    {16, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0}, /* 26 DW_DLA_VAR
21407dc194Richard Lowe                                                              UNUSED */
21507dc194Richard Lowe    {17, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0}, /* 27 DW_DLA_WEAK
21607dc194Richard Lowe                                                              UNUSED */
21707dc194Richard Lowe    {0, 1, 1, 0, 0},            /* 28 DW_DLA_ADDR */
21807dc194Richard Lowe    {0, 1,1,0,0 },              /* 29 DW_DLA_RANGES */
21907dc194Richard Lowe
22007dc194Richard Lowe    /* The following DW_DLA data types
22107dc194Richard Lowe       are known only inside libdwarf.  */
22207dc194Richard Lowe
22307dc194Richard Lowe    {18, sizeof(struct Dwarf_Abbrev_List_s), BIG_ALLOC, 0, 0},
22407dc194Richard Lowe    /* 30 DW_DLA_ABBREV_LIST */
22507dc194Richard Lowe
22607dc194Richard Lowe    {19, sizeof(struct Dwarf_Chain_s), BIG_ALLOC, 0, 0}, /* 31 DW_DLA_CHAIN */
22707dc194Richard Lowe    {20, sizeof(struct Dwarf_CU_Context_s), BASE_ALLOC, 0, 0},
22807dc194Richard Lowe    /* 32 DW_DLA_CU_CONTEXT */
22907dc194Richard Lowe    {21, sizeof(struct Dwarf_Frame_s), BASE_ALLOC,
23007dc194Richard Lowe     _dwarf_frame_constructor,
23107dc194Richard Lowe     _dwarf_frame_destructor},  /* 33 DW_DLA_FRAME */
23207dc194Richard Lowe    {22, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
23307dc194Richard Lowe    /* 34 DW_DLA_GLOBAL_CONTEXT */
23407dc194Richard Lowe    {23, sizeof(struct Dwarf_File_Entry_s), BASE_ALLOC, 0, 0},  /* 34 */
23507dc194Richard Lowe    /* 35 DW_DLA_FILE_ENTRY */
23607dc194Richard Lowe    {24, sizeof(struct Dwarf_Line_Context_s), BASE_ALLOC, 0, 0},
23707dc194Richard Lowe    /* 36 DW_DLA_LINE_CONTEXT */
23807dc194Richard Lowe    {25, sizeof(struct Dwarf_Loc_Chain_s), BASE_ALLOC, 0, 0},   /* 36 */
23907dc194Richard Lowe    /* 37 DW_DLA_LOC_CHAIN */
24007dc194Richard Lowe
24107dc194Richard Lowe    {26, sizeof(struct Dwarf_Hash_Table_s),BASE_ALLOC, 0, 0},   /* 37 */
24207dc194Richard Lowe    /* 38 DW_DLA_HASH_TABLE */
24349d3bc9Richard Lowe
24449d3bc9Richard Lowe/* The following really use Global struct: used to be unique struct
24549d3bc9Richard Lowe   per type, but now merged (11/99).  The opaque types
24607dc194Richard Lowe   are visible in the interface. The types  for
24707dc194Richard Lowe   DW_DLA_FUNC,
24807dc194Richard Lowe   DW_DLA_TYPENAME, DW_DLA_VAR, DW_DLA_WEAK also use
24907dc194Richard Lowe   the global types.
25007dc194Richard Lowe
25149d3bc9Richard Lowe*/
25207dc194Richard Lowe    {27, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
25307dc194Richard Lowe    /* 39 DW_DLA_FUNC_CONTEXT */
25407dc194Richard Lowe    {28, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
25507dc194Richard Lowe    /* 40 DW_DLA_TYPENAME_CONTEXT */
25607dc194Richard Lowe    {29, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
25707dc194Richard Lowe    /* 41 DW_DLA_VAR_CONTEXT */
25807dc194Richard Lowe    {30, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
25907dc194Richard Lowe    /* 42 DW_DLA_WEAK_CONTEXT */
26007dc194Richard Lowe    {31, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
26107dc194Richard Lowe    /* 43 DW_DLA_PUBTYPES_CONTEXT DWARF3 */
26207dc194Richard Lowe
26307dc194Richard Lowe    {0,1,1,0,0 },
26407dc194Richard Lowe    /* 44 DW_DLA_HASH_TABLE_ENTRY */
26507dc194Richard Lowe
26607dc194Richard Lowe
26749d3bc9Richard Lowe};
26849d3bc9Richard Lowe
26949d3bc9Richard Lowe#ifndef DWARF_SIMPLE_MALLOC
27049d3bc9Richard Lowe
27149d3bc9Richard Lowe/*
27249d3bc9Richard Lowe    This function is given a pointer to the header
27349d3bc9Richard Lowe    structure that is used to allocate 1 struct of
27449d3bc9Richard Lowe    the type given by alloc_type.  It first checks
27549d3bc9Richard Lowe    if a struct is available in its free list.  If
27649d3bc9Richard Lowe    not, it checks if 1 is available in its blob,
27749d3bc9Richard Lowe    which is a chunk of memory that is reserved for
27849d3bc9Richard Lowe    its use.  If not, it malloc's a chunk.  The
27949d3bc9Richard Lowe    initial part of it is used to store the end
28049d3bc9Richard Lowe    address of the chunk, and also to keep track
28149d3bc9Richard Lowe    of the number of free structs in that chunk.
28249d3bc9Richard Lowe    This information is used for freeing the chunk
28349d3bc9Richard Lowe    when all the structs in it are free.
28449d3bc9Richard Lowe
28549d3bc9Richard Lowe    Assume all input arguments have been validated.
28649d3bc9Richard Lowe
28749d3bc9Richard Lowe    This function can be used only to allocate 1
28849d3bc9Richard Lowe    struct of the given type.
28949d3bc9Richard Lowe
29049d3bc9Richard Lowe    It returns a pointer to the struct that the
29149d3bc9Richard Lowe    user can use.  It returns NULL only when it
29249d3bc9Richard Lowe    is out of free structs, and cannot malloc
29349d3bc9Richard Lowe    any more.  The struct returned is zero-ed.
29449d3bc9Richard Lowe
29549d3bc9Richard Lowe    A pointer to the chunk that the struct belongs
29649d3bc9Richard Lowe    to is stored in the bytes preceding the
29749d3bc9Richard Lowe    returned address.  Since this pointer it
29849d3bc9Richard Lowe    never overwritten, when a struct is allocated
29949d3bc9Richard Lowe    from the free_list this pointer does not
30049d3bc9Richard Lowe    have to be written.  In the 2 other cases,
30149d3bc9Richard Lowe    where the struct is allocated from a new
30249d3bc9Richard Lowe    chunk, or the blob, a pointer to the chunk
30349d3bc9Richard Lowe    is written.
30449d3bc9Richard Lowe*/
30549d3bc9Richard Lowestatic Dwarf_Ptr
30649d3bc9Richard Lowe_dwarf_find_memory(Dwarf_Alloc_Hdr alloc_hdr)
30749d3bc9Richard Lowe{
30849d3bc9Richard Lowe    /* Pointer to the struct allocated. */
30949d3bc9Richard Lowe    Dwarf_Small *ret_mem = 0;
31049d3bc9Richard Lowe
31149d3bc9Richard Lowe    /* Pointer to info about chunks allocated. */
31249d3bc9Richard Lowe    Dwarf_Alloc_Area alloc_area;
31349d3bc9Richard Lowe
31449d3bc9Richard Lowe    /* Size of chunk malloc'ed when no free structs left. */
31549d3bc9Richard Lowe    Dwarf_Signed mem_block_size;
31649d3bc9Richard Lowe
31749d3bc9Richard Lowe    /* Pointer to block malloc'ed. */
31849d3bc9Richard Lowe    Dwarf_Small *mem_block;
31949d3bc9Richard Lowe
32049d3bc9Richard Lowe    /*
32149d3bc9Richard Lowe       Check the alloc_area from which the last allocation was made
32207dc194Richard Lowe       (most recent new block). If that is not successful, then search
32307dc194Richard Lowe       the list of alloc_area's from alloc_header. */
32449d3bc9Richard Lowe    alloc_area = alloc_hdr->ah_last_alloc_area;
32549d3bc9Richard Lowe    if (alloc_area == NULL || alloc_area->aa_free_structs_in_chunk == 0)
32607dc194Richard Lowe        for (alloc_area = alloc_hdr->ah_alloc_area_head;
32707dc194Richard Lowe             alloc_area != NULL; alloc_area = alloc_area->aa_next) {
32849d3bc9Richard Lowe
32907dc194Richard Lowe            if (alloc_area->aa_free_structs_in_chunk > 0) {
33007dc194Richard Lowe                break;          /* found a free entry! */
33107dc194Richard Lowe            }
33249d3bc9Richard Lowe
33307dc194Richard Lowe        }
33449d3bc9Richard Lowe
33549d3bc9Richard Lowe    if (alloc_area != NULL) {
33607dc194Richard Lowe        alloc_area->aa_free_structs_in_chunk--;
33707dc194Richard Lowe
33807dc194Richard Lowe        if (alloc_area->aa_free_list != NULL) {
33907dc194Richard Lowe            ret_mem = alloc_area->aa_free_list;
34007dc194Richard Lowe
34107dc194Richard Lowe            /*
34207dc194Richard Lowe               Update the free list.  The initial part of the struct is
34307dc194Richard Lowe               used to hold a pointer to the next struct on the free
34407dc194Richard Lowe               list.  In this way, the free list chain is maintained at
34507dc194Richard Lowe               0 memory cost. */
34607dc194Richard Lowe            alloc_area->aa_free_list =
34707dc194Richard Lowe                ((Dwarf_Free_List) ret_mem)->fl_next;
34807dc194Richard Lowe        } else if (alloc_area->aa_blob_start < alloc_area->aa_blob_end) {
34907dc194Richard Lowe            ret_mem = alloc_area->aa_blob_start;
35007dc194Richard Lowe
35107dc194Richard Lowe            /*
35207dc194Richard Lowe               Store pointer to chunk this struct belongs to in the
35307dc194Richard Lowe               first few bytes.  Return pointer to bytes after this
35407dc194Richard Lowe               pointer storage. */
35507dc194Richard Lowe            *(Dwarf_Alloc_Area *) ret_mem = alloc_area;
35607dc194Richard Lowe            ret_mem += DW_RESERVE;
35707dc194Richard Lowe
35807dc194Richard Lowe            alloc_area->aa_blob_start += alloc_hdr->ah_bytes_one_struct;
35907dc194Richard Lowe        } else {
36007dc194Richard Lowe            /* else fall thru , though it should be impossible to fall
36107dc194Richard Lowe               thru. And represents a disastrous programming error if
36207dc194Richard Lowe               we get here. */
36349d3bc9Richard Lowe#ifdef DEBUG
36407dc194Richard Lowe            fprintf(stderr, "libdwarf Internal error start %x end %x\n",
36507dc194Richard Lowe                    (int) alloc_area->aa_blob_start,
36607dc194Richard Lowe                    (int) alloc_area->aa_blob_end);
36749d3bc9Richard Lowe#endif
36807dc194Richard Lowe        }
36949d3bc9Richard Lowe    }
37049d3bc9Richard Lowe
37149d3bc9Richard Lowe    /* New memory has to malloc'ed since there are no free structs. */
37249d3bc9Richard Lowe    if (ret_mem == 0) {
37307dc194Richard Lowe        Dwarf_Word rounded_area_hdr_size;
37407dc194Richard Lowe
37507dc194Richard Lowe        alloc_hdr->ah_chunks_allocated++;
37607dc194Richard Lowe
37707dc194Richard Lowe        {                       /* this nonsense avoids a warning */
37807dc194Richard Lowe            /* CONSTCOND would be better */
37907dc194Richard Lowe            unsigned long v = sizeof(struct Dwarf_Alloc_Area_s);
38007dc194Richard Lowe
38107dc194Richard Lowe            rounded_area_hdr_size = ROUND_SIZE(v);
38207dc194Richard Lowe        }
38307dc194Richard Lowe
38407dc194Richard Lowe        /*
38507dc194Richard Lowe           Allocate memory to contain the required number of structs
38607dc194Richard Lowe           and the Dwarf_Alloc_Area_s to control it. */
38707dc194Richard Lowe        mem_block_size = alloc_hdr->ah_bytes_malloc_per_chunk +
38807dc194Richard Lowe            rounded_area_hdr_size;
38907dc194Richard Lowe
39007dc194Richard Lowe        mem_block = malloc(mem_block_size);
39107dc194Richard Lowe        if (mem_block == NULL) {
39207dc194Richard Lowe            return (NULL);
39307dc194Richard Lowe        }
39407dc194Richard Lowe
39507dc194Richard Lowe
39607dc194Richard Lowe        /*
39707dc194Richard Lowe           Attach the Dwarf_Alloc_Area_s struct to the list of chunks
39807dc194Richard Lowe           malloc'ed for this struct type. Also initialize the fields
39907dc194Richard Lowe           of the Dwarf_Alloc_Area_s. */
40007dc194Richard Lowe        alloc_area = (Dwarf_Alloc_Area) mem_block;
40107dc194Richard Lowe        alloc_area->aa_prev = 0;
40207dc194Richard Lowe        if (alloc_hdr->ah_alloc_area_head != NULL) {
40307dc194Richard Lowe            alloc_hdr->ah_alloc_area_head->aa_prev = alloc_area;
40407dc194Richard Lowe        }
40507dc194Richard Lowe        alloc_area->aa_free_list = 0;
40607dc194Richard Lowe        alloc_area->aa_next = alloc_hdr->ah_alloc_area_head;
40707dc194Richard Lowe        alloc_hdr->ah_alloc_area_head = alloc_area;
40807dc194Richard Lowe
40907dc194Richard Lowe        alloc_area->aa_alloc_hdr = alloc_hdr;
41007dc194Richard Lowe        alloc_area->aa_free_structs_in_chunk =
41107dc194Richard Lowe            (Dwarf_Sword) alloc_hdr->ah_structs_per_chunk - 1;
41207dc194Richard Lowe        if (alloc_area->aa_free_structs_in_chunk < 1) {
41307dc194Richard Lowe            /* If we get here, there is a disastrous programming error
41407dc194Richard Lowe               somewhere. */
41549d3bc9Richard Lowe#ifdef DEBUG
41607dc194Richard Lowe            fprintf(stderr,
41707dc194Richard Lowe                    "libdwarf Internal error: free structs in chunk %d\n",
41807dc194Richard Lowe                    (int) alloc_area->aa_free_structs_in_chunk);
41949d3bc9Richard Lowe#endif
42007dc194Richard Lowe            return NULL;
42107dc194Richard Lowe        }
42207dc194Richard Lowe
42307dc194Richard Lowe        /*
42407dc194Richard Lowe           The struct returned begins immediately after the
42507dc194Richard Lowe           Dwarf_Alloc_Area_s struct. */
42607dc194Richard Lowe        ret_mem = mem_block + rounded_area_hdr_size;
42707dc194Richard Lowe        alloc_area->aa_blob_start =
42807dc194Richard Lowe            ret_mem + alloc_hdr->ah_bytes_one_struct;
42907dc194Richard Lowe        alloc_area->aa_blob_end = mem_block + mem_block_size;
43007dc194Richard Lowe
43107dc194Richard Lowe        /*
43207dc194Richard Lowe           Store pointer to chunk this struct belongs to in the first
43307dc194Richard Lowe           few bytes.  Return pointer to bytes after this pointer
43407dc194Richard Lowe           storage. */
43507dc194Richard Lowe        *(Dwarf_Alloc_Area *) ret_mem = alloc_area;
43607dc194Richard Lowe        ret_mem += DW_RESERVE;
43749d3bc9Richard Lowe    }
43849d3bc9Richard Lowe
43949d3bc9Richard Lowe    alloc_hdr->ah_last_alloc_area = alloc_area;
44049d3bc9Richard Lowe    alloc_hdr->ah_struct_user_holds++;
44107dc194Richard Lowe    memset(ret_mem, 0, alloc_hdr->ah_bytes_one_struct - DW_RESERVE);
44249d3bc9Richard Lowe    return (ret_mem);
44349d3bc9Richard Lowe}
44449d3bc9Richard Lowe
44549d3bc9Richard Lowe#endif /* ndef DWARF_SIMPLE_MALLOC */
44649d3bc9Richard Lowe
44749d3bc9Richard Lowe/*
44849d3bc9Richard Lowe    This function returns a pointer to a region
44949d3bc9Richard Lowe    of memory.  For alloc_types that are not
45049d3bc9Richard Lowe    strings or lists of pointers, only 1 struct
45149d3bc9Richard Lowe    can be requested at a time.  This is indicated
45249d3bc9Richard Lowe    by an input count of 1.  For strings, count
45349d3bc9Richard Lowe    equals the length of the string it will
45449d3bc9Richard Lowe    contain, i.e it the length of the string
45549d3bc9Richard Lowe    plus 1 for the terminating null.  For lists
45649d3bc9Richard Lowe    of pointers, count is equal to the number of
45707dc194Richard Lowe    pointers.  For DW_DLA_FRAME_BLOCK, DW_DLA_RANGES, and
45849d3bc9Richard Lowe    DW_DLA_LOC_BLOCK allocation types also, count
45949d3bc9Richard Lowe    is the count of the number of structs needed.
46049d3bc9Richard Lowe
46149d3bc9Richard Lowe    This function cannot be used to allocate a
46249d3bc9Richard Lowe    Dwarf_Debug_s struct.
46307dc194Richard Lowe
46449d3bc9Richard Lowe*/
46549d3bc9Richard LoweDwarf_Ptr
46649d3bc9Richard Lowe_dwarf_get_alloc(Dwarf_Debug dbg,
46707dc194Richard Lowe                 Dwarf_Small alloc_type, Dwarf_Unsigned count)
46849d3bc9Richard Lowe{
46949d3bc9Richard Lowe    Dwarf_Alloc_Hdr alloc_hdr;
47049d3bc9Richard Lowe
47149d3bc9Richard Lowe    Dwarf_Ptr ret_mem;
47249d3bc9Richard Lowe
47349d3bc9Richard Lowe    Dwarf_Signed size = 0;
47449d3bc9Richard Lowe    unsigned int index;
47549d3bc9Richard Lowe    unsigned int type = alloc_type;
47649d3bc9Richard Lowe
47749d3bc9Richard Lowe    if (dbg == NULL) {
47807dc194Richard Lowe        return (NULL);
47949d3bc9Richard Lowe    }
48049d3bc9Richard Lowe
48149d3bc9Richard Lowe    if (type >= ALLOC_AREA_INDEX_TABLE_MAX) {
48207dc194Richard Lowe        /* internal error */
48307dc194Richard Lowe        return NULL;
48449d3bc9Richard Lowe    }
48549d3bc9Richard Lowe    index = index_into_allocated[type].ia_al_num;
48649d3bc9Richard Lowe    /* zero also illegal but not tested for */
48749d3bc9Richard Lowe
48849d3bc9Richard Lowe    /* If the Dwarf_Debug is not fully set up, we will get index 0 for
48949d3bc9Richard Lowe       any type and must do something.  'Not fully set up' can only
49049d3bc9Richard Lowe       happen for DW_DLA_ERROR, I (davea) believe, and for that we call
49149d3bc9Richard Lowe       special code here.. */
49249d3bc9Richard Lowe
49349d3bc9Richard Lowe    if (index == 0) {
49407dc194Richard Lowe        if (alloc_type == DW_DLA_STRING) {
49507dc194Richard Lowe            size = count;
49607dc194Richard Lowe        } else if (alloc_type == DW_DLA_LIST) {
49707dc194Richard Lowe            size = count * sizeof(Dwarf_Ptr);
49807dc194Richard Lowe        } else if (alloc_type == DW_DLA_FRAME_BLOCK) {
49907dc194Richard Lowe            size = count * sizeof(Dwarf_Frame_Op);
50007dc194Richard Lowe        } else if (alloc_type == DW_DLA_LOC_BLOCK) {
50107dc194Richard Lowe            size = count * sizeof(Dwarf_Loc);
50207dc194Richard Lowe        } else if (alloc_type == DW_DLA_HASH_TABLE_ENTRY) {
50307dc194Richard Lowe            size = count * sizeof(struct Dwarf_Hash_Table_Entry_s);
50407dc194Richard Lowe        } else if (alloc_type == DW_DLA_ADDR) {
50507dc194Richard Lowe            size = count *
50607dc194Richard Lowe                (sizeof(Dwarf_Addr) > sizeof(Dwarf_Off) ?
50707dc194Richard Lowe                 sizeof(Dwarf_Addr) : sizeof(Dwarf_Off));
50807dc194Richard Lowe        } else if (alloc_type == DW_DLA_RANGES) {
50907dc194Richard Lowe            size = count * sizeof(Dwarf_Ranges);
51007dc194Richard Lowe        } else if (alloc_type == DW_DLA_ERROR) {
51107dc194Richard Lowe            void *m = _dwarf_special_no_dbg_error_malloc();
51207dc194Richard Lowe
51307dc194Richard Lowe            dwarf_malloc_check_alloc_data(m, DW_DLA_ERROR);
51407dc194Richard Lowe            return m;
51507dc194Richard Lowe
51607dc194Richard Lowe        } else {
51707dc194Richard Lowe            /* If we get here, there is a disastrous programming error
51807dc194Richard Lowe               somewhere. */
51949d3bc9Richard Lowe#ifdef DEBUG
52007dc194Richard Lowe            fprintf(stderr,
52107dc194Richard Lowe                    "libdwarf Internal error: type %d  unexpected\n",
52207dc194Richard Lowe                    (int) type);
52349d3bc9Richard Lowe#endif
52407dc194Richard Lowe        }
52549d3bc9Richard Lowe    } else {
52607dc194Richard Lowe        alloc_hdr = &dbg->de_alloc_hdr[index];
52707dc194Richard Lowe        if (alloc_hdr->ah_bytes_one_struct > 0) {
52849d3bc9Richard Lowe#ifdef DWARF_SIMPLE_MALLOC
52907dc194Richard Lowe            size = alloc_hdr->ah_bytes_one_struct;
53049d3bc9Richard Lowe#else
53107dc194Richard Lowe            {
53207dc194Richard Lowe                void *m = _dwarf_find_memory(alloc_hdr);
53307dc194Richard Lowe
53407dc194Richard Lowe                dwarf_malloc_check_alloc_data(m, type);
53507dc194Richard Lowe                if (index_into_allocated[type].specialconstructor) {
53607dc194Richard Lowe                    int res =
53707dc194Richard Lowe                        index_into_allocated[type].
53807dc194Richard Lowe                        specialconstructor(dbg, m);
53907dc194Richard Lowe                    if (res != DW_DLV_OK) {
54007dc194Richard Lowe                        /* We leak what we allocated in
54107dc194Richard Lowe                           _dwarf_find_memory when constructor fails. */
54207dc194Richard Lowe                        return NULL;
54307dc194Richard Lowe                    }
54407dc194Richard Lowe                }
54507dc194Richard Lowe                return m;
54607dc194Richard Lowe            }
54749d3bc9Richard Lowe#endif
54849d3bc9Richard Lowe
54907dc194Richard Lowe        } else {
55007dc194Richard Lowe            /* Special case: should not really happen at all. */
55107dc194Richard Lowe            if (type == DW_DLA_ERROR) {
55207dc194Richard Lowe                /* dwarf_init failure. Because dbg is incomplete we
55307dc194Richard Lowe                   won't use it to record the malloc. */
55407dc194Richard Lowe                void *m = _dwarf_special_no_dbg_error_malloc();
55507dc194Richard Lowe
55607dc194Richard Lowe                dwarf_malloc_check_alloc_data(m, DW_DLA_ERROR);
55707dc194Richard Lowe                return m;
55807dc194Richard Lowe            } else {
55907dc194Richard Lowe                /* If we get here, there is a disastrous programming
56007dc194Richard Lowe                   error somewhere. */
56149d3bc9Richard Lowe#ifdef DWARF_SIMPLE_MALLOC
56207dc194Richard Lowe                _dwarf_simple_malloc_botch(3);
56349d3bc9Richard Lowe#endif
56449d3bc9Richard Lowe#ifdef DEBUG
56507dc194Richard Lowe                fprintf(stderr,
56607dc194Richard Lowe                        "libdwarf Internal error: Type %d  unexpected\n",
56707dc194Richard Lowe                        (int) type);
56849d3bc9Richard Lowe#endif
56907dc194Richard Lowe            }
57007dc194Richard Lowe        }
57149d3bc9Richard Lowe    }
57249d3bc9Richard Lowe
57349d3bc9Richard Lowe    ret_mem = malloc(size);
57449d3bc9Richard Lowe#ifdef DWARF_SIMPLE_MALLOC
57507dc194Richard Lowe    _dwarf_simple_malloc_add_to_list(dbg, ret_mem, (unsigned long) size,
57607dc194Richard Lowe                                     type);
57749d3bc9Richard Lowe#endif
57849d3bc9Richard Lowe    if (ret_mem != NULL)
57907dc194Richard Lowe        memset(ret_mem, 0, size);
58007dc194Richard Lowe
58107dc194Richard Lowe    dwarf_malloc_check_alloc_data(ret_mem, type);
58207dc194Richard Lowe    if (index_into_allocated[type].specialconstructor) {
58307dc194Richard Lowe        int res =
58407dc194Richard Lowe            index_into_allocated[type].specialconstructor(dbg, ret_mem);
58507dc194Richard Lowe        if (res != DW_DLV_OK) {
58607dc194Richard Lowe            /* We leak what we allocated in _dwarf_find_memory when
58707dc194Richard Lowe               constructor fails. */
58807dc194Richard Lowe            return NULL;
58907dc194Richard Lowe        }
59007dc194Richard Lowe    }
59149d3bc9Richard Lowe
59249d3bc9Richard Lowe    return (ret_mem);
59349d3bc9Richard Lowe}
59449d3bc9Richard Lowe
59549d3bc9Richard Lowe
59607dc194Richard Lowe
59749d3bc9Richard Lowe/*
59849d3bc9Richard Lowe    This function is used to deallocate a region of memory
59949d3bc9Richard Lowe    that was obtained by a call to _dwarf_get_alloc.  Note
60049d3bc9Richard Lowe    that though dwarf_dealloc() is a public function,
60149d3bc9Richard Lowe    _dwarf_get_alloc() isn't.
60249d3bc9Richard Lowe
60349d3bc9Richard Lowe    For lists, typically arrays of pointers, it is assumed
60449d3bc9Richard Lowe    that the space was allocated by a direct call to malloc,
60549d3bc9Richard Lowe    and so a straight free() is done.  This is also the case
60649d3bc9Richard Lowe    for variable length blocks such as DW_DLA_FRAME_BLOCK
60707dc194Richard Lowe    and DW_DLA_LOC_BLOCK and DW_DLA_RANGES.
60849d3bc9Richard Lowe
60949d3bc9Richard Lowe    For strings, the pointer might point to a string in
61049d3bc9Richard Lowe    .debug_info or .debug_string.  After this is checked,
61149d3bc9Richard Lowe    and if found not to be the case, a free() is done,
61249d3bc9Richard Lowe    again on the assumption that a malloc was used to
61349d3bc9Richard Lowe    obtain the space.
61449d3bc9Richard Lowe
61549d3bc9Richard Lowe    For other types of structs, a pointer to the chunk that
61649d3bc9Richard Lowe    the struct was allocated out of, is present in the bytes
61749d3bc9Richard Lowe    preceding the pointer passed in.  For this chunk it is
61849d3bc9Richard Lowe    checked whether all the structs in that chunk are now free.
61949d3bc9Richard Lowe    If so, the entire chunk is free_ed.  Otherwise, the space
62049d3bc9Richard Lowe    is added to the free list for that chunk, and the free count
62149d3bc9Richard Lowe    incremented.
62249d3bc9Richard Lowe
62349d3bc9Richard Lowe    This function does not return anything.
62449d3bc9Richard Lowe*/
62549d3bc9Richard Lowevoid
62649d3bc9Richard Lowedwarf_dealloc(Dwarf_Debug dbg,
62707dc194Richard Lowe              Dwarf_Ptr space, Dwarf_Unsigned alloc_type)
62849d3bc9Richard Lowe{
62949d3bc9Richard Lowe    Dwarf_Alloc_Hdr alloc_hdr;
63049d3bc9Richard Lowe    Dwarf_Alloc_Area alloc_area;
63149d3bc9Richard Lowe    unsigned int type = alloc_type;
63249d3bc9Richard Lowe    unsigned int index;
63349d3bc9Richard Lowe
63449d3bc9Richard Lowe    if (space == NULL) {
63507dc194Richard Lowe        return;
63649d3bc9Richard Lowe    }
63707dc194Richard Lowe    if (type == DW_DLA_ERROR) {
63807dc194Richard Lowe        /* Get pointer to Dwarf_Alloc_Area this struct came from. See
63907dc194Richard Lowe           dwarf_alloc.h ROUND_SIZE_WITH_POINTER stuff */
64007dc194Richard Lowe        alloc_area =
64107dc194Richard Lowe            *(Dwarf_Alloc_Area *) ((char *) space - DW_RESERVE);
64207dc194Richard Lowe        if (alloc_area == 0) {
64307dc194Richard Lowe            /* This is the special case of a failed dwarf_init(). Also
64407dc194Richard Lowe               (and more signficantly) there are a variety of other
64507dc194Richard Lowe               situations where libdwarf does not *know* what dbg is
64607dc194Richard Lowe               involved (because of a libdwarf-caller-error) so
64707dc194Richard Lowe               libdwarf uses NULL as the dbg. Those too wind up here. */
64807dc194Richard Lowe            _dwarf_free_special_error(space);
64907dc194Richard Lowe            dwarf_malloc_check_dealloc_data(space, type);
65007dc194Richard Lowe            return;
65107dc194Richard Lowe        }
65249d3bc9Richard Lowe
65349d3bc9Richard Lowe    }
65449d3bc9Richard Lowe    if (dbg == NULL) {
65507dc194Richard Lowe        /* App error, or an app that failed to succeed in a
65607dc194Richard Lowe           dwarf_init() call. */
65707dc194Richard Lowe        return;
65849d3bc9Richard Lowe    }
65949d3bc9Richard Lowe    if (type >= ALLOC_AREA_INDEX_TABLE_MAX) {
66007dc194Richard Lowe        /* internal or user app error */
66107dc194Richard Lowe        return;
66249d3bc9Richard Lowe    }
66349d3bc9Richard Lowe
66407dc194Richard Lowe    index = index_into_allocated[type].ia_al_num;
66549d3bc9Richard Lowe    /*
66649d3bc9Richard Lowe       A string pointer may point into .debug_info or .debug_string.
66749d3bc9Richard Lowe       Otherwise, they are directly malloc'ed. */
66807dc194Richard Lowe    dwarf_malloc_check_dealloc_data(space, type);
66949d3bc9Richard Lowe    if (index == 0) {
67007dc194Richard Lowe        if (type == DW_DLA_STRING) {
67107dc194Richard Lowe            if ((Dwarf_Small *) space >= dbg->de_debug_info.dss_data &&
67207dc194Richard Lowe                (Dwarf_Small *) space <
67307dc194Richard Lowe                dbg->de_debug_info.dss_data + dbg->de_debug_info.dss_size)
67407dc194Richard Lowe                return;
67507dc194Richard Lowe
67607dc194Richard Lowe            if (dbg->de_debug_line.dss_data != NULL &&
67707dc194Richard Lowe                (Dwarf_Small *) space >= dbg->de_debug_line.dss_data &&
67807dc194Richard Lowe                (Dwarf_Small *) space <
67907dc194Richard Lowe                dbg->de_debug_line.dss_data + dbg->de_debug_line.dss_size)
68007dc194Richard Lowe                return;
68107dc194Richard Lowe
68207dc194Richard Lowe            if (dbg->de_debug_pubnames.dss_data != NULL &&
68307dc194Richard Lowe                (Dwarf_Small *) space >= dbg->de_debug_pubnames.dss_data &&
68407dc194Richard Lowe                (Dwarf_Small *) space <
68507dc194Richard Lowe                dbg->de_debug_pubnames.dss_data +
68607dc194Richard Lowe                dbg->de_debug_pubnames.dss_size)
68707dc194Richard Lowe                return;
68807dc194Richard Lowe
68907dc194Richard Lowe            if (dbg->de_debug_frame.dss_data != NULL &&
69007dc194Richard Lowe                (Dwarf_Small *) space >= dbg->de_debug_frame.dss_data &&
69107dc194Richard Lowe                (Dwarf_Small *) space <
69207dc194Richard Lowe                dbg->de_debug_frame.dss_data + dbg->de_debug_frame.dss_size)
69307dc194Richard Lowe                return;
69407dc194Richard Lowe
69507dc194Richard Lowe            if (dbg->de_debug_str.dss_data != NULL &&
69607dc194Richard Lowe                (Dwarf_Small *) space >= dbg->de_debug_str.dss_data &&
69707dc194Richard Lowe                (Dwarf_Small *) space <
69807dc194Richard Lowe                dbg->de_debug_str.dss_data + dbg->de_debug_str.dss_size)
69907dc194Richard Lowe                return;
70007dc194Richard Lowe
70107dc194Richard Lowe            if (dbg->de_debug_funcnames.dss_data != NULL &&
70207dc194Richard Lowe                (Dwarf_Small *) space >= dbg->de_debug_funcnames.dss_data &&
70307dc194Richard Lowe                (Dwarf_Small *) space <
70407dc194Richard Lowe                dbg->de_debug_funcnames.dss_data +
70507dc194Richard Lowe                dbg->de_debug_funcnames.dss_size)
70607dc194Richard Lowe                return;
70707dc194Richard Lowe
70807dc194Richard Lowe            if (dbg->de_debug_typenames.dss_data != NULL &&
70907dc194Richard Lowe                (Dwarf_Small *) space >= dbg->de_debug_typenames.dss_data &&
71007dc194Richard Lowe                (Dwarf_Small *) space <
71107dc194Richard Lowe                dbg->de_debug_typenames.dss_data +
71207dc194Richard Lowe                dbg->de_debug_typenames.dss_size)
71307dc194Richard Lowe                return;
71407dc194Richard Lowe            if (dbg->de_debug_pubtypes.dss_data != NULL &&
71507dc194Richard Lowe                (Dwarf_Small *) space >= dbg->de_debug_pubtypes.dss_data &&
71607dc194Richard Lowe                (Dwarf_Small *) space <
71707dc194Richard Lowe                    dbg->de_debug_pubtypes.dss_data +
71807dc194Richard Lowe                    dbg->de_debug_pubtypes.dss_size)
71907dc194Richard Lowe                return;
72007dc194Richard Lowe
72107dc194Richard Lowe            if (dbg->de_debug_varnames.dss_data != NULL &&
72207dc194Richard Lowe                (Dwarf_Small *) space >= dbg->de_debug_varnames.dss_data &&
72307dc194Richard Lowe                (Dwarf_Small *) space <
72407dc194Richard Lowe                dbg->de_debug_varnames.dss_data +
72507dc194Richard Lowe                dbg->de_debug_varnames.dss_size)
72607dc194Richard Lowe                return;
72707dc194Richard Lowe
72807dc194Richard Lowe            if (dbg->de_debug_weaknames.dss_data != NULL &&
72907dc194Richard Lowe                (Dwarf_Small *) space >= dbg->de_debug_weaknames.dss_data &&
73007dc194Richard Lowe                (Dwarf_Small *) space <
73107dc194Richard Lowe                dbg->de_debug_weaknames.dss_data +
73207dc194Richard Lowe                dbg->de_debug_weaknames.dss_size)
73307dc194Richard Lowe                return;
73407dc194Richard Lowe
73507dc194Richard Lowe#ifdef DWARF_SIMPLE_MALLOC
73607dc194Richard Lowe            _dwarf_simple_malloc_delete_from_list(dbg, space, type);
73707dc194Richard Lowe#endif
73807dc194Richard Lowe            free(space);
73907dc194Richard Lowe            return;
74007dc194Richard Lowe        }
74107dc194Richard Lowe
74207dc194Richard Lowe        if (type == DW_DLA_LIST ||
74307dc194Richard Lowe            type == DW_DLA_FRAME_BLOCK ||
74407dc194Richard Lowe            type == DW_DLA_LOC_BLOCK || type == DW_DLA_ADDR ||
74507dc194Richard Lowe            type == DW_DLA_RANGES ||
74607dc194Richard Lowe            type == DW_DLA_HASH_TABLE_ENTRY) {
74707dc194Richard Lowe
74807dc194Richard Lowe#ifdef DWARF_SIMPLE_MALLOC
74907dc194Richard Lowe            _dwarf_simple_malloc_delete_from_list(dbg, space, type);
75007dc194Richard Lowe#endif
75107dc194Richard Lowe            free(space);
75207dc194Richard Lowe            return;
75307dc194Richard Lowe        }
75407dc194Richard Lowe        /* else is an alloc type that is not used */
75507dc194Richard Lowe        /* app or internal error */
75649d3bc9Richard Lowe#ifdef DWARF_SIMPLE_MALLOC
75749d3bc9Richard Lowe        _dwarf_simple_malloc_botch(4);
75849d3bc9Richard Lowe#endif
75907dc194Richard Lowe        return;
76049d3bc9Richard Lowe
76149d3bc9Richard Lowe    }
76207dc194Richard Lowe    if (index_into_allocated[type].specialdestructor) {
76307dc194Richard Lowe        index_into_allocated[type].specialdestructor(space);
76407dc194Richard Lowe    }
76549d3bc9Richard Lowe#ifdef DWARF_SIMPLE_MALLOC
76607dc194Richard Lowe    _dwarf_simple_malloc_delete_from_list(dbg, space, type);
76749d3bc9Richard Lowe    free(space);
76807dc194Richard Lowe#else /* !DWARF_SIMPLE_MALLOC */
76949d3bc9Richard Lowe    alloc_hdr = &dbg->de_alloc_hdr[index];
77049d3bc9Richard Lowe
77149d3bc9Richard Lowe    /* Get pointer to Dwarf_Alloc_Area this struct came from. See
77249d3bc9Richard Lowe       dwarf_alloc.h ROUND_SIZE_WITH_POINTER stuff */
77307dc194Richard Lowe    alloc_area = *(Dwarf_Alloc_Area *) ((char *) space - DW_RESERVE);
77449d3bc9Richard Lowe
77507dc194Richard Lowe    /* ASSERT: alloc_area != NULL If NULL we could abort, let it
77607dc194Richard Lowe       coredump below, or return, pretending all is well. We go on,
77707dc194Richard Lowe       letting program crash. Is caller error. */
77849d3bc9Richard Lowe
77949d3bc9Richard Lowe    /*
78049d3bc9Richard Lowe       Check that the alloc_hdr field of the alloc_area we have is
78149d3bc9Richard Lowe       pointing to the right alloc_hdr.  This is used to catch use of
78249d3bc9Richard Lowe       incorrect deallocation code by the user. */
78349d3bc9Richard Lowe    if (alloc_area->aa_alloc_hdr != alloc_hdr) {
78407dc194Richard Lowe        /* If we get here, the user has called dwarf_dealloc wrongly or
78507dc194Richard Lowe           there is some other disastrous error. By leaking mem here we
78607dc194Richard Lowe           try to be safe... */
78749d3bc9Richard Lowe#ifdef DEBUG
78807dc194Richard Lowe        fprintf(stderr,
78907dc194Richard Lowe                "libdwarf Internal error: type %d hdr mismatch %lx %lx "
79007dc194Richard Lowe                "area ptr %lx\n",
79107dc194Richard Lowe                (int) type,
79207dc194Richard Lowe                (long) alloc_area->aa_alloc_hdr,
79307dc194Richard Lowe                (long) alloc_hdr, (long) alloc_area);
79449d3bc9Richard Lowe#endif
79507dc194Richard Lowe        return;
79649d3bc9Richard Lowe    }
79749d3bc9Richard Lowe
79849d3bc9Richard Lowe    alloc_hdr->ah_struct_user_holds--;
79949d3bc9Richard Lowe    alloc_area->aa_free_structs_in_chunk++;
80049d3bc9Richard Lowe
80149d3bc9Richard Lowe    /*
80249d3bc9Richard Lowe       Give chunk back to malloc only when every struct is freed */
80349d3bc9Richard Lowe    if (alloc_area->aa_free_structs_in_chunk ==
80407dc194Richard Lowe        alloc_hdr->ah_structs_per_chunk) {
80507dc194Richard Lowe        if (alloc_area->aa_prev != NULL) {
80607dc194Richard Lowe            alloc_area->aa_prev->aa_next = alloc_area->aa_next;
80707dc194Richard Lowe        } else {
80807dc194Richard Lowe            alloc_hdr->ah_alloc_area_head = alloc_area->aa_next;
80907dc194Richard Lowe        }
81007dc194Richard Lowe
81107dc194Richard Lowe        if (alloc_area->aa_next != NULL) {
81207dc194Richard Lowe            alloc_area->aa_next->aa_prev = alloc_area->aa_prev;
81307dc194Richard Lowe        }
81407dc194Richard Lowe
81507dc194Richard Lowe        alloc_hdr->ah_chunks_allocated--;
81607dc194Richard Lowe
81707dc194Richard Lowe        if (alloc_area == alloc_hdr->ah_last_alloc_area) {
81807dc194Richard Lowe            alloc_hdr->ah_last_alloc_area = NULL;
81907dc194Richard Lowe        }
82007dc194Richard Lowe        memset(alloc_area, 0, sizeof(*alloc_area));
82107dc194Richard Lowe        free(alloc_area);
82249d3bc9Richard Lowe    }
82349d3bc9Richard Lowe
82449d3bc9Richard Lowe    else {
82507dc194Richard Lowe        ((Dwarf_Free_List) space)->fl_next = alloc_area->aa_free_list;
82607dc194Richard Lowe        alloc_area->aa_free_list = space;
82749d3bc9Richard Lowe    }
82849d3bc9Richard Lowe#endif /* !DWARF_SIMPLE_MALLOC */
82949d3bc9Richard Lowe}
83049d3bc9Richard Lowe
83149d3bc9Richard Lowe
83249d3bc9Richard Lowe/*
83349d3bc9Richard Lowe    Allocates space for a Dwarf_Debug_s struct,
83449d3bc9Richard Lowe    since one does not exist.
83549d3bc9Richard Lowe*/
83649d3bc9Richard LoweDwarf_Debug
83749d3bc9Richard Lowe_dwarf_get_debug(void
83849d3bc9Richard Lowe    )
83949d3bc9Richard Lowe{
84049d3bc9Richard Lowe    Dwarf_Debug dbg;
84149d3bc9Richard Lowe
84249d3bc9Richard Lowe    dbg = (Dwarf_Debug) malloc(sizeof(struct Dwarf_Debug_s));
84349d3bc9Richard Lowe    if (dbg == NULL)
84407dc194Richard Lowe        return (NULL);
84549d3bc9Richard Lowe    else
84607dc194Richard Lowe        memset(dbg, 0, sizeof(struct Dwarf_Debug_s));
84749d3bc9Richard Lowe    return (dbg);
84849d3bc9Richard Lowe}
84949d3bc9Richard Lowe
85049d3bc9Richard Lowe
85149d3bc9Richard Lowe/*
85249d3bc9Richard Lowe    Sets up the Dwarf_Debug_s struct for all the
85349d3bc9Richard Lowe    allocation types currently defined.
85449d3bc9Richard Lowe    Allocation types DW_DLA_STRING, DW_DLA_LIST,
85507dc194Richard Lowe    DW_DLA_FRAME_BLOCK, DW_DLA_LOC_BLOCK, DW_DLA_RANGES are
85649d3bc9Richard Lowe    malloc'ed directly.
85749d3bc9Richard Lowe
85849d3bc9Richard Lowe    This routine should be called after _dwarf_setup(),
85949d3bc9Richard Lowe    so that information about the sizes of the Dwarf
86049d3bc9Richard Lowe    sections can be used to decide the number of
86149d3bc9Richard Lowe    structs of each type malloc'ed.
86249d3bc9Richard Lowe
86349d3bc9Richard Lowe    Also DW_DLA_ELLIST, DW_DLA_BOUNDS, DW_DLA_TYPE,
86449d3bc9Richard Lowe    DW_DLA_SUBSCR, DW_DLA_LINEBUF allocation types
86549d3bc9Richard Lowe    are currently not used.
86649d3bc9Richard Lowe    The ah_bytes_one_struct and ah_structs_per_chunk fields for
86749d3bc9Richard Lowe    these types have been set to 1 for efficiency
86849d3bc9Richard Lowe    in dwarf_get_alloc().
86949d3bc9Richard Lowe
87049d3bc9Richard Lowe    Ah_alloc_num should be greater than 1 for all
87149d3bc9Richard Lowe    types that are currently being used.
87249d3bc9Richard Lowe
87349d3bc9Richard Lowe    Therefore, for these allocation types the
87449d3bc9Richard Lowe    ah_bytes_one_struct, and ah_structs_per_chunk fields do not
87549d3bc9Richard Lowe    need to be initialized.
87649d3bc9Richard Lowe
87749d3bc9Richard Lowe    Being an internal routine, assume proper dbg.
87849d3bc9Richard Lowe*/
87949d3bc9Richard Lowe
88049d3bc9Richard LoweDwarf_Debug
88149d3bc9Richard Lowe_dwarf_setup_debug(Dwarf_Debug dbg)
88249d3bc9Richard Lowe{
88349d3bc9Richard Lowe    int i;
88449d3bc9Richard Lowe
88549d3bc9Richard Lowe    for (i = 1; i <= MAX_DW_DLA; i++) {
88607dc194Richard Lowe        const struct ial_s *ialp = &index_into_allocated[i];
88707dc194Richard Lowe        unsigned int hdr_index = ialp->ia_al_num;
88807dc194Richard Lowe        Dwarf_Word str_size = ialp->ia_struct_size;
88907dc194Richard Lowe        Dwarf_Word str_count = ialp->ia_base_count;
89007dc194Richard Lowe        Dwarf_Word rnded_size = ROUND_SIZE_WITH_POINTER(str_size);
89149d3bc9Richard Lowe
89207dc194Richard Lowe        Dwarf_Alloc_Hdr alloc_hdr = &dbg->de_alloc_hdr[hdr_index];
89349d3bc9Richard Lowe
89407dc194Richard Lowe        alloc_hdr->ah_bytes_one_struct = (Dwarf_Half) rnded_size;
89549d3bc9Richard Lowe
89607dc194Richard Lowe        /* ah_structs_per_chunk must be >0 else we are in trouble */
89707dc194Richard Lowe        alloc_hdr->ah_structs_per_chunk = str_count;
89807dc194Richard Lowe        alloc_hdr->ah_bytes_malloc_per_chunk = rnded_size * str_count;
89949d3bc9Richard Lowe    }
90049d3bc9Richard Lowe    return (dbg);
90149d3bc9Richard Lowe}
90249d3bc9Richard Lowe
90349d3bc9Richard Lowe/*
90449d3bc9Richard Lowe    This function prints out the statistics
90549d3bc9Richard Lowe    collected on allocation of memory chunks.
90649d3bc9Richard Lowe*/
90749d3bc9Richard Lowevoid
90849d3bc9Richard Lowedwarf_print_memory_stats(Dwarf_Debug dbg)
90949d3bc9Richard Lowe{
91049d3bc9Richard Lowe    Dwarf_Alloc_Hdr alloc_hdr;
91149d3bc9Richard Lowe    Dwarf_Shalf i;
91249d3bc9Richard Lowe
91349d3bc9Richard Lowe    /*
91407dc194Richard Lowe       Alloc types start at 1, not 0. Hence, the first NULL string, and
91507dc194Richard Lowe       also a size of MAX_DW_DLA + 1. */
91649d3bc9Richard Lowe    char *alloc_type_name[MAX_DW_DLA + 1] = {
91707dc194Richard Lowe        "",
91807dc194Richard Lowe        "DW_DLA_STRING",
91907dc194Richard Lowe        "DW_DLA_LOC",
92007dc194Richard Lowe        "DW_DLA_LOCDESC",
92107dc194Richard Lowe        "DW_DLA_ELLIST",
92207dc194Richard Lowe        "DW_DLA_BOUNDS",
92307dc194Richard Lowe        "DW_DLA_BLOCK",
92407dc194Richard Lowe        "DW_DLA_DEBUG",
92507dc194Richard Lowe        "DW_DLA_DIE",
92607dc194Richard Lowe        "DW_DLA_LINE",
92707dc194Richard Lowe        "DW_DLA_ATTR",
92807dc194Richard Lowe        "DW_DLA_TYPE",
92907dc194Richard Lowe        "DW_DLA_SUBSCR",
93007dc194Richard Lowe        "DW_DLA_GLOBAL",
93107dc194Richard Lowe        "DW_DLA_ERROR",
93207dc194Richard Lowe        "DW_DLA_LIST",
93307dc194Richard Lowe        "DW_DLA_LINEBUF",
93407dc194Richard Lowe        "DW_DLA_ARANGE",
93507dc194Richard Lowe        "DW_DLA_ABBREV",
93607dc194Richard Lowe        "DW_DLA_FRAME_OP",
93707dc194Richard Lowe        "DW_DLA_CIE",
93807dc194Richard Lowe        "DW_DLA_FDE",
93907dc194Richard Lowe        "DW_DLA_LOC_BLOCK",
94007dc194Richard Lowe        "DW_DLA_FRAME_BLOCK",
94107dc194Richard Lowe        "DW_DLA_FUNC",
94207dc194Richard Lowe        "DW_DLA_TYPENAME",
94307dc194Richard Lowe        "DW_DLA_VAR",
94407dc194Richard Lowe        "DW_DLA_WEAK",
94507dc194Richard Lowe        "DW_DLA_ADDR",
94607dc194Richard Lowe        "DW_DLA_RANGES",
94707dc194Richard Lowe        "DW_DLA_ABBREV_LIST",
94807dc194Richard Lowe        "DW_DLA_CHAIN",
94907dc194Richard Lowe        "DW_DLA_CU_CONTEXT",
95007dc194Richard Lowe        "DW_DLA_FRAME",
95107dc194Richard Lowe        "DW_DLA_GLOBAL_CONTEXT",
95207dc194Richard Lowe        "DW_DLA_FILE_ENTRY",
95307dc194Richard Lowe        "DW_DLA_LINE_CONTEXT",
95407dc194Richard Lowe        "DW_DLA_LOC_CHAIN",
95507dc194Richard Lowe        "DW_DLA_HASH_TABLE",
95607dc194Richard Lowe        "DW_DLA_FUNC_CONTEXT",
95707dc194Richard Lowe        "DW_DLA_TYPENAME_CONTEXT",
95807dc194Richard Lowe        "DW_DLA_VAR_CONTEXT",
95907dc194Richard Lowe        "DW_DLA_WEAK_CONTEXT",
96007dc194Richard Lowe        "DW_DLA_PUBTYPES_CONTEXT",
96107dc194Richard Lowe        "DW_DLA_HASH_TABLE_ENTRY",
96249d3bc9Richard Lowe    };
96349d3bc9Richard Lowe
96449d3bc9Richard Lowe    if (dbg == NULL)
96507dc194Richard Lowe        return;
96649d3bc9Richard Lowe
96749d3bc9Richard Lowe    printf("Size of Dwarf_Debug        %4ld bytes\n",
96807dc194Richard Lowe           (long) sizeof(*dbg));
96949d3bc9Richard Lowe    printf("Size of Dwarf_Alloc_Hdr_s  %4ld bytes\n",
97007dc194Richard Lowe           (long) sizeof(struct Dwarf_Alloc_Hdr_s));
97149d3bc9Richard Lowe    printf("size of Dwarf_Alloc_Area_s %4ld bytes\n",
97207dc194Richard Lowe           (long) sizeof(struct Dwarf_Alloc_Area_s));
97349d3bc9Richard Lowe
97449d3bc9Richard Lowe    printf("   Alloc Type                   Curr  Structs byt   str\n");
97549d3bc9Richard Lowe    printf("   ----------                   ----  ------- per   per\n");
97649d3bc9Richard Lowe    for (i = 1; i <= MAX_DW_DLA; i++) {
97707dc194Richard Lowe        int indx = index_into_allocated[i].ia_al_num;
97807dc194Richard Lowe
97907dc194Richard Lowe        alloc_hdr = &dbg->de_alloc_hdr[indx];
98007dc194Richard Lowe        if (alloc_hdr->ah_bytes_one_struct != 1) {
98107dc194Richard Lowe            printf("%2d %-25s   %6d %8d %6d %6d\n",
98207dc194Richard Lowe                   (int) i,
98307dc194Richard Lowe                   alloc_type_name[i],
98407dc194Richard Lowe                   (int) alloc_hdr->ah_chunks_allocated,
98507dc194Richard Lowe                   (int) alloc_hdr->ah_struct_user_holds,
98607dc194Richard Lowe                   (int) alloc_hdr->ah_bytes_malloc_per_chunk,
98707dc194Richard Lowe                   (int) alloc_hdr->ah_structs_per_chunk);
98807dc194Richard Lowe        }
98949d3bc9Richard Lowe    }
99049d3bc9Richard Lowe}
99149d3bc9Richard Lowe
99249d3bc9Richard Lowe
99349d3bc9Richard Lowe#ifndef DWARF_SIMPLE_MALLOC
99449d3bc9Richard Lowe/*
99507dc194Richard Lowe    This recursively frees
99607dc194Richard Lowe    the chunks still allocated, and
99749d3bc9Richard Lowe    forward chained through the aa_next
99849d3bc9Richard Lowe    pointer.
99949d3bc9Richard Lowe*/
100049d3bc9Richard Lowestatic void
100149d3bc9Richard Lowe_dwarf_recursive_free(Dwarf_Alloc_Area alloc_area)
100249d3bc9Richard Lowe{
100349d3bc9Richard Lowe    if (alloc_area->aa_next != NULL) {
100407dc194Richard Lowe        _dwarf_recursive_free(alloc_area->aa_next);
100549d3bc9Richard Lowe    }
100649d3bc9Richard Lowe
100749d3bc9Richard Lowe    alloc_area->aa_next = 0;
100849d3bc9Richard Lowe    alloc_area->aa_prev = 0;
100949d3bc9Richard Lowe    free(alloc_area);
101049d3bc9Richard Lowe}
101149d3bc9Richard Lowe#endif
101249d3bc9Richard Lowe
101307dc194Richard Lowe/* In the 'rela' relocation case we might have malloc'd
101407dc194Richard Lowe   space to ensure it is read-write. In that case, free the space.  */
101507dc194Richard Lowestatic void
101607dc194Richard Lowerela_free(struct Dwarf_Section_s * sec)
101707dc194Richard Lowe{
101807dc194Richard Lowe    if (sec->dss_data_was_malloc) {
101907dc194Richard Lowe        free(sec->dss_data);
102007dc194Richard Lowe    }
102107dc194Richard Lowe    sec->dss_data = 0;
102207dc194Richard Lowe    sec->dss_data_was_malloc = 0;
102307dc194Richard Lowe}
102407dc194Richard Lowe
102549d3bc9Richard Lowe/*
102649d3bc9Richard Lowe    Used to free all space allocated for this Dwarf_Debug.
102749d3bc9Richard Lowe    The caller should assume that the Dwarf_Debug pointer
102849d3bc9Richard Lowe    itself is no longer valid upon return from this function.
102949d3bc9Richard Lowe
103049d3bc9Richard Lowe    In case of difficulty, this function simply returns quietly.
103149d3bc9Richard Lowe*/
103249d3bc9Richard Loweint
103349d3bc9Richard Lowe_dwarf_free_all_of_one_debug(Dwarf_Debug dbg)
103449d3bc9Richard Lowe{
103549d3bc9Richard Lowe    Dwarf_Alloc_Hdr alloc_hdr;
103649d3bc9Richard Lowe    Dwarf_Shalf i;
103707dc194Richard Lowe    Dwarf_CU_Context context = 0;
103807dc194Richard Lowe    Dwarf_CU_Context nextcontext = 0;
103949d3bc9Richard Lowe
104049d3bc9Richard Lowe    if (dbg == NULL)
104107dc194Richard Lowe        return (DW_DLV_ERROR);
104207dc194Richard Lowe
104307dc194Richard Lowe    /* To do complete validation that we have no surprising missing or
104407dc194Richard Lowe       erroneous deallocs it is advisable to do the dwarf_deallocs here
104507dc194Richard Lowe       that are not things the user can otherwise request.
104607dc194Richard Lowe       Housecleaning.  */
104707dc194Richard Lowe
104807dc194Richard Lowe    for (context = dbg->de_cu_context_list;
104907dc194Richard Lowe         context; context = nextcontext) {
105007dc194Richard Lowe        Dwarf_Hash_Table hash_table = context->cc_abbrev_hash_table;
105107dc194Richard Lowe        _dwarf_free_abbrev_hash_table_contents(dbg,hash_table);
105207dc194Richard Lowe        nextcontext = context->cc_next;
105307dc194Richard Lowe        dwarf_dealloc(dbg, hash_table, DW_DLA_HASH_TABLE);
105407dc194Richard Lowe        dwarf_dealloc(dbg, context, DW_DLA_CU_CONTEXT);
105507dc194Richard Lowe    }
105649d3bc9Richard Lowe
105707dc194Richard Lowe    /* Housecleaning done. Now really free all the space. */
105849d3bc9Richard Lowe#ifdef DWARF_SIMPLE_MALLOC
105907dc194Richard Lowe    if (dbg->de_simple_malloc_base) {
106007dc194Richard Lowe        struct simple_malloc_record_s *smp = dbg->de_simple_malloc_base;
106107dc194Richard Lowe
106207dc194Richard Lowe        while (smp) {
106307dc194Richard Lowe            int i;
106407dc194Richard Lowe            struct simple_malloc_record_s *prev_smp = 0;
106507dc194Richard Lowe
106607dc194Richard Lowe            for (i = 0; i < smp->sr_used; ++i) {
106707dc194Richard Lowe                struct simple_malloc_entry_s *cur;
106807dc194Richard Lowe
106907dc194Richard Lowe                cur = &smp->sr_entry[i];
107007dc194Richard Lowe                if (cur->se_addr != 0) {
107107dc194Richard Lowe                    free(cur->se_addr);
107207dc194Richard Lowe                    cur->se_addr = 0;
107307dc194Richard Lowe                }
107407dc194Richard Lowe            }
107507dc194Richard Lowe            prev_smp = smp;
107607dc194Richard Lowe            smp = smp->sr_next;
107707dc194Richard Lowe            free(prev_smp);
107807dc194Richard Lowe        }
107907dc194Richard Lowe        dbg->de_simple_malloc_base = 0;
108049d3bc9Richard Lowe    }
108149d3bc9Richard Lowe#else
108249d3bc9Richard Lowe    for (i = 1; i < ALLOC_AREA_REAL_TABLE_MAX; i++) {
108307dc194Richard Lowe        int indx = i;
108449d3bc9Richard Lowe
108507dc194Richard Lowe        alloc_hdr = &dbg->de_alloc_hdr[indx];
108607dc194Richard Lowe        if (alloc_hdr->ah_alloc_area_head != NULL) {
108707dc194Richard Lowe            _dwarf_recursive_free(alloc_hdr->ah_alloc_area_head);
108807dc194Richard Lowe        }
108949d3bc9Richard Lowe    }
109049d3bc9Richard Lowe
109149d3bc9Richard Lowe#endif
109207dc194Richard Lowe    rela_free(&dbg->de_debug_info);
109307dc194Richard Lowe    rela_free(&dbg->de_debug_abbrev);
109407dc194Richard Lowe    rela_free(&dbg->de_debug_line);
109507dc194Richard Lowe    rela_free(&dbg->de_debug_loc);
109607dc194Richard Lowe    rela_free(&dbg->de_debug_aranges);
109707dc194Richard Lowe    rela_free(&dbg->de_debug_macinfo);
109807dc194Richard Lowe    rela_free(&dbg->de_debug_pubnames);
109907dc194Richard Lowe    rela_free(&dbg->de_debug_str);
110007dc194Richard Lowe    rela_free(&dbg->de_debug_frame);
110107dc194Richard Lowe    rela_free(&dbg->de_debug_frame_eh_gnu);
110207dc194Richard Lowe    rela_free(&dbg->de_debug_pubtypes);
110307dc194Richard Lowe    rela_free(&dbg->de_debug_funcnames);
110407dc194Richard Lowe    rela_free(&dbg->de_debug_typenames);
110507dc194Richard Lowe    rela_free(&dbg->de_debug_varnames);
110607dc194Richard Lowe    rela_free(&dbg->de_debug_weaknames);
110707dc194Richard Lowe    rela_free(&dbg->de_debug_ranges);
110807dc194Richard Lowe    dwarf_harmless_cleanout(&dbg->de_harmless_errors);
110907dc194Richard Lowe
111007dc194Richard Lowe    memset(dbg, 0, sizeof(*dbg)); /* Prevent accidental use later. */
111149d3bc9Richard Lowe    free(dbg);
111249d3bc9Richard Lowe    return (DW_DLV_OK);
111349d3bc9Richard Lowe}
111449d3bc9Richard Lowe
111549d3bc9Richard Lowe/* A special case: we have no dbg, no alloc header etc.
111649d3bc9Richard Lowe   So create something out of thin air that we can recognize
111749d3bc9Richard Lowe   in dwarf_dealloc.
111849d3bc9Richard Lowe   Something with the prefix (prefix space hidden from caller).
111949d3bc9Richard Lowe
112049d3bc9Richard Lowe   Only applies to DW_DLA_ERROR, making up an error record.
112149d3bc9Richard Lowe*/
112249d3bc9Richard Lowe
112349d3bc9Richard Lowestruct Dwarf_Error_s *
112449d3bc9Richard Lowe_dwarf_special_no_dbg_error_malloc(void)
112549d3bc9Richard Lowe{
112649d3bc9Richard Lowe    /* the union unused things are to guarantee proper alignment */
112749d3bc9Richard Lowe    union u {
112807dc194Richard Lowe        Dwarf_Alloc_Area ptr_not_used;
112907dc194Richard Lowe        struct Dwarf_Error_s base_not_used;
113007dc194Richard Lowe        char data_space[sizeof(struct Dwarf_Error_s) +
113107dc194Richard Lowe                        (DW_RESERVE * 2)];
113249d3bc9Richard Lowe    };
113349d3bc9Richard Lowe    char *mem;
113449d3bc9Richard Lowe
113549d3bc9Richard Lowe    mem = malloc(sizeof(union u));
113649d3bc9Richard Lowe
113749d3bc9Richard Lowe    if (mem == 0) {
113807dc194Richard Lowe        return 0;
113949d3bc9Richard Lowe
114049d3bc9Richard Lowe    }
114107dc194Richard Lowe    memset(mem, 0, sizeof(union u));
114207dc194Richard Lowe    mem += DW_RESERVE;
114349d3bc9Richard Lowe    return (struct Dwarf_Error_s *) mem;
114449d3bc9Richard Lowe}
114549d3bc9Richard Lowe
114649d3bc9Richard Lowe/* The free side of  _dwarf_special_no_dbg_error_malloc()
114749d3bc9Richard Lowe*/
114849d3bc9Richard Lowestatic void
114949d3bc9Richard Lowe_dwarf_free_special_error(Dwarf_Ptr space)
115049d3bc9Richard Lowe{
115149d3bc9Richard Lowe    char *mem = (char *) space;
115249d3bc9Richard Lowe
115307dc194Richard Lowe    mem -= DW_RESERVE;
115449d3bc9Richard Lowe    free(mem);
115549d3bc9Richard Lowe}
115649d3bc9Richard Lowe
115749d3bc9Richard Lowe
115849d3bc9Richard Lowe#ifdef DWARF_SIMPLE_MALLOC
115949d3bc9Richard Lowe/* here solely for planting a breakpoint. */
116049d3bc9Richard Lowe/* ARGSUSED */
116149d3bc9Richard Lowevoid
116249d3bc9Richard Lowe_dwarf_simple_malloc_botch(int err)
116349d3bc9Richard Lowe{
116407dc194Richard Lowe       fprintf(stderr,"simple malloc botch %d\n",err);
116549d3bc9Richard Lowe}
116607dc194Richard Lowestatic void
116749d3bc9Richard Lowe_dwarf_simple_malloc_add_to_list(Dwarf_Debug dbg,
116807dc194Richard Lowe                                 Dwarf_Ptr addr,
116907dc194Richard Lowe                                 unsigned long size, short alloc_type)
117049d3bc9Richard Lowe{
117107dc194Richard Lowe    struct simple_malloc_record_s *cur;
117207dc194Richard Lowe    struct simple_malloc_entry_s *newentry;
117307dc194Richard Lowe
117407dc194Richard Lowe    if (!dbg->de_simple_malloc_base) {
117507dc194Richard Lowe        /* First entry to this routine. */
117607dc194Richard Lowe        dbg->de_simple_malloc_base =
117707dc194Richard Lowe            malloc(sizeof(struct simple_malloc_record_s));
117807dc194Richard Lowe        if (!dbg->de_simple_malloc_base) {
117907dc194Richard Lowe            _dwarf_simple_malloc_botch(7);
118007dc194Richard Lowe            return;             /* no memory, give up */
118107dc194Richard Lowe        }
118207dc194Richard Lowe        memset(dbg->de_simple_malloc_base,
118307dc194Richard Lowe               0, sizeof(struct simple_malloc_record_s));
118407dc194Richard Lowe    }
118507dc194Richard Lowe    cur = dbg->de_simple_malloc_base;
118607dc194Richard Lowe
118707dc194Richard Lowe    if (cur->sr_used >= DSM_BLOCK_COUNT) {
118807dc194Richard Lowe        /* Better not be > than as that means chaos */
118907dc194Richard Lowe
119007dc194Richard Lowe        /* Create a new block to link at the head. */
119107dc194Richard Lowe
119207dc194Richard Lowe        struct simple_malloc_record_s *newblock =
119307dc194Richard Lowe            malloc(sizeof(struct simple_malloc_record_s));
119407dc194Richard Lowe        if (!newblock) {
119507dc194Richard Lowe            _dwarf_simple_malloc_botch(8);
119607dc194Richard Lowe            return;             /* Can do nothing, out of memory */
119707dc194Richard Lowe        }
119807dc194Richard Lowe        memset(newblock, 0, sizeof(struct simple_malloc_record_s));
119907dc194Richard Lowe        /* Link the new block at the head of the chain, and make it
120007dc194Richard Lowe           'current' */
120107dc194Richard Lowe        dbg->de_simple_malloc_base = newblock;
120207dc194Richard Lowe        newblock->sr_next = cur;
120307dc194Richard Lowe        cur = newblock;
120407dc194Richard Lowe    }
120507dc194Richard Lowe    newentry = &cur->sr_entry[cur->sr_used];
120607dc194Richard Lowe    newentry->se_addr = addr;
120707dc194Richard Lowe    newentry->se_size = size;
120807dc194Richard Lowe    newentry->se_type = alloc_type;
120907dc194Richard Lowe    ++cur->sr_used;
121049d3bc9Richard Lowe}
121107dc194Richard Lowe
121249d3bc9Richard Lowe/*
121307dc194Richard Lowe   DWARF_SIMPLE_MALLOC: testing the hypothesis that the existing
121407dc194Richard Lowe   malloc scheme here (see _dwarf_get_alloc()) is pointless complexity.
121549d3bc9Richard Lowe
121649d3bc9Richard Lowe   DWARF_SIMPLE_MALLOC also makes it easy for a malloc-tracing
121749d3bc9Richard Lowe   tool to verify libdwarf malloc has no botches (though of course
121849d3bc9Richard Lowe   such does not test the complicated standard-libdwarf-alloc code).
121949d3bc9Richard Lowe
122049d3bc9Richard Lowe   To properly answer the question, the simple-malloc allocate
122149d3bc9Richard Lowe   and delete should be something other than a simple list.
122249d3bc9Richard Lowe   Perhaps a heap, or perhaps a red-black tree.
122349d3bc9Richard Lowe
122449d3bc9Richard Lowe*/
122549d3bc9Richard Lowestatic void
122607dc194Richard Lowe_dwarf_simple_malloc_delete_from_list(Dwarf_Debug dbg,
122707dc194Richard Lowe                                      Dwarf_Ptr space, short alloc_type)
122849d3bc9Richard Lowe{
122907dc194Richard Lowe    if (space == 0) {
123007dc194Richard Lowe        _dwarf_simple_malloc_botch(6);
123149d3bc9Richard Lowe    }
123207dc194Richard Lowe    if (dbg->de_simple_malloc_base) {
123349d3bc9Richard Lowe        struct simple_malloc_record_s *smp = dbg->de_simple_malloc_base;
123407dc194Richard Lowe
123507dc194Richard Lowe        while (smp) {
123649d3bc9Richard Lowe            int i;
123749d3bc9Richard Lowe
123807dc194Richard Lowe            for (i = 0; i < smp->sr_used; ++i) {
123949d3bc9Richard Lowe                struct simple_malloc_entry_s *cur;
124007dc194Richard Lowe
124149d3bc9Richard Lowe                cur = &smp->sr_entry[i];
124207dc194Richard Lowe                if (cur->se_addr == space) {
124307dc194Richard Lowe                    if (cur->se_type != alloc_type) {
124407dc194Richard Lowe                        _dwarf_simple_malloc_botch(0);
124507dc194Richard Lowe                    }
124607dc194Richard Lowe                    cur->se_addr = 0;
124707dc194Richard Lowe                    return;
124849d3bc9Richard Lowe                }
124949d3bc9Richard Lowe            }
125049d3bc9Richard Lowe            smp = smp->sr_next;
125149d3bc9Richard Lowe        }
125249d3bc9Richard Lowe    }
125307dc194Richard Lowe    /* Never found the space. */
125449d3bc9Richard Lowe    _dwarf_simple_malloc_botch(1);
125549d3bc9Richard Lowe    return;
125649d3bc9Richard Lowe
125749d3bc9Richard Lowe}
125849d3bc9Richard Lowe#endif
1259