summaryrefslogtreecommitdiff
path: root/usr/src/lib/libdwarf/common/pro_alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libdwarf/common/pro_alloc.c')
-rw-r--r--usr/src/lib/libdwarf/common/pro_alloc.c200
1 files changed, 114 insertions, 86 deletions
diff --git a/usr/src/lib/libdwarf/common/pro_alloc.c b/usr/src/lib/libdwarf/common/pro_alloc.c
index 1ca7806239..dd475d8dcb 100644
--- a/usr/src/lib/libdwarf/common/pro_alloc.c
+++ b/usr/src/lib/libdwarf/common/pro_alloc.c
@@ -1,68 +1,74 @@
/*
-
Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved.
Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of version 2.1 of the GNU Lesser General Public License
- as published by the Free Software Foundation.
-
- This program is distributed in the hope that it would be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
- Further, this software is distributed without any warranty that it is
- free of the rightful claim of any third person regarding infringement
- or the like. Any license provided herein, whether implied or
- otherwise, applies only to this software file. Patent licenses, if
- any, provided herein do not apply to combinations of this program with
- other software, or any other product whatsoever.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this program; if not, write the Free Software
- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
- USA.
-
- Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
- Mountain View, CA 94043, or:
-
- http://www.sgi.com
-
- For further information regarding this notice, see:
-
- http://oss.sgi.com/projects/GenInfo/NoticeExplan
+ Portions Copyright 2011-2019. David Anderson. All Rights Reserved.
+
+ This program is free software; you can redistribute it
+ and/or modify it under the terms of version 2.1 of the
+ GNU Lesser General Public License as published by the Free
+ Software Foundation.
+
+ This program is distributed in the hope that it would be
+ useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+ Further, this software is distributed without any warranty
+ that it is free of the rightful claim of any third person
+ regarding infringement or the like. Any license provided
+ herein, whether implied or otherwise, applies only to this
+ software file. Patent licenses, if any, provided herein
+ do not apply to combinations of this program with other
+ software, or any other product whatsoever.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this program; if not, write the
+ Free Software Foundation, Inc., 51 Franklin Street - Fifth
+ Floor, Boston MA 02110-1301, USA.
*/
-
-
#include "config.h"
#include "pro_incl.h"
+#include <stddef.h>
+#include "dwarf.h"
+#include "libdwarf.h"
+#include "pro_opaque.h"
+#include "pro_alloc.h"
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif /* HAVE_STDLIB_H */
+#ifdef HAVE_MALLOC_H
+/* Useful include for some Windows compilers. */
+#include <malloc.h>
+#endif /* HAVE_MALLOC_H */
#ifdef HAVE_STRING_H
#include <string.h>
#endif /* HAVE_STRING_H */
-#include <malloc.h>
-
-/*
- When each block is allocated, there is a two-word structure
- allocated at the beginning so the block can go on a list.
- The address returned is the address *after* the two pointers
- at the start. But this allows us to be given a pointer to
- a generic block, and go backwards to find the list-node. Then
- we can remove this block from it's list without the need to search
- through a linked list in order to remove the node. It also allows
- us to 'delete' a memory block without needing the dbg structure.
- We still need the dbg structure on allocation so that we know which
- linked list to add the block to.
-
- Only the allocation of the dbg structure itself cannot use _dwarf_p_get_alloc.
- That structure should be set up by hand, and the two list pointers
- should be initialized to point at the node itself. That initializes
- the doubly linked list.
-*/
+#ifdef HAVE_STDINT_H
+#include <stdint.h> /* For uintptr_t */
+#endif /* HAVE_STDINT_H */
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif /* HAVE_INTTYPES_H */
+#include "dwarf_tsearch.h"
+
+/* When each block is allocated, there is a two-word structure
+ allocated at the beginning so the block can go on a list.
+ The address returned is the address *after* the two pointers
+ at the start. But this allows us to be given a pointer to
+ a generic block, and go backwards to find the list-node. Then
+ we can remove this block from it's list without the need to search
+ through a linked list in order to remove the node. It also allows
+ us to 'delete' a memory block without needing the dbg structure.
+ We still need the dbg structure on allocation so that we know which
+ linked list to add the block to.
+
+ Only the allocation of the dbg structure itself cannot use
+ _dwarf_p_get_alloc.
+ That structure should be set up by hand, and the two list pointers
+ should be initialized to point at the node itself. That initializes
+ the doubly linked list. */
#define LIST_TO_BLOCK(lst) ((void*) (((char *)lst) + sizeof(memory_list_t)))
#define BLOCK_TO_LIST(blk) ((memory_list_t*) (((char*)blk) - sizeof(memory_list_t)))
@@ -87,7 +93,7 @@ _dwarf_p_get_alloc(Dwarf_P_Debug dbg, Dwarf_Unsigned size)
/* should throw an error */
return NULL;
}
-
+
/* point to 'size' bytes just beyond lp struct */
sp = LIST_TO_BLOCK(lp);
memset(sp, 0, size);
@@ -99,7 +105,7 @@ _dwarf_p_get_alloc(Dwarf_P_Debug dbg, Dwarf_Unsigned size)
dbglp = BLOCK_TO_LIST(dbg);
nextblock = dbglp->next;
-
+
/* Insert between dbglp and nextblock */
dbglp->next = lp;
lp->prev = dbglp;
@@ -113,9 +119,9 @@ _dwarf_p_get_alloc(Dwarf_P_Debug dbg, Dwarf_Unsigned size)
/*
This routine is only here in case a caller of an older version of the
library is calling this for some reason.
- We will clean up any stray blocks when the session is closed.
- No need to remove this block. In theory the user might be
- depending on the fact that we used to just 'free' this.
+ This does nothing!
+ No need to remove this block. In theory the user might be
+ depending on the fact that we used to just 'free' this.
In theory they might also be
passing a block that they got from libdwarf. So we don't know if we
should try to remove this block from our global list. Safest just to
@@ -123,11 +129,12 @@ _dwarf_p_get_alloc(Dwarf_P_Debug dbg, Dwarf_Unsigned size)
!!!
This function is deprecated! Don't call it inside libdwarf or outside of it.
+ Does nothing!
!!!
*/
-
+
void
-dwarf_p_dealloc(Dwarf_Small * ptr)
+dwarf_p_dealloc(UNUSEDARG Dwarf_Small * ptr)
{
return;
}
@@ -137,23 +144,42 @@ dwarf_p_dealloc(Dwarf_Small * ptr)
*/
void
-_dwarf_p_dealloc(Dwarf_P_Debug dbg, Dwarf_Small * ptr) /* ARGSUSED */
+_dwarf_p_dealloc(UNUSEDARG Dwarf_P_Debug dbg,
+ Dwarf_Small * ptr) /* ARGSUSED */
+{
+ memory_list_t *lp;
+ lp = BLOCK_TO_LIST(ptr);
+
+ /* Remove from a doubly linked, circular list.
+ Read carefully, use a white board if necessary.
+ If this is an empty list, the following statements are no-ops, and
+ will write to the same memory location they read from.
+ This should only happen when we deallocate the dbg structure itself.
+ */
+ if (lp == lp->next) {
+ /* The list has a single item, itself. */
+ lp->prev = 0;
+ lp->next = 0;
+ } else if (lp->next == lp->prev) {
+ /* List had exactly two entries. Reduce it to one,
+ cutting lp out. */
+ memory_list_t * remaining = lp->next;
+ remaining->next = remaining;
+ remaining->prev = remaining;
+ } else {
+ /* Multi=entry. Just cut lp out. */
+ lp->prev->next = lp->next;
+ lp->next->prev = lp->prev;
+ lp->prev = lp->next = 0;
+ }
+ free((void*)lp);
+}
+
+
+static void
+_dwarf_str_hashtab_freenode(void * nodep)
{
- memory_list_t *lp;
- lp = BLOCK_TO_LIST(ptr);
-
- /*
- Remove from a doubly linked, circular list.
- Read carefully, use a white board if necessary.
- If this is an empty list, the following statements are no-ops, and
- will write to the same memory location they read from.
- This should only happen when we deallocate the dbg structure itself.
- */
-
- lp->prev->next = lp->next;
- lp->next->prev = lp->prev;
-
- free((void*)lp);
+ free(nodep);
}
@@ -166,23 +192,25 @@ void
_dwarf_p_dealloc_all(Dwarf_P_Debug dbg)
{
memory_list_t *dbglp;
+ memory_list_t *base_dbglp;
if (dbg == NULL) {
/* should throw an error */
return;
}
-
- dbglp = BLOCK_TO_LIST(dbg);
- while (dbglp->next != dbglp) {
- _dwarf_p_dealloc(dbg, LIST_TO_BLOCK(dbglp->next));
- }
- if (dbglp->next != dbglp ||
- dbglp->prev != dbglp) {
- /* should throw error */
- /* For some reason we couldn't free all the blocks? */
- return;
+ base_dbglp = BLOCK_TO_LIST(dbg);
+ dbglp = base_dbglp->next;
+
+ while (dbglp != base_dbglp) {
+ memory_list_t*next = dbglp->next;
+
+ _dwarf_p_dealloc(dbg, LIST_TO_BLOCK(dbglp));
+ dbglp = next;
}
- _dwarf_p_dealloc(NULL, (void*)dbg);
+ dwarf_tdestroy(dbg->de_debug_str_hashtab,
+ _dwarf_str_hashtab_freenode);
+ dwarf_tdestroy(dbg->de_debug_line_str_hashtab,
+ _dwarf_str_hashtab_freenode);
+ free((void *)base_dbglp);
}
-