/* Read dbx symbol tables and convert to internal format, for GDB.
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
- 1996, 1997, 1998, 1999, 2000, 2001
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
This file is part of GDB.
#include <fcntl.h>
#endif
-#include "obstack.h"
+#include "gdb_obstack.h"
#include "gdb_stat.h"
#include "symtab.h"
#include "breakpoint.h"
struct symloc
{
- /* The start (inclusive) and end (exclusive) addresses for this
- partial symtab's text. STABS doesn't reliably give us nice
- start and end addresses for each function. Instead, we are
- told the addresses of various boundary points, and we have to
- gather those together to build ranges. These are our running
- best guess as to the range of text addresses for this psymtab. */
- CORE_ADDR textlow, texthigh;
-
/* Offset within the file symbol table of first local symbol for this
file. */
#define LDSYMOFF(p) (((struct symloc *)((p)->read_symtab_private))->ldsymoff)
#define LDSYMLEN(p) (((struct symloc *)((p)->read_symtab_private))->ldsymlen)
#define SYMLOC(p) ((struct symloc *)((p)->read_symtab_private))
-#define TEXTLOW(p) (SYMLOC(p)->textlow)
-#define TEXTHIGH(p) (SYMLOC(p)->texthigh)
#define SYMBOL_SIZE(p) (SYMLOC(p)->symbol_size)
#define SYMBOL_OFFSET(p) (SYMLOC(p)->symbol_offset)
#define STRING_OFFSET(p) (SYMLOC(p)->string_offset)
struct complaint unclaimed_bincl_complaint =
{"N_BINCL %s not in entries for any file, at symtab pos %d", 0, 0};
+
+struct complaint discarding_local_symbols_complaint =
+{"misplaced N_LBRAC entry; discarding local symbols which have no enclosing block", 0, 0};
\f
/* find_text_range --- find start and end of loadable code sections
read_dbx_dynamic_symtab (objfile);
- /* Take the text ranges the STABS partial symbol scanner computed
- for each of the psymtabs and convert it into the canonical form
- for psymtabs. */
- {
- struct partial_symtab *p;
-
- ALL_OBJFILE_PSYMTABS (objfile, p)
- {
- p->textlow = TEXTLOW (p);
- p->texthigh = TEXTHIGH (p);
- }
- }
-
/* Install any minimal symbols that have been collected as the current
minimal symbols for this objfile. */
do_cleanups (back_to);
}
+#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+CORE_ADDR
+find_stab_function_addr (char *namestring, char *filename,
+ struct objfile *objfile)
+{
+ struct minimal_symbol *msym;
+ char *p;
+ int n;
+
+ p = strchr (namestring, ':');
+ if (p == NULL)
+ p = namestring;
+ n = p - namestring;
+ p = alloca (n + 2);
+ strncpy (p, namestring, n);
+ p[n] = 0;
+
+ msym = lookup_minimal_symbol (p, filename, 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, filename, objfile);
+ }
+
+ if (msym == NULL && filename != NULL)
+ {
+ /* Try again without the filename. */
+ p[n] = 0;
+ msym = lookup_minimal_symbol (p, NULL, objfile);
+ }
+ if (msym == NULL && filename != NULL)
+ {
+ /* And try again for Sun Fortran, but without the filename. */
+ p[n] = '_';
+ p[n + 1] = 0;
+ msym = lookup_minimal_symbol (p, NULL, objfile);
+ }
+
+ return msym == NULL ? 0 : SYMBOL_VALUE_ADDRESS (msym);
+}
+#endif /* SOFUN_ADDRESS_MAYBE_MISSING */
+
/* Setup partial_symtab's describing each source file for which
debugging information is available. */
if (past_first_source_file && pst
/* The gould NP1 uses low values for .o and -l symbols
which are not the address. */
- && nlist.n_value >= TEXTLOW (pst))
+ && nlist.n_value >= pst->textlow)
{
end_psymtab (pst, psymtab_include_list, includes_used,
symnum * symbol_size,
- nlist.n_value > TEXTHIGH (pst)
- ? nlist.n_value : TEXTHIGH (pst),
+ nlist.n_value > pst->texthigh
+ ? nlist.n_value : pst->texthigh,
dependency_list, dependencies_used, textlow_not_set);
pst = (struct partial_symtab *) 0;
includes_used = 0;
{
end_psymtab (pst, psymtab_include_list, includes_used,
symnum * symbol_size,
- valu > TEXTHIGH (pst) ? valu : TEXTHIGH (pst),
+ valu > pst->texthigh ? valu : pst->texthigh,
dependency_list, dependencies_used,
prev_textlow_not_set);
pst = (struct partial_symtab *) 0;
function relative stabs, or the address of the function's
end for old style stabs. */
valu = nlist.n_value + last_function_start;
- if (TEXTHIGH (pst) == 0 || valu > TEXTHIGH (pst))
- TEXTHIGH (pst) = valu;
+ if (pst->texthigh == 0 || valu > pst->texthigh)
+ pst->texthigh = valu;
break;
}
}
if (pst && textlow_not_set)
{
- TEXTLOW (pst) = nlist.n_value;
+ pst->textlow = nlist.n_value;
textlow_not_set = 0;
}
#endif
the partial symbol table. */
if (pst
&& (textlow_not_set
- || (nlist.n_value < TEXTLOW (pst)
+ || (nlist.n_value < pst->textlow
&& (nlist.n_value
!= ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile))))))
{
- TEXTLOW (pst) = nlist.n_value;
+ pst->textlow = nlist.n_value;
textlow_not_set = 0;
}
add_psymbol_to_list (namestring, p - namestring,
}
if (pst && textlow_not_set)
{
- TEXTLOW (pst) = nlist.n_value;
+ pst->textlow = nlist.n_value;
textlow_not_set = 0;
}
#endif
the partial symbol table. */
if (pst
&& (textlow_not_set
- || (nlist.n_value < TEXTLOW (pst)
+ || (nlist.n_value < pst->textlow
&& (nlist.n_value
!= ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile))))))
{
- TEXTLOW (pst) = nlist.n_value;
+ pst->textlow = nlist.n_value;
textlow_not_set = 0;
}
add_psymbol_to_list (namestring, p - namestring,
case N_ENDM:
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
/* Solaris 2 end of module, finish current partial symbol table.
- end_psymtab will set TEXTHIGH (pst) to the proper value, which
+ end_psymtab will set pst->texthigh to the proper value, which
is necessary if a module compiled without debugging info
follows this module. */
if (pst)
end_psymtab (pst, psymtab_include_list, includes_used,
symnum * symbol_size,
- text_end > TEXTHIGH (pst) ? text_end : TEXTHIGH (pst),
+ text_end > pst->texthigh ? text_end : pst->texthigh,
dependency_list, dependencies_used, textlow_not_set);
}
result->read_symtab_private = (char *)
obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc));
- TEXTLOW (result) = result->textlow;
- TEXTHIGH (result) = result->texthigh;
LDSYMOFF (result) = ldsymoff;
result->read_symtab = dbx_psymtab_to_symtab;
SYMBOL_SIZE (result) = symbol_size;
if (capping_symbol_offset != -1)
LDSYMLEN (pst) = capping_symbol_offset - LDSYMOFF (pst);
- TEXTHIGH (pst) = capping_text;
+ pst->texthigh = capping_text;
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
/* Under Solaris, the N_SO symbols always have a value of 0,
a reliable texthigh by taking the address plus size of the
last function in the file. */
- if (TEXTHIGH (pst) == 0 && last_function_name)
+ if (pst->texthigh == 0 && last_function_name)
{
char *p;
int n;
}
if (minsym)
- TEXTHIGH (pst) = SYMBOL_VALUE_ADDRESS (minsym) + MSYMBOL_SIZE (minsym);
+ pst->texthigh = SYMBOL_VALUE_ADDRESS (minsym) + MSYMBOL_SIZE (minsym);
last_function_name = NULL;
}
/* this test will be true if the last .o file is only data */
if (textlow_not_set)
- TEXTLOW (pst) = TEXTHIGH (pst);
+ pst->textlow = pst->texthigh;
else
{
struct partial_symtab *p1;
ALL_OBJFILE_PSYMTABS (objfile, p1)
{
- if (TEXTHIGH (p1) == 0 && TEXTLOW (p1) != 0 && p1 != pst)
+ if (p1->texthigh == 0 && p1->textlow != 0 && p1 != pst)
{
- TEXTHIGH (p1) = TEXTLOW (pst);
+ p1->texthigh = pst->textlow;
/* if this file has only data, then make textlow match texthigh */
- if (TEXTLOW (p1) == 0)
- TEXTLOW (p1) = TEXTHIGH (p1);
+ if (p1->textlow == 0)
+ p1->textlow = p1->texthigh;
}
}
}
sizeof (struct symloc));
LDSYMOFF (subpst) =
LDSYMLEN (subpst) =
- TEXTLOW (subpst) =
- TEXTHIGH (subpst) = 0;
+ subpst->textlow =
+ subpst->texthigh = 0;
/* We could save slight bits of space by only making one of these,
shared by the entire set of include files. FIXME-someday. */
objfile = pst->objfile;
sym_offset = LDSYMOFF (pst);
sym_size = LDSYMLEN (pst);
- text_offset = TEXTLOW (pst);
- text_size = TEXTHIGH (pst) - TEXTLOW (pst);
+ text_offset = pst->textlow;
+ text_size = pst->texthigh - pst->textlow;
/* This cannot be simply objfile->section_offsets because of
elfstab_offset_sections() which initializes the psymtab section
offsets information in a special way, and that is different from
/* In a Solaris elf file, this variable, which comes from the
value of the N_SO symbol, will still be 0. Luckily, text_offset,
- which comes from TEXTLOW (pst) is correct. */
+ which comes from pst->textlow is correct. */
if (last_source_start_addr == 0)
last_source_start_addr = text_offset;
/* In reordered executables last_source_start_addr may not be the
lower bound for this symtab, instead use text_offset which comes
- from TEXTLOW (pst) which is correct. */
+ from pst->textlow which is correct. */
if (last_source_start_addr > text_offset)
last_source_start_addr = text_offset;
used to relocate these symbol types rather than SECTION_OFFSETS. */
static CORE_ADDR function_start_offset;
+ /* This holds the address of the start of a function, without the system
+ peculiarities of function_start_offset. */
+ static CORE_ADDR last_function_start;
+
+ /* If this is nonzero, we've seen an N_SLINE since the start of the current
+ function. Initialized to nonzero to assure that last_function_start
+ is never used uninitialized. */
+ static int sline_found_in_function = 1;
+
/* If this is nonzero, we've seen a non-gcc N_OPT symbol for this source
file. Used to detect the SunPRO solaris compiler. */
static int n_opt_found;
{
/* This N_FUN marks the end of a function. This closes off the
current block. */
+ record_line (current_subfile, 0, function_start_offset + valu);
within_function = 0;
new = pop_context ();
break;
}
+ sline_found_in_function = 0;
+
/* Relocate for dynamic loading */
valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
-#ifdef SMASH_TEXT_ADDRESS
- SMASH_TEXT_ADDRESS (valu);
-#endif
+ valu = SMASH_TEXT_ADDRESS (valu);
+ last_function_start = valu;
+
goto define_a_symbol;
case N_LBRAC:
/* Can only use new->locals as local symbols here if we're in
gcc or on a machine that puts them before the lbrack. */
if (!VARIABLES_INSIDE_BLOCK (desc, processing_gcc_compilation))
- local_symbols = new->locals;
+ {
+ if (local_symbols != NULL)
+ {
+ /* GCC development snapshots from March to December of
+ 2000 would output N_LSYM entries after N_LBRAC
+ entries. As a consequence, these symbols are simply
+ discarded. Complain if this is the case. Note that
+ there are some compilers which legitimately put local
+ symbols within an LBRAC/RBRAC block; this complaint
+ might also help sort out problems in which
+ VARIABLES_INSIDE_BLOCK is incorrectly defined. */
+ complain (&discarding_local_symbols_complaint);
+ }
+ local_symbols = new->locals;
+ }
if (context_stack_depth
> !VARIABLES_INSIDE_BLOCK (desc, processing_gcc_compilation))
#ifdef SUN_FIXED_LBRAC_BUG
last_pc_address = valu; /* Save for SunOS bug circumcision */
#endif
- record_line (current_subfile, desc, valu);
+ /* If this is the first SLINE note in the function, record it at
+ the start of the function instead of at the listed location. */
+ if (within_function && sline_found_in_function == 0)
+ {
+ record_line (current_subfile, desc, last_function_start);
+ sline_found_in_function = 1;
+ }
+ else
+ record_line (current_subfile, desc, valu);
break;
case N_BCOMM: