149d3bc91SRichard Lowe /* 249d3bc91SRichard Lowe Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. 307dc1947SRichard Lowe Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. 4*4d9fdb46SRobert Mustacchi Portions Copyright 2011-2019. David Anderson. All Rights Reserved. 5*4d9fdb46SRobert Mustacchi 6*4d9fdb46SRobert Mustacchi This program is free software; you can redistribute it 7*4d9fdb46SRobert Mustacchi and/or modify it under the terms of version 2.1 of the 8*4d9fdb46SRobert Mustacchi GNU Lesser General Public License as published by the Free 9*4d9fdb46SRobert Mustacchi Software Foundation. 10*4d9fdb46SRobert Mustacchi 11*4d9fdb46SRobert Mustacchi This program is distributed in the hope that it would be 12*4d9fdb46SRobert Mustacchi useful, but WITHOUT ANY WARRANTY; without even the implied 13*4d9fdb46SRobert Mustacchi warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 14*4d9fdb46SRobert Mustacchi PURPOSE. 15*4d9fdb46SRobert Mustacchi 16*4d9fdb46SRobert Mustacchi Further, this software is distributed without any warranty 17*4d9fdb46SRobert Mustacchi that it is free of the rightful claim of any third person 18*4d9fdb46SRobert Mustacchi regarding infringement or the like. Any license provided 19*4d9fdb46SRobert Mustacchi herein, whether implied or otherwise, applies only to this 20*4d9fdb46SRobert Mustacchi software file. Patent licenses, if any, provided herein 21*4d9fdb46SRobert Mustacchi do not apply to combinations of this program with other 22*4d9fdb46SRobert Mustacchi software, or any other product whatsoever. 23*4d9fdb46SRobert Mustacchi 24*4d9fdb46SRobert Mustacchi You should have received a copy of the GNU Lesser General 25*4d9fdb46SRobert Mustacchi Public License along with this program; if not, write the 26*4d9fdb46SRobert Mustacchi Free Software Foundation, Inc., 51 Franklin Street - Fifth 27*4d9fdb46SRobert Mustacchi Floor, Boston MA 02110-1301, USA. 2849d3bc91SRichard Lowe 2949d3bc91SRichard Lowe */ 3049d3bc91SRichard Lowe 3149d3bc91SRichard Lowe #include "config.h" 3207dc1947SRichard Lowe #include "pro_incl.h" 33*4d9fdb46SRobert Mustacchi #include <stddef.h> 34*4d9fdb46SRobert Mustacchi #include "dwarf.h" 35*4d9fdb46SRobert Mustacchi #include "libdwarf.h" 36*4d9fdb46SRobert Mustacchi #include "pro_opaque.h" 37*4d9fdb46SRobert Mustacchi #include "pro_alloc.h" 3807dc1947SRichard Lowe #ifdef HAVE_STDLIB_H 3949d3bc91SRichard Lowe #include <stdlib.h> 4007dc1947SRichard Lowe #endif /* HAVE_STDLIB_H */ 41*4d9fdb46SRobert Mustacchi #ifdef HAVE_MALLOC_H 42*4d9fdb46SRobert Mustacchi /* Useful include for some Windows compilers. */ 43*4d9fdb46SRobert Mustacchi #include <malloc.h> 44*4d9fdb46SRobert Mustacchi #endif /* HAVE_MALLOC_H */ 4507dc1947SRichard Lowe #ifdef HAVE_STRING_H 4607dc1947SRichard Lowe #include <string.h> 4707dc1947SRichard Lowe #endif /* HAVE_STRING_H */ 48*4d9fdb46SRobert Mustacchi #ifdef HAVE_STDINT_H 49*4d9fdb46SRobert Mustacchi #include <stdint.h> /* For uintptr_t */ 50*4d9fdb46SRobert Mustacchi #endif /* HAVE_STDINT_H */ 51*4d9fdb46SRobert Mustacchi #ifdef HAVE_INTTYPES_H 52*4d9fdb46SRobert Mustacchi #include <inttypes.h> 53*4d9fdb46SRobert Mustacchi #endif /* HAVE_INTTYPES_H */ 54*4d9fdb46SRobert Mustacchi #include "dwarf_tsearch.h" 55*4d9fdb46SRobert Mustacchi 56*4d9fdb46SRobert Mustacchi /* When each block is allocated, there is a two-word structure 57*4d9fdb46SRobert Mustacchi allocated at the beginning so the block can go on a list. 58*4d9fdb46SRobert Mustacchi The address returned is the address *after* the two pointers 59*4d9fdb46SRobert Mustacchi at the start. But this allows us to be given a pointer to 60*4d9fdb46SRobert Mustacchi a generic block, and go backwards to find the list-node. Then 61*4d9fdb46SRobert Mustacchi we can remove this block from it's list without the need to search 62*4d9fdb46SRobert Mustacchi through a linked list in order to remove the node. It also allows 63*4d9fdb46SRobert Mustacchi us to 'delete' a memory block without needing the dbg structure. 64*4d9fdb46SRobert Mustacchi We still need the dbg structure on allocation so that we know which 65*4d9fdb46SRobert Mustacchi linked list to add the block to. 66*4d9fdb46SRobert Mustacchi 67*4d9fdb46SRobert Mustacchi Only the allocation of the dbg structure itself cannot use 68*4d9fdb46SRobert Mustacchi _dwarf_p_get_alloc. 69*4d9fdb46SRobert Mustacchi That structure should be set up by hand, and the two list pointers 70*4d9fdb46SRobert Mustacchi should be initialized to point at the node itself. That initializes 71*4d9fdb46SRobert Mustacchi the doubly linked list. */ 7207dc1947SRichard Lowe 7307dc1947SRichard Lowe #define LIST_TO_BLOCK(lst) ((void*) (((char *)lst) + sizeof(memory_list_t))) 7407dc1947SRichard Lowe #define BLOCK_TO_LIST(blk) ((memory_list_t*) (((char*)blk) - sizeof(memory_list_t))) 7507dc1947SRichard Lowe 7607dc1947SRichard Lowe 7707dc1947SRichard Lowe /* 7807dc1947SRichard Lowe dbg should be NULL only when allocating dbg itself. In that 7907dc1947SRichard Lowe case we initialize it to an empty circular doubly-linked list. 8007dc1947SRichard Lowe */ 8107dc1947SRichard Lowe 8207dc1947SRichard Lowe Dwarf_Ptr 8307dc1947SRichard Lowe _dwarf_p_get_alloc(Dwarf_P_Debug dbg, Dwarf_Unsigned size) 8449d3bc91SRichard Lowe { 8549d3bc91SRichard Lowe void *sp; 8607dc1947SRichard Lowe memory_list_t *lp = NULL; 8707dc1947SRichard Lowe memory_list_t *dbglp = NULL; 8807dc1947SRichard Lowe memory_list_t *nextblock = NULL; 8907dc1947SRichard Lowe 9007dc1947SRichard Lowe /* alloc control struct and data block together for performance reasons */ 9107dc1947SRichard Lowe lp = (memory_list_t *) malloc(size + sizeof(memory_list_t)); 9207dc1947SRichard Lowe if (lp == NULL) { 9307dc1947SRichard Lowe /* should throw an error */ 9407dc1947SRichard Lowe return NULL; 9507dc1947SRichard Lowe } 96*4d9fdb46SRobert Mustacchi 9707dc1947SRichard Lowe /* point to 'size' bytes just beyond lp struct */ 9807dc1947SRichard Lowe sp = LIST_TO_BLOCK(lp); 9907dc1947SRichard Lowe memset(sp, 0, size); 10007dc1947SRichard Lowe 10107dc1947SRichard Lowe if (dbg == NULL) { 10207dc1947SRichard Lowe lp->next = lp->prev = lp; 10307dc1947SRichard Lowe } else { 10407dc1947SRichard Lowe /* I always have to draw a picture to understand this part. */ 10507dc1947SRichard Lowe 10607dc1947SRichard Lowe dbglp = BLOCK_TO_LIST(dbg); 10707dc1947SRichard Lowe nextblock = dbglp->next; 108*4d9fdb46SRobert Mustacchi 10907dc1947SRichard Lowe /* Insert between dbglp and nextblock */ 11007dc1947SRichard Lowe dbglp->next = lp; 11107dc1947SRichard Lowe lp->prev = dbglp; 11207dc1947SRichard Lowe lp->next = nextblock; 11307dc1947SRichard Lowe nextblock->prev = lp; 11407dc1947SRichard Lowe } 11549d3bc91SRichard Lowe 11649d3bc91SRichard Lowe return sp; 11749d3bc91SRichard Lowe } 11849d3bc91SRichard Lowe 11907dc1947SRichard Lowe /* 12007dc1947SRichard Lowe This routine is only here in case a caller of an older version of the 12107dc1947SRichard Lowe library is calling this for some reason. 122*4d9fdb46SRobert Mustacchi This does nothing! 123*4d9fdb46SRobert Mustacchi No need to remove this block. In theory the user might be 124*4d9fdb46SRobert Mustacchi depending on the fact that we used to just 'free' this. 12507dc1947SRichard Lowe In theory they might also be 12607dc1947SRichard Lowe passing a block that they got from libdwarf. So we don't know if we 12707dc1947SRichard Lowe should try to remove this block from our global list. Safest just to 12807dc1947SRichard Lowe do nothing at this point. 12907dc1947SRichard Lowe 13007dc1947SRichard Lowe !!! 13107dc1947SRichard Lowe This function is deprecated! Don't call it inside libdwarf or outside of it. 132*4d9fdb46SRobert Mustacchi Does nothing! 13307dc1947SRichard Lowe !!! 13407dc1947SRichard Lowe */ 135*4d9fdb46SRobert Mustacchi 13607dc1947SRichard Lowe void 137*4d9fdb46SRobert Mustacchi dwarf_p_dealloc(UNUSEDARG Dwarf_Small * ptr) 13849d3bc91SRichard Lowe { 13949d3bc91SRichard Lowe return; 14049d3bc91SRichard Lowe } 14149d3bc91SRichard Lowe 14207dc1947SRichard Lowe /* 14307dc1947SRichard Lowe The dbg structure is not needed here anymore. 14407dc1947SRichard Lowe */ 14549d3bc91SRichard Lowe 14607dc1947SRichard Lowe void 147*4d9fdb46SRobert Mustacchi _dwarf_p_dealloc(UNUSEDARG Dwarf_P_Debug dbg, 148*4d9fdb46SRobert Mustacchi Dwarf_Small * ptr) /* ARGSUSED */ 149*4d9fdb46SRobert Mustacchi { 150*4d9fdb46SRobert Mustacchi memory_list_t *lp; 151*4d9fdb46SRobert Mustacchi lp = BLOCK_TO_LIST(ptr); 152*4d9fdb46SRobert Mustacchi 153*4d9fdb46SRobert Mustacchi /* Remove from a doubly linked, circular list. 154*4d9fdb46SRobert Mustacchi Read carefully, use a white board if necessary. 155*4d9fdb46SRobert Mustacchi If this is an empty list, the following statements are no-ops, and 156*4d9fdb46SRobert Mustacchi will write to the same memory location they read from. 157*4d9fdb46SRobert Mustacchi This should only happen when we deallocate the dbg structure itself. 158*4d9fdb46SRobert Mustacchi */ 159*4d9fdb46SRobert Mustacchi if (lp == lp->next) { 160*4d9fdb46SRobert Mustacchi /* The list has a single item, itself. */ 161*4d9fdb46SRobert Mustacchi lp->prev = 0; 162*4d9fdb46SRobert Mustacchi lp->next = 0; 163*4d9fdb46SRobert Mustacchi } else if (lp->next == lp->prev) { 164*4d9fdb46SRobert Mustacchi /* List had exactly two entries. Reduce it to one, 165*4d9fdb46SRobert Mustacchi cutting lp out. */ 166*4d9fdb46SRobert Mustacchi memory_list_t * remaining = lp->next; 167*4d9fdb46SRobert Mustacchi remaining->next = remaining; 168*4d9fdb46SRobert Mustacchi remaining->prev = remaining; 169*4d9fdb46SRobert Mustacchi } else { 170*4d9fdb46SRobert Mustacchi /* Multi=entry. Just cut lp out. */ 171*4d9fdb46SRobert Mustacchi lp->prev->next = lp->next; 172*4d9fdb46SRobert Mustacchi lp->next->prev = lp->prev; 173*4d9fdb46SRobert Mustacchi lp->prev = lp->next = 0; 174*4d9fdb46SRobert Mustacchi } 175*4d9fdb46SRobert Mustacchi free((void*)lp); 176*4d9fdb46SRobert Mustacchi } 177*4d9fdb46SRobert Mustacchi 178*4d9fdb46SRobert Mustacchi 179*4d9fdb46SRobert Mustacchi static void 180*4d9fdb46SRobert Mustacchi _dwarf_str_hashtab_freenode(void * nodep) 18149d3bc91SRichard Lowe { 182*4d9fdb46SRobert Mustacchi free(nodep); 18349d3bc91SRichard Lowe } 18407dc1947SRichard Lowe 18507dc1947SRichard Lowe 18607dc1947SRichard Lowe /* 18707dc1947SRichard Lowe This routine deallocates all the nodes on the dbg list, 18807dc1947SRichard Lowe and then deallocates the dbg structure itself. 18907dc1947SRichard Lowe */ 19007dc1947SRichard Lowe 19107dc1947SRichard Lowe void 19207dc1947SRichard Lowe _dwarf_p_dealloc_all(Dwarf_P_Debug dbg) 19307dc1947SRichard Lowe { 19407dc1947SRichard Lowe memory_list_t *dbglp; 195*4d9fdb46SRobert Mustacchi memory_list_t *base_dbglp; 19607dc1947SRichard Lowe 19707dc1947SRichard Lowe if (dbg == NULL) { 19807dc1947SRichard Lowe /* should throw an error */ 19907dc1947SRichard Lowe return; 20007dc1947SRichard Lowe } 20107dc1947SRichard Lowe 202*4d9fdb46SRobert Mustacchi base_dbglp = BLOCK_TO_LIST(dbg); 203*4d9fdb46SRobert Mustacchi dbglp = base_dbglp->next; 204*4d9fdb46SRobert Mustacchi 205*4d9fdb46SRobert Mustacchi while (dbglp != base_dbglp) { 206*4d9fdb46SRobert Mustacchi memory_list_t*next = dbglp->next; 207*4d9fdb46SRobert Mustacchi 208*4d9fdb46SRobert Mustacchi _dwarf_p_dealloc(dbg, LIST_TO_BLOCK(dbglp)); 209*4d9fdb46SRobert Mustacchi dbglp = next; 21007dc1947SRichard Lowe } 211*4d9fdb46SRobert Mustacchi dwarf_tdestroy(dbg->de_debug_str_hashtab, 212*4d9fdb46SRobert Mustacchi _dwarf_str_hashtab_freenode); 213*4d9fdb46SRobert Mustacchi dwarf_tdestroy(dbg->de_debug_line_str_hashtab, 214*4d9fdb46SRobert Mustacchi _dwarf_str_hashtab_freenode); 215*4d9fdb46SRobert Mustacchi free((void *)base_dbglp); 21607dc1947SRichard Lowe } 217