49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe/*
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe This program is free software; you can redistribute it and/or modify it
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe under the terms of version 2.1 of the GNU Lesser General Public License
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe as published by the Free Software Foundation.
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe This program is distributed in the hope that it would be useful, but
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe WITHOUT ANY WARRANTY; without even the implied warranty of
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe Further, this software is distributed without any warranty that it is
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe free of the rightful claim of any third person regarding infringement
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe or the like. Any license provided herein, whether implied or
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe otherwise, applies only to this software file. Patent licenses, if
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe any, provided herein do not apply to combinations of this program with
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe other software, or any other product whatsoever.
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe You should have received a copy of the GNU Lesser General Public
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe License along with this program; if not, write the Free Software
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe USA.
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe Mountain View, CA 94043, or:
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe http://www.sgi.com
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe For further information regarding this notice, see:
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe http://oss.sgi.com/projects/GenInfo/NoticeExplan
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe*/
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe#include "config.h"
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#include "pro_incl.h"
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#ifdef HAVE_STDLIB_H
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe#include <stdlib.h>
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif /* HAVE_STDLIB_H */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#ifdef HAVE_STRING_H
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#include <string.h>
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#endif /* HAVE_STRING_H */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#include <malloc.h>
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe When each block is allocated, there is a two-word structure
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe allocated at the beginning so the block can go on a list.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe The address returned is the address *after* the two pointers
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe at the start. But this allows us to be given a pointer to
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe a generic block, and go backwards to find the list-node. Then
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe we can remove this block from it's list without the need to search
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe through a linked list in order to remove the node. It also allows
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe us to 'delete' a memory block without needing the dbg structure.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe We still need the dbg structure on allocation so that we know which
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe linked list to add the block to.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Only the allocation of the dbg structure itself cannot use _dwarf_p_get_alloc.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe That structure should be set up by hand, and the two list pointers
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe should be initialized to point at the node itself. That initializes
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe the doubly linked list.
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe*/
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#define LIST_TO_BLOCK(lst) ((void*) (((char *)lst) + sizeof(memory_list_t)))
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe#define BLOCK_TO_LIST(blk) ((memory_list_t*) (((char*)blk) - sizeof(memory_list_t)))
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dbg should be NULL only when allocating dbg itself. In that
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe case we initialize it to an empty circular doubly-linked list.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe*/
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard LoweDwarf_Ptr
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe_dwarf_p_get_alloc(Dwarf_P_Debug dbg, Dwarf_Unsigned size)
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe{
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe void *sp;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe memory_list_t *lp = NULL;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe memory_list_t *dbglp = NULL;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe memory_list_t *nextblock = NULL;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* alloc control struct and data block together for performance reasons */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe lp = (memory_list_t *) malloc(size + sizeof(memory_list_t));
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (lp == NULL) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* should throw an error */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return NULL;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* point to 'size' bytes just beyond lp struct */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe sp = LIST_TO_BLOCK(lp);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe memset(sp, 0, size);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (dbg == NULL) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe lp->next = lp->prev = lp;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe } else {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* I always have to draw a picture to understand this part. */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dbglp = BLOCK_TO_LIST(dbg);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe nextblock = dbglp->next;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* Insert between dbglp and nextblock */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dbglp->next = lp;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe lp->prev = dbglp;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe lp->next = nextblock;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe nextblock->prev = lp;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe return sp;
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe}
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe This routine is only here in case a caller of an older version of the
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe library is calling this for some reason.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe We will clean up any stray blocks when the session is closed.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe No need to remove this block. In theory the user might be
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe depending on the fact that we used to just 'free' this.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe In theory they might also be
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe passing a block that they got from libdwarf. So we don't know if we
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe should try to remove this block from our global list. Safest just to
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe do nothing at this point.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe !!!
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe This function is deprecated! Don't call it inside libdwarf or outside of it.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe !!!
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe*/
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowevoid
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowedwarf_p_dealloc(Dwarf_Small * ptr)
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe{
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe return;
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe}
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe The dbg structure is not needed here anymore.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe*/
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowevoid
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe_dwarf_p_dealloc(Dwarf_P_Debug dbg, Dwarf_Small * ptr) /* ARGSUSED */
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe memory_list_t *lp;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe lp = BLOCK_TO_LIST(ptr);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Remove from a doubly linked, circular list.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Read carefully, use a white board if necessary.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe If this is an empty list, the following statements are no-ops, and
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe will write to the same memory location they read from.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe This should only happen when we deallocate the dbg structure itself.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe lp->prev->next = lp->next;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe lp->next->prev = lp->prev;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe free((void*)lp);
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe/*
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe This routine deallocates all the nodes on the dbg list,
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe and then deallocates the dbg structure itself.
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe*/
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowevoid
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe_dwarf_p_dealloc_all(Dwarf_P_Debug dbg)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe{
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe memory_list_t *dbglp;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (dbg == NULL) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* should throw an error */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dbglp = BLOCK_TO_LIST(dbg);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe while (dbglp->next != dbglp) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe _dwarf_p_dealloc(dbg, LIST_TO_BLOCK(dbglp->next));
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (dbglp->next != dbglp ||
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe dbglp->prev != dbglp) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* should throw error */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* For some reason we couldn't free all the blocks? */
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe _dwarf_p_dealloc(NULL, (void*)dbg);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe}
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe