summaryrefslogtreecommitdiff
path: root/usr/src/tools/ctf/dwarf/common/malloc_check.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/tools/ctf/dwarf/common/malloc_check.c')
-rw-r--r--usr/src/tools/ctf/dwarf/common/malloc_check.c339
1 files changed, 0 insertions, 339 deletions
diff --git a/usr/src/tools/ctf/dwarf/common/malloc_check.c b/usr/src/tools/ctf/dwarf/common/malloc_check.c
deleted file mode 100644
index 1c6e7738e4..0000000000
--- a/usr/src/tools/ctf/dwarf/common/malloc_check.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
-
- Copyright (C) 2005 Silicon Graphics, 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
-
-*/
-
-
-
-/* malloc_check.c For checking dealloc completeness.
-
- This code is as simple as possible and works ok for
- reasonable size allocation counts.
-
- It treats allocation as global, and so will not
- work very well if an application opens more than one
- Dwarf_Debug.
-
-*/
-
-#include <stdio.h>
-#include <stdlib.h> /* for exit() and various malloc
- prototypes */
-#include "config.h"
-#include "dwarf_incl.h"
-#include "malloc_check.h"
-#ifdef WANT_LIBBDWARF_MALLOC_CHECK
-
-/* To turn off printing every entry, just change the define
- to set PRINT_MALLOC_DETAILS 0.
-*/
-#define PRINT_MALLOC_DETAILS 0
-
-#define MC_TYPE_UNKNOWN 0
-#define MC_TYPE_ALLOC 1
-#define MC_TYPE_DEALLOC 2
-
-struct mc_data_s {
- struct mc_data_s *mc_prev;
- unsigned long mc_address; /* Assumes this is large enough to hold
- a pointer! */
-
- long mc_alloc_number; /* Assigned in order by when record
- created. */
- unsigned char mc_alloc_code; /* Allocation code, libdwarf. */
- unsigned char mc_type;
- unsigned char mc_dealloc_noted; /* Used on an ALLOC node. */
- unsigned char mc_dealloc_noted_count; /* Used on an ALLOC
- node. */
-};
-
-/*
-
-
-*/
-#define HASH_TABLE_SIZE 10501
-static struct mc_data_s *mc_data_hash[HASH_TABLE_SIZE];
-static long mc_data_list_size = 0;
-
-static char *alloc_type_name[MAX_DW_DLA + 1] = {
- "",
- "DW_DLA_STRING",
- "DW_DLA_LOC",
- "DW_DLA_LOCDESC",
- "DW_DLA_ELLIST",
- "DW_DLA_BOUNDS",
- "DW_DLA_BLOCK",
- "DW_DLA_DEBUG",
- "DW_DLA_DIE",
- "DW_DLA_LINE",
- "DW_DLA_ATTR",
- "DW_DLA_TYPE",
- "DW_DLA_SUBSCR",
- "DW_DLA_GLOBAL",
- "DW_DLA_ERROR",
- "DW_DLA_LIST",
- "DW_DLA_LINEBUF",
- "DW_DLA_ARANGE",
- "DW_DLA_ABBREV",
- "DW_DLA_FRAME_OP",
- "DW_DLA_CIE",
- "DW_DLA_FDE",
- "DW_DLA_LOC_BLOCK",
- "DW_DLA_FRAME_BLOCK",
- "DW_DLA_FUNC",
- "DW_DLA_TYPENAME",
- "DW_DLA_VAR",
- "DW_DLA_WEAK",
- "DW_DLA_ADDR",
- "DW_DLA_ABBREV_LIST",
- "DW_DLA_CHAIN",
- "DW_DLA_CU_CONTEXT",
- "DW_DLA_FRAME",
- "DW_DLA_GLOBAL_CONTEXT",
- "DW_DLA_FILE_ENTRY",
- "DW_DLA_LINE_CONTEXT",
- "DW_DLA_LOC_CHAIN",
- "DW_DLA_HASH_TABLE",
- "DW_DLA_FUNC_CONTEXT",
- "DW_DLA_TYPENAME_CONTEXT",
- "DW_DLA_VAR_CONTEXT",
- "DW_DLA_WEAK_CONTEXT",
- "DW_DLA_PUBTYPES_CONTEXT"
- /* Don't forget to expand this list if the list of codes
- expands. */
-};
-
-static unsigned
-hash_address(unsigned long addr)
-{
- unsigned long a = addr >> 2;
-
- return a % HASH_TABLE_SIZE;
-}
-
-#if PRINT_MALLOC_DETAILS
-static void
-print_alloc_dealloc_detail(unsigned long addr,
- int code, char *whichisit)
-{
- fprintf(stderr,
- "%s addr 0x%lx code %d (%s) entry %ld\n",
- whichisit, addr, code, alloc_type_name[code],
- mc_data_list_size);
-}
-#else
-#define print_alloc_dealloc_detail(a,b,c) /* nothing */
-#endif
-
-/* Create a zeroed struct or die. */
-static void *
-newone(void)
-{
- struct mc_data_s *newd = malloc(sizeof(struct mc_data_s));
-
- if (newd == 0) {
- fprintf(stderr, "out of memory , # %ld\n", mc_data_list_size);
- exit(1);
- }
- memset(newd, 0, sizeof(struct mc_data_s));
- return newd;
-}
-
-/* Notify checker that get_alloc has allocated user data. */
-void
-dwarf_malloc_check_alloc_data(void *addr_in, unsigned char code)
-{
- struct mc_data_s *newd = newone();
- unsigned long addr = (unsigned long) addr_in;
- struct mc_data_s **base = &mc_data_hash[hash_address(addr)];
-
- print_alloc_dealloc_detail(addr, code, "alloc ");
- newd->mc_address = addr;
- newd->mc_alloc_code = code;
- newd->mc_type = MC_TYPE_ALLOC;
- newd->mc_alloc_number = mc_data_list_size;
- newd->mc_prev = *base;
- *base = newd;
- newd->mc_alloc_number = mc_data_list_size;
- mc_data_list_size += 1;
-}
-
-static void
-print_entry(char *msg, struct mc_data_s *data)
-{
- fprintf(stderr,
- "%s: 0x%08lx code %2d (%s) type %s dealloc noted %u ct %u\n",
- msg,
- (long) data->mc_address,
- data->mc_alloc_code,
- alloc_type_name[data->mc_alloc_code],
- (data->mc_type == MC_TYPE_ALLOC) ? "alloc " :
- (data->mc_type == MC_TYPE_DEALLOC) ? "dealloc" : "unknown",
- (unsigned) data->mc_dealloc_noted,
- (unsigned) data->mc_dealloc_noted_count);
-}
-
-/* newd is a 'dealloc'.
-*/
-static long
-balanced_by_alloc_p(struct mc_data_s *newd,
- long *addr_match_num,
- struct mc_data_s **addr_match,
- struct mc_data_s *base)
-{
- struct mc_data_s *cur = base;
-
- for (; cur; cur = cur->mc_prev) {
- if (cur->mc_address == newd->mc_address) {
- if (cur->mc_type == MC_TYPE_ALLOC) {
- if (cur->mc_alloc_code == newd->mc_alloc_code) {
- *addr_match = cur;
- *addr_match_num = cur->mc_alloc_number;
- return cur->mc_alloc_number;
- } else {
- /* code mismatch */
- *addr_match = cur;
- *addr_match_num = cur->mc_alloc_number;
- return -1;
- }
- } else {
- /* Unbalanced new/del */
- *addr_match = cur;
- *addr_match_num = cur->mc_alloc_number;
- return -1;
- }
- }
- }
- return -1;
-}
-
-/* A dealloc is to take place. Ensure it balances an alloc.
-*/
-void
-dwarf_malloc_check_dealloc_data(void *addr_in, unsigned char code)
-{
- struct mc_data_s *newd = newone();
- long prev;
- long addr_match_num = -1;
- struct mc_data_s *addr_match = 0;
- unsigned long addr = (unsigned long) addr_in;
- struct mc_data_s **base = &mc_data_hash[hash_address(addr)];
-
-
- print_alloc_dealloc_detail(addr, code, "dealloc ");
- newd->mc_address = (unsigned long) addr;
- newd->mc_alloc_code = code;
- newd->mc_type = MC_TYPE_DEALLOC;
- newd->mc_prev = *base;
- prev =
- balanced_by_alloc_p(newd, &addr_match_num, &addr_match, *base);
- if (prev < 0) {
- fprintf(stderr,
- "Unbalanced dealloc at index %ld\n", mc_data_list_size);
- print_entry("new", newd);
- fprintf(stderr, "addr-match_num? %ld\n", addr_match_num);
- if (addr_match) {
- print_entry("prev entry", addr_match);
- if (addr_match->mc_dealloc_noted > 1) {
- fprintf(stderr, "Above is Duplicate dealloc!\n");
- }
- }
- abort();
- exit(3);
- }
- addr_match->mc_dealloc_noted = 1;
- addr_match->mc_dealloc_noted_count += 1;
- if (addr_match->mc_dealloc_noted_count > 1) {
- fprintf(stderr, "Double dealloc entry %ld\n", addr_match_num);
- print_entry("new dealloc entry", newd);
- print_entry("bad alloc entry", addr_match);
- }
- *base = newd;
- mc_data_list_size += 1;
-}
-
-/* Final check for leaks.
-*/
-void
-dwarf_malloc_check_complete(char *msg)
-{
- long i = 0;
- long total = mc_data_list_size;
- long hash_slots_used = 0;
- long max_chain_length = 0;
-
- fprintf(stderr, "Run complete, %s. %ld entries\n", msg, total);
- for (; i < HASH_TABLE_SIZE; ++i) {
- struct mc_data_s *cur = mc_data_hash[i];
- long cur_chain_length = 0;
-
- if (cur == 0)
- continue;
- ++hash_slots_used;
- for (; cur; cur = cur->mc_prev) {
- ++cur_chain_length;
- if (cur->mc_type == MC_TYPE_ALLOC) {
- if (cur->mc_dealloc_noted) {
- if (cur->mc_dealloc_noted > 1) {
- fprintf(stderr,
- " Duplicate dealloc! entry %ld\n",
- cur->mc_alloc_number);
- print_entry("duplicate dealloc", cur);
-
- }
- continue;
- } else {
- fprintf(stderr, "malloc no dealloc, entry %ld\n",
- cur->mc_alloc_number);
- print_entry("dangle", cur);
- }
- } else {
- /* mc_type is MC_TYPE_DEALLOC, already checked */
-
- }
- }
- if (cur_chain_length > max_chain_length) {
- max_chain_length = cur_chain_length;
- }
- }
- fprintf(stderr, "mc hash table slots=%ld, "
- "used=%ld, maxchain=%ld\n",
- (long) HASH_TABLE_SIZE, hash_slots_used, max_chain_length);
- return;
-}
-
-#else
-
-extern void *libdwarf_an_unused_function_so_not_empty_c_file();
-
-#endif /* WANT_LIBBDWARF_MALLOC_CHECK */