/* Read dbx symbol tables and convert to internal format, for GDB.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 1998
Free Software Foundation, Inc.
This file is part of GDB.
#define FILE_STRING_OFFSET(p) (SYMLOC(p)->file_string_offset)
\f
-/* Macro to determine which symbols to ignore when reading the first symbol
- of a file. Some machines override this definition. */
-#ifndef IGNORE_SYMBOL
-/* This code is used on Ultrix systems. Ignore it */
-#define IGNORE_SYMBOL(type) (type == (int)N_NSYMS)
-#endif
-
/* Remember what we deduced to be the source language of this psymtab. */
static enum language psymtab_language = language_unknown;
/* Nonzero means give verbose info on gdb action. From main.c. */
+
extern int info_verbose;
/* The BFD for this file -- implicit parameter to next_symbol_text. */
static unsigned symbol_size;
-/* This is the offset of the symbol table in the executable file */
+/* This is the offset of the symbol table in the executable file. */
+
static unsigned symbol_table_offset;
-/* This is the offset of the string table in the executable file */
+/* This is the offset of the string table in the executable file. */
+
static unsigned string_table_offset;
/* For elf+stab executables, the n_strx field is not a simple index
- into the string table. Instead, each .o file has a base offset
- in the string table, and the associated symbols contain offsets
- from this base. The following two variables contain the base
- offset for the current and next .o files. */
+ into the string table. Instead, each .o file has a base offset in
+ the string table, and the associated symbols contain offsets from
+ this base. The following two variables contain the base offset for
+ the current and next .o files. */
+
static unsigned int file_string_table_offset;
static unsigned int next_file_string_table_offset;
-/* .o and NLM files contain unrelocated addresses which are based at 0. When
- non-zero, this flag disables some of the special cases for Solaris elf+stab
- text addresses at location 0. */
+/* .o and NLM files contain unrelocated addresses which are based at
+ 0. When non-zero, this flag disables some of the special cases for
+ Solaris elf+stab text addresses at location 0. */
static int symfile_relocatable = 0;
- /* If this is nonzero, N_LBRAC, N_RBRAC, and N_SLINE entries are relative
- to the function start address. */
+/* If this is nonzero, N_LBRAC, N_RBRAC, and N_SLINE entries are
+ relative to the function start address. */
static int block_address_function_relative = 0;
\f
what address the program is actually going to be loaded at, so we
need to make guesses based on the symbols (which *are* relocated to
reflect the address it will be loaded at). */
+
static CORE_ADDR lowest_text_address;
+/* Non-zero if there is any line number info in the objfile. Prevents
+ end_psymtab from discarding an otherwise empty psymtab. */
+
+static int has_line_numbers;
+
/* Complaints about the symbols we have encountered. */
struct complaint lbrac_complaint =
symbol_table_offset = DBX_SYMTAB_OFFSET (objfile);
free_pending_blocks ();
- back_to = make_cleanup (really_free_pendings, 0);
+ back_to = make_cleanup ((make_cleanup_func) really_free_pendings, 0);
init_minimal_symbol_collection ();
- make_cleanup (discard_minimal_symbols, 0);
+ make_cleanup ((make_cleanup_func) discard_minimal_symbols, 0);
/* Now that the symbol table data of the executable file are all in core,
process them and define symbols accordingly. */
unsigned char size_temp[DBX_STRINGTAB_SIZE_SIZE];
/* Allocate struct to keep track of the symfile */
- objfile->sym_stab_info = (PTR)
+ objfile->sym_stab_info = (struct dbx_symfile_info *)
xmmalloc (objfile -> md, sizeof (struct dbx_symfile_info));
memset ((PTR) objfile->sym_stab_info, 0, sizeof (struct dbx_symfile_info));
static int cont_limit = 0;
static int cont_count = 0;
+/* Arrange for function F to be called with arguments SYM and P later
+ in the stabs reading process. */
void
process_later (sym, p, f)
- struct symbol * sym;
- char * p;
+ struct symbol *sym;
+ char *p;
int (*f) PARAMS ((struct objfile *, struct symbol *, char *));
{
+
+ /* Allocate more space for the deferred list. */
if (cont_count >= cont_limit - 1)
{
cont_limit += 32; /* chunk size */
- cont_list = (struct cont_elem *) realloc (cont_list,
- cont_limit * sizeof (struct cont_elem));
+
+ cont_list
+ = (struct cont_elem *) xrealloc (cont_list,
+ (cont_limit
+ * sizeof (struct cont_elem)));
if (!cont_list)
error ("Virtual memory exhausted\n");
}
- /* save state so we can process these stabs later */
+
+ /* Save state variables so we can process these stabs later. */
cont_list[cont_count].sym_idx = symbuf_idx;
cont_list[cont_count].sym_end = symbuf_end;
cont_list[cont_count].symnum = symnum;
cont_count++;
}
+/* Call deferred funtions in CONT_LIST. */
+
static void
process_now (objfile)
- struct objfile * objfile;
+ struct objfile *objfile;
{
int i;
- /* save original state */
- int save_symbuf_idx = symbuf_idx;
- int save_symbuf_end = symbuf_end;
- int save_symnum = symnum;
+ int save_symbuf_idx;
+ int save_symbuf_end;
+ int save_symnum;
struct symbol *sym;
char *stabs;
int err;
int (*func) PARAMS ((struct objfile *, struct symbol *, char *));
- for (i=0; i<cont_count; i++)
+ /* Save the state of our caller, we'll want to restore it before
+ returning. */
+ save_symbuf_idx = symbuf_idx;
+ save_symbuf_end = symbuf_end;
+ save_symnum = symnum;
+
+ /* Iterate over all the deferred stabs. */
+ for (i = 0; i < cont_count; i++)
{
- /* Set state as if we were parsing stabs strings
- for this symbol */
- symbuf_idx = cont_list[i].sym_idx; /* statics used by gdb */
+ /* Restore the state for this deferred stab. */
+ symbuf_idx = cont_list[i].sym_idx;
symbuf_end = cont_list[i].sym_end;
symnum = cont_list[i].symnum;
sym = cont_list[i].sym;
stabs = cont_list[i].stabs;
func = cont_list[i].func;
+ /* Call the function to handle this deferrd stab. */
err = (*func) (objfile, sym, stabs);
if (err)
error ("Internal error: unable to resolve stab.\n");
}
- /* restore original state */
+
+ /* Restore our caller's state. */
symbuf_idx = save_symbuf_idx;
symbuf_end = save_symbuf_end;
symnum = save_symnum;
- cont_count=0; /* reset for next run */
+ cont_count = 0;
}
/* Init bincl list */
init_bincl_list (20, objfile);
- back_to = make_cleanup (free_bincl_list, objfile);
+ back_to = make_cleanup ((make_cleanup_func) free_bincl_list, objfile);
last_source_file = NULL;
symbuf_end = symbuf_idx = 0;
next_symbol_text_func = dbx_next_symbol_text;
textlow_not_set = 1;
+ has_line_numbers = 0;
for (symnum = 0; symnum < DBX_SYMCOUNT (objfile); symnum++)
{
* Special case to speed up readin.
*/
if (bfd_h_get_8 (abfd, bufp->e_type) == N_SLINE)
- continue;
+ {
+ has_line_numbers = 1;
+ continue;
+ }
INTERNALIZE_SYMBOL (nlist, bufp, abfd);
OBJSTAT (objfile, n_stabs++);
if (pst)
{
+ /* Don't set pst->texthigh lower than it already is. */
+ CORE_ADDR text_end =
+ (lowest_text_address == (CORE_ADDR)-1
+ ? (text_addr + section_offsets->offsets[SECT_OFF_TEXT])
+ : lowest_text_address)
+ + text_size;
+
end_psymtab (pst, psymtab_include_list, includes_used,
symnum * symbol_size,
- (lowest_text_address == (CORE_ADDR)-1
- ? (text_addr + section_offsets->offsets[SECT_OFF_TEXT])
- : lowest_text_address)
- + text_size,
+ text_end > pst->texthigh ? text_end : pst->texthigh,
dependency_list, dependencies_used, textlow_not_set);
}
if (p == NULL)
p = last_function_name;
n = p - last_function_name;
- p = alloca (n + 1);
+ p = alloca (n + 2);
strncpy (p, last_function_name, n);
p[n] = 0;
minsym = lookup_minimal_symbol (p, pst->filename, objfile);
+ if (minsym == NULL)
+ {
+ /* Sun Fortran appends an underscore to the minimal symbol name,
+ try again with an appended underscore if the minimal symbol
+ was not found. */
+ p[n] = '_';
+ p[n + 1] = 0;
+ minsym = lookup_minimal_symbol (p, pst->filename, objfile);
+ }
if (minsym)
pst->texthigh = SYMBOL_VALUE_ADDRESS (minsym) + MSYMBOL_SIZE (minsym);
if (num_includes == 0
&& number_dependencies == 0
&& pst->n_global_syms == 0
- && pst->n_static_syms == 0)
+ && pst->n_static_syms == 0
+ && has_line_numbers == 0)
{
/* Throw away this psymtab, it's empty. We can't deallocate it, since
it is on the obstack, but we can forget to chain it on the list. */
is wrong, in that a psymtab with N_SLINE entries but nothing else
is not empty, but we don't realize that. Fixing that without slowing
things down might be tricky. */
- struct partial_symtab *prev_pst;
-
- /* First, snip it out of the psymtab chain */
-
- if (pst->objfile->psymtabs == pst)
- pst->objfile->psymtabs = pst->next;
- else
- for (prev_pst = pst->objfile->psymtabs; prev_pst; prev_pst = pst->next)
- if (prev_pst->next == pst)
- prev_pst->next = pst->next;
- /* Next, put it on a free list for recycling */
-
- pst->next = pst->objfile->free_psymtabs;
- pst->objfile->free_psymtabs = pst;
+ discard_psymtab (pst);
/* Indicate that psymtab was thrown away. */
pst = (struct partial_symtab *)NULL;
/* Init stuff necessary for reading in symbols */
stabsread_init ();
buildsym_init ();
- old_chain = make_cleanup (really_free_pendings, 0);
+ old_chain = make_cleanup ((make_cleanup_func) really_free_pendings, 0);
file_string_table_offset = FILE_STRING_OFFSET (pst);
symbol_size = SYMBOL_SIZE (pst);
pst->symtab = end_symtab (text_offset + text_size, objfile, SECT_OFF_TEXT);
/* Process items which we had to "process_later" due to dependancies
- on other stabs. */
+ on other stabs. */
process_now (objfile);
end_stabs ();
if (last_source_file == NULL && type != (unsigned char)N_SO)
{
- /* Ignore any symbols which appear before an N_SO symbol. Currently
- no one puts symbols there, but we should deal gracefully with the
- case. A complain()t might be in order (if !IGNORE_SYMBOL (type)),
+ /* Ignore any symbols which appear before an N_SO symbol.
+ Currently no one puts symbols there, but we should deal
+ gracefully with the case. A complain()t might be in order,
but this should not be an error (). */
return;
}
finish_block (new->name, &local_symbols, new->old_blocks,
new->start_addr, new->start_addr + valu,
objfile);
+
+ /* May be switching to an assembler file which may not be using
+ block relative stabs, so reset the offset. */
+ if (block_address_function_relative)
+ function_start_offset = 0;
+
break;
}
/* Relocate for dynamic loading */
valu += ANOFFSET (section_offsets, SECT_OFF_TEXT);
+#ifdef SMASH_TEXT_ADDRESS
+ SMASH_TEXT_ADDRESS (valu);
+#endif
goto define_a_symbol;
case N_LBRAC:
if (n_opt_found && desc == 1)
break;
-#if defined(BLOCK_ADDRESS_ABSOLUTE)
- /* Relocate for dynamic loading (?). */
- valu += function_start_offset;
-#else
if (block_address_function_relative)
/* Relocate for Sun ELF acc fn-relative syms. */
valu += function_start_offset;
/* On most machines, the block addresses are relative to the
N_SO, the linker did not relocate them (sigh). */
valu += last_source_start_addr;
-#endif
#ifdef SUN_FIXED_LBRAC_BUG
if (!SUN_FIXED_LBRAC_BUG && valu < last_pc_address) {
if (n_opt_found && desc == 1)
break;
-#if defined(BLOCK_ADDRESS_ABSOLUTE)
- /* Relocate for dynamic loading (?). */
- valu += function_start_offset;
-#else
if (block_address_function_relative)
/* Relocate for Sun ELF acc fn-relative syms. */
valu += function_start_offset;
/* On most machines, the block addresses are relative to the
N_SO, the linker did not relocate them (sigh). */
valu += last_source_start_addr;
-#endif
new = pop_context();
if (desc != new->depth)
if (*name == '\000')
break;
+ if (block_address_function_relative)
+ function_start_offset = 0;
+
start_stabs ();
start_symtab (name, NULL, valu);
record_debugformat ("stabs");
/* This type of "symbol" really just records
one line-number -- core-address correspondence.
Enter it in the line list for this symbol table. */
+
/* Relocate for dynamic loading and for ELF acc fn-relative syms. */
valu += function_start_offset;
+
#ifdef SUN_FIXED_LBRAC_BUG
last_pc_address = valu; /* Save for SunOS bug circumcision */
#endif
if (p == NULL)
p = name;
n = p - name;
- p = alloca (n + 1);
+ p = alloca (n + 2);
strncpy (p, name, n);
p[n] = 0;
msym = lookup_minimal_symbol (p, last_source_file,
objfile);
+ if (msym == NULL)
+ {
+ /* Sun Fortran appends an underscore to the minimal
+ symbol name, try again with an appended underscore
+ if the minimal symbol was not found. */
+ p[n] = '_';
+ p[n + 1] = 0;
+ msym = lookup_minimal_symbol (p, last_source_file,
+ objfile);
+ }
if (msym)
valu = SYMBOL_VALUE_ADDRESS (msym);
}
file's symbols at once. */
case N_ENDM: /* Solaris 2: End of module */
case N_MAIN: /* Name of main routine. */
+ case N_ALIAS: /* SunPro F77: alias name, ignore for now. */
break;
}
- /* Special GNU C extension for referencing names. */
+ /* '#' is a GNU C extension to allow one symbol to refer to another
+ related symbol.
+
+ Generally this is used so that an alias can refer to its main
+ symbol. */
if (name[0] == '#')
{
/* Initialize symbol reference names and determine if this is
a definition. If symbol reference is being defined, go
ahead and add it. Otherwise, just return sym. */
- char *s;
+
+ char *s = name;
int refnum;
- /* If defined, store away a pointer to the symbol;
- we'll use it later when we resolve references in
- "resolve_symbol_reference". */
- s = name;
- if (refnum = symbol_reference_defined (&s), refnum)
+ /* If this stab defines a new reference ID that is not on the
+ reference list, then put it on the reference list.
+
+ We go ahead and advance NAME past the reference, even though
+ it is not strictly necessary at this time. */
+ refnum = symbol_reference_defined (&s);
+ if (refnum >= 0)
if (!ref_search (refnum))
ref_add (refnum, 0, name, valu);
- name = s; /* Advance past refid. */
+ name = s;
}
error ("stabsect_build_psymtabs: Found stabs (%s), but not string section (%s)",
stab_name, stabstr_name);
- objfile->sym_stab_info = (PTR) xmalloc (sizeof (struct dbx_symfile_info));
+ objfile->sym_stab_info = (struct dbx_symfile_info *)
+ xmalloc (sizeof (struct dbx_symfile_info));
memset (objfile->sym_stab_info, 0, sizeof (struct dbx_symfile_info));
text_sect = bfd_get_section_by_name (sym_bfd, text_name);