/* 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.
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 =
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;
}
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;
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 ();
finish_block (new->name, &local_symbols, new->old_blocks,
new->start_addr, new->start_addr + valu,
objfile);
+
+ 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);