+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/* dbus-break-loader.c Program to find byte streams that break the message loader
- *
- * Copyright (C) 2003 Red Hat Inc.
- *
- * Licensed under the Academic Free License version 2.1
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#include <config.h>
-#include <dbus/dbus.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/wait.h>
-#include <string.h>
-
-#include <dbus/dbus-string.h>
-#include <dbus/dbus-internals.h>
-#include <dbus/dbus-test.h>
-#include <dbus/dbus-marshal-basic.h>
-
-static DBusString failure_dir;
-static int total_attempts;
-static int failures_this_iteration;
-
-static int
-random_int_in_range (int start,
- int end)
-{
- /* such elegant math */
- double gap;
- double v_double;
- int v;
-
- if (start == end)
- return start;
-
- _dbus_assert (end > start);
-
- gap = end - start - 1; /* -1 to not include "end" */
- v_double = ((double)start) + (((double)rand ())/RAND_MAX) * gap;
- if (v_double < 0.0)
- v = (v_double - 0.5);
- else
- v = (v_double + 0.5);
-
- if (v < start)
- {
- fprintf (stderr, "random_int_in_range() generated %d for range [%d,%d)\n",
- v, start, end);
- v = start;
- }
- else if (v >= end)
- {
- fprintf (stderr, "random_int_in_range() generated %d for range [%d,%d)\n",
- v, start, end);
- v = end - 1;
- }
-
- /* printf (" %d of [%d,%d)\n", v, start, end); */
-
- return v;
-}
-
-static dbus_bool_t
-try_mutated_data (const DBusString *data)
-{
- int pid;
-
- total_attempts += 1;
- /* printf (" attempt %d\n", total_attempts); */
-
- pid = fork ();
-
- if (pid < 0)
- {
- fprintf (stderr, "fork() failed: %s\n",
- strerror (errno));
- exit (1);
- return FALSE;
- }
-
- if (pid == 0)
- {
- /* Child, try loading the data */
- if (!dbus_internal_do_not_use_try_message_data (data, _DBUS_MESSAGE_UNKNOWN))
- exit (1);
- else
- exit (0);
- }
- else
- {
- /* Parent, wait for child */
- int status;
- DBusString filename;
- dbus_bool_t failed;
-
- if (waitpid (pid, &status, 0) < 0)
- {
- fprintf (stderr, "waitpid() failed: %s\n", strerror (errno));
- exit (1);
- return FALSE;
- }
-
- failed = FALSE;
-
- if (!_dbus_string_init (&filename) ||
- !_dbus_string_copy (&failure_dir, 0,
- &filename, 0) ||
- !_dbus_string_append_byte (&filename, '/'))
- {
- fprintf (stderr, "out of memory\n");
- exit (1);
- }
-
- _dbus_string_append_int (&filename, total_attempts);
-
- if (WIFEXITED (status))
- {
- if (WEXITSTATUS (status) != 0)
- {
- _dbus_string_append (&filename, "-exited-");
- _dbus_string_append_int (&filename, WEXITSTATUS (status));
- failed = TRUE;
- }
- }
- else if (WIFSIGNALED (status))
- {
- _dbus_string_append (&filename, "signaled-");
- _dbus_string_append_int (&filename, WTERMSIG (status));
- failed = TRUE;
- }
-
- if (failed)
- {
- DBusError error;
-
- _dbus_string_append (&filename, ".message-raw");
-
- printf ("Child failed, writing %s\n", _dbus_string_get_const_data (&filename));
-
- dbus_error_init (&error);
- if (!_dbus_string_save_to_file (data, &filename, FALSE, &error))
- {
- fprintf (stderr, "Failed to save failed message data: %s\n",
- error.message);
- dbus_error_free (&error);
- exit (1); /* so we can see the seed that was printed out */
- }
-
- failures_this_iteration += 1;
-
- _dbus_string_free (&filename);
-
- return FALSE;
- }
- else
- {
- _dbus_string_free (&filename);
- return TRUE;
- }
- }
-
- _dbus_assert_not_reached ("should not be reached");
- return TRUE;
-}
-
-static void
-randomly_shorten_or_lengthen (const DBusString *orig_data,
- DBusString *mutated)
-{
- int delta;
-
- if (orig_data != mutated)
- {
- _dbus_string_set_length (mutated, 0);
-
- if (!_dbus_string_copy (orig_data, 0, mutated, 0))
- _dbus_assert_not_reached ("out of mem");
- }
-
- if (_dbus_string_get_length (mutated) == 0)
- delta = random_int_in_range (0, 10);
- else
- delta = random_int_in_range (- _dbus_string_get_length (mutated),
- _dbus_string_get_length (mutated) * 3);
-
- if (delta < 0)
- _dbus_string_shorten (mutated, - delta);
- else if (delta > 0)
- {
- int i = 0;
-
- i = _dbus_string_get_length (mutated);
- if (!_dbus_string_lengthen (mutated, delta))
- _dbus_assert_not_reached ("couldn't lengthen string");
-
- while (i < _dbus_string_get_length (mutated))
- {
- _dbus_string_set_byte (mutated,
- i,
- random_int_in_range (0, 256));
- ++i;
- }
- }
-}
-
-static void
-randomly_change_one_byte (const DBusString *orig_data,
- DBusString *mutated)
-{
- int i;
-
- if (orig_data != mutated)
- {
- _dbus_string_set_length (mutated, 0);
-
- if (!_dbus_string_copy (orig_data, 0, mutated, 0))
- _dbus_assert_not_reached ("out of mem");
- }
-
- if (_dbus_string_get_length (mutated) == 0)
- return;
-
- i = random_int_in_range (0, _dbus_string_get_length (mutated));
-
- _dbus_string_set_byte (mutated, i,
- random_int_in_range (0, 256));
-}
-
-static void
-randomly_remove_one_byte (const DBusString *orig_data,
- DBusString *mutated)
-{
- int i;
-
- if (orig_data != mutated)
- {
- _dbus_string_set_length (mutated, 0);
-
- if (!_dbus_string_copy (orig_data, 0, mutated, 0))
- _dbus_assert_not_reached ("out of mem");
- }
-
- if (_dbus_string_get_length (mutated) == 0)
- return;
-
- i = random_int_in_range (0, _dbus_string_get_length (mutated));
-
- _dbus_string_delete (mutated, i, 1);
-}
-
-
-static void
-randomly_add_one_byte (const DBusString *orig_data,
- DBusString *mutated)
-{
- int i;
-
- if (orig_data != mutated)
- {
- _dbus_string_set_length (mutated, 0);
-
- if (!_dbus_string_copy (orig_data, 0, mutated, 0))
- _dbus_assert_not_reached ("out of mem");
- }
-
- i = random_int_in_range (0, _dbus_string_get_length (mutated));
-
- _dbus_string_insert_bytes (mutated, i, 1,
- random_int_in_range (0, 256));
-}
-
-static void
-randomly_modify_length (const DBusString *orig_data,
- DBusString *mutated)
-{
- int i;
- int byte_order;
- const char *d;
- dbus_uint32_t orig;
- int delta;
-
- if (orig_data != mutated)
- {
- _dbus_string_set_length (mutated, 0);
-
- if (!_dbus_string_copy (orig_data, 0, mutated, 0))
- _dbus_assert_not_reached ("out of mem");
- }
-
- if (_dbus_string_get_length (mutated) < 12)
- return;
-
- d = _dbus_string_get_const_data (mutated);
-
- if (!(*d == DBUS_LITTLE_ENDIAN ||
- *d == DBUS_BIG_ENDIAN))
- return;
-
- byte_order = *d;
-
- i = random_int_in_range (4, _dbus_string_get_length (mutated) - 8);
- i = _DBUS_ALIGN_VALUE (i, 4);
-
- orig = _dbus_demarshal_uint32 (mutated, byte_order, i, NULL);
-
- delta = random_int_in_range (-10, 10);
-
- _dbus_marshal_set_uint32 (mutated, byte_order, i,
- (unsigned) (orig + delta));
-}
-
-static void
-randomly_set_extreme_ints (const DBusString *orig_data,
- DBusString *mutated)
-{
- int i;
- int byte_order;
- const char *d;
- dbus_uint32_t orig;
- static int which = 0;
- unsigned int extreme_ints[] = {
- _DBUS_INT_MAX,
- _DBUS_UINT_MAX,
- _DBUS_INT_MAX - 1,
- _DBUS_UINT_MAX - 1,
- _DBUS_INT_MAX - 2,
- _DBUS_UINT_MAX - 2,
- _DBUS_INT_MAX - 17,
- _DBUS_UINT_MAX - 17,
- _DBUS_INT_MAX / 2,
- _DBUS_INT_MAX / 3,
- _DBUS_UINT_MAX / 2,
- _DBUS_UINT_MAX / 3,
- 0, 1, 2, 3,
- (unsigned int) -1,
- (unsigned int) -2,
- (unsigned int) -3
- };
-
- if (orig_data != mutated)
- {
- _dbus_string_set_length (mutated, 0);
-
- if (!_dbus_string_copy (orig_data, 0, mutated, 0))
- _dbus_assert_not_reached ("out of mem");
- }
-
- if (_dbus_string_get_length (mutated) < 12)
- return;
-
- d = _dbus_string_get_const_data (mutated);
-
- if (!(*d == DBUS_LITTLE_ENDIAN ||
- *d == DBUS_BIG_ENDIAN))
- return;
-
- byte_order = *d;
-
- i = random_int_in_range (4, _dbus_string_get_length (mutated) - 8);
- i = _DBUS_ALIGN_VALUE (i, 4);
-
- orig = _dbus_demarshal_uint32 (mutated, byte_order, i, NULL);
-
- which = random_int_in_range (0, _DBUS_N_ELEMENTS (extreme_ints));
-
- _dbus_assert (which >= 0);
- _dbus_assert (which < _DBUS_N_ELEMENTS (extreme_ints));
-
- _dbus_marshal_set_uint32 (mutated, byte_order, i,
- extreme_ints[which]);
-}
-
-static int
-random_type (void)
-{
- const char types[] = {
- DBUS_TYPE_INVALID,
- DBUS_TYPE_NIL,
- DBUS_TYPE_BYTE,
- DBUS_TYPE_BOOLEAN,
- DBUS_TYPE_INT32,
- DBUS_TYPE_UINT32,
- DBUS_TYPE_INT64,
- DBUS_TYPE_UINT64,
- DBUS_TYPE_DOUBLE,
- DBUS_TYPE_STRING,
- DBUS_TYPE_CUSTOM,
- DBUS_TYPE_ARRAY,
- DBUS_TYPE_DICT,
- DBUS_TYPE_OBJECT_PATH
- };
-
- _dbus_assert (_DBUS_N_ELEMENTS (types) == DBUS_NUMBER_OF_TYPES + 1);
-
- return types[ random_int_in_range (0, _DBUS_N_ELEMENTS (types)) ];
-}
-
-static void
-randomly_change_one_type (const DBusString *orig_data,
- DBusString *mutated)
-{
- int i;
- int len;
-
- if (orig_data != mutated)
- {
- _dbus_string_set_length (mutated, 0);
-
- if (!_dbus_string_copy (orig_data, 0, mutated, 0))
- _dbus_assert_not_reached ("out of mem");
- }
-
- if (_dbus_string_get_length (mutated) == 0)
- return;
-
- len = _dbus_string_get_length (mutated);
- i = random_int_in_range (0, len);
-
- /* Look for a type starting at a random location,
- * and replace with a different type
- */
- while (i < len)
- {
- int b;
- b = _dbus_string_get_byte (mutated, i);
- if (dbus_type_is_valid (b))
- {
- _dbus_string_set_byte (mutated, i, random_type ());
- return;
- }
- ++i;
- }
-}
-
-static int times_we_did_each_thing[7] = { 0, };
-
-static void
-randomly_do_n_things (const DBusString *orig_data,
- DBusString *mutated,
- int n)
-{
- int i;
- void (* functions[]) (const DBusString *orig_data,
- DBusString *mutated) =
- {
- randomly_shorten_or_lengthen,
- randomly_change_one_byte,
- randomly_add_one_byte,
- randomly_remove_one_byte,
- randomly_modify_length,
- randomly_set_extreme_ints,
- randomly_change_one_type
- };
-
- _dbus_string_set_length (mutated, 0);
-
- if (!_dbus_string_copy (orig_data, 0, mutated, 0))
- _dbus_assert_not_reached ("out of mem");
-
- i = 0;
- while (i < n)
- {
- int which;
-
- which = random_int_in_range (0, _DBUS_N_ELEMENTS (functions));
-
- (* functions[which]) (mutated, mutated);
- times_we_did_each_thing[which] += 1;
-
- ++i;
- }
-}
-
-static dbus_bool_t
-find_breaks_based_on (const DBusString *filename,
- dbus_bool_t is_raw,
- DBusMessageValidity expected_validity,
- void *data)
-{
- DBusString orig_data;
- DBusString mutated;
- const char *filename_c;
- dbus_bool_t retval;
- int i;
-
- filename_c = _dbus_string_get_const_data (filename);
-
- retval = FALSE;
-
- if (!_dbus_string_init (&orig_data))
- _dbus_assert_not_reached ("could not allocate string");
-
- if (!_dbus_string_init (&mutated))
- _dbus_assert_not_reached ("could not allocate string");
-
- if (!dbus_internal_do_not_use_load_message_file (filename, is_raw,
- &orig_data))
- {
- fprintf (stderr, "could not load file %s\n", filename_c);
- goto failed;
- }
-
- printf (" changing one random byte 100 times\n");
- i = 0;
- while (i < 100)
- {
- randomly_change_one_byte (&orig_data, &mutated);
- try_mutated_data (&mutated);
-
- ++i;
- }
-
- printf (" changing length 50 times\n");
- i = 0;
- while (i < 50)
- {
- randomly_modify_length (&orig_data, &mutated);
- try_mutated_data (&mutated);
-
- ++i;
- }
-
- printf (" removing one byte 50 times\n");
- i = 0;
- while (i < 50)
- {
- randomly_remove_one_byte (&orig_data, &mutated);
- try_mutated_data (&mutated);
-
- ++i;
- }
-
- printf (" adding one byte 50 times\n");
- i = 0;
- while (i < 50)
- {
- randomly_add_one_byte (&orig_data, &mutated);
- try_mutated_data (&mutated);
-
- ++i;
- }
-
- printf (" changing ints to boundary values 50 times\n");
- i = 0;
- while (i < 50)
- {
- randomly_set_extreme_ints (&orig_data, &mutated);
- try_mutated_data (&mutated);
-
- ++i;
- }
-
- printf (" changing typecodes 50 times\n");
- i = 0;
- while (i < 50)
- {
- randomly_change_one_type (&orig_data, &mutated);
- try_mutated_data (&mutated);
-
- ++i;
- }
-
- printf (" changing message length 15 times\n");
- i = 0;
- while (i < 15)
- {
- randomly_shorten_or_lengthen (&orig_data, &mutated);
- try_mutated_data (&mutated);
-
- ++i;
- }
-
- printf (" randomly making 2 of above modifications 42 times\n");
- i = 0;
- while (i < 42)
- {
- randomly_do_n_things (&orig_data, &mutated, 2);
- try_mutated_data (&mutated);
-
- ++i;
- }
-
- printf (" randomly making 3 of above modifications 42 times\n");
- i = 0;
- while (i < 42)
- {
- randomly_do_n_things (&orig_data, &mutated, 3);
- try_mutated_data (&mutated);
-
- ++i;
- }
-
- printf (" randomly making 4 of above modifications 42 times\n");
- i = 0;
- while (i < 42)
- {
- randomly_do_n_things (&orig_data, &mutated, 4);
- try_mutated_data (&mutated);
-
- ++i;
- }
-
- retval = TRUE;
-
- failed:
-
- _dbus_string_free (&orig_data);
- _dbus_string_free (&mutated);
-
- /* FALSE means end the whole process */
- return retval;
-}
-
-static unsigned int
-get_random_seed (void)
-{
- DBusString bytes;
- unsigned int seed;
- int fd;
- const char *s;
-
- seed = 0;
-
- if (!_dbus_string_init (&bytes))
- exit (1);
-
- fd = open ("/dev/urandom", O_RDONLY);
- if (fd < 0)
- goto use_fallback;
-
- if (_dbus_read (fd, &bytes, 4) != 4)
- goto use_fallback;
-
- close (fd);
-
- s = _dbus_string_get_const_data (&bytes);
-
- seed = * (unsigned int*) s;
- goto out;
-
- use_fallback:
- {
- long tv_usec;
-
- fprintf (stderr, "could not open/read /dev/urandom, using current time for seed\n");
-
- _dbus_get_monotonic_time (NULL, &tv_usec);
-
- seed = tv_usec;
- }
-
- out:
- _dbus_string_free (&bytes);
-
- return seed;
-}
-
-int
-main (int argc,
- char **argv)
-{
- const char *test_data_dir;
- const char *failure_dir_c;
- int total_failures_found;
-
- if (argc > 1)
- test_data_dir = argv[1];
- else
- {
- fprintf (stderr, "Must specify a top_srcdir/test/data directory\n");
- return 1;
- }
-
- total_failures_found = 0;
- total_attempts = 0;
-
- if (!_dbus_string_init (&failure_dir))
- return 1;
-
- /* so you can leave it overnight safely */
-#define MAX_FAILURES 1000
-
- while (total_failures_found < MAX_FAILURES)
- {
- unsigned int seed;
-
- failures_this_iteration = 0;
-
- seed = get_random_seed ();
-
- _dbus_string_set_length (&failure_dir, 0);
-
- if (!_dbus_string_append (&failure_dir, "failures-"))
- return 1;
-
- if (!_dbus_string_append_uint (&failure_dir, seed))
- return 1;
-
- failure_dir_c = _dbus_string_get_const_data (&failure_dir);
-
- if (mkdir (failure_dir_c, 0700) < 0)
- {
- if (errno != EEXIST)
- fprintf (stderr, "didn't mkdir %s: %s\n",
- failure_dir_c, strerror (errno));
- }
-
- printf ("next seed = %u \ttotal failures %d of %d attempts\n",
- seed, total_failures_found, total_attempts);
-
- srand (seed);
-
- if (!dbus_internal_do_not_use_foreach_message_file (test_data_dir,
- find_breaks_based_on,
- NULL))
- {
- fprintf (stderr, "fatal error iterating over message files\n");
- rmdir (failure_dir_c);
- return 1;
- }
-
- printf (" did %d random mutations: %d %d %d %d %d %d %d\n",
- _DBUS_N_ELEMENTS (times_we_did_each_thing),
- times_we_did_each_thing[0],
- times_we_did_each_thing[1],
- times_we_did_each_thing[2],
- times_we_did_each_thing[3],
- times_we_did_each_thing[4],
- times_we_did_each_thing[5],
- times_we_did_each_thing[6]);
-
- printf ("Found %d failures with seed %u stored in %s\n",
- failures_this_iteration, seed, failure_dir_c);
-
- total_failures_found += failures_this_iteration;
-
- rmdir (failure_dir_c); /* does nothing if non-empty */
- }
-
- return 0;
-}
+++ /dev/null
-#! /usr/bin/python
-
-import os
-import sys
-import string
-import re
-
-## hash from symbol name to list of symbols with that name,
-## where the list of symbols contains a list representing each symbol
-symbols = {}
-roots = {}
-
-def createBacklinks(name, syms):
- for s in syms:
- refs = s[2]
- for r in refs:
- ## for each ref, add ourselves as a referencer
- if symbols.has_key(r):
- targets = symbols[r]
- for t in targets:
- if name not in t[5]:
- t[5].append(name)
-
-def markSymbol(frm, name):
- if not symbols.has_key(name):
- print "%s referenced but was not in the objdump"
- syms = symbols[name]
- ## print ambiguous references unless they are internal noise like ".L129"
- if len(syms) > 1 and name[0] != '.':
- print "Reference to symbol '%s' from '%s' is ambiguous, marking all '%s'" % (name, frm, name)
- print syms
- for s in syms:
- if s[4]:
- pass ## already marked
- else:
- s[4] = 1
- refs = s[2]
- for r in refs:
- markSymbol(s[0], r)
-
-def cmpFilename(a, b):
- v = cmp(a[1], b[1])
- if v == 0:
- v = cmp(a[0], b[0])
- return v
-
-def sizeAsString(bytes):
- if bytes < 1024:
- return "%d bytes" % bytes
- elif bytes < 1024*1024:
- return "%.2gK" % (bytes / 1024.0)
- else:
- return "%.2gM" % (bytes / 1024.0 / 1024.0)
-
-def printLost():
- list = []
- filename = None
- for (name, syms) in symbols.items():
- s = syms[0] ## we always mark all or none for now
- if not s[4] and name[0] != '.': ## skip .L129 type symbols
- filename = s[3]
- if not filename:
- filename = "unknown file"
- list.append ((name, filename, s[5], s[7]))
-
- file_summaries = []
- total_unused = 0
- total_this_file = 0
- filename = None
- list.sort(cmpFilename)
- for l in list:
- next_filename = l[1]
- if next_filename != filename:
- if total_this_file > 0:
- file_summaries.append (" %s may be unused in %s" % (sizeAsString(total_this_file), filename))
- print "%s has these symbols not reachable from exported symbols:" % next_filename
- filename = next_filename
- total_this_file = 0
- print " %s %s" % (l[0], sizeAsString(l[3]))
- total_unused = total_unused + l[3]
- total_this_file = total_this_file + l[3]
- for trace in l[2]:
- print " referenced from %s" % trace
-
- for fs in file_summaries:
- print fs
- print "%s total may be unused" % sizeAsString(total_unused)
-
-def main():
-
- ## 0001aa44 <_dbus_message_get_network_data>:
- sym_re = re.compile ('([0-9a-f]+) <([^>]+)>:')
- ## 1aa49: e8 00 00 00 00 call 1aa4e <_dbus_message_get_network_data+0xa>
- ref_re = re.compile (' <([^>]+)> *$')
- ## /home/hp/dbus-cvs/dbus/dbus/dbus-message.c:139
- file_re = re.compile ('^(\/[^:].*):[0-9]+$')
- ## _dbus_message_get_network_data+0xa
- funcname_re = re.compile ('([^+]+)\+[0-9a-fx]+')
- ## 00005410 T dbus_address_entries_free
- dynsym_re = re.compile ('T ([^ \n]+)$')
-
- filename = sys.argv[1]
-
- command = """
- objdump -D --demangle -l %s
- """ % filename
-
- command = string.strip (command)
-
- print "Running: %s" % command
-
- f = os.popen(command)
-
- ## first we find which functions reference which other functions
- current_sym = None
- lines = f.readlines()
- for l in lines:
- addr = None
- name = None
- target = None
- file = None
-
- match = sym_re.match(l)
- if match:
- addr = match.group(1)
- name = match.group(2)
- else:
- match = ref_re.search(l)
- if match:
- target = match.group(1)
- else:
- match = file_re.match(l)
- if match:
- file = match.group(1)
-
- if name:
- ## 0 symname, 1 address, 2 references, 3 filename, 4 reached, 5 referenced-by 6 backlinked 7 approx size
- item = [name, addr, [], None, 0, [], 0, 0]
- if symbols.has_key(name):
- symbols[name].append(item)
- else:
- symbols[name] = [item]
-
- if current_sym:
- prev_addr = long(current_sym[1], 16)
- our_addr = long(item[1], 16)
- item[7] = our_addr - prev_addr
- if item[7] < 0:
- print "Computed negative size %d for %s" % (item[7], item[0])
- item[7] = 0
-
- current_sym = item
-
- elif target and current_sym:
- match = funcname_re.match(target)
- if match:
- ## dump the "+address"
- target = match.group(1)
- if target == current_sym[0]:
- pass ## skip self-references
- else:
- current_sym[2].append (target)
-
- elif file and current_sym:
- if file.startswith('/usr/include'):
- ## inlined libc thingy
- pass
- elif current_sym[0].startswith('.debug'):
- ## debug info
- pass
- elif current_sym[3] and current_sym[3] != file:
- raise Exception ("%s in both %s and %s" % (current_sym[0], current_sym[3], file))
- else:
- current_sym[3] = file
-
- ## now we need to find the roots (exported symbols)
- command = "nm -D %s" % filename
- print "Running: %s" % command
- f = os.popen(command)
- lines = f.readlines ()
- for l in lines:
- match = dynsym_re.search(l)
- if match:
- name = match.group(1)
- if roots.has_key(name):
- raise Exception("symbol %s exported twice?" % name)
- else:
- roots[name] = 1
-
- print "%d symbols exported from this object" % len(roots)
-
- ## these functions are used only indirectly, so we don't
- ## notice they are used. Manually add them as roots...
- vtable_roots = ['unix_finalize',
- 'unix_handle_watch',
- 'unix_disconnect',
- 'unix_connection_set',
- 'unix_do_iteration',
- 'unix_live_messages_changed',
- 'unix_get_unix_fd',
- 'handle_client_data_cookie_sha1_mech',
- 'handle_client_data_external_mech',
- 'handle_server_data_cookie_sha1_mech',
- 'handle_server_data_external_mech',
- 'handle_client_initial_response_cookie_sha1_mech',
- 'handle_client_initial_response_external_mech',
- 'handle_client_shutdown_cookie_sha1_mech',
- 'handle_client_shutdown_external_mech',
- 'handle_server_shutdown_cookie_sha1_mech',
- 'handle_server_shutdown_external_mech'
- ]
-
- for vr in vtable_roots:
- if roots.has_key(vr):
- raise Exception("%s is already a root" % vr)
- roots[vr] = 1
-
- for k in roots.keys():
- markSymbol("root", k)
-
- for (k, v) in symbols.items():
- createBacklinks(k, v)
-
- print """
-
-The symbols mentioned below don't appear to be reachable starting from
-the dynamic exports of the library. However, this program is pretty
-dumb; a limitation that creates false positives is that it can only
-trace 'reachable' through hardcoded function calls, if a function is
-called only through a vtable, it won't be marked reachable (and
-neither will its children in the call graph).
-
-Also, the sizes mentioned are more or less completely bogus.
-
-"""
-
- print "The following are hardcoded in as vtable roots: %s" % vtable_roots
-
- printLost()
-
-if __name__ == "__main__":
- main()