#define IGNORE_SYMBOL(type) (type == (int)N_NSYMS)
#endif
-/* Macro for name of symbol to indicate a file compiled with gcc. */
-#ifndef GCC_COMPILED_FLAG_SYMBOL
-#define GCC_COMPILED_FLAG_SYMBOL "gcc_compiled."
-#endif
-
-/* Macro for name of symbol to indicate a file compiled with gcc2. */
-#ifndef GCC2_COMPILED_FLAG_SYMBOL
-#define GCC2_COMPILED_FLAG_SYMBOL "gcc2_compiled."
-#endif
-
-/* Define this as 1 if a pcc declaration of a char or short argument
- gives the correct address. Otherwise assume pcc gives the
- address of the corresponding int, which is not the same on a
- big-endian machine. */
-
-#ifndef BELIEVE_PCC_PROMOTION
-#define BELIEVE_PCC_PROMOTION 0
-#endif
-
/* Remember what we deduced to be the source language of this psymtab. */
static enum language psymtab_language = language_unknown;
offset for the current and next .o files. */
static unsigned int file_string_table_offset;
static unsigned int next_file_string_table_offset;
+\f
+/* This is the lowest text address we have yet encountered. */
+static CORE_ADDR lowest_text_address;
/* Complaints about the symbols we have encountered. */
{"unknown symbol type %s", 0, 0};
struct complaint unknown_symchar_complaint =
- {"unknown symbol type character `%c'", 0, 0};
+ {"unknown symbol descriptor `%c'", 0, 0};
struct complaint lbrac_rbrac_complaint =
{"block start larger than block end", 0, 0};
static void
dbx_psymtab_to_symtab_1 PARAMS ((struct partial_symtab *));
+static void
+read_dbx_dynamic_symtab PARAMS ((struct section_offsets *,
+ struct objfile *objfile));
+
static void
read_dbx_symtab PARAMS ((struct section_offsets *, struct objfile *,
CORE_ADDR, int));
break;
#endif
case N_TEXT:
- /* Don't put gcc_compiled, __gnu_compiled_cplus, and friends into
- the minimal symbols, because if there is also another symbol
- at the same address (e.g. the first function of the file),
- lookup_minimal_symbol_by_pc would have no way of getting the
- right one. */
- if (name[0] == 'g'
- && (strcmp (name, GCC_COMPILED_FLAG_SYMBOL) == 0
- || strcmp (name, GCC2_COMPILED_FLAG_SYMBOL) == 0))
- return;
-
- {
- char *tempstring = name;
- if (tempstring[0] == bfd_get_symbol_leading_char (objfile->obfd))
- ++tempstring;
- if (STREQN (tempstring, "__gnu_compiled", 14))
- return;
- }
-
case N_NBTEXT:
case N_FN:
case N_FN_SEQ:
default: ms_type = mst_unknown; break;
}
+ if (ms_type == mst_file_text || ms_type == mst_text
+ && address < lowest_text_address)
+ lowest_text_address = address;
+
prim_record_minimal_symbol
(obsavestring (name, strlen (name), &objfile -> symbol_obstack),
address,
- ms_type);
+ ms_type,
+ objfile);
}
\f
/* Scan and build partial symbols for a symbol file.
bfd_section_vma (sym_bfd, DBX_TEXT_SECT (objfile)),
bfd_section_size (sym_bfd, DBX_TEXT_SECT (objfile)));
+ /* Add the dynamic symbols if we are reading the main symbol table. */
+
+ if (mainline)
+ read_dbx_dynamic_symtab (section_offsets, objfile);
+
/* Install any minimal symbols that have been collected as the current
minimal symbols for this objfile. */
bincls_allocated = 0;
}
+/* Scan a SunOs dynamic symbol table for symbols of interest and
+ add them to the minimal symbol table. */
+
+static void
+read_dbx_dynamic_symtab (section_offsets, objfile)
+ struct section_offsets *section_offsets;
+ struct objfile *objfile;
+{
+ bfd *abfd = objfile->obfd;
+ int counter;
+ bfd_size_type dynsym_count = 0;
+ struct external_nlist *dynsyms = NULL;
+ char *dynstrs = NULL;
+ bfd_size_type dynstr_size;
+ struct external_nlist *ext_symptr;
+ bfd_byte *ext_relptr;
+ bfd_size_type dynrel_count = 0;
+ PTR dynrels = NULL;
+ CORE_ADDR sym_value;
+ bfd_vma strx;
+ char *namestring;
+
+ /* Check that the symbol file has dynamic symbols that we know about.
+ bfd_arch_unknown can happen if we are reading a sun3 symbol file
+ on a sun4 host (and vice versa) and bfd is not configured
+ --with-target=all. This would trigger an assertion in bfd/sunos.c,
+ so we ignore the dynamic symbols in this case. */
+ if (bfd_get_flavour (abfd) != bfd_target_aout_flavour
+ || (bfd_get_file_flags (abfd) & DYNAMIC) == 0
+ || bfd_get_arch (abfd) == bfd_arch_unknown
+ || aout_backend_info (abfd)->read_dynamic_symbols == NULL)
+ return;
+
+ dynsym_count = ((*aout_backend_info (abfd)->read_dynamic_symbols)
+ (abfd, &dynsyms, &dynstrs, &dynstr_size));
+ if (dynsym_count == (bfd_size_type) -1)
+ return;
+
+ /* Enter dynamic symbols into the minimal symbol table
+ if this is a stripped executable. */
+ if (bfd_get_symcount (abfd) <= 0)
+ {
+ ext_symptr = dynsyms;
+ for (counter = 0; counter < dynsym_count; counter++, ext_symptr++)
+ {
+ int type = bfd_h_get_8 (abfd, ext_symptr->e_type);
+
+ switch (type)
+ {
+ case N_TEXT | N_EXT:
+ sym_value = bfd_h_get_32 (abfd, ext_symptr->e_value)
+ + ANOFFSET (section_offsets, SECT_OFF_TEXT);
+ break;
+
+ case N_DATA:
+ case N_DATA | N_EXT:
+ sym_value = bfd_h_get_32 (abfd, ext_symptr->e_value)
+ + ANOFFSET (section_offsets, SECT_OFF_DATA);
+ break;
+
+ case N_BSS:
+ case N_BSS | N_EXT:
+ sym_value = bfd_h_get_32 (abfd, ext_symptr->e_value)
+ + ANOFFSET (section_offsets, SECT_OFF_BSS);
+ break;
+
+ default:
+ continue;
+ }
+
+ strx = bfd_h_get_32 (abfd, ext_symptr->e_strx);
+ if (strx >= dynstr_size)
+ {
+ complain (&string_table_offset_complaint, counter);
+ namestring = "<bad dynamic string table offset>";
+ }
+ else
+ namestring = strx + dynstrs;
+ record_minimal_symbol (namestring, sym_value, type, objfile);
+ }
+ }
+
+ /* Symbols from shared libraries have a dynamic relocation entry
+ that points to the associated slot in the procedure linkage table.
+ We make a mininal symbol table entry with type mst_solib_trampoline
+ at the address in the procedure linkage table. */
+ if (aout_backend_info (abfd)->read_dynamic_relocs == NULL)
+ return;
+
+ dynrel_count = ((*aout_backend_info (abfd)->read_dynamic_relocs)
+ (abfd, &dynrels));
+ if (dynrel_count == (bfd_size_type) -1)
+ return;
+
+ for (counter = 0, ext_relptr = (bfd_byte *) dynrels;
+ counter < dynrel_count;
+ counter++, ext_relptr += obj_reloc_entry_size (abfd))
+ {
+ int r_index;
+
+ if (bfd_get_arch (abfd) == bfd_arch_sparc)
+ {
+ struct reloc_ext_external *rptr =
+ (struct reloc_ext_external *) ext_relptr;
+ int r_type;
+
+ r_type = (rptr->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
+ >> RELOC_EXT_BITS_TYPE_SH_BIG;
+
+ if (r_type != RELOC_JMP_SLOT)
+ continue;
+
+ r_index = (rptr->r_index[0] << 16)
+ | (rptr->r_index[1] << 8)
+ | rptr->r_index[2];
+
+ sym_value = bfd_h_get_32 (abfd, rptr->r_address);
+ }
+ else if (bfd_get_arch (abfd) == bfd_arch_m68k)
+ {
+ struct reloc_std_external *rptr =
+ (struct reloc_std_external *) ext_relptr;
+
+ if ((rptr->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG) == 0)
+ continue;
+
+ r_index = (rptr->r_index[0] << 16)
+ | (rptr->r_index[1] << 8)
+ | rptr->r_index[2];
+
+ /* Adjust address in procedure linkage table to point to
+ the start of the bsr instruction. */
+ sym_value = bfd_h_get_32 (abfd, rptr->r_address) - 2;
+ }
+ else
+ {
+ continue;
+ }
+
+ if (r_index >= dynsym_count)
+ continue;
+ ext_symptr = dynsyms + r_index;
+ if (bfd_h_get_8 (abfd, ext_symptr->e_type) != N_EXT)
+ continue;
+
+ strx = bfd_h_get_32 (abfd, ext_symptr->e_strx);
+ if (strx >= dynstr_size)
+ {
+ complain (&string_table_offset_complaint, r_index);
+ namestring = "<bad dynamic string table offset>";
+ }
+ else
+ namestring = strx + dynstrs;
+
+ prim_record_minimal_symbol (obsavestring (namestring,
+ strlen (namestring),
+ &objfile -> symbol_obstack),
+ sym_value,
+ mst_solib_trampoline,
+ objfile);
+ }
+}
+
/* Given pointers to an a.out symbol table in core containing dbx
style data, setup partial_symtab's describing each source file for
which debugging information is available.
last_source_file = NULL;
-#ifdef END_OF_TEXT_DEFAULT
- end_of_text_addr = END_OF_TEXT_DEFAULT;
-#else
- end_of_text_addr = text_addr + section_offsets->offsets[SECT_OFF_TEXT]
- + text_size; /* Relocate */
-#endif
+ lowest_text_address = (CORE_ADDR)-1;
symfile_bfd = objfile->obfd; /* For next_text_symbol */
abfd = objfile->obfd;
if (((unsigned)bufp->n_strx + file_string_table_offset) >= \
DBX_STRINGTAB_SIZE (objfile)) { \
complain (&string_table_offset_complaint, symnum); \
- namestring = "foo"; \
+ namestring = "<bad string table offset>"; \
} else \
namestring = bufp->n_strx + file_string_table_offset + \
DBX_STRINGTAB (objfile)
if (pst)
{
end_psymtab (pst, psymtab_include_list, includes_used,
- symnum * symbol_size, end_of_text_addr,
+ symnum * symbol_size,
+ (lowest_text_address == (CORE_ADDR)-1
+ ? text_addr : lowest_text_address)
+ + text_size,
dependency_list, dependencies_used);
}
CORE_ADDR capping_text;
struct partial_symtab **dependency_list;
int number_dependencies;
-/* struct partial_symbol *capping_global, *capping_static;*/
{
int i;
struct partial_symtab *p1;
LDSYMLEN(pst) = capping_symbol_offset - LDSYMOFF(pst);
pst->texthigh = capping_text;
+#ifdef N_SO_ADDRESS_MAYBE_MISSING
/* Under Solaris, the N_SO symbols always have a value of 0,
instead of the usual address of the .o file. Therefore,
we have to do some tricks to fill in texthigh and textlow.
/* this test will be true if the last .o file is only data */
if (pst->textlow == 0)
+ /* This loses if the text section really starts at address zero
+ (generally true when we are debugging a .o file, for example).
+ That is why this whole thing is inside N_SO_ADDRESS_MAYBE_MISSING. */
pst->textlow = pst->texthigh;
/* If we know our own starting text address, then walk through all other
}
/* End of kludge for patching Solaris textlow and texthigh. */
-
+#endif /* N_SO_ADDRESS_MAYBE_MISSING. */
pst->n_global_syms =
objfile->global_psymbols.next - (objfile->global_psymbols.list + pst->globals_offset);
free_named_symtabs (pst->filename);
if (num_includes == 0
- && number_dependencies == 0
- && pst->n_global_syms == 0
- && pst->n_static_syms == 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. */
- 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;
+ && number_dependencies == 0
+ && pst->n_global_syms == 0
+ && pst->n_static_syms == 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. */
+ /* Empty psymtabs happen as a result of header files which don't have
+ any symbols in them. There can be a lot of them. But this check
+ 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 */
+ /* Next, put it on a free list for recycling */
- pst->next = pst->objfile->free_psymtabs;
- pst->objfile->free_psymtabs = pst;
+ pst->next = pst->objfile->free_psymtabs;
+ pst->objfile->free_psymtabs = pst;
- /* Indicate that psymtab was thrown away. */
- pst = (struct partial_symtab *)NULL;
- }
+ /* Indicate that psymtab was thrown away. */
+ pst = (struct partial_symtab *)NULL;
+ }
return pst;
}
\f
if (pst->readin)
{
- fprintf (stderr, "Psymtab for %s already read in. Shouldn't happen.\n",
+ fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in. Shouldn't happen.\n",
pst->filename);
return;
}
/* Inform about additional files that need to be read in. */
if (info_verbose)
{
- fputs_filtered (" ", stdout);
+ fputs_filtered (" ", gdb_stdout);
wrap_here ("");
- fputs_filtered ("and ", stdout);
+ fputs_filtered ("and ", gdb_stdout);
wrap_here ("");
printf_filtered ("%s...", pst->dependencies[i]->filename);
wrap_here (""); /* Flush output */
- fflush (stdout);
+ gdb_flush (gdb_stdout);
}
dbx_psymtab_to_symtab_1 (pst->dependencies[i]);
}
if (pst->readin)
{
- fprintf (stderr, "Psymtab for %s already read in. Shouldn't happen.\n",
+ fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in. Shouldn't happen.\n",
pst->filename);
return;
}
if (info_verbose)
{
printf_filtered ("Reading in symbols for %s...", pst->filename);
- fflush (stdout);
+ gdb_flush (gdb_stdout);
}
sym_bfd = pst->objfile->obfd;
processing_gcc_compilation = 0;
if (bufp->n_type == N_TEXT)
{
+ const char *tempstring = namestring;
+
if (STREQ (namestring, GCC_COMPILED_FLAG_SYMBOL))
processing_gcc_compilation = 1;
else if (STREQ (namestring, GCC2_COMPILED_FLAG_SYMBOL))
processing_gcc_compilation = 2;
+ if (tempstring[0] == bfd_get_symbol_leading_char (symfile_bfd))
+ ++tempstring;
+ if (STREQN (tempstring, "__gnu_compiled", 14))
+ processing_gcc_compilation = 2;
}
/* Try to select a C++ demangling based on the compilation unit
N_STSYM or N_GSYM for SunOS4 acc; N_FUN for other compilers. */
static int function_stab_type = 0;
- /* This is true for Solaris (and all other stabs-in-elf systems, hopefully,
- since it would be silly to do things differently from Solaris), and
- false for SunOS4 and other a.out file formats. */
+ /* This is true for Solaris (and all other systems which put stabs
+ in sections, hopefully, since it would be silly to do things
+ differently from Solaris), and false for SunOS4 and other a.out
+ file formats. */
block_address_function_relative =
- 0 == strncmp (bfd_get_target (objfile->obfd), "elf", 3);
+ ((0 == strncmp (bfd_get_target (objfile->obfd), "elf", 3))
+ || (0 == strncmp (bfd_get_target (objfile->obfd), "som", 3))
+ || (0 == strncmp (bfd_get_target (objfile->obfd), "coff", 4)));
if (!block_address_function_relative)
/* N_LBRAC, N_RBRAC and N_SLINE entries are not relative to the
if (!VARIABLES_INSIDE_BLOCK(desc, processing_gcc_compilation))
local_symbols = new->locals;
- /* If this is not the outermost LBRAC...RBRAC pair in the
- function, its local symbols preceded it, and are the ones
- just recovered from the context stack. Defined the block for them.
-
- If this is the outermost LBRAC...RBRAC pair, there is no
- need to do anything; leave the symbols that preceded it
- to be attached to the function's own block. However, if
- it is so, we need to indicate that we just moved outside
- of the function. */
- if (local_symbols
- && (context_stack_depth
- > !VARIABLES_INSIDE_BLOCK(desc, processing_gcc_compilation)))
+ if (context_stack_depth
+ > !VARIABLES_INSIDE_BLOCK(desc, processing_gcc_compilation))
{
- /* FIXME Muzzle a compiler bug that makes end < start. */
- if (new->start_addr > valu)
+ /* This is not the outermost LBRAC...RBRAC pair in the function,
+ its local symbols preceded it, and are the ones just recovered
+ from the context stack. Define the block for them (but don't
+ bother if the block contains no symbols. Should we complain
+ on blocks without symbols? I can't think of any useful purpose
+ for them). */
+ if (local_symbols != NULL)
{
- complain (&lbrac_rbrac_complaint);
- new->start_addr = valu;
+ /* Muzzle a compiler bug that makes end < start. (which
+ compilers? Is this ever harmful?). */
+ if (new->start_addr > valu)
+ {
+ complain (&lbrac_rbrac_complaint);
+ new->start_addr = valu;
+ }
+ /* Make a block for the local symbols within. */
+ finish_block (0, &local_symbols, new->old_blocks,
+ new->start_addr, valu, objfile);
}
- /* Make a block for the local symbols within. */
- finish_block (0, &local_symbols, new->old_blocks,
- new->start_addr, valu, objfile);
}
else
{
+ /* This is the outermost LBRAC...RBRAC pair. There is no
+ need to do anything; leave the symbols that preceded it
+ to be attached to the function's own block. We need to
+ indicate that we just moved outside of the function. */
within_function = 0;
}
+
if (VARIABLES_INSIDE_BLOCK(desc, processing_gcc_compilation))
/* Now pop locals of block just finished. */
local_symbols = new->locals;
p = strchr (name, ':');
if (p != 0 && p[1] == 'S')
{
- /* The linker relocated it. There used to be a kludge here
- to add the text offset, but that will break if we ever
- start using the text offset (currently it is always zero). */
+ /* The linker relocated it. We don't want to add an
+ elfstab_offset_sections-type offset, but we *do* want
+ to add whatever solib.c passed to symbol_file_add as
+ addr (this is known to affect SunOS4, and I suspect ELF
+ too). Since elfstab_offset_sections currently does not
+ muck with the text offset (there is no Ttext.text
+ symbol), we can get addr from the text offset. If
+ elfstab_offset_sections ever starts dealing with the
+ text offset, and we still need to do this, we need to
+ invent a SECT_OFF_ADDR_KLUDGE or something. */
+ valu += ANOFFSET (section_offsets, SECT_OFF_TEXT);
goto define_a_symbol;
}
/* Since it's not the kludge case, re-dispatch to the right handler. */
case N_NBBSS:
case N_NBSTS:
case N_NBLCS:
- complain (&unknown_symtype_complaint,
- local_hex_string((unsigned long) type));
+ complain (&unknown_symtype_complaint, local_hex_string (type));
/* FALLTHROUGH */
/* The following symbol types don't need the address field relocated,
free_header_files ();
init_header_files ();
+ /* This is needed to debug objects assembled with gas2. */
+ processing_acc_compilation = 1;
+
/* In a PA file, we've already installed the minimal symbols that came
from the PA (non-stab) symbol table, so always act like an
incremental load here. */
return section_offsets;
}
\f
-/* Register our willingness to decode symbols for SunOS and a.out and
- NetBSD and b.out files handled by BFD... */
-static struct sym_fns sunos_sym_fns =
-{
- "sunOs", /* sym_name: name or name prefix of BFD target type */
- 6, /* sym_namelen: number of significant sym_name chars */
- dbx_new_init, /* sym_new_init: init anything gbl to entire symtab */
- dbx_symfile_init, /* sym_init: read initial info, setup for sym_read() */
- dbx_symfile_read, /* sym_read: read a symbol file into symtab */
- dbx_symfile_finish, /* sym_finish: finished with file, cleanup */
- dbx_symfile_offsets, /* sym_offsets: parse user's offsets to internal form */
- NULL /* next: pointer to next struct sym_fns */
-};
-
static struct sym_fns aout_sym_fns =
{
- "a.out", /* sym_name: name or name prefix of BFD target type */
- 5, /* sym_namelen: number of significant sym_name chars */
- dbx_new_init, /* sym_new_init: init anything gbl to entire symtab */
- dbx_symfile_init, /* sym_init: read initial info, setup for sym_read() */
- dbx_symfile_read, /* sym_read: read a symbol file into symtab */
- dbx_symfile_finish, /* sym_finish: finished with file, cleanup */
- dbx_symfile_offsets, /* sym_offsets: parse user's offsets to internal form */
- NULL /* next: pointer to next struct sym_fns */
-};
-
-static struct sym_fns bout_sym_fns =
-{
- "b.out", /* sym_name: name or name prefix of BFD target type */
- 5, /* sym_namelen: number of significant sym_name chars */
+ bfd_target_aout_flavour,
dbx_new_init, /* sym_new_init: init anything gbl to entire symtab */
dbx_symfile_init, /* sym_init: read initial info, setup for sym_read() */
dbx_symfile_read, /* sym_read: read a symbol file into symtab */
void
_initialize_dbxread ()
{
- add_symtab_fns(&sunos_sym_fns);
add_symtab_fns(&aout_sym_fns);
- add_symtab_fns(&bout_sym_fns);
}