#include "defs.h"
#include "gdb_string.h"
#if defined(USG) || defined(__CYGNUSCLIB__)
#include <sys/types.h>
#include <fcntl.h>
#endif
#ifndef TEXT_SECTION_NAME
#define TEXT_SECTION_NAME ".text"
#endif
#ifndef DATA_SECTION_NAME
#define DATA_SECTION_NAME ".data"
#endif
#if HAVE_MMAP
static int mmap_strtabflag = 0;
#endif
static int read_type_psym_p = 1;
#include <assert.h>
#include "gdb_obstack.h"
#include "gdb_stat.h"
#include "symtab.h"
#include "breakpoint.h"
#include "command.h"
#include "gdbcmd.h"
#include "target.h"
#include "gdbcore.h"
#include "libaout.h"
#include "symfile.h"
#include "objfiles.h"
#include "buildsym.h"
#include "stabsread.h"
#include "gdb-stabs.h"
#include "demangle.h"
#include "language.h"
#include "complaints.h"
#include "cp-abi.h"
#include "aout/aout64.h"
#include "aout/stab_gnu.h"
#ifndef MSYMBOL_SIZE
#define MSYMBOL_SIZE(msym) ((long) MSYMBOL_INFO (msym))
#endif
struct symloc
{
int ldsymoff;
int ldsymlen;
int symbol_size;
int symbol_offset;
int string_offset;
int file_string_offset;
char *prefix;
};
#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 SYMBOL_SIZE(p) (SYMLOC(p)->symbol_size)
#define SYMBOL_OFFSET(p) (SYMLOC(p)->symbol_offset)
#define STRING_OFFSET(p) (SYMLOC(p)->string_offset)
#define FILE_STRING_OFFSET(p) (SYMLOC(p)->file_string_offset)
#define SYMBOL_PREFIX(p) (SYMLOC(p)->prefix)
static enum language psymtab_language = language_unknown;
extern int info_verbose;
static bfd *symfile_bfd;
static unsigned symbol_size;
static unsigned symbol_table_offset;
static unsigned string_table_offset;
static unsigned int file_string_table_offset;
static unsigned int next_file_string_table_offset;
static int symfile_relocatable = 0;
static int block_address_function_relative = 0;
static CORE_ADDR lowest_text_address;
static int has_line_numbers;
static void
unknown_symtype_complaint (const char *arg1)
{
complaint (&symfile_complaints, "unknown symbol type %s", arg1);
}
static void
lbrac_mismatch_complaint (int arg1)
{
complaint (&symfile_complaints,
"N_LBRAC/N_RBRAC symbol mismatch at symtab pos %d", arg1);
}
static void
repeated_header_complaint (const char *arg1, int arg2)
{
complaint (&symfile_complaints,
"\"repeated\" header file %s not previously seen, at symtab pos %d",
arg1, arg2);
}
static void
find_text_range (bfd * sym_bfd, struct objfile *objfile)
{
asection *sec;
int found_any = 0;
CORE_ADDR start = 0;
CORE_ADDR end = 0;
for (sec = sym_bfd->sections; sec; sec = sec->next)
if (bfd_get_section_flags (sym_bfd, sec) & SEC_CODE)
{
CORE_ADDR sec_start = bfd_section_vma (sym_bfd, sec);
CORE_ADDR sec_end = sec_start + bfd_section_size (sym_bfd, sec);
if (found_any)
{
if (sec_start < start)
start = sec_start;
if (sec_end > end)
end = sec_end;
}
else
{
start = sec_start;
end = sec_end;
}
found_any = 1;
}
if (!found_any)
error ("Can't find any code sections in symbol file");
DBX_TEXT_ADDR (objfile) = start;
DBX_TEXT_SIZE (objfile) = end - start;
}
struct header_file_location
{
char *name;
unsigned long hash;
int instance;
struct partial_symtab *pst;
};
static struct header_file_location *bincl_list, *next_bincl;
static int bincls_allocated;
extern void _initialize_dbxread (void);
#if 0
#endif
static void read_ofile_symtab (struct partial_symtab *);
static void dbx_psymtab_to_symtab (struct partial_symtab *);
static void dbx_psymtab_to_symtab_1 (struct partial_symtab *);
static void read_dbx_dynamic_symtab (struct objfile *objfile);
static void read_dbx_symtab (struct objfile *);
static void free_bincl_list (struct objfile *);
static struct partial_symtab *find_corresponding_bincl_psymtab (char *, int);
static void add_bincl_to_list (struct partial_symtab *, char *, int);
static void init_bincl_list (int, struct objfile *);
static char *dbx_next_symbol_text (struct objfile *);
static void fill_symbuf (bfd *);
static void dbx_symfile_init (struct objfile *);
static void dbx_new_init (struct objfile *);
static void dbx_symfile_read (struct objfile *, int);
static void dbx_symfile_finish (struct objfile *);
static void record_minimal_symbol (char *, CORE_ADDR, int, struct objfile *);
static void add_new_header_file (char *, int);
static void add_old_header_file (char *, int);
static void add_this_object_header_file (int);
static struct partial_symtab *start_psymtab (struct objfile *, char *,
CORE_ADDR, int,
struct partial_symbol **,
struct partial_symbol **,
const char *prefix);
void
free_header_files (void)
{
if (this_object_header_files)
{
xfree (this_object_header_files);
this_object_header_files = NULL;
}
n_allocated_this_object_header_files = 0;
}
void
init_header_files (void)
{
n_allocated_this_object_header_files = 10;
this_object_header_files = (int *) xmalloc (10 * sizeof (int));
}
static void
add_this_object_header_file (int i)
{
if (n_this_object_header_files == n_allocated_this_object_header_files)
{
n_allocated_this_object_header_files *= 2;
this_object_header_files
= (int *) xrealloc ((char *) this_object_header_files,
n_allocated_this_object_header_files * sizeof (int));
}
this_object_header_files[n_this_object_header_files++] = i;
}
static void
add_old_header_file (char *name, int instance)
{
register struct header_file *p = HEADER_FILES (current_objfile);
register int i;
for (i = 0; i < N_HEADER_FILES (current_objfile); i++)
if (STREQ (p[i].name, name) && instance == p[i].instance)
{
add_this_object_header_file (i);
return;
}
repeated_header_complaint (name, symnum);
}
static void
add_new_header_file (char *name, int instance)
{
register int i;
register struct header_file *hfile;
i = N_ALLOCATED_HEADER_FILES (current_objfile);
if (N_HEADER_FILES (current_objfile) == i)
{
if (i == 0)
{
N_ALLOCATED_HEADER_FILES (current_objfile) = 10;
HEADER_FILES (current_objfile) = (struct header_file *)
xmalloc (10 * sizeof (struct header_file));
}
else
{
i *= 2;
N_ALLOCATED_HEADER_FILES (current_objfile) = i;
HEADER_FILES (current_objfile) = (struct header_file *)
xrealloc ((char *) HEADER_FILES (current_objfile),
(i * sizeof (struct header_file)));
}
}
i = N_HEADER_FILES (current_objfile)++;
hfile = HEADER_FILES (current_objfile) + i;
hfile->name = savestring (name, strlen (name));
hfile->instance = instance;
hfile->length = 10;
hfile->vector
= (struct type **) xmalloc (10 * sizeof (struct type *));
memset (hfile->vector, 0, 10 * sizeof (struct type *));
add_this_object_header_file (i);
}
#if 0
static struct type **
explicit_lookup_type (int real_filenum, int index)
{
register struct header_file *f = &HEADER_FILES (current_objfile)[real_filenum];
if (index >= f->length)
{
f->length *= 2;
f->vector = (struct type **)
xrealloc (f->vector, f->length * sizeof (struct type *));
memset (&f->vector[f->length / 2],
'\0', f->length * sizeof (struct type *) / 2);
}
return &f->vector[index];
}
#endif
static void
record_minimal_symbol (char *name, CORE_ADDR address, int type,
struct objfile *objfile)
{
enum minimal_symbol_type ms_type;
int section;
asection *bfd_section;
switch (type)
{
case N_TEXT | N_EXT:
ms_type = mst_text;
section = SECT_OFF_TEXT (objfile);
bfd_section = DBX_TEXT_SECTION (objfile);
break;
case N_DATA | N_EXT:
ms_type = mst_data;
section = SECT_OFF_DATA (objfile);
bfd_section = DBX_DATA_SECTION (objfile);
break;
case N_BSS | N_EXT:
ms_type = mst_bss;
section = SECT_OFF_BSS (objfile);
bfd_section = DBX_BSS_SECTION (objfile);
break;
case N_ABS | N_EXT:
ms_type = mst_abs;
section = -1;
bfd_section = NULL;
break;
#ifdef N_SETV
case N_SETV | N_EXT:
ms_type = mst_data;
section = SECT_OFF_DATA (objfile);
bfd_section = DBX_DATA_SECTION (objfile);
break;
case N_SETV:
ms_type = mst_file_data;
section = SECT_OFF_DATA (objfile);
bfd_section = DBX_DATA_SECTION (objfile);
break;
#endif
case N_TEXT:
case N_NBTEXT:
case N_FN:
case N_FN_SEQ:
ms_type = mst_file_text;
section = SECT_OFF_TEXT (objfile);
bfd_section = DBX_TEXT_SECTION (objfile);
break;
case N_DATA:
ms_type = mst_file_data;
if (name[8] == 'C' && STREQ ("__DYNAMIC", name))
ms_type = mst_data;
{
char *tempstring = name;
if (tempstring[0] == bfd_get_symbol_leading_char (objfile->obfd))
++tempstring;
if (is_vtable_name (tempstring))
ms_type = mst_data;
}
section = SECT_OFF_DATA (objfile);
bfd_section = DBX_DATA_SECTION (objfile);
break;
case N_BSS:
ms_type = mst_file_bss;
section = SECT_OFF_BSS (objfile);
bfd_section = DBX_BSS_SECTION (objfile);
break;
default:
ms_type = mst_unknown;
section = -1;
bfd_section = NULL;
break;
}
if ((ms_type == mst_file_text || ms_type == mst_text)
&& address < lowest_text_address)
lowest_text_address = address;
prim_record_minimal_symbol_and_info
(name, address, ms_type, NULL, section, bfd_section, objfile);
}
static void
dbx_symfile_read (struct objfile *objfile, int mainline)
{
bfd *sym_bfd;
int val;
struct cleanup *back_to;
sym_bfd = objfile->obfd;
symfile_relocatable = bfd_get_file_flags (sym_bfd) & HAS_RELOC;
block_address_function_relative =
((0 == strncmp (bfd_get_target (sym_bfd), "elf", 3))
|| (0 == strncmp (bfd_get_target (sym_bfd), "som", 3))
|| (0 == strncmp (bfd_get_target (sym_bfd), "coff", 4))
|| (0 == strncmp (bfd_get_target (sym_bfd), "pe", 2))
|| (0 == strncmp (bfd_get_target (sym_bfd), "epoc-pe", 7))
|| (0 == strncmp (bfd_get_target (sym_bfd), "nlm", 3)));
#if defined(NeXT_PDO) && defined(__WIN32__)
block_address_function_relative = 0;
#endif
val = bfd_seek (sym_bfd, DBX_SYMTAB_OFFSET (objfile), SEEK_SET);
if (val < 0)
perror_with_name (objfile->name);
if (mainline
|| (objfile->global_psymbols.size == 0
&& objfile->static_psymbols.size == 0))
init_psymbol_list (objfile, DBX_SYMCOUNT (objfile));
symbol_size = DBX_SYMBOL_SIZE (objfile);
symbol_table_offset = DBX_SYMTAB_OFFSET (objfile);
free_pending_blocks ();
back_to = make_cleanup (really_free_pendings, 0);
#if 0
init_minimal_symbol_collection ();
make_cleanup_discard_minimal_symbols ();
#endif
read_dbx_symtab (objfile);
read_dbx_dynamic_symtab (objfile);
#if 0
install_minimal_symbols (objfile);
#endif
do_cleanups (back_to);
}
static void
dbx_new_init (struct objfile *ignore)
{
stabsread_new_init ();
buildsym_new_init ();
init_header_files ();
}
#define DBX_STRINGTAB_SIZE_SIZE sizeof(long)
static void
dbx_symfile_init (struct objfile *objfile)
{
int val;
bfd *sym_bfd = objfile->obfd;
char *name = bfd_get_filename (sym_bfd);
asection *text_sect;
unsigned char size_temp[DBX_STRINGTAB_SIZE_SIZE];
objfile->sym_stab_info = (struct dbx_symfile_info *)
xmmalloc (objfile->md, sizeof (struct dbx_symfile_info));
memset (objfile->sym_stab_info, 0, sizeof (struct dbx_symfile_info));
DBX_TEXT_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, TEXT_SECTION_NAME);
DBX_DATA_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, DATA_SECTION_NAME);
DBX_BSS_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, ".bss");
#define STRING_TABLE_OFFSET (sym_bfd->origin + obj_str_filepos (sym_bfd))
#define SYMBOL_TABLE_OFFSET (sym_bfd->origin + obj_sym_filepos (sym_bfd))
DBX_SYMFILE_INFO (objfile)->stab_section_info = NULL;
text_sect = bfd_get_section_by_name (sym_bfd, TEXT_SECTION_NAME);
if (!text_sect)
error ("Can't find .text section in symbol file");
DBX_TEXT_ADDR (objfile) = bfd_section_vma (sym_bfd, text_sect);
DBX_TEXT_SIZE (objfile) = bfd_section_size (sym_bfd, text_sect);
DBX_SYMBOL_SIZE (objfile) = obj_symbol_entry_size (sym_bfd);
DBX_SYMCOUNT (objfile) = bfd_get_symcount (sym_bfd);
DBX_SYMTAB_OFFSET (objfile) = SYMBOL_TABLE_OFFSET;
if (STRING_TABLE_OFFSET == 0)
{
DBX_STRINGTAB_SIZE (objfile) = 0;
DBX_STRINGTAB (objfile) = NULL;
}
else
{
val = bfd_seek (sym_bfd, STRING_TABLE_OFFSET, SEEK_SET);
if (val < 0)
perror_with_name (name);
memset (size_temp, 0, sizeof (size_temp));
val = bfd_bread (size_temp, sizeof (size_temp), sym_bfd);
if (val < 0)
{
perror_with_name (name);
}
else if (val == 0)
{
DBX_STRINGTAB_SIZE (objfile) = 0;
DBX_STRINGTAB (objfile) = NULL;
}
else
{
DBX_STRINGTAB_SIZE (objfile) = bfd_h_get_32 (sym_bfd, size_temp);
if (DBX_STRINGTAB_SIZE (objfile) < sizeof (size_temp))
error ("error parsing symbol file: invalid string table size (%d bytes).",
DBX_STRINGTAB_SIZE (objfile));
if (DBX_STRINGTAB_SIZE (objfile) > bfd_get_size (sym_bfd))
error ("error parsing symbol file: invalid string table size (%d bytes).",
DBX_STRINGTAB_SIZE (objfile));
DBX_STRINGTAB (objfile) =
(char *) obstack_alloc (&objfile->psymbol_obstack,
DBX_STRINGTAB_SIZE (objfile));
OBJSTAT (objfile, sz_strtab += DBX_STRINGTAB_SIZE (objfile));
val = bfd_seek (sym_bfd, STRING_TABLE_OFFSET, SEEK_SET);
if (val < 0)
perror_with_name (name);
val = bfd_bread (DBX_STRINGTAB (objfile),
DBX_STRINGTAB_SIZE (objfile),
sym_bfd);
if (val != DBX_STRINGTAB_SIZE (objfile))
perror_with_name (name);
}
}
}
static void
dbx_symfile_finish (struct objfile *objfile)
{
if (objfile->sym_stab_info != NULL)
{
if (HEADER_FILES (objfile) != NULL)
{
register int i = N_HEADER_FILES (objfile);
register struct header_file *hfiles = HEADER_FILES (objfile);
while (--i >= 0)
{
xfree (hfiles[i].name);
xfree (hfiles[i].vector);
}
xfree (hfiles);
}
xmfree (objfile->md, objfile->sym_stab_info);
}
free_header_files ();
}
static struct external_nlist symbuf[4096];
static int symbuf_idx;
static int symbuf_end;
struct cont_elem
{
struct symbol *sym;
char *stabs;
int sym_idx;
int sym_end;
int symnum;
int (*func) (struct objfile *, struct symbol *, char *);
};
static struct cont_elem *cont_list = 0;
static int cont_limit = 0;
static int cont_count = 0;
void
process_later (struct symbol *sym, char *p,
int (*f) (struct objfile *, struct symbol *, char *))
{
if (cont_count >= cont_limit - 1)
{
cont_limit += 32;
cont_list
= (struct cont_elem *) xrealloc (cont_list,
(cont_limit
* sizeof (struct cont_elem)));
if (!cont_list)
error ("Virtual memory exhausted\n");
}
cont_list[cont_count].sym_idx = symbuf_idx;
cont_list[cont_count].sym_end = symbuf_end;
cont_list[cont_count].symnum = symnum;
cont_list[cont_count].sym = sym;
cont_list[cont_count].stabs = p;
cont_list[cont_count].func = f;
cont_count++;
}
#if 0
#endif
static char *last_function_name;
static char *stringtab_global;
static struct stab_section_list *symbuf_sections;
static unsigned int symbuf_left;
static unsigned int symbuf_read;
static void
fill_symbuf (bfd *sym_bfd)
{
unsigned int count;
int nbytes;
if (symbuf_sections == NULL)
count = sizeof (symbuf);
else
{
if (symbuf_left <= 0)
{
file_ptr filepos = symbuf_sections->section->filepos;
if (bfd_seek (sym_bfd, filepos, SEEK_SET) != 0)
perror_with_name (bfd_get_filename (sym_bfd));
symbuf_left = bfd_section_size (sym_bfd, symbuf_sections->section);
symbol_table_offset = filepos - symbuf_read;
symbuf_sections = symbuf_sections->next;
}
count = symbuf_left;
if (count > sizeof (symbuf))
count = sizeof (symbuf);
}
nbytes = bfd_bread (symbuf, count, sym_bfd);
if (nbytes < 0)
perror_with_name (bfd_get_filename (sym_bfd));
else if (nbytes == 0)
error ("Premature end of file reading symbol table");
symbuf_end = nbytes / symbol_size;
symbuf_idx = 0;
symbuf_left -= nbytes;
symbuf_read += nbytes;
}
#ifndef INTERNALIZE_SYMBOL
#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_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); \
else \
(intern).n_value = bfd_h_get_32 (abfd, (extern)->e_value); \
}
#endif
#ifndef PEEK_SYMBOL
#define PEEK_SYMBOL(intern, abfd) \
{ \
if (symbuf_idx == symbuf_end) \
fill_symbuf (symfile_bfd); \
INTERNALIZE_SYMBOL (intern, &symbuf[symbuf_idx], abfd); \
}
#endif
#ifndef NEXT_SYMBOL
#define NEXT_SYMBOL(intern, abfd) \
{ \
PEEK_SYMBOL (intern, abfd); \
symbuf_idx++; \
}
#endif
static char *
dbx_next_symbol_text (struct objfile *objfile)
{
struct internal_nlist nlist1;
struct internal_nlist nlist2;
struct external_nlist elist1;
PEEK_SYMBOL (nlist1, symfile_bfd);
if (nlist1.n_type & N_STAB)
{
symbuf_idx++;
symnum++;
OBJSTAT (objfile, n_stabs++);
return (nlist1.n_strx + stringtab_global + file_string_table_offset);
}
elist1 = symbuf[symbuf_idx];
symbuf_idx++;
PEEK_SYMBOL (nlist2, symfile_bfd);
if (nlist2.n_type & N_STAB)
{
symbuf[symbuf_idx] = elist1;
symnum++;
OBJSTAT (objfile, n_stabs++);
return (nlist2.n_strx + stringtab_global + file_string_table_offset);
}
complaint (&symfile_complaints, "unable to find symbol continuation");
return (nlist1.n_strx + stringtab_global + file_string_table_offset);
}
#define bincl_hash msymbol_hash
static void
init_bincl_list (int number, struct objfile *objfile)
{
bincls_allocated = number;
next_bincl = bincl_list = (struct header_file_location *)
xmmalloc (objfile->md, bincls_allocated * sizeof (struct header_file_location));
}
static void
add_bincl_to_list (struct partial_symtab *pst, char *name, int instance)
{
if (next_bincl >= bincl_list + bincls_allocated)
{
int offset = next_bincl - bincl_list;
bincls_allocated *= 2;
bincl_list = (struct header_file_location *)
xmrealloc (pst->objfile->md, (char *) bincl_list,
bincls_allocated * sizeof (struct header_file_location));
next_bincl = bincl_list + offset;
}
next_bincl->pst = pst;
next_bincl->hash = bincl_hash (name);
next_bincl->instance = instance;
next_bincl++->name = name;
}
static struct partial_symtab *
find_corresponding_bincl_psymtab (char *name, int instance)
{
struct header_file_location *bincl;
unsigned long hash = bincl_hash (name);
for (bincl = bincl_list; bincl < next_bincl; bincl++)
if ((bincl->hash == hash)
&& (bincl->instance == instance)
&& STREQ (name, bincl->name))
return bincl->pst;
repeated_header_complaint (name, symnum);
return (struct partial_symtab *) 0;
}
static void
free_bincl_list (struct objfile *objfile)
{
xmfree (objfile->md, bincl_list);
bincls_allocated = 0;
}
static void
do_free_bincl_list_cleanup (void *objfile)
{
free_bincl_list (objfile);
}
static struct cleanup *
make_cleanup_free_bincl_list (struct objfile *objfile)
{
return make_cleanup (do_free_bincl_list_cleanup, objfile);
}
static char *
set_namestring (struct objfile *objfile, struct internal_nlist nlist, const char *prefix)
{
char *namestring;
static char *namebuf = NULL;
static size_t namebuf_len = 0;
if (((unsigned int) 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
{
char *p = prefix;
char *s = nlist.n_strx + file_string_table_offset +
DBX_STRINGTAB (objfile);
char l = bfd_get_symbol_leading_char (objfile->obfd);
if ((p != NULL) && (p[0] != '\0') && (s[0] == l))
{
size_t req = 1 + strlen (p) + strlen (s) + 1 - 1;
while (namebuf_len < req)
{
if (namebuf_len == 0)
namebuf_len = 1024;
namebuf_len *= 2;
}
namebuf = xrealloc (namebuf, namebuf_len);
sprintf (namebuf, "%c%s%s", l, p, s + 1);
namestring = namebuf;
} else {
namestring = s;
}
}
return namestring;
}
static void
read_dbx_dynamic_symtab (struct objfile *objfile)
{
bfd *abfd = objfile->obfd;
struct cleanup *back_to;
int counter;
long dynsym_size;
long dynsym_count;
asymbol **dynsyms;
asymbol **symptr;
arelent **relptr;
long dynrel_size;
long dynrel_count;
arelent **dynrels;
CORE_ADDR sym_value;
char *name;
if (bfd_get_flavour (abfd) != bfd_target_aout_flavour
|| (bfd_get_file_flags (abfd) & DYNAMIC) == 0
|| bfd_get_arch (abfd) == bfd_arch_unknown)
return;
dynsym_size = bfd_get_dynamic_symtab_upper_bound (abfd);
if (dynsym_size < 0)
return;
dynsyms = (asymbol **) xmalloc (dynsym_size);
back_to = make_cleanup (xfree, dynsyms);
dynsym_count = bfd_canonicalize_dynamic_symtab (abfd, dynsyms);
if (dynsym_count < 0)
{
do_cleanups (back_to);
return;
}
if (bfd_get_symcount (abfd) <= 0)
{
symptr = dynsyms;
for (counter = 0; counter < dynsym_count; counter++, symptr++)
{
asymbol *sym = *symptr;
asection *sec;
int type;
sec = bfd_get_section (sym);
sym_value = sym->value + sec->vma;
if (bfd_get_section_flags (abfd, sec) & SEC_CODE)
{
sym_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
type = N_TEXT;
}
else if (bfd_get_section_flags (abfd, sec) & SEC_DATA)
{
sym_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
type = N_DATA;
}
else if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
{
sym_value += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
type = N_BSS;
}
else
continue;
if (sym->flags & BSF_GLOBAL)
type |= N_EXT;
record_minimal_symbol ((char *) bfd_asymbol_name (sym), sym_value,
type, objfile);
}
}
dynrel_size = bfd_get_dynamic_reloc_upper_bound (abfd);
if (dynrel_size < 0)
{
do_cleanups (back_to);
return;
}
dynrels = (arelent **) xmalloc (dynrel_size);
make_cleanup (xfree, dynrels);
dynrel_count = bfd_canonicalize_dynamic_reloc (abfd, dynrels, dynsyms);
if (dynrel_count < 0)
{
do_cleanups (back_to);
return;
}
for (counter = 0, relptr = dynrels;
counter < dynrel_count;
counter++, relptr++)
{
arelent *rel = *relptr;
CORE_ADDR address =
rel->address + ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
switch (bfd_get_arch (abfd))
{
case bfd_arch_sparc:
if (rel->howto->type != RELOC_JMP_SLOT)
continue;
break;
case bfd_arch_m68k:
if (rel->howto->type != 16)
continue;
address -= 2;
break;
default:
continue;
}
name = (char *) bfd_asymbol_name (*rel->sym_ptr_ptr);
prim_record_minimal_symbol (name, address, mst_solib_trampoline,
objfile);
}
do_cleanups (back_to);
}
const char *
unparse_stabtype (int i)
{
#undef __define_stab
#undef __define_stab_duplicate
#define __define_stab(t,n,s) if (i == n) { return s; }
#define __define_stab_duplicate(t,n,s)
#include "aout/stab.def"
#undef __define_stab
#undef __define_stab_duplicate
return "[UNKNOWN]";
}
#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)
{
p[n] = '_';
p[n + 1] = 0;
msym = lookup_minimal_symbol (p, filename, objfile);
}
if (msym == NULL && filename != NULL)
{
p[n] = 0;
msym = lookup_minimal_symbol (p, NULL, objfile);
}
if (msym == NULL && filename != NULL)
{
p[n] = '_';
p[n + 1] = 0;
msym = lookup_minimal_symbol (p, NULL, objfile);
}
return msym == NULL ? 0 : SYMBOL_VALUE_ADDRESS (msym);
}
#endif
static void
function_outside_compilation_unit_complaint (const char *arg1)
{
complaint (&symfile_complaints,
"function `%s' appears to be defined outside of all compilation units",
arg1);
}
static void
read_dbx_symtab (struct objfile *objfile)
{
register struct external_nlist *bufp = 0;
struct internal_nlist nlist;
CORE_ADDR text_addr;
int text_size;
register char *namestring;
int nsl;
int past_first_source_file = 0;
CORE_ADDR last_o_file_start = 0;
CORE_ADDR last_function_start = 0;
struct cleanup *back_to;
bfd *abfd;
int textlow_not_set;
const char *prefix = NULL;
struct partial_symtab *pst;
char **psymtab_include_list;
int includes_allocated;
int includes_used;
struct partial_symtab **dependency_list;
int dependencies_used, dependencies_allocated;
text_addr = DBX_TEXT_ADDR (objfile);
text_size = DBX_TEXT_SIZE (objfile);
prefix = objfile->prefix;
file_string_table_offset = 0;
next_file_string_table_offset = 0;
stringtab_global = DBX_STRINGTAB (objfile);
pst = (struct partial_symtab *) 0;
includes_allocated = 30;
includes_used = 0;
psymtab_include_list = (char **) alloca (includes_allocated *
sizeof (char *));
dependencies_allocated = 30;
dependencies_used = 0;
dependency_list =
(struct partial_symtab **) alloca (dependencies_allocated *
sizeof (struct partial_symtab *));
init_bincl_list (20, objfile);
back_to = make_cleanup_free_bincl_list (objfile);
last_source_file = NULL;
lowest_text_address = (CORE_ADDR) -1;
symfile_bfd = objfile->obfd;
abfd = objfile->obfd;
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++)
{
QUIT;
namestring = NULL;
NEXT_SYMBOL (nlist, abfd);
if (nlist.n_type == N_SLINE)
{
has_line_numbers = 1;
continue;
}
OBJSTAT (objfile, n_stabs++);
switch (nlist.n_type)
{
char *p;
case N_TEXT | N_EXT:
case N_NBTEXT | N_EXT:
nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
goto record_it;
case N_DATA | N_EXT:
case N_NBDATA | N_EXT:
nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
goto record_it;
case N_BSS:
case N_BSS | N_EXT:
case N_NBBSS | N_EXT:
case N_SETV | N_EXT:
nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
goto record_it;
case N_ABS | N_EXT:
record_it:
namestring = set_namestring (objfile, nlist, prefix);
bss_ext_symbol:
record_minimal_symbol (namestring, nlist.n_value,
nlist.n_type, objfile);
continue;
}
switch (nlist.n_type)
{
case N_NBTEXT:
case N_FN:
case N_FN_SEQ:
case N_TEXT:
nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
namestring = set_namestring (objfile, nlist, prefix);
if ((! (objfile->symflags & (OBJF_SYM_LOCAL | OBJF_SYM_DEBUG)))
&& ((namestring[0] != '+') && (namestring[0] != '-')))
continue;
if ((namestring[0] == '-' && namestring[1] == 'l')
|| (namestring[(nsl = strlen (namestring)) - 1] == 'o'
&& namestring[nsl - 2] == '.'))
{
if (objfile->ei.entry_point < nlist.n_value &&
objfile->ei.entry_point >= last_o_file_start)
{
objfile->ei.entry_file_lowpc = last_o_file_start;
objfile->ei.entry_file_highpc = nlist.n_value;
}
if (past_first_source_file && pst
&& nlist.n_value >= pst->textlow)
{
end_psymtab (pst, psymtab_include_list, includes_used,
symnum * symbol_size,
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;
dependencies_used = 0;
}
else
past_first_source_file = 1;
last_o_file_start = nlist.n_value;
}
else
goto record_it;
continue;
}
switch (nlist.n_type)
{
char *p;
case N_DATA:
nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
goto record_it;
case N_UNDF | N_EXT:
if (nlist.n_value != 0)
{
CORE_ADDR reladdr;
namestring = set_namestring (objfile, nlist, prefix);
if (target_lookup_symbol (namestring, &reladdr))
{
continue;
}
nlist.n_type ^= (N_BSS ^ N_UNDF);
nlist.n_value = reladdr;
goto bss_ext_symbol;
}
continue;
case N_UNDF:
if (processing_acc_compilation && nlist.n_strx == 1)
{
past_first_source_file = 1;
file_string_table_offset = next_file_string_table_offset;
next_file_string_table_offset =
file_string_table_offset + nlist.n_value;
if (next_file_string_table_offset < file_string_table_offset)
error ("string table offset backs up at %d", symnum);
continue;
}
continue;
case N_ABS:
case N_NBDATA:
case N_NBBSS:
continue;
case N_INDR:
case N_INDR | N_EXT:
case N_SETA:
case N_SETA | N_EXT:
case N_SETT:
case N_SETT | N_EXT:
case N_SETD:
case N_SETD | N_EXT:
case N_SETB:
case N_SETB | N_EXT:
case N_SETV:
continue;
case N_SO:
{
CORE_ADDR valu;
static int prev_so_symnum = -10;
static int first_so_symnum;
char *p;
int prev_textlow_not_set;
valu = nlist.n_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
prev_textlow_not_set = textlow_not_set;
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
if (nlist.n_value == 0)
{
textlow_not_set = 1;
valu = 0;
}
else
textlow_not_set = 0;
#else
textlow_not_set = 0;
#endif
past_first_source_file = 1;
if (prev_so_symnum != symnum - 1)
{
first_so_symnum = symnum;
if (pst)
{
end_psymtab (pst, psymtab_include_list, includes_used,
symnum * symbol_size,
valu > pst->texthigh ? valu : pst->texthigh,
dependency_list, dependencies_used,
prev_textlow_not_set);
pst = (struct partial_symtab *) 0;
includes_used = 0;
dependencies_used = 0;
}
}
prev_so_symnum = symnum;
namestring = set_namestring (objfile, nlist, NULL);
if (*namestring == '\000')
continue;
p = strrchr (namestring, '/');
if (p && *(p + 1) == '\000')
continue;
if (!pst)
pst = start_psymtab (objfile,
namestring, valu,
first_so_symnum * symbol_size,
objfile->global_psymbols.next,
objfile->static_psymbols.next, prefix);
continue;
}
case N_BINCL:
{
enum language tmp_language;
struct internal_nlist nlist2;
namestring = set_namestring (objfile, nlist, NULL);
tmp_language = deduce_language_from_filename (namestring);
if (tmp_language != language_unknown
&& (tmp_language != language_c
|| psymtab_language != language_cplus))
psymtab_language = tmp_language;
if (pst == NULL)
{
complaint (&symfile_complaints,
"N_BINCL %s not in entries for any file, at symtab pos %d",
namestring, symnum);
continue;
}
add_bincl_to_list (pst, namestring, nlist.n_value);
goto record_include_file;
}
case N_SOL:
{
enum language tmp_language;
namestring = set_namestring (objfile, nlist, NULL);
tmp_language = deduce_language_from_filename (namestring);
if (tmp_language != language_unknown
&& (tmp_language != language_c
|| psymtab_language != language_cplus))
psymtab_language = tmp_language;
if (pst && STREQ (namestring, pst->filename))
continue;
{
register int i;
for (i = 0; i < includes_used; i++)
if (STREQ (namestring, psymtab_include_list[i]))
{
i = -1;
break;
}
if (i == -1)
continue;
}
record_include_file:
psymtab_include_list[includes_used++] = namestring;
if (includes_used >= includes_allocated)
{
char **orig = psymtab_include_list;
psymtab_include_list = (char **)
alloca ((includes_allocated *= 2) *
sizeof (char *));
memcpy (psymtab_include_list, orig,
includes_used * sizeof (char *));
}
continue;
}
case N_LSYM:
case N_STSYM:
case N_LCSYM:
case N_ROSYM:
case N_NBSTS:
case N_NBLCS:
if (!read_type_psym_p)
break;
case N_FUN:
case N_GSYM:
case N_PC:
case N_M2C:
case N_SCOPE:
namestring = set_namestring (objfile, nlist, NULL);
if (pst && nlist.n_type == N_FUN && *namestring == '\000')
{
CORE_ADDR valu;
valu = nlist.n_value + last_function_start;
if (pst->texthigh == 0 || valu > pst->texthigh)
pst->texthigh = valu;
break;
}
p = (char *) find_name_end (namestring);
if (!p)
continue;
switch (p[1])
{
case 'S':
nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
#ifdef STATIC_TRANSFORM_NAME
namestring = STATIC_TRANSFORM_NAME (namestring);
#endif
add_psymbol_to_list (namestring, p - namestring,
VAR_NAMESPACE, LOC_STATIC,
&objfile->static_psymbols,
0, nlist.n_value,
psymtab_language, objfile);
continue;
case 'G':
nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
add_psymbol_to_list (namestring, p - namestring,
VAR_NAMESPACE, LOC_STATIC,
&objfile->global_psymbols,
0, nlist.n_value,
psymtab_language, objfile);
continue;
case 'T':
if (p >= namestring + 2
|| (p == namestring + 1
&& namestring[0] != ' '))
{
add_psymbol_to_list (namestring, p - namestring,
STRUCT_NAMESPACE, LOC_TYPEDEF,
&objfile->static_psymbols,
nlist.n_value, 0,
psymtab_language, objfile);
if (p[2] == 't')
{
add_psymbol_to_list (namestring, p - namestring,
VAR_NAMESPACE, LOC_TYPEDEF,
&objfile->static_psymbols,
nlist.n_value, 0,
psymtab_language, objfile);
p += 1;
}
#if 0
#endif
}
goto check_enum;
case 't':
if (p != namestring)
{
add_psymbol_to_list (namestring, p - namestring,
VAR_NAMESPACE, LOC_TYPEDEF,
&objfile->static_psymbols,
nlist.n_value, 0,
psymtab_language, objfile);
}
check_enum:
p += 2;
while ((*p >= '0' && *p <= '9')
|| *p == '(' || *p == ',' || *p == ')'
|| *p == '=')
p++;
if (*p++ == 'e')
{
if (*p == '-')
{
while (*p != ':')
p++;
p++;
}
while (*p && *p != ';' && *p != ',')
{
char *q;
if (*p == '\\' || (*p == '?' && p[1] == '\0'))
p = next_symbol_text (objfile);
for (q = p; *q && *q != ':'; q++)
;
add_psymbol_to_list (p, q - p,
VAR_NAMESPACE, LOC_CONST,
&objfile->static_psymbols, 0,
0, psymtab_language, objfile);
p = q;
while (*p && *p != ',')
p++;
if (*p)
p++;
}
}
continue;
case 'c':
add_psymbol_to_list (namestring, p - namestring,
VAR_NAMESPACE, LOC_CONST,
&objfile->static_psymbols, nlist.n_value,
0, psymtab_language, objfile);
continue;
case 'f':
if (! pst)
{
int name_len = p - namestring;
char *name = xmalloc (name_len + 1);
memcpy (name, namestring, name_len);
name[name_len] = '\0';
function_outside_compilation_unit_complaint (name);
xfree (name);
}
nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
last_function_name = namestring;
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
if (nlist.n_value == ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile)))
{
CORE_ADDR minsym_valu =
find_stab_function_addr (namestring, pst->filename, objfile);
if (minsym_valu != 0)
nlist.n_value = minsym_valu;
}
if (pst && textlow_not_set)
{
pst->textlow = nlist.n_value;
textlow_not_set = 0;
}
#endif
last_function_start = nlist.n_value;
if (pst
&& (textlow_not_set
|| (nlist.n_value < pst->textlow
&& (nlist.n_value
!= ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile))))))
{
pst->textlow = nlist.n_value;
textlow_not_set = 0;
}
add_psymbol_to_list (namestring, p - namestring,
VAR_NAMESPACE, LOC_BLOCK,
&objfile->static_psymbols,
0, nlist.n_value,
psymtab_language, objfile);
continue;
case 'F':
if (! pst)
{
int name_len = p - namestring;
char *name = xmalloc (name_len + 1);
memcpy (name, namestring, name_len);
name[name_len] = '\0';
function_outside_compilation_unit_complaint (name);
xfree (name);
}
nlist.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
last_function_name = namestring;
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
if (nlist.n_value == ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile)))
{
CORE_ADDR minsym_valu =
find_stab_function_addr (namestring, pst->filename, objfile);
if (minsym_valu != 0)
nlist.n_value = minsym_valu;
}
if (pst && textlow_not_set)
{
pst->textlow = nlist.n_value;
textlow_not_set = 0;
}
#endif
last_function_start = nlist.n_value;
if (pst
&& (textlow_not_set
|| (nlist.n_value < pst->textlow
&& (nlist.n_value
!= ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile))))))
{
pst->textlow = nlist.n_value;
textlow_not_set = 0;
}
add_psymbol_to_list (namestring, p - namestring,
VAR_NAMESPACE, LOC_BLOCK,
&objfile->global_psymbols,
0, nlist.n_value,
psymtab_language, objfile);
continue;
case 'V':
case '(':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '-':
case '#':
#if 0
#endif
continue;
case ':':
continue;
default:
complaint (&symfile_complaints, "unknown symbol descriptor `%c'",
p[1]);
continue;
}
case N_EXCL:
namestring = set_namestring (objfile, nlist, NULL);
{
struct partial_symtab *needed_pst
= find_corresponding_bincl_psymtab (namestring, nlist.n_value);
if (needed_pst == pst)
continue;
if (needed_pst)
{
int i;
int found = 0;
for (i = 0; i < dependencies_used; i++)
if (dependency_list[i] == needed_pst)
{
found = 1;
break;
}
if (found)
continue;
dependency_list[dependencies_used++] = needed_pst;
if (dependencies_used >= dependencies_allocated)
{
struct partial_symtab **orig = dependency_list;
dependency_list =
(struct partial_symtab **)
alloca ((dependencies_allocated *= 2)
* sizeof (struct partial_symtab *));
memcpy (dependency_list, orig,
(dependencies_used
* sizeof (struct partial_symtab *)));
#ifdef DEBUG_INFO
fprintf_unfiltered (gdb_stderr, "Had to reallocate dependency list.\n");
fprintf_unfiltered (gdb_stderr, "New dependencies allocated: %d\n",
dependencies_allocated);
#endif
}
}
}
continue;
case N_ENDM:
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
if (pst)
{
end_psymtab (pst, psymtab_include_list, includes_used,
symnum * symbol_size,
(CORE_ADDR) 0,
dependency_list, dependencies_used, textlow_not_set);
pst = (struct partial_symtab *) 0;
includes_used = 0;
dependencies_used = 0;
}
#endif
continue;
case N_RBRAC:
#ifdef HANDLE_RBRAC
HANDLE_RBRAC (nlist.n_value);
continue;
#endif
case N_EINCL:
case N_DSLINE:
case N_BSLINE:
case N_SSYM:
case N_ENTRY:
case N_MAIN:
case N_CATCH:
case N_EHDECL:
case N_LENG:
case N_BCOMM:
case N_ECOMM:
case N_ECOML:
case N_FNAME:
case N_SLINE:
case N_RSYM:
case N_PSYM:
case N_LBRAC:
case N_NSYMS:
case N_DEFD:
case N_ALIAS:
case N_OBJ:
case N_OPT:
case N_BNSYM:
case N_ENSYM:
continue;
default:
unknown_symtype_complaint (local_hex_string (nlist.n_type));
continue;
}
while ((namestring != NULL) && (namestring[strlen (namestring) - 1] == '\\'))
{
namestring = next_symbol_text (objfile);
}
}
if (DBX_SYMCOUNT (objfile) > 0
&& last_o_file_start
&& objfile->ei.entry_point < nlist.n_value
&& objfile->ei.entry_point >= last_o_file_start)
{
objfile->ei.entry_file_lowpc = last_o_file_start;
objfile->ei.entry_file_highpc = nlist.n_value;
}
if (pst)
{
CORE_ADDR text_end =
(lowest_text_address == (CORE_ADDR) -1
? (text_addr + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)))
: lowest_text_address)
+ text_size;
end_psymtab (pst, psymtab_include_list, includes_used,
symnum * symbol_size,
text_end > pst->texthigh ? text_end : pst->texthigh,
dependency_list, dependencies_used, textlow_not_set);
}
#if defined(NeXT_PDO) && defined(__WIN32__)
{
if (lowest_text_address == (CORE_ADDR) - 1)
lowest_text_address =
text_addr + ANOFFSET (section_offsets, SECT_OFF_TEXT);
ALL_OBJFILE_PSYMTABS (objfile, pst)
{
if (pst->textlow < lowest_text_address)
pst->textlow = pst->texthigh;
if (pst->next)
if (pst->next->texthigh < lowest_text_address)
pst->next->texthigh = pst->textlow;
}
}
#endif
do_cleanups (back_to);
}
static struct partial_symtab *
start_psymtab (struct objfile *objfile, char *filename, CORE_ADDR textlow,
int ldsymoff, struct partial_symbol **global_syms,
struct partial_symbol **static_syms, const char *prefix)
{
struct partial_symtab *result =
start_psymtab_common (objfile, objfile->section_offsets,
filename, textlow, global_syms, static_syms);
result->read_symtab_private = (char *)
obstack_alloc (&objfile->psymbol_obstack, sizeof (struct symloc));
LDSYMOFF (result) = ldsymoff;
result->read_symtab = dbx_psymtab_to_symtab;
SYMBOL_SIZE (result) = symbol_size;
SYMBOL_OFFSET (result) = symbol_table_offset;
STRING_OFFSET (result) = string_table_offset;
FILE_STRING_OFFSET (result) = file_string_table_offset;
SYMBOL_PREFIX (result) = prefix;
elfstab_offset_sections (objfile, result);
psymtab_language = deduce_language_from_filename (filename);
return result;
}
struct partial_symtab *
end_psymtab (struct partial_symtab *pst, char **include_list, int num_includes,
int capping_symbol_offset, CORE_ADDR capping_text,
struct partial_symtab **dependency_list, int number_dependencies,
int textlow_not_set)
{
int i;
struct objfile *objfile = pst->objfile;
if (capping_symbol_offset != -1)
LDSYMLEN (pst) = capping_symbol_offset - LDSYMOFF (pst);
pst->texthigh = capping_text;
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
if (pst->texthigh == 0 && last_function_name)
{
char *p;
int n;
struct minimal_symbol *minsym;
p = find_name_end (last_function_name);
if (p == NULL)
p = last_function_name;
n = p - last_function_name;
p = alloca (n + 2);
strncpy (p, last_function_name, n);
p[n] = 0;
minsym = lookup_minimal_symbol (p, pst->filename, objfile);
if (minsym == NULL)
{
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);
last_function_name = NULL;
}
if (textlow_not_set)
pst->textlow = pst->texthigh;
else
{
struct partial_symtab *p1;
ALL_OBJFILE_PSYMTABS (objfile, p1)
{
if (p1->texthigh == 0 && p1->textlow != 0 && p1 != pst)
{
p1->texthigh = pst->textlow;
if (p1->textlow == 0)
p1->textlow = p1->texthigh;
}
}
}
#endif
pst->n_global_syms =
objfile->global_psymbols.next - (objfile->global_psymbols.list + pst->globals_offset);
pst->n_static_syms =
objfile->static_psymbols.next - (objfile->static_psymbols.list + pst->statics_offset);
pst->number_of_dependencies = number_dependencies;
if (number_dependencies)
{
pst->dependencies = (struct partial_symtab **)
obstack_alloc (&objfile->psymbol_obstack,
number_dependencies * sizeof (struct partial_symtab *));
memcpy (pst->dependencies, dependency_list,
number_dependencies * sizeof (struct partial_symtab *));
}
else
pst->dependencies = 0;
for (i = 0; i < num_includes; i++)
{
struct partial_symtab *subpst =
allocate_psymtab (include_list[i], objfile);
subpst->section_offsets = pst->section_offsets;
subpst->read_symtab_private =
(char *) obstack_alloc (&objfile->psymbol_obstack,
sizeof (struct symloc));
LDSYMOFF (subpst) =
LDSYMLEN (subpst) =
subpst->textlow =
subpst->texthigh = 0;
subpst->dependencies = (struct partial_symtab **)
obstack_alloc (&objfile->psymbol_obstack,
sizeof (struct partial_symtab *));
subpst->dependencies[0] = pst;
subpst->number_of_dependencies = 1;
subpst->globals_offset =
subpst->n_global_syms =
subpst->statics_offset =
subpst->n_static_syms = 0;
subpst->readin = 0;
subpst->symtab = 0;
subpst->read_symtab = pst->read_symtab;
}
sort_pst_symbols (pst);
free_named_symtabs (pst->filename);
PSYMTAB_OBSOLETED (pst) = 50;
if (num_includes == 0
&& number_dependencies == 0
&& pst->n_global_syms == 0
&& pst->n_static_syms == 0
&& has_line_numbers == 0)
{
discard_psymtab (pst);
pst = (struct partial_symtab *) NULL;
}
return pst;
}
static void
dbx_psymtab_to_symtab_1 (struct partial_symtab *pst)
{
struct cleanup *old_chain;
int i;
if (!pst)
return;
if (pst->readin)
{
fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in. Shouldn't happen.\n",
pst->filename);
return;
}
for (i = 0; i < pst->number_of_dependencies; i++)
if (!pst->dependencies[i]->readin)
{
if (info_verbose)
{
fputs_filtered (" ", gdb_stdout);
wrap_here ("");
fputs_filtered ("and ", gdb_stdout);
wrap_here ("");
printf_filtered ("%s...", pst->dependencies[i]->filename);
wrap_here ("");
gdb_flush (gdb_stdout);
}
dbx_psymtab_to_symtab_1 (pst->dependencies[i]);
}
if (LDSYMLEN (pst))
{
stabsread_init ();
buildsym_init ();
old_chain = make_cleanup (really_free_pendings, 0);
file_string_table_offset = FILE_STRING_OFFSET (pst);
symbol_size = SYMBOL_SIZE (pst);
bfd_seek (pst->objfile->obfd, SYMBOL_OFFSET (pst), SEEK_SET);
read_ofile_symtab (pst);
sort_symtab_syms (pst->symtab);
do_cleanups (old_chain);
}
pst->readin = 1;
}
static void
dbx_psymtab_to_symtab (struct partial_symtab *pst)
{
bfd *sym_bfd;
if (!pst)
return;
if (pst->readin)
{
fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in. Shouldn't happen.\n",
pst->filename);
return;
}
if (LDSYMLEN (pst) || pst->number_of_dependencies)
{
if (info_verbose)
{
printf_filtered ("Reading in symbols for %s...", pst->filename);
gdb_flush (gdb_stdout);
}
sym_bfd = pst->objfile->obfd;
next_symbol_text_func = dbx_next_symbol_text;
dbx_psymtab_to_symtab_1 (pst);
scan_file_globals (pst->objfile);
if (info_verbose)
printf_filtered ("done.\n");
}
}
static void
read_ofile_symtab (struct partial_symtab *pst)
{
register char *namestring = NULL;
struct internal_nlist nlist;
unsigned char type;
unsigned max_symnum;
register bfd *abfd;
struct objfile *objfile;
int sym_offset;
int sym_size;
CORE_ADDR text_offset;
int text_size;
struct section_offsets *section_offsets;
char *prefix;
objfile = pst->objfile;
sym_offset = LDSYMOFF (pst);
sym_size = LDSYMLEN (pst);
text_offset = pst->textlow;
text_size = pst->texthigh - pst->textlow;
section_offsets = pst->section_offsets;
prefix = SYMBOL_PREFIX (pst);
current_objfile = objfile;
subfile_stack = NULL;
stringtab_global = DBX_STRINGTAB (objfile);
last_source_file = NULL;
abfd = objfile->obfd;
symfile_bfd = objfile->obfd;
symbuf_end = symbuf_idx = 0;
if (!processing_acc_compilation && sym_offset >= (int) symbol_size)
{
bfd_seek (symfile_bfd, sym_offset - symbol_size, SEEK_CUR);
NEXT_SYMBOL (nlist, abfd);
OBJSTAT (objfile, n_stabs++);
namestring = set_namestring (objfile, nlist, prefix);
processing_gcc_compilation = 0;
if (nlist.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;
}
#if 0
if (processing_gcc_compilation)
{
if (AUTO_DEMANGLING)
{
set_demangling_style (GNU_DEMANGLING_STYLE_STRING);
}
}
#endif
}
else
{
bfd_seek (symfile_bfd, sym_offset, SEEK_CUR);
processing_gcc_compilation = 0;
}
PEEK_SYMBOL (nlist, abfd);
if (nlist.n_type != N_SO)
error ("First symbol in segment of executable not a source symbol");
max_symnum = sym_size / symbol_size;
for (symnum = 0;
symnum < max_symnum;
symnum++)
{
QUIT;
NEXT_SYMBOL (nlist, abfd);
OBJSTAT (objfile, n_stabs++);
type = nlist.n_type;
namestring = set_namestring (objfile, nlist, prefix);
if (type & N_STAB)
{
process_one_symbol (type, nlist.n_desc, nlist.n_value,
namestring, prefix, section_offsets, objfile);
}
else if (type == N_TEXT)
{
if (STREQ (namestring, GCC_COMPILED_FLAG_SYMBOL))
processing_gcc_compilation = 1;
else if (STREQ (namestring, GCC2_COMPILED_FLAG_SYMBOL))
processing_gcc_compilation = 2;
#if 0
if (AUTO_DEMANGLING)
{
set_demangling_style (GNU_DEMANGLING_STYLE_STRING);
}
#endif
}
else if (type & N_EXT || type == (unsigned char) N_TEXT
|| type == (unsigned char) N_NBTEXT
)
{
;
}
}
current_objfile = NULL;
if (last_source_start_addr == 0)
last_source_start_addr = text_offset;
if (last_source_start_addr > text_offset)
last_source_start_addr = text_offset;
pst->symtab = end_symtab (text_offset + text_size, objfile, SECT_OFF_TEXT (objfile));
#if 0
#endif
end_stabs ();
}
void
process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
const char *prefix,
struct section_offsets *section_offsets,
struct objfile *objfile)
{
#ifdef SUN_FIXED_LBRAC_BUG
static CORE_ADDR last_pc_address;
#endif
register struct context_stack *new = NULL;
static CORE_ADDR function_start_offset;
static CORE_ADDR last_function_start;
static int sline_found_in_function = 1;
static int n_opt_found;
static int function_stab_type = 0;
static int saw_fun_start = 0;
if (!block_address_function_relative)
function_start_offset = ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
if (last_source_file == NULL && type != (unsigned char) N_SO)
{
return;
}
switch (type)
{
case N_FUN:
case N_FNAME:
if (*name == '\000')
{
if (context_stack_depth <= 0)
{
lbrac_mismatch_complaint (symnum);
break;
}
if (!saw_fun_start)
{
complaint (&symfile_complaints,
"Found an end function stab with no corresponding begin");
break;
}
saw_fun_start = 0;
record_line (current_subfile, 0, last_function_start + valu);
within_function = 0;
new = pop_context ();
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;
}
sline_found_in_function = 0;
valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
valu = SMASH_TEXT_ADDRESS (valu);
last_function_start = valu;
goto define_a_symbol;
case N_LBRAC:
if (n_opt_found && desc == 1)
break;
#if defined(BLOCK_ADDRESS_ABSOLUTE)
valu += function_start_offset;
#else
if (block_address_function_relative)
valu += function_start_offset;
else
valu += last_source_start_addr;
#endif
#ifdef SUN_FIXED_LBRAC_BUG
if (!SUN_FIXED_LBRAC_BUG && valu < last_pc_address)
{
complaint (&symfile_complaints, "bad block start address patched");
valu = last_pc_address;
}
#endif
new = push_context (desc, valu);
break;
case N_RBRAC:
if (n_opt_found && desc == 1)
break;
#if defined(BLOCK_ADDRESS_ABSOLUTE)
valu += function_start_offset;
#else
if (block_address_function_relative)
valu += function_start_offset;
else
valu += last_source_start_addr;
#endif
if (context_stack_depth <= 0)
{
lbrac_mismatch_complaint (symnum);
break;
}
new = pop_context ();
if (desc != new->depth)
lbrac_mismatch_complaint (symnum);
#if !defined (VARIABLES_INSIDE_BLOCK)
#define VARIABLES_INSIDE_BLOCK(desc, gcc_p) 0
#endif
if (!VARIABLES_INSIDE_BLOCK (desc, processing_gcc_compilation))
{
if (local_symbols != NULL)
{
complaint (&symfile_complaints,
"misplaced N_LBRAC entry; discarding local symbols which have no enclosing block");
}
local_symbols = new->locals;
}
if (context_stack_depth
> !VARIABLES_INSIDE_BLOCK (desc, processing_gcc_compilation))
{
if (local_symbols != NULL)
{
if (new->start_addr > valu)
{
complaint (&symfile_complaints,
"block start larger than block end");
new->start_addr = valu;
}
finish_block (0, &local_symbols, new->old_blocks,
new->start_addr, valu, objfile);
}
}
else
{
within_function = 0;
}
if (VARIABLES_INSIDE_BLOCK (desc, processing_gcc_compilation))
local_symbols = new->locals;
break;
case N_FN:
case N_FN_SEQ:
valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
break;
case N_SO:
valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
n_opt_found = 0;
#ifdef SUN_FIXED_LBRAC_BUG
last_pc_address = valu;
#endif
#ifdef PCC_SOL_BROKEN
if (context_stack_depth > 0)
{
start_subfile (name, NULL);
break;
}
#endif
if (last_source_file)
{
if (previous_stab_code == (unsigned char) N_SO)
{
patch_subfile_names (current_subfile, name);
break;
}
end_symtab (valu, objfile, SECT_OFF_TEXT (objfile));
end_stabs ();
}
if (*name == '\000')
break;
if (block_address_function_relative)
function_start_offset = 0;
start_stabs ();
start_symtab (name, NULL, valu);
record_debugformat ("stabs");
break;
case N_SOL:
valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
start_subfile (name, current_subfile->dirname);
break;
case N_BINCL:
push_subfile ();
add_new_header_file (name, valu);
start_subfile (name, current_subfile->dirname);
break;
case N_EINCL:
start_subfile (pop_subfile (), current_subfile->dirname);
break;
case N_EXCL:
add_old_header_file (name, valu);
break;
case N_SLINE:
valu += function_start_offset;
#ifdef SUN_FIXED_LBRAC_BUG
last_pc_address = valu;
#endif
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:
common_block_start (name, objfile);
break;
case N_ECOMM:
common_block_end (objfile);
break;
case N_STSYM:
case N_LCSYM:
case N_ROSYM:
{
char *p;
if (!symfile_relocatable)
{
p = find_name_end (name);
if (p != 0 && p[1] == 'S')
{
valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
goto define_a_symbol;
}
}
switch (type)
{
case N_STSYM:
goto case_N_STSYM;
case N_LCSYM:
goto case_N_LCSYM;
case N_ROSYM:
goto case_N_ROSYM;
default:
internal_error (__FILE__, __LINE__, "failed internal consistency check");
}
}
case_N_STSYM:
case N_DSLINE:
valu += ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
goto define_a_symbol;
case_N_LCSYM:
case N_BSLINE:
valu += ANOFFSET (section_offsets, SECT_OFF_BSS (objfile));
goto define_a_symbol;
case_N_ROSYM:
valu += ANOFFSET (section_offsets, SECT_OFF_RODATA (objfile));
goto define_a_symbol;
case N_ENTRY:
valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
goto define_a_symbol;
case N_ENSYM:
case N_BNSYM:
break;
default:
case N_CATCH:
case N_EHDECL:
case N_PC:
case N_M2C:
case N_SCOPE:
case N_ECOML:
case N_NBTEXT:
case N_NBDATA:
case N_NBBSS:
case N_NBSTS:
case N_NBLCS:
unknown_symtype_complaint (local_hex_string (type));
define_a_symbol:
case N_GSYM:
case N_NSYMS:
case N_NOMAP:
case N_RSYM:
case N_DEFD:
case N_SSYM:
case N_LSYM:
case N_PSYM:
case N_LENG:
if (name)
{
int deftype;
char *colon_pos = find_name_end (name);
if (colon_pos == NULL)
deftype = '\0';
else
deftype = colon_pos[1];
switch (deftype)
{
case 'f':
case 'F':
function_stab_type = type;
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
if (type == N_FUN
&& valu == ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile)))
{
CORE_ADDR minsym_valu =
find_stab_function_addr (name, last_source_file, objfile);
if (minsym_valu != 0)
valu = minsym_valu;
}
#endif
#ifdef SUN_FIXED_LBRAC_BUG
if (type == N_GSYM || type == N_STSYM
|| (type == N_FUN
&& n_opt_found && !block_address_function_relative))
{
struct minimal_symbol *m;
int l = colon_pos - name;
m = lookup_minimal_symbol_by_pc (last_pc_address);
if (m && STREQN (SYMBOL_NAME (m), name, l)
&& SYMBOL_NAME (m)[l] == '\0')
valu = SYMBOL_VALUE (m);
else if (m && SYMBOL_NAME (m + 1)
&& STREQN (SYMBOL_NAME (m + 1), name, l)
&& SYMBOL_NAME (m + 1)[l] == '\0')
valu = SYMBOL_VALUE (m + 1);
else
valu = last_pc_address;
}
last_pc_address = valu;
#endif
if (block_address_function_relative)
function_start_offset = valu;
within_function = 1;
saw_fun_start = 1;
if (context_stack_depth > 1)
{
complaint (&symfile_complaints,
"unmatched N_LBRAC before symtab pos %d", symnum);
break;
}
if (context_stack_depth > 0)
{
new = pop_context ();
finish_block (new->name, &local_symbols, new->old_blocks,
new->start_addr, valu, objfile);
}
new = push_context (0, valu);
new->name = define_symbol (valu, name, prefix, desc, type, objfile);
break;
default:
define_symbol (valu, name, prefix, desc, type, objfile);
break;
}
}
break;
case N_OPT:
if (name)
{
if (STREQ (name, GCC2_COMPILED_FLAG_SYMBOL))
{
processing_gcc_compilation = 2;
#if 0
if (AUTO_DEMANGLING)
{
set_demangling_style (GNU_DEMANGLING_STYLE_STRING);
}
#endif
}
else
n_opt_found = 1;
}
break;
case N_MAIN:
if (name != NULL)
set_main_name (name);
break;
case N_OBJ:
case N_ENDM:
case N_ALIAS:
break;
}
if (name[0] == '#')
{
char *s = name;
int refnum;
refnum = symbol_reference_defined (&s);
if (refnum >= 0)
if (!ref_search (refnum))
ref_add (refnum, 0, name, valu);
name = s;
}
previous_stab_code = type;
}
void
coffstab_build_psymtabs (struct objfile *objfile, int mainline,
CORE_ADDR textaddr, unsigned int textsize,
struct stab_section_list *stabsects,
file_ptr stabstroffset, unsigned int stabstrsize)
{
int val;
bfd *sym_bfd = objfile->obfd;
char *name = bfd_get_filename (sym_bfd);
struct dbx_symfile_info *info;
unsigned int stabsize;
info = objfile->sym_stab_info;
DBX_TEXT_ADDR (objfile) = textaddr;
DBX_TEXT_SIZE (objfile) = textsize;
#define COFF_STABS_SYMBOL_SIZE 12
DBX_SYMBOL_SIZE (objfile) = COFF_STABS_SYMBOL_SIZE;
DBX_STRINGTAB_SIZE (objfile) = stabstrsize;
if (stabstrsize > bfd_get_size (sym_bfd))
error ("error parsing symbol file: invalid string table size (%d bytes).", stabstrsize);
DBX_STRINGTAB (objfile) = (char *)
obstack_alloc (&objfile->psymbol_obstack, stabstrsize + 1);
OBJSTAT (objfile, sz_strtab += stabstrsize + 1);
val = bfd_seek (sym_bfd, stabstroffset, SEEK_SET);
if (val < 0)
perror_with_name (name);
val = bfd_bread (DBX_STRINGTAB (objfile), stabstrsize, sym_bfd);
if (val != stabstrsize)
perror_with_name (name);
stabsread_new_init ();
buildsym_new_init ();
free_header_files ();
init_header_files ();
processing_acc_compilation = 1;
if (stabsects->next == NULL)
{
stabsize = bfd_section_size (sym_bfd, stabsects->section);
DBX_SYMCOUNT (objfile) = stabsize / DBX_SYMBOL_SIZE (objfile);
DBX_SYMTAB_OFFSET (objfile) = stabsects->section->filepos;
}
else
{
struct stab_section_list *stabsect;
DBX_SYMCOUNT (objfile) = 0;
for (stabsect = stabsects; stabsect != NULL; stabsect = stabsect->next)
{
stabsize = bfd_section_size (sym_bfd, stabsect->section);
DBX_SYMCOUNT (objfile) += stabsize / DBX_SYMBOL_SIZE (objfile);
}
DBX_SYMTAB_OFFSET (objfile) = stabsects->section->filepos;
symbuf_sections = stabsects->next;
symbuf_left = bfd_section_size (sym_bfd, stabsects->section);
symbuf_read = 0;
}
dbx_symfile_read (objfile, 0);
}
void
elfstab_build_psymtabs (struct objfile *objfile, int mainline,
file_ptr staboffset, unsigned int stabsize,
file_ptr stabstroffset, unsigned int stabstrsize)
{
int val;
bfd *sym_bfd = objfile->obfd;
char *name = bfd_get_filename (sym_bfd);
struct dbx_symfile_info *info;
info = objfile->sym_stab_info;
find_text_range (sym_bfd, objfile);
#define ELF_STABS_SYMBOL_SIZE 12
DBX_SYMBOL_SIZE (objfile) = ELF_STABS_SYMBOL_SIZE;
DBX_SYMCOUNT (objfile) = stabsize / DBX_SYMBOL_SIZE (objfile);
DBX_STRINGTAB_SIZE (objfile) = stabstrsize;
DBX_SYMTAB_OFFSET (objfile) = staboffset;
if (stabstrsize > bfd_get_size (sym_bfd))
error ("error parsing symbol file: invalid string table size (%d bytes).", stabstrsize);
DBX_STRINGTAB (objfile) = (char *)
obstack_alloc (&objfile->psymbol_obstack, stabstrsize + 1);
OBJSTAT (objfile, sz_strtab += stabstrsize + 1);
val = bfd_seek (sym_bfd, stabstroffset, SEEK_SET);
if (val < 0)
perror_with_name (name);
val = bfd_bread (DBX_STRINGTAB (objfile), stabstrsize, sym_bfd);
if (val != stabstrsize)
perror_with_name (name);
stabsread_new_init ();
buildsym_new_init ();
free_header_files ();
init_header_files ();
install_minimal_symbols (objfile);
processing_acc_compilation = 1;
dbx_symfile_read (objfile, 0);
}
void stabsect_build_psymtabs (struct objfile *objfile, int mainline,
char *stab_name, char *stabstr_name,
char *text_name, char *data_name, char *bss_name)
{
int val;
bfd *sym_bfd = objfile->obfd;
char *name = bfd_get_filename (sym_bfd);
asection *stabsect;
asection *stabstrsect;
asection *text_sect;
#if 0
init_minimal_symbol_collection ();
make_cleanup (discard_minimal_symbols, 0);
#endif
stabsect = bfd_get_section_by_name (sym_bfd, stab_name);
stabstrsect = bfd_get_section_by_name (sym_bfd, stabstr_name);
if (!stabsect)
return;
if (!stabstrsect)
error ("stabsect_build_psymtabs: Found stabs (%s), but not string section (%s)",
stab_name, stabstr_name);
objfile->sym_stab_info = (struct dbx_symfile_info *)
xmmalloc (objfile->md, sizeof (struct dbx_symfile_info));
memset (objfile->sym_stab_info, 0, sizeof (struct dbx_symfile_info));
assert (text_name != NULL);
assert (data_name != NULL);
DBX_TEXT_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, text_name);
DBX_DATA_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, data_name);
if (bss_name != NULL)
{
DBX_BSS_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, bss_name);
}
if (!DBX_TEXT_SECTION (objfile))
{
error ("Can't find %s section in symbol file", text_name);
}
if (!DBX_DATA_SECTION (objfile))
{
error ("Can't find %s section in symbol file", data_name);
}
text_sect = DBX_TEXT_SECTION (objfile);
DBX_TEXT_ADDR (objfile) = bfd_section_vma (sym_bfd, text_sect);
DBX_TEXT_SIZE (objfile) = bfd_section_size (sym_bfd, text_sect);
DBX_SYMBOL_SIZE (objfile) = sizeof (struct external_nlist);
DBX_SYMCOUNT (objfile) = bfd_section_size (sym_bfd, stabsect) / DBX_SYMBOL_SIZE (objfile);
DBX_STRINGTAB_SIZE (objfile) = bfd_section_size (sym_bfd, stabstrsect);
DBX_SYMTAB_OFFSET (objfile) = stabsect->filepos;
#if HAVE_MMAP
if (mmap_strtabflag)
{
bfd_window w;
bfd_init_window (&w);
val = bfd_get_section_contents_in_window
(sym_bfd, stabstrsect, &w, 0, DBX_STRINGTAB_SIZE (objfile));
if (!val)
perror_with_name (name);
DBX_STRINGTAB (objfile) = w.data;
}
else
{
#endif
if (DBX_STRINGTAB_SIZE (objfile) > bfd_get_size (sym_bfd))
error ("error parsing symbol file: invalid string table size (%d bytes)", DBX_STRINGTAB_SIZE (objfile));
DBX_STRINGTAB (objfile) =
(char *) obstack_alloc (&objfile->psymbol_obstack, DBX_STRINGTAB_SIZE (objfile) + 1);
OBJSTAT (objfile, sz_strtab += DBX_STRINGTAB_SIZE (objfile) + 1);
val = bfd_get_section_contents
(sym_bfd, stabstrsect, DBX_STRINGTAB (objfile), 0, DBX_STRINGTAB_SIZE (objfile));
if (!val)
perror_with_name (name);
#if HAVE_MMAP
}
#endif
stabsread_new_init ();
buildsym_new_init ();
free_header_files ();
init_header_files ();
#if 0
install_minimal_symbols (objfile);
#endif
processing_acc_compilation = 1;
dbx_symfile_read (objfile, mainline);
}
static struct sym_fns aout_sym_fns =
{
bfd_target_aout_flavour,
dbx_new_init,
dbx_symfile_init,
dbx_symfile_read,
dbx_symfile_finish,
default_symfile_offsets,
NULL
};
void
_initialize_dbxread (void)
{
struct cmd_list_element *c;
#if HAVE_MMAP
c = add_set_cmd ("mmap-string-tables", class_obscure, var_boolean,
(char *) &mmap_strtabflag,
"Set if GDB should use mmap() to read STABS info.",
&setlist);
add_show_from_set (c, &showlist);
#endif
c = add_set_cmd ("read-type-psyms", class_obscure, var_boolean,
(char *) &read_type_psym_p,
"Set if we should create partial symbols for types.",
&setlist);
add_show_from_set (c, &showlist);
add_symtab_fns (&aout_sym_fns);
}