#include "core.h"
#include "symtab.h"
-#ifndef MIN_INSN_SIZE
-/* If not defined in MACHINE_H, assume smallest instruction is 1 byte
- long. THis is safe but may be needlessly slow on machines where
- all instructions are longer. */
-#define MIN_INSN_SIZE 1
-#endif
-
bfd *core_bfd;
int core_num_syms;
asymbol **core_syms;
asection *core_text_sect;
PTR core_text_space;
+int min_insn_size;
+int offset_to_code;
+
/* For mapping symbols to specific .o files during file ordering. */
struct function_map {
char *function_name;
struct function_map *symbol_map;
int symbol_map_count;
+extern void i386_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
+extern void alpha_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
+extern void vax_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
+extern void tahoe_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
+extern void sparc_find_call PARAMS ((Sym *, bfd_vma, bfd_vma));
+
static void
DEFUN (read_function_mappings, (filename), const char *filename)
{
}
/* Now we know how big we need to make our table. */
- symbol_map = xmalloc (count * sizeof (struct function_map));
+ symbol_map = ((struct function_map *)
+ xmalloc (count * sizeof (struct function_map)));
/* Rewind the input file so we can read it again. */
rewind (file);
done (1);
}
+ min_insn_size = 1;
+ offset_to_code = 0;
+
+ switch (bfd_get_arch (core_bfd))
+ {
+ case bfd_arch_vax:
+ case bfd_arch_tahoe:
+ offset_to_code = 2;
+ break;
+
+ case bfd_arch_alpha:
+ min_insn_size = 4;
+ break;
+
+ default:
+ break;
+ }
+
if (function_mapping_file)
read_function_mappings (function_mapping_file);
}
}
+void
+DEFUN (find_call, (parent, p_lowpc, p_highpc),
+ Sym * parent AND bfd_vma p_lowpc AND bfd_vma p_highpc)
+{
+ switch (bfd_get_arch (core_bfd))
+ {
+ case bfd_arch_i386:
+ i386_find_call (parent, p_lowpc, p_highpc);
+ break;
+
+ case bfd_arch_alpha:
+ alpha_find_call (parent, p_lowpc, p_highpc);
+ break;
+
+ case bfd_arch_vax:
+ vax_find_call (parent, p_lowpc, p_highpc);
+ break;
+
+ case bfd_arch_sparc:
+ sparc_find_call (parent, p_lowpc, p_highpc);
+ break;
+
+ case bfd_arch_tahoe:
+ tahoe_find_call (parent, p_lowpc, p_highpc);
+ break;
+
+ default:
+ fprintf (stderr, "%s: -c not supported on architecture %s\n",
+ whoami, bfd_printable_name(core_bfd));
+
+ /* Don't give the error more than once. */
+ ignore_direct_calls = FALSE;
+ }
+}
+
/*
* Return class of symbol SYM. The returned class can be any of:
* 0 -> symbol is not interesting to us
return i; /* it's a global symbol */
}
+ if (i == 'W')
+ {
+ /* Treat weak symbols as text symbols. FIXME: a weak symbol may
+ also be a data symbol. */
+ return 'T';
+ }
+
if (i != 't')
{
/* not a static text symbol */
* other systems. Perhaps it should be made configurable.
*/
sym_prefix = bfd_get_symbol_leading_char (core_bfd);
- if (sym_prefix && sym_prefix != sym->name[0]
+ if ((sym_prefix && sym_prefix != sym->name[0])
/*
* GCC may add special symbols to help gdb figure out the file
* language. We want to ignore these, since sometimes they mask
DEFUN (core_create_function_syms, (core_bfd), bfd * core_bfd)
{
bfd_vma min_vma = ~0, max_vma = 0;
- const char *filename, *func_name;
int class;
long i, j, found, skip;
symtab.limit->mapped = 0;
}
+ /* Lookup filename and line number, if we can */
+
+ {
+ const char *filename, *func_name;
+
+ if (get_src_info (symtab.limit->addr, &filename, &func_name,
+ &symtab.limit->line_num))
+ {
+ symtab.limit->file = source_file_lookup_path (filename);
+
+ /* FIXME: Checking __osf__ here does not work with a cross
+ gprof. */
#ifdef __osf__
- /*
- * Suppress symbols that are not function names. This is
- * useful to suppress code-labels and aliases.
- *
- * This is known to be useful under DEC's OSF/1. Under SunOS 4.x,
- * labels do not appear in the symbol table info, so this isn't
- * necessary.
- */
- if (get_src_info (symtab.limit->addr, &filename, &func_name,
- &symtab.limit->line_num))
- {
- symtab.limit->file = source_file_lookup_path (filename);
-
- if (strcmp (symtab.limit->name, func_name) != 0)
- {
- /*
- * The symbol's address maps to a different name, so
- * it can't be a function-entry point. This happens
- * for labels, for example.
- */
- DBG (AOUTDEBUG,
- printf ("[core_create_function_syms: rej %s (maps to %s)\n",
- symtab.limit->name, func_name));
- continue;
- }
- }
+ /*
+ * Suppress symbols that are not function names. This is
+ * useful to suppress code-labels and aliases.
+ *
+ * This is known to be useful under DEC's OSF/1. Under SunOS 4.x,
+ * labels do not appear in the symbol table info, so this isn't
+ * necessary.
+ */
+
+ if (strcmp (symtab.limit->name, func_name) != 0)
+ {
+ /*
+ * The symbol's address maps to a different name, so
+ * it can't be a function-entry point. This happens
+ * for labels, for example.
+ */
+ DBG (AOUTDEBUG,
+ printf ("[core_create_function_syms: rej %s (maps to %s)\n",
+ symtab.limit->name, func_name));
+ continue;
+ }
#endif
+ }
+ }
symtab.limit->is_func = TRUE;
symtab.limit->is_bb_head = TRUE;
{
char prev_name[PATH_MAX], prev_filename[PATH_MAX];
bfd_vma vma, min_vma = ~0, max_vma = 0;
- bfd_vma offset, prev_offset, min_dist;
+ bfd_vma offset;
Sym *prev, dummy, *sentinel, *sym;
const char *filename;
- int prev_line_num, i;
+ int prev_line_num;
Sym_Table ltab;
/*
* Create symbols for functions as usual. This is necessary in
* it is time to create a new symbol.
*
* Of course, this is rather slow and it would be better if
- * bfd would provide an iterator for enumerating all line
- * infos, but for now, we try to speed up the second pass
- * by determining what the minimum code distance between two
- * lines is.
+ * bfd would provide an iterator for enumerating all line infos
*/
prev_name[0] = '\0';
ltab.len = 0;
- min_dist = core_text_sect->_raw_size;
- prev_offset = -min_dist;
prev_filename[0] = '\0';
prev_line_num = 0;
- for (offset = 0; offset < core_text_sect->_raw_size; offset += MIN_INSN_SIZE)
+ for (offset = 0; offset < core_text_sect->_raw_size; offset += min_insn_size)
{
vma = core_text_sect->vma + offset;
if (!get_src_info (vma, &filename, &dummy.name, &dummy.line_num)
strcpy (prev_name, dummy.name);
strcpy (prev_filename, filename);
- if (offset - prev_offset < min_dist)
- {
- min_dist = offset - prev_offset;
- }
- prev_offset = offset;
-
min_vma = MIN (vma, min_vma);
max_vma = MAX (vma, max_vma);
}
- DBG (AOUTDEBUG, printf ("[core_create_line_syms] min_dist=%lx\n", min_dist));
-
/* make room for function symbols, too: */
ltab.len += symtab.len;
ltab.base = (Sym *) xmalloc (ltab.len * sizeof (Sym));
/* pass 2 - create symbols: */
+ /* We now set is_static as we go along, rather than by running
+ through the symbol table at the end.
+
+ The old way called symtab_finalize before the is_static pass,
+ causing a problem since symtab_finalize uses is_static as part of
+ its address conflict resolution algorithm. Since global symbols
+ were prefered over static symbols, and all line symbols were
+ global at that point, static function names that conflicted with
+ their own line numbers (static, but labeled as global) were
+ rejected in favor of the line num.
+
+ This was not the desired functionality. We always want to keep
+ our function symbols and discard any conflicting line symbols.
+ Perhaps symtab_finalize should be modified to make this
+ distinction as well, but the current fix works and the code is a
+ lot cleaner now. */
+
prev = 0;
- for (offset = 0; offset < core_text_sect->_raw_size; offset += min_dist)
+ for (offset = 0; offset < core_text_sect->_raw_size; offset += min_insn_size)
{
sym_init (ltab.limit);
if (!get_src_info (core_text_sect->vma + offset, &filename,
}
/* make name pointer a malloc'ed string: */
- ltab.limit->name = strdup (ltab.limit->name);
+ ltab.limit->name = xstrdup (ltab.limit->name);
ltab.limit->file = source_file_lookup_path (filename);
ltab.limit->addr = core_text_sect->vma + offset;
+
+ /* Set is_static based on the enclosing function, using either:
+ * 1) the previous symbol, if it's from the same function, or
+ * 2) a symtab lookup
+ */
+
+ if (prev && ltab.limit->file == prev->file &&
+ strcmp (ltab.limit->name, prev->name) == 0)
+ {
+ ltab.limit->is_static = prev->is_static;
+ }
+ else
+ {
+ sym = sym_lookup(&symtab, ltab.limit->addr);
+ ltab.limit->is_static = sym->is_static;
+ }
+
prev = ltab.limit;
/*
}
DBG (AOUTDEBUG, printf ("[core_create_line_syms] %d %s 0x%lx\n",
- ltab.len, ltab.limit->name,
+ ltab.limit - ltab.base, ltab.limit->name,
ltab.limit->addr));
++ltab.limit;
}
if (ltab.limit - ltab.base != ltab.len)
{
fprintf (stderr,
- "%s: somebody miscounted: ltab.len=%ld instead of %d\n",
- whoami, (long) (ltab.limit - ltab.base), ltab.len);
+ "%s: somebody miscounted: ltab.len=%d instead of %ld\n",
+ whoami, ltab.len, (long) (ltab.limit - ltab.base));
done (1);
}
free (symtab.base);
symtab = ltab;
- /* now go through all core symbols and set is_static accordingly: */
-
- for (i = 0; i < core_num_syms; ++i)
- {
- if (core_sym_class (core_syms[i]) == 't')
- {
- sym = sym_lookup (&symtab, core_syms[i]->value
- + core_syms[i]->section->vma);
- do
- {
- sym++->is_static = TRUE;
- }
- while (sym->file == sym[-1].file &&
- strcmp (sym->name, sym[-1].name) == 0);
- }
- }
-
}