/* Read dbx symbol tables and convert to internal format, for GDB.
Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
- 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004.
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2008.
Free Software Foundation, Inc.
This file is part of GDB.
#include "demangle.h"
#include "complaints.h"
#include "cp-abi.h"
+#include "cp-support.h"
#include "gdb_assert.h"
#include "gdb_string.h"
i = N_HEADER_FILES (current_objfile)++;
hfile = HEADER_FILES (current_objfile) + i;
- hfile->name = savestring (name, strlen (name));
+ hfile->name = xstrdup (name);
hfile->instance = instance;
hfile->length = 10;
hfile->vector
lowest_text_address = address;
prim_record_minimal_symbol_and_info
- (name, address, ms_type, NULL, section, bfd_section, objfile);
+ (name, address, ms_type, section, bfd_section, objfile);
}
\f
/* Scan and build partial symbols for a symbol file.
#define INTERNALIZE_SYMBOL(intern, extern, abfd) \
{ \
- (intern).n_type = bfd_h_get_8 (abfd, (extern)->e_type); \
(intern).n_strx = bfd_h_get_32 (abfd, (extern)->e_strx); \
+ (intern).n_type = bfd_h_get_8 (abfd, (extern)->e_type); \
+ (intern).n_other = 0; \
(intern).n_desc = bfd_h_get_16 (abfd, (extern)->e_desc); \
if (bfd_get_sign_extend_vma (abfd)) \
(intern).n_value = bfd_h_get_signed_32 (abfd, (extern)->e_value); \
rather than abort the symbol reading or flood the user with messages. */
static char *
-set_namestring (struct objfile *objfile, struct internal_nlist nlist)
+set_namestring (struct objfile *objfile, const struct internal_nlist *nlist)
{
char *namestring;
- if (((unsigned) nlist.n_strx + file_string_table_offset) >=
- DBX_STRINGTAB_SIZE (objfile))
+ if (((unsigned) nlist->n_strx + file_string_table_offset)
+ >= DBX_STRINGTAB_SIZE (objfile))
{
complaint (&symfile_complaints, _("bad string table offset in symbol %d"),
symnum);
namestring = "<bad string table offset>";
}
else
- namestring = nlist.n_strx + file_string_table_offset +
- DBX_STRINGTAB (objfile);
+ namestring = (nlist->n_strx + file_string_table_offset
+ + DBX_STRINGTAB (objfile));
return namestring;
}
static void
read_dbx_symtab (struct objfile *objfile)
{
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
struct external_nlist *bufp = 0; /* =0 avoids gcc -Wall glitch */
struct internal_nlist nlist;
CORE_ADDR text_addr;
int text_size;
+ char *sym_name;
+ int sym_len;
char *namestring;
int nsl;
switch (nlist.n_type)
{
- char *p;
/*
* Standard, external, non-debugger, symbols
*/
case N_ABS | N_EXT:
record_it:
- namestring = set_namestring (objfile, nlist);
+ namestring = set_namestring (objfile, &nlist);
bss_ext_symbol:
record_minimal_symbol (namestring, nlist.n_value,
case N_TEXT:
nlist.n_value += ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile));
- namestring = set_namestring (objfile, nlist);
+ namestring = set_namestring (objfile, &nlist);
if ((namestring[0] == '-' && namestring[1] == 'l')
|| (namestring[(nsl = strlen (namestring)) - 1] == 'o'
pst = (struct partial_symtab *) 0;
includes_used = 0;
dependencies_used = 0;
+ has_line_numbers = 0;
}
else
past_first_source_file = 1;
CORE_ADDR reladdr;
- namestring = set_namestring (objfile, nlist);
+ namestring = set_namestring (objfile, &nlist);
if (target_lookup_symbol (namestring, &reladdr))
{
continue; /* Error in lookup; ignore symbol for now. */
don't relocate it. */
if (nlist.n_value == 0
- && gdbarch_sofun_address_maybe_missing (current_gdbarch))
+ && gdbarch_sofun_address_maybe_missing (gdbarch))
{
textlow_not_set = 1;
valu = 0;
pst = (struct partial_symtab *) 0;
includes_used = 0;
dependencies_used = 0;
+ has_line_numbers = 0;
}
}
/* End the current partial symtab and start a new one */
- namestring = set_namestring (objfile, nlist);
+ namestring = set_namestring (objfile, &nlist);
/* Null name means end of .o file. Don't start a new one. */
if (*namestring == '\000')
}
/* Some other compilers (C++ ones in particular) emit useless
- SOs for non-existant .c files. We ignore all subsequent SOs that
- immediately follow the first. */
+ SOs for non-existant .c files. We ignore all subsequent SOs
+ that immediately follow the first. */
if (!pst)
{
need to save the string; it'll be around until
read_dbx_symtab function returns */
- namestring = set_namestring (objfile, nlist);
+ namestring = set_namestring (objfile, &nlist);
tmp_language = deduce_language_from_filename (namestring);
/* Only change the psymtab's language if we've learned
enum language tmp_language;
/* Mark down an include file in the current psymtab */
- namestring = set_namestring (objfile, nlist);
+ namestring = set_namestring (objfile, &nlist);
tmp_language = deduce_language_from_filename (namestring);
/* Only change the psymtab's language if we've learned
char **orig = psymtab_include_list;
psymtab_include_list = (char **)
- alloca ((includes_allocated *= 2) *
- sizeof (char *));
+ alloca ((includes_allocated *= 2) * sizeof (char *));
memcpy (psymtab_include_list, orig,
includes_used * sizeof (char *));
}
suspect not. */
case N_M2C: /* I suspect that I can ignore this here. */
case N_SCOPE: /* Same. */
+ {
+ char *p;
- namestring = set_namestring (objfile, nlist);
+ namestring = set_namestring (objfile, &nlist);
/* See if this is an end of function stab. */
if (pst && nlist.n_type == N_FUN && *namestring == '\000')
if (!p)
continue; /* Not a debugging symbol. */
+ sym_len = 0;
+ sym_name = NULL; /* pacify "gcc -Werror" */
+ if (psymtab_language == language_cplus)
+ {
+ char *new_name, *name = alloca (p - namestring + 1);
+ memcpy (name, namestring, p - namestring);
+ name[p - namestring] = '\0';
+ new_name = cp_canonicalize_string (name);
+ if (new_name != NULL)
+ {
+ sym_len = strlen (new_name);
+ sym_name = obsavestring (new_name, sym_len,
+ &objfile->objfile_obstack);
+ xfree (new_name);
+ }
+ }
+ if (sym_len == 0)
+ {
+ sym_name = namestring;
+ sym_len = p - namestring;
+ }
/* Main processing section for debugging symbols which
the initial read through the symbol tables needs to worry
nlist.n_value += ANOFFSET (objfile->section_offsets,
data_sect_index);
- if (gdbarch_static_transform_name_p (current_gdbarch))
- namestring = gdbarch_static_transform_name
- (current_gdbarch, namestring);
+ if (gdbarch_static_transform_name_p (gdbarch))
+ namestring = gdbarch_static_transform_name (gdbarch,
+ namestring);
- add_psymbol_to_list (namestring, p - namestring,
+ add_psymbol_to_list (sym_name, sym_len,
VAR_DOMAIN, LOC_STATIC,
&objfile->static_psymbols,
0, nlist.n_value,
psymtab_language, objfile);
continue;
+
case 'G':
nlist.n_value += ANOFFSET (objfile->section_offsets,
data_sect_index);
/* The addresses in these entries are reported to be
wrong. See the code that reads 'G's for symtabs. */
- add_psymbol_to_list (namestring, p - namestring,
+ add_psymbol_to_list (sym_name, sym_len,
VAR_DOMAIN, LOC_STATIC,
&objfile->global_psymbols,
0, nlist.n_value,
|| (p == namestring + 1
&& namestring[0] != ' '))
{
- add_psymbol_to_list (namestring, p - namestring,
+ add_psymbol_to_list (sym_name, sym_len,
STRUCT_DOMAIN, LOC_TYPEDEF,
&objfile->static_psymbols,
nlist.n_value, 0,
if (p[2] == 't')
{
/* Also a typedef with the same name. */
- add_psymbol_to_list (namestring, p - namestring,
+ add_psymbol_to_list (sym_name, sym_len,
VAR_DOMAIN, LOC_TYPEDEF,
&objfile->static_psymbols,
nlist.n_value, 0,
}
}
goto check_enum;
+
case 't':
if (p != namestring) /* a name is there, not just :T... */
{
- add_psymbol_to_list (namestring, p - namestring,
+ add_psymbol_to_list (sym_name, sym_len,
VAR_DOMAIN, LOC_TYPEDEF,
&objfile->static_psymbols,
nlist.n_value, 0,
}
}
continue;
+
case 'c':
/* Constant, e.g. from "const" in Pascal. */
- add_psymbol_to_list (namestring, p - namestring,
+ add_psymbol_to_list (sym_name, sym_len,
VAR_DOMAIN, LOC_CONST,
&objfile->static_psymbols, nlist.n_value,
0, psymtab_language, objfile);
value for the bottom of the text seg in those cases. */
if (nlist.n_value == ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile))
- && gdbarch_sofun_address_maybe_missing (current_gdbarch))
+ && gdbarch_sofun_address_maybe_missing (gdbarch))
{
CORE_ADDR minsym_valu =
find_stab_function_addr (namestring,
nlist.n_value = minsym_valu;
}
if (pst && textlow_not_set
- && gdbarch_sofun_address_maybe_missing (current_gdbarch))
+ && gdbarch_sofun_address_maybe_missing (gdbarch))
{
pst->textlow = nlist.n_value;
textlow_not_set = 0;
pst->textlow = nlist.n_value;
textlow_not_set = 0;
}
- add_psymbol_to_list (namestring, p - namestring,
+ add_psymbol_to_list (sym_name, sym_len,
VAR_DOMAIN, LOC_BLOCK,
&objfile->static_psymbols,
0, nlist.n_value,
value for the bottom of the text seg in those cases. */
if (nlist.n_value == ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile))
- && gdbarch_sofun_address_maybe_missing (current_gdbarch))
+ && gdbarch_sofun_address_maybe_missing (gdbarch))
{
CORE_ADDR minsym_valu =
find_stab_function_addr (namestring,
nlist.n_value = minsym_valu;
}
if (pst && textlow_not_set
- && gdbarch_sofun_address_maybe_missing (current_gdbarch))
+ && gdbarch_sofun_address_maybe_missing (gdbarch))
{
pst->textlow = nlist.n_value;
textlow_not_set = 0;
pst->textlow = nlist.n_value;
textlow_not_set = 0;
}
- add_psymbol_to_list (namestring, p - namestring,
+ add_psymbol_to_list (sym_name, sym_len,
VAR_DOMAIN, LOC_BLOCK,
&objfile->global_psymbols,
0, nlist.n_value,
know about. */
continue;
}
+ }
case N_EXCL:
- namestring = set_namestring (objfile, nlist);
+ namestring = set_namestring (objfile, &nlist);
/* Find the corresponding bincl and mark that psymtab on the
psymtab dependency list */
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 && gdbarch_sofun_address_maybe_missing (current_gdbarch))
+ if (pst && gdbarch_sofun_address_maybe_missing (gdbarch))
{
end_psymtab (pst, psymtab_include_list, includes_used,
symnum * symbol_size,
pst = (struct partial_symtab *) 0;
includes_used = 0;
dependencies_used = 0;
+ has_line_numbers = 0;
}
continue;
is the address relative to which its symbols are (incremental) or 0
(normal). */
-
static struct partial_symtab *
start_psymtab (struct objfile *objfile, char *filename, CORE_ADDR textlow,
int ldsymoff, struct partial_symbol **global_syms,
{
int i;
struct objfile *objfile = pst->objfile;
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
if (capping_symbol_offset != -1)
LDSYMLEN (pst) = capping_symbol_offset - LDSYMOFF (pst);
last function in the file. */
if (pst->texthigh == 0 && last_function_name
- && gdbarch_sofun_address_maybe_missing (current_gdbarch))
+ && gdbarch_sofun_address_maybe_missing (gdbarch))
{
char *p;
int n;
last_function_name = NULL;
}
- if (!gdbarch_sofun_address_maybe_missing (current_gdbarch))
+ if (!gdbarch_sofun_address_maybe_missing (gdbarch))
;
/* this test will be true if the last .o file is only data */
else if (textlow_not_set)
{
pst->dependencies = (struct partial_symtab **)
obstack_alloc (&objfile->objfile_obstack,
- number_dependencies * sizeof (struct partial_symtab *));
+ number_dependencies * sizeof (struct partial_symtab *));
memcpy (pst->dependencies, dependency_list,
number_dependencies * sizeof (struct partial_symtab *));
}
INTERNALIZE_SYMBOL (nlist, bufp, abfd);
OBJSTAT (objfile, n_stabs++);
- namestring = set_namestring (objfile, nlist);
+ namestring = set_namestring (objfile, &nlist);
processing_gcc_compilation = 0;
if (nlist.n_type == N_TEXT)
type = bfd_h_get_8 (abfd, bufp->e_type);
- namestring = set_namestring (objfile, nlist);
+ namestring = set_namestring (objfile, &nlist);
if (type & N_STAB)
{
+ if (sizeof (nlist.n_value) > 4
+ /* We are a 64-bit debugger debugging a 32-bit program. */
+ && (type == N_LSYM || type == N_PSYM))
+ /* We have to be careful with the n_value in the case of N_LSYM
+ and N_PSYM entries, because they are signed offsets from frame
+ pointer, but we actually read them as unsigned 32-bit values.
+ This is not a problem for 32-bit debuggers, for which negative
+ values end up being interpreted correctly (as negative
+ offsets) due to integer overflow.
+ But we need to sign-extend the value for 64-bit debuggers,
+ or we'll end up interpreting negative values as very large
+ positive offsets. */
+ nlist.n_value = (nlist.n_value ^ 0x80000000) - 0x80000000;
process_one_symbol (type, nlist.n_desc, nlist.n_value,
namestring, section_offsets, objfile);
}
struct section_offsets *section_offsets,
struct objfile *objfile)
{
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
struct context_stack *new;
/* This remembers the address of the start of a function. It is
used because in Solaris 2, N_LBRAC, N_RBRAC, and N_SLINE entries
{
/* This N_FUN marks the end of a function. This closes off
the current block. */
+ struct block *block;
if (context_stack_depth <= 0)
{
which may have an N_FUN stabs at the end of the function,
but no N_SLINE stabs. */
if (sline_found_in_function)
- record_line (current_subfile, 0, last_function_start + valu);
+ {
+ CORE_ADDR addr = last_function_start + valu;
+ record_line (current_subfile, 0,
+ gdbarch_addr_bits_remove (gdbarch, addr));
+ }
within_function = 0;
new = pop_context ();
/* Make a block for the local symbols within. */
- finish_block (new->name, &local_symbols, new->old_blocks,
- new->start_addr, new->start_addr + valu,
- objfile);
+ block = finish_block (new->name, &local_symbols, new->old_blocks,
+ new->start_addr, new->start_addr + valu,
+ objfile);
+
+ /* For C++, set the block's scope. */
+ if (SYMBOL_LANGUAGE (new->name) == language_cplus)
+ cp_set_block_scope (new->name, block, &objfile->objfile_obstack,
+ "", 0);
/* May be switching to an assembler file which may not be using
block relative stabs, so reset the offset. */
/* Relocate for dynamic loading. */
valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
- valu = gdbarch_smash_text_address (current_gdbarch, valu);
+ valu = gdbarch_smash_text_address (gdbarch, valu);
last_function_start = valu;
goto define_a_symbol;
if (within_function && sline_found_in_function == 0)
{
- if (processing_gcc_compilation == 2)
- record_line (current_subfile, desc, last_function_start);
- else
- record_line (current_subfile, desc, valu);
+ CORE_ADDR addr = processing_gcc_compilation == 2 ?
+ last_function_start : valu;
+ record_line (current_subfile, desc,
+ gdbarch_addr_bits_remove (gdbarch, addr));
sline_found_in_function = 1;
}
else
- record_line (current_subfile, desc, valu);
+ record_line (current_subfile, desc,
+ gdbarch_addr_bits_remove (gdbarch, valu));
break;
case N_BCOMM:
if (type == N_FUN
&& valu == ANOFFSET (section_offsets,
SECT_OFF_TEXT (objfile))
- && gdbarch_sofun_address_maybe_missing (current_gdbarch))
+ && gdbarch_sofun_address_maybe_missing (gdbarch))
{
CORE_ADDR minsym_valu =
find_stab_function_addr (name, last_source_file, objfile);
if (context_stack_depth > 0)
{
+ struct block *block;
+
new = pop_context ();
/* Make a block for the local symbols within. */
- finish_block (new->name, &local_symbols, new->old_blocks,
- new->start_addr, valu, objfile);
+ block = finish_block (new->name, &local_symbols,
+ new->old_blocks, new->start_addr,
+ valu, objfile);
+
+ /* For C++, set the block's scope. */
+ if (SYMBOL_LANGUAGE (new->name) == language_cplus)
+ cp_set_block_scope (new->name, block,
+ &objfile->objfile_obstack,
+ "", 0);
}
new = push_context (0, valu);