#include "defs.h"
#include "bfd.h"
#include "gdb_string.h"
#include "hp-symtab.h"
#include "syms.h"
#include "symtab.h"
#include "symfile.h"
#include "objfiles.h"
#include "buildsym.h"
#include "complaints.h"
#include "gdb-stabs.h"
#include "gdbtypes.h"
#include "demangle.h"
#include "somsolib.h"
#include "gdb_assert.h"
struct hpread_symfile_info
{
char *gntt;
char *lntt;
char *slt;
char *vt;
unsigned int vt_size;
unsigned int lntt_symcount;
unsigned int gntt_symcount;
struct type **dntt_type_vector;
int dntt_type_vector_length;
sltpointer sl_index;
int within_function;
unsigned int current_function_value;
};
#define HPUX_SYMFILE_INFO(o) \
((struct hpread_symfile_info *)((o)->sym_private))
#define GNTT(o) (HPUX_SYMFILE_INFO(o)->gntt)
#define LNTT(o) (HPUX_SYMFILE_INFO(o)->lntt)
#define SLT(o) (HPUX_SYMFILE_INFO(o)->slt)
#define VT(o) (HPUX_SYMFILE_INFO(o)->vt)
#define VT_SIZE(o) (HPUX_SYMFILE_INFO(o)->vt_size)
#define LNTT_SYMCOUNT(o) (HPUX_SYMFILE_INFO(o)->lntt_symcount)
#define GNTT_SYMCOUNT(o) (HPUX_SYMFILE_INFO(o)->gntt_symcount)
#define DNTT_TYPE_VECTOR(o) (HPUX_SYMFILE_INFO(o)->dntt_type_vector)
#define DNTT_TYPE_VECTOR_LENGTH(o) \
(HPUX_SYMFILE_INFO(o)->dntt_type_vector_length)
#define SL_INDEX(o) (HPUX_SYMFILE_INFO(o)->sl_index)
#define WITHIN_FUNCTION(o) (HPUX_SYMFILE_INFO(o)->within_function)
#define CURRENT_FUNCTION_VALUE(o) (HPUX_SYMFILE_INFO(o)->current_function_value)
struct symloc
{
int ldsymoff;
int ldsymlen;
};
#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))
static void
lbrac_unmatched_complaint (int arg1)
{
complaint (&symfile_complaints, "unmatched N_LBRAC before symtab pos %d",
arg1);
}
static void
lbrac_mismatch_complaint (int arg1)
{
complaint (&symfile_complaints,
"N_LBRAC/N_RBRAC symbol mismatch at symtab pos %d", arg1);
}
#define QUICK_LOOK_UP 1
#define USE_PXDB 1
void hpread_symfile_init (struct objfile *);
void do_pxdb (bfd *);
void hpread_build_psymtabs (struct objfile *, int);
void hpread_symfile_finish (struct objfile *);
static void set_namestring (union dnttentry *sym, char **namep,
struct objfile *objfile);
static union dnttentry *hpread_get_gntt (int, struct objfile *);
static union dnttentry *hpread_get_lntt (int index, struct objfile *objfile);
static unsigned long hpread_get_textlow (int, int, struct objfile *, int);
static struct partial_symtab *hpread_start_psymtab
(struct objfile *, char *, CORE_ADDR, int,
struct partial_symbol **, struct partial_symbol **);
static struct partial_symtab *hpread_end_psymtab
(struct partial_symtab *, char **, int, int, CORE_ADDR,
struct partial_symtab **, int);
static unsigned long hpread_get_scope_start (sltpointer, struct objfile *);
static unsigned long hpread_get_line (sltpointer, struct objfile *);
static CORE_ADDR hpread_get_location (sltpointer, struct objfile *);
static int hpread_has_name (enum dntt_entry_type kind);
static void hpread_psymtab_to_symtab_1 (struct partial_symtab *);
static void hpread_psymtab_to_symtab (struct partial_symtab *);
static struct symtab *hpread_expand_symtab
(struct objfile *, int, int, CORE_ADDR, int,
struct section_offsets *, char *);
static int hpread_type_translate (dnttpointer);
static struct type **hpread_lookup_type (dnttpointer, struct objfile *);
static struct type *hpread_alloc_type (dnttpointer, struct objfile *);
static struct type *hpread_read_enum_type
(dnttpointer, union dnttentry *, struct objfile *);
static struct type *hpread_read_function_type
(dnttpointer, union dnttentry *, struct objfile *, int);
static struct type *hpread_read_doc_function_type
(dnttpointer, union dnttentry *, struct objfile *, int);
static struct type *hpread_read_struct_type
(dnttpointer, union dnttentry *, struct objfile *);
static struct type *hpread_get_nth_template_arg (struct objfile *, int);
static struct type *hpread_read_templ_arg_type
(dnttpointer, union dnttentry *, struct objfile *, char *);
static struct type *hpread_read_set_type
(dnttpointer, union dnttentry *, struct objfile *);
static struct type *hpread_read_array_type
(dnttpointer, union dnttentry *dn_bufp, struct objfile *objfile);
static struct type *hpread_read_subrange_type
(dnttpointer, union dnttentry *, struct objfile *);
static struct type *hpread_type_lookup (dnttpointer, struct objfile *);
static sltpointer hpread_record_lines
(struct subfile *, sltpointer, sltpointer, struct objfile *, CORE_ADDR);
static void hpread_process_one_debug_symbol
(union dnttentry *, char *, struct section_offsets *,
struct objfile *, CORE_ADDR, int, char *, int, int *);
static int hpread_get_scope_depth (union dnttentry *, struct objfile *, int);
static void fix_static_member_physnames
(struct type *, char *, struct objfile *);
static void fixup_class_method_type
(struct type *, struct type *, struct objfile *);
static void hpread_adjust_bitoffsets (struct type *, int);
static dnttpointer hpread_get_next_skip_over_anon_unions
(int, dnttpointer, union dnttentry **, struct objfile *);
extern int hp_som_som_object_present;
static struct type *fixup_class = NULL;
static struct type *fixup_method = NULL;
#ifdef USE_PXDB
#define PXDB_SVR4 "/opt/langtools/bin/pxdb"
#define PXDB_BSD "/usr/bin/pxdb"
#include <stdlib.h>
#include "gdb_string.h"
static int
file_exists (char *filename)
{
if (filename)
return (access (filename, F_OK) == 0);
return 0;
}
static enum language
trans_lang (enum hp_language in_lang)
{
if (in_lang == HP_LANGUAGE_C)
return language_c;
else if (in_lang == HP_LANGUAGE_CPLUSPLUS)
return language_cplus;
else if (in_lang == HP_LANGUAGE_FORTRAN)
return language_fortran;
else
return language_unknown;
}
static char main_string[] = "main";
static void
set_namestring (union dnttentry *sym, char **namep, struct objfile *objfile)
{
if (! hpread_has_name (sym->dblock.kind))
*namep = "";
else if ((unsigned) sym->dsfile.name >= VT_SIZE (objfile))
{
complaint (&symfile_complaints, "bad string table offset in symbol %d",
symnum);
*namep = "";
}
else
*namep = sym->dsfile.name + VT (objfile);
}
static int
hpread_call_pxdb (const char *file_name)
{
char *p;
int status;
int retval;
if (file_exists (PXDB_SVR4))
{
p = xmalloc (strlen (PXDB_SVR4) + strlen (file_name) + 2);
strcpy (p, PXDB_SVR4);
strcat (p, " ");
strcat (p, file_name);
warning ("File not processed by pxdb--about to process now.\n");
status = system (p);
retval = (status == 0);
}
else
{
warning ("pxdb not found at standard location: /opt/langtools/bin\ngdb will not be able to debug %s.\nPlease install pxdb at the above location and then restart gdb.\nYou can also run pxdb on %s with the command\n\"pxdb %s\" and then restart gdb.", file_name, file_name, file_name);
retval = 0;
}
return retval;
}
static int
hpread_pxdb_needed (bfd *sym_bfd)
{
asection *pinfo_section, *debug_section, *header_section;
unsigned int do_pxdb;
char *buf;
bfd_size_type header_section_size;
unsigned long tmp;
unsigned int pxdbed;
header_section = bfd_get_section_by_name (sym_bfd, "$HEADER$");
if (!header_section)
{
return 0;
}
debug_section = bfd_get_section_by_name (sym_bfd, "$DEBUG$");
pinfo_section = bfd_get_section_by_name (sym_bfd, "$PINFO$");
if (pinfo_section && !debug_section)
{
header_section_size = bfd_section_size (objfile->obfd, header_section);
if (header_section_size == (bfd_size_type) sizeof (DOC_info_PXDB_header))
{
buf = alloca (sizeof (DOC_info_PXDB_header));
if (!bfd_get_section_contents (sym_bfd,
header_section,
buf, 0,
header_section_size))
error ("bfd_get_section_contents\n");
tmp = bfd_get_32 (sym_bfd, (bfd_byte *) (buf + sizeof (int) * 4));
pxdbed = (tmp >> 31) & 0x1;
if (!pxdbed)
error ("file debug header info invalid\n");
do_pxdb = 0;
}
else
error ("invalid $HEADER$ size in executable \n");
}
else
{
header_section_size = bfd_section_size (objfile->obfd, header_section);
if (header_section_size == (bfd_size_type) sizeof (PXDB_header))
{
buf = alloca (sizeof (PXDB_header));
if (!bfd_get_section_contents (sym_bfd,
header_section,
buf, 0,
header_section_size))
error ("bfd_get_section_contents\n");
tmp = bfd_get_32 (sym_bfd, (bfd_byte *) (buf + sizeof (int) * 3));
pxdbed = (tmp >> 31) & 0x1;
if (pxdbed)
do_pxdb = 0;
else
error ("file debug header invalid\n");
}
else
do_pxdb = 1;
}
if (do_pxdb)
{
return 1;
}
else
{
return 0;
}
}
#endif
void
do_pxdb (bfd *sym_bfd)
{
if (hpread_pxdb_needed (sym_bfd))
{
if (hpread_call_pxdb (sym_bfd->filename))
{
bfd_close (sym_bfd);
}
}
}
#ifdef QUICK_LOOK_UP
#define VALID_FILE(i) ((i) < pxdb_header_p->fd_entries)
#define VALID_MODULE(i) ((i) < pxdb_header_p->md_entries)
#define VALID_PROC(i) ((i) < pxdb_header_p->pd_entries)
#define VALID_CLASS(i) ((i) < pxdb_header_p->cd_entries)
#define FILE_START(i) (qFD[i].adrStart)
#define MODULE_START(i) (qMD[i].adrStart)
#define PROC_START(i) (qPD[i].adrStart)
#define FILE_END(i) (qFD[i].adrEnd)
#define MODULE_END(i) (qMD[i].adrEnd)
#define PROC_END(i) (qPD[i].adrEnd)
#define FILE_ISYM(i) (qFD[i].isym)
#define MODULE_ISYM(i) (qMD[i].isym)
#define PROC_ISYM(i) (qPD[i].isym)
#define VALID_CURR_FILE (curr_fd < pxdb_header_p->fd_entries)
#define VALID_CURR_MODULE (curr_md < pxdb_header_p->md_entries)
#define VALID_CURR_PROC (curr_pd < pxdb_header_p->pd_entries)
#define VALID_CURR_CLASS (curr_cd < pxdb_header_p->cd_entries)
#define CURR_FILE_START (qFD[curr_fd].adrStart)
#define CURR_MODULE_START (qMD[curr_md].adrStart)
#define CURR_PROC_START (qPD[curr_pd].adrStart)
#define CURR_FILE_END (qFD[curr_fd].adrEnd)
#define CURR_MODULE_END (qMD[curr_md].adrEnd)
#define CURR_PROC_END (qPD[curr_pd].adrEnd)
#define CURR_FILE_ISYM (qFD[curr_fd].isym)
#define CURR_MODULE_ISYM (qMD[curr_md].isym)
#define CURR_PROC_ISYM (qPD[curr_pd].isym)
#define TELL_OBJFILE \
do { \
if( !told_objfile ) { \
told_objfile = 1; \
warning ("\nIn object file \"%s\":\n", \
objfile->name); \
} \
} while (0)
typedef struct
{
int start;
int end;
}
pst_syms_struct;
static pst_syms_struct *pst_syms_array = 0;
static int pst_syms_count = 0;
static int pst_syms_size = 0;
static int told_objfile = 0;
static void
init_pst_syms (void)
{
pst_syms_count = 0;
pst_syms_size = 20;
pst_syms_array = (pst_syms_struct *) xmalloc (20 * sizeof (pst_syms_struct));
}
static void
clear_pst_syms (void)
{
pst_syms_count = 0;
pst_syms_size = 0;
xfree (pst_syms_array);
pst_syms_array = 0;
}
static void
record_pst_syms (int start_sym, int end_sym)
{
if (++pst_syms_count > pst_syms_size)
{
pst_syms_array = (pst_syms_struct *) xrealloc (pst_syms_array,
2 * pst_syms_size * sizeof (pst_syms_struct));
pst_syms_size *= 2;
}
pst_syms_array[pst_syms_count - 1].start = start_sym;
pst_syms_array[pst_syms_count - 1].end = end_sym;
}
static int
find_next_pst_start (int index)
{
int i;
for (i = pst_syms_count - 1; i >= 0; i--)
if (pst_syms_array[i].end <= index)
return (i == pst_syms_count - 1) ? 0 : pst_syms_array[i + 1].start - 1;
if (pst_syms_array[0].start > index)
return pst_syms_array[0].start - 1;
return 0;
}
static int
find_next_file_isym (int index, quick_file_entry *qFD, int curr_fd,
PXDB_header_ptr pxdb_header_p)
{
while (VALID_CURR_FILE)
{
if (CURR_FILE_ISYM >= index)
return CURR_FILE_ISYM - 1;
curr_fd++;
}
return 0;
}
static int
find_next_proc_isym (int index, quick_procedure_entry *qPD, int curr_pd,
PXDB_header_ptr pxdb_header_p)
{
while (VALID_CURR_PROC)
{
if (CURR_PROC_ISYM >= index)
return CURR_PROC_ISYM - 1;
curr_pd++;
}
return 0;
}
static int
find_next_module_isym (int index, quick_module_entry *qMD, int curr_md,
PXDB_header_ptr pxdb_header_p)
{
while (VALID_CURR_MODULE)
{
if (CURR_MODULE_ISYM >= index)
return CURR_MODULE_ISYM - 1;
curr_md++;
}
return 0;
}
static int
scan_procs (int *curr_pd_p, quick_procedure_entry *qPD, int max_procs,
CORE_ADDR start_adr, CORE_ADDR end_adr, struct partial_symtab *pst,
char *vt_bits, struct objfile *objfile)
{
union dnttentry *dn_bufp;
int symbol_count = 0;
int curr_pd = *curr_pd_p;
#ifdef DUMPING
static int dumping = 0;
#endif
#ifdef DUMPING
if (dumping)
{
printf ("Scan_procs called, addresses %x to %x, proc %x\n", start_adr, end_adr, curr_pd);
}
#endif
while ((CURR_PROC_START <= end_adr) && (curr_pd < max_procs))
{
char *rtn_name;
char *rtn_dem_name;
char *class_name;
int class;
if ((trans_lang ((enum hp_language) qPD[curr_pd].language) == language_cplus) &&
vt_bits[(long) qPD[curr_pd].sbAlias])
{
rtn_name = &vt_bits[(long) qPD[curr_pd].sbAlias];
rtn_dem_name = cplus_demangle (rtn_name, DMGL_ANSI | DMGL_PARAMS);
}
else
{
rtn_name = &vt_bits[(long) qPD[curr_pd].sbProc];
rtn_dem_name = NULL;
}
if ((strcmp (rtn_name, "_MAIN_") == 0) &&
(strcmp (&vt_bits[(long) qPD[curr_pd].sbProc], "main") == 0))
rtn_dem_name = rtn_name = main_string;
#ifdef DUMPING
if (dumping)
{
printf ("..add %s (demangled %s), index %x to this psymtab\n", rtn_name, rtn_dem_name, curr_pd);
}
#endif
if (CURR_PROC_END > end_adr)
{
TELL_OBJFILE;
warning ("Procedure \"%s\" [0x%x] spans file or module boundaries.", rtn_name, curr_pd);
}
dn_bufp = hpread_get_lntt (qPD[curr_pd].isym, objfile);
if (dn_bufp->dfunc.global)
add_psymbol_with_dem_name_to_list (rtn_name,
strlen (rtn_name),
rtn_dem_name,
strlen (rtn_dem_name),
VAR_DOMAIN,
LOC_BLOCK,
&objfile->global_psymbols,
(qPD[curr_pd].adrStart +
ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile))),
0,
trans_lang ((enum hp_language) qPD[curr_pd].language),
objfile);
else
add_psymbol_with_dem_name_to_list (rtn_name,
strlen (rtn_name),
rtn_dem_name,
strlen (rtn_dem_name),
VAR_DOMAIN,
LOC_BLOCK,
&objfile->static_psymbols,
(qPD[curr_pd].adrStart +
ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile))),
0,
trans_lang ((enum hp_language) qPD[curr_pd].language),
objfile);
symbol_count++;
*curr_pd_p = ++curr_pd;
}
#ifdef DUMPING
if (dumping)
{
if (symbol_count == 0)
printf ("Scan_procs: no symbols found!\n");
}
#endif
return symbol_count;
}
static int
hpread_quick_traverse (struct objfile *objfile, char *gntt_bits,
char *vt_bits, PXDB_header_ptr pxdb_header_p)
{
struct partial_symtab *pst;
char *addr;
quick_procedure_entry *qPD;
quick_file_entry *qFD;
quick_module_entry *qMD;
quick_class_entry *qCD;
int idx;
int i;
CORE_ADDR start_adr;
CORE_ADDR end_adr;
CORE_ADDR next_mod_adr;
int curr_pd;
int curr_fd;
int curr_md;
int start_sym;
int end_sym;
int max_LNTT_sym_index;
int syms_in_pst;
B_TYPE *class_entered;
struct partial_symbol **global_syms;
struct partial_symbol **static_syms;
#ifdef DUMPING
static int dumping = 0;
#endif
pst = (struct partial_symtab *) 0;
init_pst_syms ();
told_objfile = 0;
if (current_demangling_style != edg_demangling)
{
set_demangling_style (HP_DEMANGLING_STYLE_STRING);
}
addr = gntt_bits;
qPD = (quick_procedure_entry_ptr) addr;
addr += pxdb_header_p->pd_entries * sizeof (quick_procedure_entry);
#ifdef DUMPING
if (dumping)
{
printf ("\n Printing routines as we see them\n");
for (i = 0; VALID_PROC (i); i++)
{
idx = (long) qPD[i].sbProc;
printf ("%s %x..%x\n", &vt_bits[idx],
(int) PROC_START (i),
(int) PROC_END (i));
}
}
#endif
qFD = (quick_file_entry_ptr) addr;
addr += pxdb_header_p->fd_entries * sizeof (quick_file_entry);
#ifdef DUMPING
if (dumping)
{
printf ("\n Printing files as we see them\n");
for (i = 0; VALID_FILE (i); i++)
{
idx = (long) qFD[i].sbFile;
printf ("%s %x..%x\n", &vt_bits[idx],
(int) FILE_START (i),
(int) FILE_END (i));
}
}
#endif
qMD = (quick_module_entry_ptr) addr;
addr += pxdb_header_p->md_entries * sizeof (quick_module_entry);
#ifdef DUMPING
if (dumping)
{
printf ("\n Printing modules as we see them\n");
for (i = 0; i < pxdb_header_p->md_entries; i++)
{
idx = (long) qMD[i].sbMod;
printf ("%s\n", &vt_bits[idx]);
}
}
#endif
qCD = (quick_class_entry_ptr) addr;
addr += pxdb_header_p->cd_entries * sizeof (quick_class_entry);
#ifdef DUMPING
if (dumping)
{
printf ("\n Printing classes as we see them\n");
for (i = 0; VALID_CLASS (i); i++)
{
idx = (long) qCD[i].sbClass;
printf ("%s\n", &vt_bits[idx]);
}
printf ("\n Done with dump, on to build!\n");
}
#endif
max_LNTT_sym_index = LNTT_SYMCOUNT (objfile);
curr_pd = 0;
curr_fd = 0;
curr_md = 0;
start_adr = 0;
end_adr = 0;
start_sym = 0;
end_sym = 0;
syms_in_pst = 0;
global_syms = objfile->global_psymbols.list;
static_syms = objfile->static_psymbols.list;
while (VALID_CURR_PROC && (CURR_PROC_START == 0))
curr_pd++;
while (VALID_CURR_FILE || VALID_CURR_MODULE)
{
char *mod_name_string = NULL;
char *full_name_string;
if (VALID_CURR_MODULE && (CURR_MODULE_START == -1) && (CURR_MODULE_END == 0))
{
mod_name_string = &vt_bits[(long) qMD[curr_md].sbMod];
#ifdef DUMPING
if (dumping)
printf ("Module with data only %s\n", mod_name_string);
#endif
pst = hpread_start_psymtab (objfile,
mod_name_string,
CURR_MODULE_START,
(CURR_MODULE_ISYM * sizeof (struct dntt_type_block)),
global_syms,
static_syms);
pst = hpread_end_psymtab (pst,
NULL,
0,
end_sym * sizeof (struct dntt_type_block),
0,
NULL,
0);
global_syms = objfile->global_psymbols.next;
static_syms = objfile->static_psymbols.next;
curr_md++;
}
else if (VALID_CURR_MODULE &&
((CURR_MODULE_START == 0) || (CURR_MODULE_START == -1) ||
(CURR_MODULE_END == 0) || (CURR_MODULE_END == -1)))
{
TELL_OBJFILE;
warning ("Module \"%s\" [0x%s] has non-standard addresses. It starts at 0x%s, ends at 0x%s, and will be skipped.",
mod_name_string, paddr_nz (curr_md), paddr_nz (start_adr), paddr_nz (end_adr));
curr_md++;
}
else
{
if (VALID_CURR_FILE ? (VALID_CURR_MODULE ? (CURR_FILE_END < CURR_MODULE_START) : 1) : 0)
{
full_name_string = &vt_bits[(long) qFD[curr_fd].sbFile];
start_adr = CURR_FILE_START;
end_adr = CURR_FILE_END;
start_sym = CURR_FILE_ISYM;
if (CURR_PROC_START < start_adr)
{
TELL_OBJFILE;
warning ("Found procedure \"%s\" [0x%x] that is not in any file or module.",
&vt_bits[(long) qPD[curr_pd].sbProc], curr_pd);
start_adr = CURR_PROC_START;
if (CURR_PROC_ISYM < start_sym)
start_sym = CURR_PROC_ISYM;
}
if (VALID_FILE (curr_fd + 1) && (FILE_START (curr_fd + 1) <= end_adr))
{
TELL_OBJFILE;
warning ("File \"%s\" [0x%x] has ending address after starting address of next file; adjusting ending address down.",
full_name_string, curr_fd);
end_adr = FILE_START (curr_fd + 1) - 1;
}
if (VALID_MODULE (curr_md) && (CURR_MODULE_START <= end_adr))
{
TELL_OBJFILE;
warning ("File \"%s\" [0x%x] has ending address after starting address of next module; adjusting ending address down.",
full_name_string, curr_fd);
end_adr = CURR_MODULE_START - 1;
}
#ifdef DUMPING
if (dumping)
{
printf ("Make new psymtab for file %s (%x to %x).\n",
full_name_string, start_adr, end_adr);
}
#endif
pst = hpread_start_psymtab (objfile,
full_name_string,
start_adr,
(start_sym * sizeof (struct dntt_type_block)),
global_syms,
static_syms);
class_entered = xmalloc (B_BYTES (pxdb_header_p->cd_entries));
B_CLRALL (class_entered, pxdb_header_p->cd_entries);
syms_in_pst = scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries,
start_adr, end_adr, pst, vt_bits, objfile);
end_sym = 0;
if (pst_syms_count && start_sym < pst_syms_array[pst_syms_count - 1].end)
{
end_sym = find_next_pst_start (start_sym);
}
if (!end_sym)
{
int next_file_isym = find_next_file_isym (start_sym, qFD, curr_fd + 1, pxdb_header_p);
int next_module_isym = find_next_module_isym (start_sym, qMD, curr_md, pxdb_header_p);
int next_proc_isym = find_next_proc_isym (start_sym, qPD, curr_pd, pxdb_header_p);
if (next_file_isym && next_module_isym)
{
end_sym = min (next_file_isym, next_module_isym);
}
else
{
end_sym = max (next_file_isym, next_module_isym);
}
if (!end_sym)
end_sym = next_proc_isym;
else
end_sym = min (end_sym, next_proc_isym);
}
if (!end_sym)
end_sym = pxdb_header_p->globals;
#ifdef DUMPING
if (dumping)
{
printf ("File psymtab indices: %x to %x\n", start_sym, end_sym);
}
#endif
pst = hpread_end_psymtab (pst,
NULL,
0,
end_sym * sizeof (struct dntt_type_block),
end_adr,
NULL,
0);
record_pst_syms (start_sym, end_sym);
if (NULL == pst)
warning ("No symbols in psymtab for file \"%s\" [0x%x].", full_name_string, curr_fd);
#ifdef DUMPING
if (dumping)
{
printf ("Made new psymtab for file %s (%x to %x), sym %x to %x.\n",
full_name_string, start_adr, end_adr, CURR_FILE_ISYM, end_sym);
}
#endif
global_syms = objfile->global_psymbols.next;
static_syms = objfile->static_psymbols.next;
xfree (class_entered);
curr_fd++;
}
else
{
mod_name_string = &vt_bits[(long) qMD[curr_md].sbMod];
start_adr = CURR_MODULE_START;
if (VALID_CURR_FILE)
{
if (CURR_FILE_START < CURR_MODULE_START)
{
TELL_OBJFILE;
warning ("File \"%s\" [0x%x] crosses beginning of module \"%s\".",
&vt_bits[(long) qFD[curr_fd].sbFile],
curr_fd, mod_name_string);
start_adr = CURR_FILE_START;
}
}
start_sym = CURR_MODULE_ISYM;
if (VALID_CURR_FILE && (CURR_FILE_ISYM < CURR_MODULE_ISYM))
start_sym = CURR_FILE_ISYM;
end_adr = CURR_MODULE_END;
if (VALID_CURR_FILE)
{
while (VALID_CURR_FILE && (CURR_FILE_START < end_adr))
{
#ifdef DUMPING
if (dumping)
printf ("Maybe skipping file %s which overlaps with module %s\n",
&vt_bits[(long) qFD[curr_fd].sbFile], mod_name_string);
#endif
if (CURR_FILE_END > end_adr)
{
TELL_OBJFILE;
warning ("File \"%s\" [0x%x] crosses end of module \"%s\".",
&vt_bits[(long) qFD[curr_fd].sbFile],
curr_fd, mod_name_string);
end_adr = CURR_FILE_END;
}
curr_fd++;
}
curr_fd--;
}
if (VALID_MODULE (curr_md + 1) && (MODULE_START (curr_md + 1) <= end_adr))
{
TELL_OBJFILE;
warning ("Module \"%s\" [0x%x] has ending address after starting address of next module; adjusting ending address down.",
mod_name_string, curr_md);
end_adr = MODULE_START (curr_md + 1) - 1;
}
if (VALID_FILE (curr_fd + 1) && (FILE_START (curr_fd + 1) <= end_adr))
{
TELL_OBJFILE;
warning ("Module \"%s\" [0x%x] has ending address after starting address of next file; adjusting ending address down.",
mod_name_string, curr_md);
end_adr = FILE_START (curr_fd + 1) - 1;
}
if (VALID_CURR_FILE)
full_name_string = &vt_bits[(long) qFD[curr_fd].sbFile];
else
full_name_string = mod_name_string;
if (CURR_PROC_START < start_adr)
{
TELL_OBJFILE;
warning ("Found procedure \"%s\" [0x%x] that is not in any file or module.",
&vt_bits[(long) qPD[curr_pd].sbProc], curr_pd);
start_adr = CURR_PROC_START;
if (CURR_PROC_ISYM < start_sym)
start_sym = CURR_PROC_ISYM;
}
#ifdef DUMPING
if (dumping)
{
printf ("Make new psymtab for module %s (%x to %x), using file %s\n",
mod_name_string, start_adr, end_adr, full_name_string);
}
#endif
pst = hpread_start_psymtab (objfile,
full_name_string,
start_adr,
(start_sym * sizeof (struct dntt_type_block)),
global_syms,
static_syms);
class_entered = xmalloc (B_BYTES (pxdb_header_p->cd_entries));
B_CLRALL (class_entered, pxdb_header_p->cd_entries);
syms_in_pst = scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries,
start_adr, end_adr, pst, vt_bits, objfile);
end_sym = 0;
if (pst_syms_count && start_sym < pst_syms_array[pst_syms_count - 1].end)
{
end_sym = find_next_pst_start (start_sym);
}
if (!end_sym)
{
int next_file_isym = find_next_file_isym (start_sym, qFD, curr_fd + 1, pxdb_header_p);
int next_module_isym = find_next_module_isym (start_sym, qMD, curr_md + 1, pxdb_header_p);
int next_proc_isym = find_next_proc_isym (start_sym, qPD, curr_pd, pxdb_header_p);
if (next_file_isym && next_module_isym)
{
end_sym = min (next_file_isym, next_module_isym);
}
else
{
end_sym = max (next_file_isym, next_module_isym);
}
if (!end_sym)
end_sym = next_proc_isym;
else
end_sym = min (end_sym, next_proc_isym);
}
if (!end_sym)
end_sym = pxdb_header_p->globals;
#ifdef DUMPING
if (dumping)
{
printf ("Module psymtab indices: %x to %x\n", start_sym, end_sym);
}
#endif
pst = hpread_end_psymtab (pst,
NULL,
0,
end_sym * sizeof (struct dntt_type_block),
end_adr,
NULL,
0);
record_pst_syms (start_sym, end_sym);
if (NULL == pst)
warning ("No symbols in psymtab for module \"%s\" [0x%x].", mod_name_string, curr_md);
#ifdef DUMPING
if (dumping)
{
printf ("Made new psymtab for module %s (%x to %x), sym %x to %x.\n",
mod_name_string, start_adr, end_adr, CURR_MODULE_ISYM, end_sym);
}
#endif
global_syms = objfile->global_psymbols.next;
static_syms = objfile->static_psymbols.next;
xfree (class_entered);
curr_md++;
curr_fd++;
}
}
}
if (VALID_CURR_PROC)
{
start_adr = CURR_PROC_START;
end_adr = qPD[pxdb_header_p->pd_entries - 1].adrEnd;
TELL_OBJFILE;
warning ("Found functions beyond end of all files and modules [0x%x].", curr_pd);
#ifdef DUMPING
if (dumping)
{
printf ("Orphan functions at end, PD %d and beyond (%x to %x)\n",
curr_pd, start_adr, end_adr);
}
#endif
pst = hpread_start_psymtab (objfile,
"orphans",
start_adr,
(CURR_PROC_ISYM * sizeof (struct dntt_type_block)),
global_syms,
static_syms);
scan_procs (&curr_pd, qPD, pxdb_header_p->pd_entries,
start_adr, end_adr, pst, vt_bits, objfile);
pst = hpread_end_psymtab (pst,
NULL,
0,
pxdb_header_p->globals * sizeof (struct dntt_type_block),
end_adr,
NULL,
0);
}
#ifdef NEVER_NEVER
pst = hpread_start_psymtab (objfile,
"globals",
0,
(pxdb_header_p->globals
* sizeof (struct dntt_type_block)),
objfile->global_psymbols.next,
objfile->static_psymbols.next);
hpread_end_psymtab (pst,
NULL, 0,
(max_LNTT_sym_index * sizeof (struct dntt_type_block)),
0,
NULL, 0);
#endif
clear_pst_syms ();
return 1;
}
static int
hpread_get_header (struct objfile *objfile, PXDB_header_ptr pxdb_header_p)
{
asection *pinfo_section, *debug_section, *header_section;
#ifdef DUMPING
static int dumping = 0;
#endif
header_section = bfd_get_section_by_name (objfile->obfd, "$HEADER$");
if (!header_section)
{
#ifdef DUMPING
if (dumping)
printf ("==No debug info at all for %s.\n", objfile->name);
#endif
return 0;
}
debug_section = bfd_get_section_by_name (objfile->obfd, "$DEBUG$");
pinfo_section = bfd_get_section_by_name (objfile->obfd, "$PINFO$");
if (debug_section)
{
bfd_get_section_contents (objfile->obfd, header_section,
pxdb_header_p, 0, sizeof (PXDB_header));
if (!pxdb_header_p->pxdbed)
{
return 0;
}
}
else if (pinfo_section)
{
DOC_info_PXDB_header doc_header;
#ifdef DUMPING
if (dumping)
{
printf ("==OOps, PINFO, let's try to handle this, %s.\n", objfile->name);
}
#endif
bfd_get_section_contents (objfile->obfd,
header_section,
&doc_header, 0,
sizeof (DOC_info_PXDB_header));
if (!doc_header.pxdbed)
{
warning ("File \"%s\" not processed by pxdb!", objfile->name);
return 0;
}
pxdb_header_p->pd_entries = doc_header.pd_entries;
pxdb_header_p->fd_entries = doc_header.fd_entries;
pxdb_header_p->md_entries = doc_header.md_entries;
pxdb_header_p->pxdbed = doc_header.pxdbed;
pxdb_header_p->bighdr = doc_header.bighdr;
pxdb_header_p->sa_header = doc_header.sa_header;
pxdb_header_p->inlined = doc_header.inlined;
pxdb_header_p->globals = doc_header.globals;
pxdb_header_p->time = doc_header.time;
pxdb_header_p->pg_entries = doc_header.pg_entries;
pxdb_header_p->functions = doc_header.functions;
pxdb_header_p->files = doc_header.files;
pxdb_header_p->cd_entries = doc_header.cd_entries;
pxdb_header_p->aa_entries = doc_header.aa_entries;
pxdb_header_p->oi_entries = doc_header.oi_entries;
pxdb_header_p->version = doc_header.version;
}
else
{
#ifdef DUMPING
if (dumping)
printf ("==No debug info at all for %s.\n", objfile->name);
#endif
return 0;
}
return 1;
}
#endif
void
hpread_symfile_init (struct objfile *objfile)
{
asection *vt_section, *slt_section, *lntt_section, *gntt_section;
objfile->sym_private =
xmmalloc (objfile->md, sizeof (struct hpread_symfile_info));
memset (objfile->sym_private, 0, sizeof (struct hpread_symfile_info));
DNTT_TYPE_VECTOR (objfile) = 0;
gntt_section = bfd_get_section_by_name (objfile->obfd, "$GNTT$");
if (!gntt_section)
return;
GNTT (objfile)
= obstack_alloc (&objfile->objfile_obstack,
bfd_section_size (objfile->obfd, gntt_section));
bfd_get_section_contents (objfile->obfd, gntt_section, GNTT (objfile),
0, bfd_section_size (objfile->obfd, gntt_section));
GNTT_SYMCOUNT (objfile)
= bfd_section_size (objfile->obfd, gntt_section)
/ sizeof (struct dntt_type_block);
lntt_section = bfd_get_section_by_name (objfile->obfd, "$LNTT$");
if (!lntt_section)
return;
LNTT (objfile)
= obstack_alloc (&objfile->objfile_obstack,
bfd_section_size (objfile->obfd, lntt_section));
bfd_get_section_contents (objfile->obfd, lntt_section, LNTT (objfile),
0, bfd_section_size (objfile->obfd, lntt_section));
LNTT_SYMCOUNT (objfile)
= bfd_section_size (objfile->obfd, lntt_section)
/ sizeof (struct dntt_type_block);
slt_section = bfd_get_section_by_name (objfile->obfd, "$SLT$");
if (!slt_section)
return;
SLT (objfile) =
obstack_alloc (&objfile->objfile_obstack,
bfd_section_size (objfile->obfd, slt_section));
bfd_get_section_contents (objfile->obfd, slt_section, SLT (objfile),
0, bfd_section_size (objfile->obfd, slt_section));
vt_section = bfd_get_section_by_name (objfile->obfd, "$VT$");
if (!vt_section)
return;
VT_SIZE (objfile) = bfd_section_size (objfile->obfd, vt_section);
VT (objfile) =
(char *) obstack_alloc (&objfile->objfile_obstack,
VT_SIZE (objfile));
bfd_get_section_contents (objfile->obfd, vt_section, VT (objfile),
0, VT_SIZE (objfile));
}
void
hpread_build_psymtabs (struct objfile *objfile, int mainline)
{
#ifdef DUMPING
static int dumping = 0;
#endif
char *namestring;
int past_first_source_file = 0;
struct cleanup *old_chain;
int hp_symnum, symcount, i;
int scan_start = 0;
union dnttentry *dn_bufp;
unsigned long valu;
char *p;
int texthigh = 0;
int have_name = 0;
struct partial_symtab *pst;
char **psymtab_include_list;
int includes_allocated;
int includes_used;
struct partial_symtab **dependency_list;
int dependencies_used, dependencies_allocated;
free_pending_blocks ();
make_cleanup (really_free_pendings, 0);
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 *));
old_chain = make_cleanup_free_objfile (objfile);
last_source_file = 0;
#ifdef QUICK_LOOK_UP
{
PXDB_header pxdb_header;
int found_modules_in_program;
if (hpread_get_header (objfile, &pxdb_header))
{
#ifdef DUMPING
if (dumping)
printf ("\nNew method for %s\n", objfile->name);
#endif
found_modules_in_program = hpread_quick_traverse (objfile,
GNTT (objfile),
VT (objfile),
&pxdb_header);
discard_cleanups (old_chain);
if (found_modules_in_program)
scan_start = pxdb_header.globals;
}
#ifdef DUMPING
else
{
if (dumping)
printf ("\nGoing on to old method for %s\n", objfile->name);
}
#endif
}
#endif
for (i = 0; i < 1; i++)
{
int within_function = 0;
if (i)
symcount = GNTT_SYMCOUNT (objfile);
else
symcount = LNTT_SYMCOUNT (objfile);
for (hp_symnum = scan_start; hp_symnum < symcount; hp_symnum++)
{
QUIT;
if (i)
dn_bufp = hpread_get_gntt (hp_symnum, objfile);
else
dn_bufp = hpread_get_lntt (hp_symnum, objfile);
if (dn_bufp->dblock.extension)
continue;
switch (dn_bufp->dblock.kind)
{
case DNTT_TYPE_SRCFILE:
{
#ifdef QUICK_LOOK_UP
if (scan_start == hp_symnum
&& symcount == hp_symnum + 1)
{
continue;
}
#endif
set_namestring (dn_bufp, &namestring, objfile);
if (pst && !strcmp (namestring, pst->filename))
continue;
p = strrchr (namestring, '.');
if (!strcmp (p, ".h"))
{
int j, found;
found = 0;
for (j = 0; j < includes_used; j++)
if (!strcmp (namestring, psymtab_include_list[j]))
{
found = 1;
break;
}
if (found)
continue;
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;
}
if (pst)
{
if (!have_name)
{
pst->filename = (char *)
obstack_alloc (&pst->objfile->objfile_obstack,
strlen (namestring) + 1);
strcpy (pst->filename, namestring);
have_name = 1;
continue;
}
continue;
}
if (pst && past_first_source_file)
{
hpread_end_psymtab (pst, psymtab_include_list,
includes_used,
(hp_symnum
* sizeof (struct dntt_type_block)),
texthigh,
dependency_list, dependencies_used);
pst = (struct partial_symtab *) 0;
includes_used = 0;
dependencies_used = 0;
}
else
past_first_source_file = 1;
valu = hpread_get_textlow (i, hp_symnum, objfile, symcount);
valu += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
pst = hpread_start_psymtab (objfile,
namestring, valu,
(hp_symnum
* sizeof (struct dntt_type_block)),
objfile->global_psymbols.next,
objfile->static_psymbols.next);
texthigh = valu;
have_name = 1;
continue;
}
case DNTT_TYPE_MODULE:
if (pst)
{
hpread_end_psymtab (pst, psymtab_include_list, includes_used,
((hp_symnum - 1)
* sizeof (struct dntt_type_block)),
texthigh,
dependency_list, dependencies_used);
pst = (struct partial_symtab *) 0;
includes_used = 0;
dependencies_used = 0;
have_name = 0;
}
set_namestring (dn_bufp, &namestring, objfile);
valu = hpread_get_textlow (i, hp_symnum, objfile, symcount);
valu += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
if (!pst)
{
pst = hpread_start_psymtab (objfile,
namestring, valu,
(hp_symnum
* sizeof (struct dntt_type_block)),
objfile->global_psymbols.next,
objfile->static_psymbols.next);
texthigh = valu;
have_name = 0;
}
continue;
case DNTT_TYPE_FUNCTION:
case DNTT_TYPE_ENTRY:
valu = dn_bufp->dfunc.hiaddr + ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile));
if (valu > texthigh)
texthigh = valu;
valu = dn_bufp->dfunc.lowaddr +
ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
set_namestring (dn_bufp, &namestring, objfile);
if (dn_bufp->dfunc.global)
add_psymbol_to_list (namestring, strlen (namestring),
VAR_DOMAIN, LOC_BLOCK,
&objfile->global_psymbols, valu,
0, language_unknown, objfile);
else
add_psymbol_to_list (namestring, strlen (namestring),
VAR_DOMAIN, LOC_BLOCK,
&objfile->static_psymbols, valu,
0, language_unknown, objfile);
within_function = 1;
continue;
case DNTT_TYPE_DOC_FUNCTION:
valu = dn_bufp->ddocfunc.hiaddr + ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile));
if (valu > texthigh)
texthigh = valu;
valu = dn_bufp->ddocfunc.lowaddr +
ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
set_namestring (dn_bufp, &namestring, objfile);
if (dn_bufp->ddocfunc.global)
add_psymbol_to_list (namestring, strlen (namestring),
VAR_DOMAIN, LOC_BLOCK,
&objfile->global_psymbols, valu,
0, language_unknown, objfile);
else
add_psymbol_to_list (namestring, strlen (namestring),
VAR_DOMAIN, LOC_BLOCK,
&objfile->static_psymbols, valu,
0, language_unknown, objfile);
within_function = 1;
continue;
case DNTT_TYPE_BEGIN:
case DNTT_TYPE_END:
#ifdef QUICK_LOOK_UP
if (scan_start == hp_symnum
&& symcount == hp_symnum + 1)
{
continue;
}
#endif
if ((dn_bufp->dend.endkind == DNTT_TYPE_FUNCTION) ||
(dn_bufp->dend.endkind == DNTT_TYPE_DOC_FUNCTION))
within_function = 0;
continue;
case DNTT_TYPE_SVAR:
case DNTT_TYPE_DVAR:
case DNTT_TYPE_TYPEDEF:
case DNTT_TYPE_TAGDEF:
{
enum address_class storage;
domain_enum domain;
if (within_function
&& (dn_bufp->dblock.kind == DNTT_TYPE_SVAR
|| dn_bufp->dblock.kind == DNTT_TYPE_DVAR))
continue;
if (dn_bufp->dblock.kind == DNTT_TYPE_TAGDEF)
domain = STRUCT_DOMAIN;
else
domain = VAR_DOMAIN;
if (dn_bufp->dblock.kind == DNTT_TYPE_SVAR)
storage = LOC_STATIC;
else if (dn_bufp->dblock.kind == DNTT_TYPE_DVAR
&& dn_bufp->ddvar.regvar)
storage = LOC_REGISTER;
else if (dn_bufp->dblock.kind == DNTT_TYPE_DVAR)
storage = LOC_LOCAL;
else
storage = LOC_UNDEF;
set_namestring (dn_bufp, &namestring, objfile);
if (!pst)
{
pst = hpread_start_psymtab (objfile,
"globals", 0,
(hp_symnum
* sizeof (struct dntt_type_block)),
objfile->global_psymbols.next,
objfile->static_psymbols.next);
}
valu = dn_bufp->dsvar.location;
if (storage == LOC_STATIC)
valu += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
if (dn_bufp->dsvar.global)
{
add_psymbol_to_list (namestring, strlen (namestring),
domain, storage,
&objfile->global_psymbols,
valu,
0, language_unknown, objfile);
}
else
{
add_psymbol_to_list (namestring, strlen (namestring),
domain, storage,
&objfile->static_psymbols,
valu,
0, language_unknown, objfile);
}
if (dn_bufp->dblock.kind == DNTT_TYPE_TAGDEF &&
dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile))
{
int global = dn_bufp->dtag.global;
dn_bufp = hpread_get_lntt (dn_bufp->dtype.type.dnttp.index, objfile);
if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS ||
dn_bufp->dblock.kind == DNTT_TYPE_ENUM ||
dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
{
if (global)
{
add_psymbol_to_list (namestring, strlen (namestring),
VAR_DOMAIN, storage,
&objfile->global_psymbols,
dn_bufp->dsvar.location,
0, language_unknown, objfile);
}
else
{
add_psymbol_to_list (namestring, strlen (namestring),
VAR_DOMAIN, storage,
&objfile->static_psymbols,
dn_bufp->dsvar.location,
0, language_unknown, objfile);
}
}
}
}
continue;
case DNTT_TYPE_MEMENUM:
case DNTT_TYPE_CONST:
set_namestring (dn_bufp, &namestring, objfile);
if (!pst)
{
pst = hpread_start_psymtab (objfile,
"globals", 0,
(hp_symnum
* sizeof (struct dntt_type_block)),
objfile->global_psymbols.next,
objfile->static_psymbols.next);
}
if (dn_bufp->dconst.global)
add_psymbol_to_list (namestring, strlen (namestring),
VAR_DOMAIN, LOC_CONST,
&objfile->global_psymbols, 0,
0, language_unknown, objfile);
else
add_psymbol_to_list (namestring, strlen (namestring),
VAR_DOMAIN, LOC_CONST,
&objfile->static_psymbols, 0,
0, language_unknown, objfile);
continue;
default:
continue;
}
}
}
if (pst)
{
hpread_end_psymtab (pst, psymtab_include_list, includes_used,
hp_symnum * sizeof (struct dntt_type_block),
0, dependency_list, dependencies_used);
}
discard_cleanups (old_chain);
}
void
hpread_symfile_finish (struct objfile *objfile)
{
if (objfile->sym_private != NULL)
{
xmfree (objfile->md, objfile->sym_private);
}
}
static union dnttentry *
hpread_get_lntt (int index, struct objfile *objfile)
{
return (union dnttentry *)
&(LNTT (objfile)[(index * sizeof (struct dntt_type_block))]);
}
static union dnttentry *
hpread_get_gntt (int index, struct objfile *objfile)
{
return (union dnttentry *)
&(GNTT (objfile)[(index * sizeof (struct dntt_type_block))]);
}
static union sltentry *
hpread_get_slt (int index, struct objfile *objfile)
{
return (union sltentry *) &(SLT (objfile)[index * sizeof (union sltentry)]);
}
static unsigned long
hpread_get_textlow (int global, int index, struct objfile *objfile,
int symcount)
{
union dnttentry *dn_bufp = NULL;
struct minimal_symbol *msymbol;
if (index < symcount)
{
do
{
if (global)
dn_bufp = hpread_get_gntt (index++, objfile);
else
dn_bufp = hpread_get_lntt (index++, objfile);
}
while (dn_bufp->dblock.kind != DNTT_TYPE_FUNCTION
&& dn_bufp->dblock.kind != DNTT_TYPE_DOC_FUNCTION
&& dn_bufp->dblock.kind != DNTT_TYPE_END
&& index < symcount);
}
gdb_assert (dn_bufp != NULL);
if (dn_bufp->dblock.kind == DNTT_TYPE_END)
return 0;
if (index == symcount)
return 0;
if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION)
msymbol = lookup_minimal_symbol (dn_bufp->dfunc.name + VT (objfile), NULL,
objfile);
else
msymbol = lookup_minimal_symbol (dn_bufp->ddocfunc.name + VT (objfile), NULL,
objfile);
if (msymbol)
return SYMBOL_VALUE_ADDRESS (msymbol);
else
return dn_bufp->dfunc.lowaddr;
}
static struct partial_symtab *
hpread_start_psymtab (struct objfile *objfile, char *filename,
CORE_ADDR textlow, int ldsymoff,
struct partial_symbol **global_syms,
struct partial_symbol **static_syms)
{
int offset = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
extern void hpread_psymtab_to_symtab ();
struct partial_symtab *result =
start_psymtab_common (objfile, objfile->section_offsets,
filename, textlow, global_syms, static_syms);
result->textlow += offset;
result->read_symtab_private = (char *)
obstack_alloc (&objfile->objfile_obstack, sizeof (struct symloc));
LDSYMOFF (result) = ldsymoff;
result->read_symtab = hpread_psymtab_to_symtab;
return result;
}
static struct partial_symtab *
hpread_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 i;
struct objfile *objfile = pst->objfile;
int offset = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile));
#ifdef DUMPING
static int dumping = 0;
#endif
if (capping_symbol_offset != -1)
LDSYMLEN (pst) = capping_symbol_offset - LDSYMOFF (pst);
else
LDSYMLEN (pst) = 0;
pst->texthigh = capping_text + offset;
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);
#ifdef DUMPING
if (dumping)
{
printf ("\nPst %s, LDSYMOFF %x (%x), LDSYMLEN %x (%x), globals %d, statics %d\n",
pst->filename,
LDSYMOFF (pst),
LDSYMOFF (pst) / sizeof (struct dntt_type_block),
LDSYMLEN (pst),
LDSYMLEN (pst) / sizeof (struct dntt_type_block),
pst->n_global_syms, pst->n_static_syms);
}
#endif
pst->number_of_dependencies = number_dependencies;
if (number_dependencies)
{
pst->dependencies = (struct partial_symtab **)
obstack_alloc (&objfile->objfile_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->objfile_obstack,
sizeof (struct symloc));
LDSYMOFF (subpst) =
LDSYMLEN (subpst) =
subpst->textlow =
subpst->texthigh = 0;
subpst->dependencies = (struct partial_symtab **)
obstack_alloc (&objfile->objfile_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);
if (num_includes == 0
&& number_dependencies == 0
&& pst->n_global_syms == 0
&& pst->n_static_syms == 0)
{
discard_psymtab (pst);
pst = (struct partial_symtab *) NULL;
}
return pst;
}
static unsigned long
hpread_get_scope_start (sltpointer index, struct objfile *objfile)
{
union sltentry *sl_bufp;
sl_bufp = hpread_get_slt (index, objfile);
return sl_bufp->sspec.backptr.dnttp.index;
}
static unsigned long
hpread_get_line (sltpointer index, struct objfile *objfile)
{
union sltentry *sl_bufp;
sl_bufp = hpread_get_slt (index, objfile);
return sl_bufp->snorm.line;
}
static CORE_ADDR
hpread_get_location (sltpointer index, struct objfile *objfile)
{
union sltentry *sl_bufp;
int i;
sl_bufp = hpread_get_slt (index, objfile);
if (sl_bufp->snorm.sltdesc == SLT_END)
{
for (i = 0; ((sl_bufp->snorm.sltdesc != SLT_NORMAL) &&
(sl_bufp->snorm.sltdesc != SLT_NORMAL_OFFSET) &&
(sl_bufp->snorm.sltdesc != SLT_EXIT)); i++)
sl_bufp = hpread_get_slt (index - i, objfile);
if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET)
return sl_bufp->snormoff.address;
else
return sl_bufp->snorm.address;
}
for (i = 0; ((sl_bufp->snorm.sltdesc != SLT_NORMAL) &&
(sl_bufp->snorm.sltdesc != SLT_NORMAL_OFFSET) &&
(sl_bufp->snorm.sltdesc != SLT_EXIT)); i++)
sl_bufp = hpread_get_slt (index + i, objfile);
if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET)
return sl_bufp->snormoff.address;
else
return sl_bufp->snorm.address;
}
static int
hpread_has_name (enum dntt_entry_type kind)
{
switch (kind)
{
case DNTT_TYPE_SRCFILE:
case DNTT_TYPE_MODULE:
case DNTT_TYPE_FUNCTION:
case DNTT_TYPE_DOC_FUNCTION:
case DNTT_TYPE_ENTRY:
case DNTT_TYPE_IMPORT:
case DNTT_TYPE_LABEL:
case DNTT_TYPE_FPARAM:
case DNTT_TYPE_SVAR:
case DNTT_TYPE_DVAR:
case DNTT_TYPE_CONST:
case DNTT_TYPE_TYPEDEF:
case DNTT_TYPE_TAGDEF:
case DNTT_TYPE_MEMENUM:
case DNTT_TYPE_FIELD:
case DNTT_TYPE_SA:
case DNTT_TYPE_BLOCKDATA:
case DNTT_TYPE_MEMFUNC:
case DNTT_TYPE_DOC_MEMFUNC:
return 1;
case DNTT_TYPE_BEGIN:
case DNTT_TYPE_END:
case DNTT_TYPE_POINTER:
case DNTT_TYPE_ENUM:
case DNTT_TYPE_SET:
case DNTT_TYPE_ARRAY:
case DNTT_TYPE_STRUCT:
case DNTT_TYPE_UNION:
case DNTT_TYPE_VARIANT:
case DNTT_TYPE_FILE:
case DNTT_TYPE_FUNCTYPE:
case DNTT_TYPE_SUBRANGE:
case DNTT_TYPE_WITH:
case DNTT_TYPE_COMMON:
case DNTT_TYPE_COBSTRUCT:
case DNTT_TYPE_XREF:
case DNTT_TYPE_MACRO:
case DNTT_TYPE_CLASS_SCOPE:
case DNTT_TYPE_REFERENCE:
case DNTT_TYPE_PTRMEM:
case DNTT_TYPE_PTRMEMFUNC:
case DNTT_TYPE_CLASS:
case DNTT_TYPE_GENFIELD:
case DNTT_TYPE_VFUNC:
case DNTT_TYPE_MEMACCESS:
case DNTT_TYPE_INHERITANCE:
case DNTT_TYPE_FRIEND_CLASS:
case DNTT_TYPE_FRIEND_FUNC:
case DNTT_TYPE_MODIFIER:
case DNTT_TYPE_OBJECT_ID:
case DNTT_TYPE_TEMPLATE:
case DNTT_TYPE_TEMPLATE_ARG:
case DNTT_TYPE_FUNC_TEMPLATE:
case DNTT_TYPE_LINK:
default:
return 0;
}
}
static void
hpread_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);
}
hpread_psymtab_to_symtab_1 (pst->dependencies[i]);
}
if (LDSYMLEN (pst))
{
buildsym_init ();
old_chain = make_cleanup (really_free_pendings, 0);
pst->symtab =
hpread_expand_symtab (pst->objfile, LDSYMOFF (pst), LDSYMLEN (pst),
pst->textlow, pst->texthigh - pst->textlow,
pst->section_offsets, pst->filename);
do_cleanups (old_chain);
}
pst->readin = 1;
}
static void
hpread_psymtab_to_symtab (struct partial_symtab *pst)
{
if (!pst)
return;
if (pst->readin)
{
fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in."
" Shouldn't happen.\n",
pst->filename);
return;
}
processing_gcc_compilation = 0;
if (LDSYMLEN (pst) || pst->number_of_dependencies)
{
if (info_verbose)
{
printf_filtered ("Reading in symbols for %s...", pst->filename);
gdb_flush (gdb_stdout);
}
hpread_psymtab_to_symtab_1 (pst);
scan_file_globals (pst->objfile);
if (info_verbose)
printf_filtered ("done.\n");
}
}
static struct symtab *
hpread_expand_symtab (struct objfile *objfile, int sym_offset, int sym_size,
CORE_ADDR text_offset, int text_size,
struct section_offsets *section_offsets, char *filename)
{
char *namestring;
union dnttentry *dn_bufp;
unsigned max_symnum;
int at_module_boundary = 0;
int sym_index = sym_offset / sizeof (struct dntt_type_block);
current_objfile = objfile;
subfile_stack = 0;
last_source_file = 0;
if (current_demangling_style != edg_demangling)
{
set_demangling_style (HP_DEMANGLING_STYLE_STRING);
}
dn_bufp = hpread_get_lntt (sym_index, objfile);
if (!((dn_bufp->dblock.kind == (unsigned char) DNTT_TYPE_SRCFILE) ||
(dn_bufp->dblock.kind == (unsigned char) DNTT_TYPE_MODULE)))
{
start_symtab ("globals", NULL, 0);
record_debugformat ("HP");
}
max_symnum = sym_size / sizeof (struct dntt_type_block);
for (symnum = 0;
symnum < max_symnum;
symnum++)
{
QUIT;
dn_bufp = hpread_get_lntt (sym_index + symnum, objfile);
if (dn_bufp->dblock.extension)
continue;
set_namestring (dn_bufp, &namestring, objfile);
hpread_process_one_debug_symbol (dn_bufp, namestring, section_offsets,
objfile, text_offset, text_size,
filename, symnum + sym_index,
&at_module_boundary
);
if (at_module_boundary == -1)
break;
}
current_objfile = NULL;
hp_som_som_object_present = 1;
return end_symtab (text_offset + text_size, objfile, SECT_OFF_TEXT (objfile));
}
static int
hpread_type_translate (dnttpointer typep)
{
if (!typep.dntti.immediate)
{
error ("error in hpread_type_translate\n.");
return FT_VOID;
}
switch (typep.dntti.type)
{
case HP_TYPE_BOOLEAN:
case HP_TYPE_BOOLEAN_S300_COMPAT:
case HP_TYPE_BOOLEAN_VAX_COMPAT:
return FT_BOOLEAN;
case HP_TYPE_CHAR:
case HP_TYPE_WIDE_CHAR:
return FT_CHAR;
case HP_TYPE_INT:
if (typep.dntti.bitlength <= 8)
return FT_SIGNED_CHAR;
if (typep.dntti.bitlength <= 16)
return FT_SHORT;
if (typep.dntti.bitlength <= 32)
return FT_INTEGER;
return FT_LONG_LONG;
case HP_TYPE_LONG:
if (typep.dntti.bitlength <= 8)
return FT_SIGNED_CHAR;
return FT_LONG;
case HP_TYPE_UNSIGNED_LONG:
if (typep.dntti.bitlength <= 8)
return FT_UNSIGNED_CHAR;
if (typep.dntti.bitlength <= 16)
return FT_UNSIGNED_SHORT;
if (typep.dntti.bitlength <= 32)
return FT_UNSIGNED_LONG;
return FT_UNSIGNED_LONG_LONG;
case HP_TYPE_UNSIGNED_INT:
if (typep.dntti.bitlength <= 8)
return FT_UNSIGNED_CHAR;
if (typep.dntti.bitlength <= 16)
return FT_UNSIGNED_SHORT;
if (typep.dntti.bitlength <= 32)
return FT_UNSIGNED_INTEGER;
return FT_UNSIGNED_LONG_LONG;
case HP_TYPE_REAL:
case HP_TYPE_REAL_3000:
case HP_TYPE_DOUBLE:
if (typep.dntti.bitlength == 64)
return FT_DBL_PREC_FLOAT;
if (typep.dntti.bitlength == 128)
return FT_EXT_PREC_FLOAT;
return FT_FLOAT;
case HP_TYPE_COMPLEX:
case HP_TYPE_COMPLEXS3000:
if (typep.dntti.bitlength == 128)
return FT_DBL_PREC_COMPLEX;
if (typep.dntti.bitlength == 192)
return FT_EXT_PREC_COMPLEX;
return FT_COMPLEX;
case HP_TYPE_VOID:
return FT_VOID;
case HP_TYPE_STRING200:
case HP_TYPE_LONGSTRING200:
case HP_TYPE_FTN_STRING_SPEC:
case HP_TYPE_MOD_STRING_SPEC:
case HP_TYPE_MOD_STRING_3000:
case HP_TYPE_FTN_STRING_S300_COMPAT:
case HP_TYPE_FTN_STRING_VAX_COMPAT:
return FT_STRING;
case HP_TYPE_TEMPLATE_ARG:
return FT_TEMPLATE_ARG;
case HP_TYPE_TEXT:
case HP_TYPE_FLABEL:
case HP_TYPE_PACKED_DECIMAL:
case HP_TYPE_ANYPOINTER:
case HP_TYPE_GLOBAL_ANYPOINTER:
case HP_TYPE_LOCAL_ANYPOINTER:
default:
warning ("hpread_type_translate: unhandled type code.\n");
return FT_VOID;
}
}
static struct type **
hpread_lookup_type (dnttpointer hp_type, struct objfile *objfile)
{
unsigned old_len;
int index = hp_type.dnttp.index;
int size_changed = 0;
if (hp_type.dntti.immediate)
return NULL;
if (index < LNTT_SYMCOUNT (objfile))
{
if (index >= DNTT_TYPE_VECTOR_LENGTH (objfile))
{
old_len = DNTT_TYPE_VECTOR_LENGTH (objfile);
if (old_len == 0)
{
DNTT_TYPE_VECTOR_LENGTH (objfile) = LNTT_SYMCOUNT (objfile) + GNTT_SYMCOUNT (objfile);
DNTT_TYPE_VECTOR (objfile) = (struct type **)
xmmalloc (objfile->md, DNTT_TYPE_VECTOR_LENGTH (objfile) * sizeof (struct type *));
memset (&DNTT_TYPE_VECTOR (objfile)[old_len], 0,
(DNTT_TYPE_VECTOR_LENGTH (objfile) - old_len) *
sizeof (struct type *));
}
while (index >= DNTT_TYPE_VECTOR_LENGTH (objfile))
{
DNTT_TYPE_VECTOR_LENGTH (objfile) *= 2;
size_changed = 1;
}
if (size_changed)
{
DNTT_TYPE_VECTOR (objfile) = (struct type **)
xmrealloc (objfile->md,
(char *) DNTT_TYPE_VECTOR (objfile),
(DNTT_TYPE_VECTOR_LENGTH (objfile) * sizeof (struct type *)));
memset (&DNTT_TYPE_VECTOR (objfile)[old_len], 0,
(DNTT_TYPE_VECTOR_LENGTH (objfile) - old_len) *
sizeof (struct type *));
}
}
return &DNTT_TYPE_VECTOR (objfile)[index];
}
else
return NULL;
}
static struct type *
hpread_alloc_type (dnttpointer hp_type, struct objfile *objfile)
{
struct type **type_addr;
type_addr = hpread_lookup_type (hp_type, objfile);
if (*type_addr == 0)
{
*type_addr = alloc_type (objfile);
TYPE_CPLUS_SPECIFIC (*type_addr)
= (struct cplus_struct_type *) &cplus_struct_default;
}
return *type_addr;
}
static struct type *
hpread_read_enum_type (dnttpointer hp_type, union dnttentry *dn_bufp,
struct objfile *objfile)
{
struct type *type;
struct pending **symlist, *osyms, *syms;
struct pending *local_list = NULL;
int o_nsyms, nsyms = 0;
dnttpointer mem;
union dnttentry *memp;
char *name;
long n;
struct symbol *sym;
type = hpread_alloc_type (hp_type, objfile);
if (TYPE_CODE (type) == TYPE_CODE_ENUM)
return type;
TYPE_LENGTH (type) = dn_bufp->denum.bitlength / 8;
symlist = &file_symbols;
osyms = *symlist;
o_nsyms = osyms ? osyms->nsyms : 0;
mem = dn_bufp->denum.firstmem;
while (mem.word && mem.word != DNTTNIL)
{
memp = hpread_get_lntt (mem.dnttp.index, objfile);
name = VT (objfile) + memp->dmember.name;
sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
sizeof (struct symbol));
memset (sym, 0, sizeof (struct symbol));
DEPRECATED_SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
&objfile->objfile_obstack);
SYMBOL_CLASS (sym) = LOC_CONST;
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
SYMBOL_VALUE (sym) = memp->dmember.value;
add_symbol_to_list (sym, symlist);
nsyms++;
mem = memp->dmember.nextmem;
}
TYPE_CODE (type) = TYPE_CODE_ENUM;
TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB;
TYPE_NFIELDS (type) = nsyms;
TYPE_FIELDS (type) = (struct field *)
obstack_alloc (&objfile->objfile_obstack, sizeof (struct field) * nsyms);
for (syms = *symlist, n = 0; syms; syms = syms->next)
{
int j = 0;
if (syms == osyms)
j = o_nsyms;
for (; j < syms->nsyms; j++, n++)
{
struct symbol *xsym = syms->symbol[j];
SYMBOL_TYPE (xsym) = type;
TYPE_FIELD_NAME (type, n) = DEPRECATED_SYMBOL_NAME (xsym);
TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
TYPE_FIELD_BITSIZE (type, n) = 0;
TYPE_FIELD_STATIC_KIND (type, n) = 0;
}
if (syms == osyms)
break;
}
return type;
}
static struct type *
hpread_read_function_type (dnttpointer hp_type, union dnttentry *dn_bufp,
struct objfile *objfile, int newblock)
{
struct type *type, *type1;
struct pending *syms;
struct pending *local_list = NULL;
int nsyms = 0;
dnttpointer param;
union dnttentry *paramp;
char *name;
long n;
struct symbol *sym;
int record_args = 1;
type = hpread_alloc_type (hp_type, objfile);
if (TYPE_CODE (type) == TYPE_CODE_FUNC)
{
record_args = 0;
}
else
{
if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION ||
dn_bufp->dblock.kind == DNTT_TYPE_MEMFUNC)
type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunc.retval,
objfile));
else if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTYPE)
type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunctype.retval,
objfile));
else
type1 = lookup_function_type (hpread_type_lookup (dn_bufp->dfunc_template.retval,
objfile));
replace_type (type, type1);
TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE;
}
if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTION ||
dn_bufp->dblock.kind == DNTT_TYPE_MEMFUNC)
param = dn_bufp->dfunc.firstparam;
else if (dn_bufp->dblock.kind == DNTT_TYPE_FUNCTYPE)
param = dn_bufp->dfunctype.firstparam;
else
param = dn_bufp->dfunc_template.firstparam;
while (param.word && param.word != DNTTNIL)
{
paramp = hpread_get_lntt (param.dnttp.index, objfile);
nsyms++;
param = paramp->dfparam.nextparam;
name = VT (objfile) + paramp->dfparam.name;
sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
sizeof (struct symbol));
(void) memset (sym, 0, sizeof (struct symbol));
DEPRECATED_SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
&objfile->objfile_obstack);
if (paramp->dfparam.regparam)
SYMBOL_CLASS (sym) = LOC_REGPARM;
else if (paramp->dfparam.indirect)
SYMBOL_CLASS (sym) = LOC_REF_ARG;
else
SYMBOL_CLASS (sym) = LOC_ARG;
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
if (paramp->dfparam.copyparam)
{
SYMBOL_VALUE (sym) = paramp->dfparam.location;
#ifdef HPREAD_ADJUST_STACK_ADDRESS
SYMBOL_VALUE (sym)
+= HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
#endif
#if 0
SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
#endif
}
else
SYMBOL_VALUE (sym) = paramp->dfparam.location;
SYMBOL_TYPE (sym) = hpread_type_lookup (paramp->dfparam.type, objfile);
add_symbol_to_list (sym, &local_list);
}
if (!record_args)
goto finish;
TYPE_NFIELDS (type) = nsyms;
TYPE_FIELDS (type) = (struct field *)
obstack_alloc (&objfile->objfile_obstack,
sizeof (struct field) * nsyms);
for (syms = local_list, n = 0; syms; syms = syms->next)
{
int j = 0;
for (j = 0; j < syms->nsyms; j++, n++)
{
struct symbol *xsym = syms->symbol[j];
TYPE_FIELD_NAME (type, n) = DEPRECATED_SYMBOL_NAME (xsym);
TYPE_FIELD_TYPE (type, n) = SYMBOL_TYPE (xsym);
TYPE_FIELD_ARTIFICIAL (type, n) = 0;
TYPE_FIELD_BITSIZE (type, n) = 0;
TYPE_FIELD_STATIC_KIND (type, n) = 0;
}
}
TYPE_FLAGS (type) &= ~(TYPE_FLAG_INCOMPLETE);
if (fixup_class && (fixup_method == type))
{
fixup_class_method_type (fixup_class, fixup_method, objfile);
fixup_class = NULL;
fixup_method = NULL;
}
finish:
if (newblock)
param_symbols = local_list;
return type;
}
static struct type *
hpread_read_doc_function_type (dnttpointer hp_type, union dnttentry *dn_bufp,
struct objfile *objfile, int newblock)
{
struct pending *syms;
struct pending *local_list = NULL;
int nsyms = 0;
struct type *type;
dnttpointer param;
union dnttentry *paramp;
char *name;
long n;
struct symbol *sym;
int record_args = 1;
type = hpread_alloc_type (hp_type, objfile);
if (TYPE_CODE (type) == TYPE_CODE_FUNC)
{
record_args = 0;
}
else
{
struct type *type1 = NULL;
if (dn_bufp->dblock.kind == DNTT_TYPE_DOC_FUNCTION ||
dn_bufp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC)
type1 = lookup_function_type (hpread_type_lookup (dn_bufp->ddocfunc.retval,
objfile));
gdb_assert (type1 != NULL);
replace_type (type, type1);
TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE;
}
if (dn_bufp->dblock.kind == DNTT_TYPE_DOC_FUNCTION ||
dn_bufp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC)
param = dn_bufp->ddocfunc.firstparam;
while (param.word && param.word != DNTTNIL)
{
paramp = hpread_get_lntt (param.dnttp.index, objfile);
nsyms++;
param = paramp->dfparam.nextparam;
name = VT (objfile) + paramp->dfparam.name;
sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
sizeof (struct symbol));
(void) memset (sym, 0, sizeof (struct symbol));
DEPRECATED_SYMBOL_NAME (sym) = name;
if (paramp->dfparam.regparam)
SYMBOL_CLASS (sym) = LOC_REGPARM;
else if (paramp->dfparam.indirect)
SYMBOL_CLASS (sym) = LOC_REF_ARG;
else
SYMBOL_CLASS (sym) = LOC_ARG;
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
if (paramp->dfparam.copyparam)
{
SYMBOL_VALUE (sym) = paramp->dfparam.location;
#ifdef HPREAD_ADJUST_STACK_ADDRESS
SYMBOL_VALUE (sym)
+= HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
#endif
#if 0
SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
#endif
}
else
SYMBOL_VALUE (sym) = paramp->dfparam.location;
SYMBOL_TYPE (sym) = hpread_type_lookup (paramp->dfparam.type, objfile);
add_symbol_to_list (sym, &local_list);
}
if (!record_args)
goto finish;
TYPE_NFIELDS (type) = nsyms;
TYPE_FIELDS (type) = (struct field *)
obstack_alloc (&objfile->objfile_obstack,
sizeof (struct field) * nsyms);
for (syms = local_list, n = 0; syms; syms = syms->next)
{
int j = 0;
for (j = 0; j < syms->nsyms; j++, n++)
{
struct symbol *xsym = syms->symbol[j];
TYPE_FIELD_NAME (type, n) = DEPRECATED_SYMBOL_NAME (xsym);
TYPE_FIELD_TYPE (type, n) = SYMBOL_TYPE (xsym);
TYPE_FIELD_ARTIFICIAL (type, n) = 0;
TYPE_FIELD_BITSIZE (type, n) = 0;
TYPE_FIELD_STATIC_KIND (type, n) = 0;
}
}
TYPE_FLAGS (type) &= ~(TYPE_FLAG_INCOMPLETE);
if (fixup_class && (fixup_method == type))
{
fixup_class_method_type (fixup_class, fixup_method, objfile);
fixup_class = NULL;
fixup_method = NULL;
}
finish:
if (newblock)
param_symbols = local_list;
return type;
}
static struct type *current_template = NULL;
static struct type *
hpread_read_struct_type (dnttpointer hp_type, union dnttentry *dn_bufp,
struct objfile *objfile)
{
struct nextfield
{
struct nextfield *next;
struct field field;
unsigned char attributes;
#define ATTR_VIRTUAL 1
#define ATTR_PRIVATE 2
#define ATTR_PROTECT 3
};
struct next_fn_field
{
struct next_fn_field *next;
struct fn_fieldlist field;
struct fn_field fn_field;
int num_fn_fields;
};
struct next_template
{
struct next_template *next;
struct template_arg arg;
};
struct next_instantiation
{
struct next_instantiation *next;
struct type *t;
};
struct type *type;
struct type *baseclass;
struct type *memtype;
struct nextfield *list = 0, *tmp_list = 0;
struct next_fn_field *fn_list = 0;
struct next_fn_field *fn_p;
struct next_template *t_new, *t_list = 0;
struct nextfield *new;
struct next_fn_field *fn_new;
struct next_instantiation *i_new, *i_list = 0;
int n, nfields = 0, n_fn_fields = 0, n_fn_fields_total = 0;
int n_base_classes = 0, n_templ_args = 0;
int ninstantiations = 0;
dnttpointer field, fn_field, parent;
union dnttentry *fieldp, *fn_fieldp, *parentp;
int i;
int static_member = 0;
int const_member = 0;
int volatile_member = 0;
unsigned long vtbl_offset;
int need_bitvectors = 0;
char *method_name = NULL;
char *method_alias = NULL;
type = hpread_alloc_type (hp_type, objfile);
if ((TYPE_CODE (type) == TYPE_CODE_STRUCT) ||
(TYPE_CODE (type) == TYPE_CODE_UNION) ||
(TYPE_CODE (type) == TYPE_CODE_CLASS) ||
(TYPE_CODE (type) == TYPE_CODE_TEMPLATE))
return type;
if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT)
{
TYPE_CODE (type) = TYPE_CODE_STRUCT;
TYPE_LENGTH (type) = dn_bufp->dstruct.bitlength / 8;
}
else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION)
{
TYPE_CODE (type) = TYPE_CODE_UNION;
TYPE_LENGTH (type) = dn_bufp->dunion.bitlength / 8;
}
else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS)
{
TYPE_CODE (type) = TYPE_CODE_CLASS;
TYPE_LENGTH (type) = dn_bufp->dclass.bitlength / 8;
allocate_cplus_struct_type (type);
TYPE_DECLARED_TYPE (type) = dn_bufp->dclass.class_decl;
}
else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
{
TYPE_CODE (type) = TYPE_CODE_TEMPLATE;
allocate_cplus_struct_type (type);
TYPE_DECLARED_TYPE (type) = DECLARED_TYPE_TEMPLATE;
}
else
return type;
TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB;
if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS)
{
parent = dn_bufp->dclass.parentlist;
while (parent.word && parent.word != DNTTNIL)
{
parentp = hpread_get_lntt (parent.dnttp.index, objfile);
new = (struct nextfield *) alloca (sizeof (struct nextfield));
new->next = list;
list = new;
FIELD_BITSIZE (list->field) = 0;
FIELD_STATIC_KIND (list->field) = 0;
baseclass = hpread_type_lookup (parentp->dinheritance.classname,
objfile);
FIELD_TYPE (list->field) = baseclass;
list->field.name = type_name_no_tag (FIELD_TYPE (list->field));
list->attributes = 0;
if (parentp->dinheritance.Virtual)
{
B_SET (&(list->attributes), ATTR_VIRTUAL);
parentp->dinheritance.offset = -1;
}
else
FIELD_BITPOS (list->field) = parentp->dinheritance.offset;
switch (parentp->dinheritance.visibility)
{
case 1:
B_SET (&(list->attributes), ATTR_PROTECT);
break;
case 2:
B_SET (&(list->attributes), ATTR_PRIVATE);
break;
}
n_base_classes++;
nfields++;
parent = parentp->dinheritance.next;
}
}
if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
{
current_template = type;
field = dn_bufp->dtemplate.arglist;
while (field.word && field.word != DNTTNIL)
{
fieldp = hpread_get_lntt (field.dnttp.index, objfile);
if (fieldp->dblock.kind != DNTT_TYPE_TEMPLATE_ARG)
{
warning ("Invalid debug info: Template argument entry is of wrong kind");
break;
}
n_templ_args++;
t_new = (struct next_template *) alloca (sizeof (struct next_template));
t_new->next = t_list;
t_list = t_new;
t_list->arg.name = VT (objfile) + fieldp->dtempl_arg.name;
t_list->arg.type = hpread_read_templ_arg_type (field, fieldp,
objfile, t_list->arg.name);
field = fieldp->dtempl_arg.nextarg;
}
}
TYPE_NTEMPLATE_ARGS (type) = n_templ_args;
if (n_templ_args > 0)
TYPE_TEMPLATE_ARGS (type) = (struct template_arg *)
obstack_alloc (&objfile->objfile_obstack, sizeof (struct template_arg) * n_templ_args);
for (n = n_templ_args; t_list; t_list = t_list->next)
{
n -= 1;
TYPE_TEMPLATE_ARG (type, n) = t_list->arg;
}
if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT)
field = dn_bufp->dstruct.firstfield;
else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION)
field = dn_bufp->dunion.firstfield;
else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS)
field = dn_bufp->dclass.memberlist;
else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
field = dn_bufp->dtemplate.memberlist;
else
field.word = DNTTNIL;
while (field.word && field.word != DNTTNIL)
{
fieldp = hpread_get_lntt (field.dnttp.index, objfile);
vtbl_offset = 0;
static_member = 0;
const_member = 0;
volatile_member = 0;
if (fieldp->dblock.kind == DNTT_TYPE_GENFIELD)
{
fn_field = fieldp->dgenfield.field;
fn_fieldp = hpread_get_lntt (fn_field.dnttp.index, objfile);
if (fn_fieldp->dblock.kind == DNTT_TYPE_VFUNC)
{
vtbl_offset = fn_fieldp->dvfunc.vtbl_offset;
fn_field = fn_fieldp->dvfunc.funcptr;
fn_fieldp = hpread_get_lntt (fn_field.dnttp.index, objfile);
}
if (fn_fieldp->dblock.kind == DNTT_TYPE_MODIFIER)
{
static_member = fn_fieldp->dmodifier.m_static;
const_member = fn_fieldp->dmodifier.m_const;
volatile_member = fn_fieldp->dmodifier.m_volatile;
fn_field = fn_fieldp->dmodifier.type;
fn_fieldp = hpread_get_lntt (fn_field.dnttp.index, objfile);
}
if ((fn_fieldp->dblock.kind == DNTT_TYPE_MEMFUNC) ||
(fn_fieldp->dblock.kind == DNTT_TYPE_FUNCTION) ||
(fn_fieldp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC) ||
(fn_fieldp->dblock.kind == DNTT_TYPE_DOC_FUNCTION))
{
short ix = 0;
memtype = hpread_type_lookup (fn_field, objfile);
if (TYPE_INCOMPLETE (memtype))
{
TYPE_FLAGS (type) |= TYPE_FLAG_INCOMPLETE;
if (fixup_class)
warning ("Two classes to fix up for method?? Type information may be incorrect for some classes.");
if (fixup_method)
warning ("Two methods to be fixed up at once?? Type information may be incorrect for some classes.");
fixup_class = type;
fixup_method = memtype;
}
method_name = (char *) (VT (objfile) + fn_fieldp->dfunc.name);
method_alias = (char *) (VT (objfile) + fn_fieldp->dfunc.alias);
if (!method_name ||
!*method_name ||
cplus_mangle_opname (method_name, DMGL_ANSI))
{
char *tmp_name = cplus_demangle (method_alias, DMGL_ANSI);
char *op_string = strstr (tmp_name, "operator");
method_name = xmalloc (strlen (op_string) + 1);
strcpy (method_name, op_string);
}
fn_p = fn_list;
while (fn_p)
{
if (DEPRECATED_STREQ (fn_p->field.name, method_name))
break;
fn_p = fn_p->next;
}
if (!fn_p)
{
fn_new = (struct next_fn_field *) alloca (sizeof (struct next_fn_field));
fn_new->next = fn_list;
fn_list = fn_new;
fn_list->field.name = method_name;
fn_list->field.fn_fields = (struct fn_field *) xmalloc (5 * (sizeof (struct fn_field)));
fn_list->field.length = 1;
fn_list->num_fn_fields = 5;
fn_p = fn_list;
ix = 0;
n_fn_fields++;
}
else
{
if (++(fn_p->field.length) > fn_p->num_fn_fields)
{
fn_p->field.fn_fields
= (struct fn_field *) xrealloc (fn_p->field.fn_fields,
(fn_p->num_fn_fields + 5) * sizeof (struct fn_field));
fn_p->num_fn_fields += 5;
}
ix = fn_p->field.length - 1;
}
if ((fn_fieldp->dfunc.language == HP_LANGUAGE_CPLUSPLUS) &&
method_alias &&
*method_alias)
fn_p->field.fn_fields[ix].physname = method_alias;
else
fn_p->field.fn_fields[ix].physname = method_name;
if (TYPE_INCOMPLETE (memtype))
fn_p->field.fn_fields[ix].type = NULL;
else
fn_p->field.fn_fields[ix].type = memtype;
if (static_member)
fn_p->field.fn_fields[ix].voffset = VOFFSET_STATIC;
else
fn_p->field.fn_fields[ix].voffset = vtbl_offset ? vtbl_offset + 1 : 0;
if (vtbl_offset != 0)
fn_p->field.fn_fields[ix].fcontext = type;
else
fn_p->field.fn_fields[ix].fcontext = NULL;
fn_p->field.fn_fields[ix].is_const = const_member;
fn_p->field.fn_fields[ix].is_volatile = volatile_member;
switch (fieldp->dgenfield.visibility)
{
case 1:
fn_p->field.fn_fields[ix].is_protected = 1;
fn_p->field.fn_fields[ix].is_private = 0;
break;
case 2:
fn_p->field.fn_fields[ix].is_protected = 0;
fn_p->field.fn_fields[ix].is_private = 1;
break;
default:
fn_p->field.fn_fields[ix].is_protected = 0;
fn_p->field.fn_fields[ix].is_private = 0;
}
fn_p->field.fn_fields[ix].is_stub = 0;
if ((fn_fieldp->dblock.kind == DNTT_TYPE_MEMFUNC) ||
(fn_fieldp->dblock.kind == DNTT_TYPE_DOC_MEMFUNC))
fn_p->field.fn_fields[ix].is_inlined = 1;
else
fn_p->field.fn_fields[ix].is_inlined = 0;
fn_p->field.fn_fields[ix].dummy = 0;
n_fn_fields_total++;
}
else if (fn_fieldp->dblock.kind == DNTT_TYPE_SVAR)
{
new = (struct nextfield *) alloca (sizeof (struct nextfield));
new->next = list;
list = new;
list->field.name = VT (objfile) + fn_fieldp->dsvar.name;
SET_FIELD_PHYSNAME (list->field, 0);
memtype = hpread_type_lookup (fn_fieldp->dsvar.type, objfile);
FIELD_TYPE (list->field) = memtype;
list->attributes = 0;
switch (fieldp->dgenfield.visibility)
{
case 1:
B_SET (&(list->attributes), ATTR_PROTECT);
break;
case 2:
B_SET (&(list->attributes), ATTR_PRIVATE);
break;
}
nfields++;
}
else if (fn_fieldp->dblock.kind == DNTT_TYPE_FIELD)
{
if (!fn_fieldp->dfield.a_union)
warning ("Debug info inconsistent: FIELD of anonymous union doesn't have a_union bit set");
new = (struct nextfield *) alloca (sizeof (struct nextfield));
new->next = list;
list = new;
list->field.name = VT (objfile) + fn_fieldp->dfield.name;
FIELD_BITPOS (list->field) = fn_fieldp->dfield.bitoffset;
if (fn_fieldp->dfield.bitlength % 8)
list->field.bitsize = fn_fieldp->dfield.bitlength;
else
list->field.bitsize = 0;
memtype = hpread_type_lookup (fn_fieldp->dfield.type, objfile);
list->field.type = memtype;
list->attributes = 0;
switch (fn_fieldp->dfield.visibility)
{
case 1:
B_SET (&(list->attributes), ATTR_PROTECT);
break;
case 2:
B_SET (&(list->attributes), ATTR_PRIVATE);
break;
}
nfields++;
}
else if (fn_fieldp->dblock.kind == DNTT_TYPE_SVAR)
{
if (!fn_fieldp->dsvar.a_union)
warning ("Debug info inconsistent: SVAR field in anonymous union doesn't have a_union bit set");
new = (struct nextfield *) alloca (sizeof (struct nextfield));
new->next = list;
list = new;
list->field.name = VT (objfile) + fn_fieldp->dsvar.name;
FIELD_BITPOS (list->field) = 0;
FIELD_BITSIZE (list->field) = 0;
FIELD_STATIC_KIND (list->field) = 0;
memtype = hpread_type_lookup (fn_fieldp->dsvar.type, objfile);
list->field.type = memtype;
list->attributes = 0;
nfields++;
}
else if (fn_fieldp->dblock.kind == DNTT_TYPE_DVAR)
{
if (!fn_fieldp->ddvar.a_union)
warning ("Debug info inconsistent: DVAR field in anonymous union doesn't have a_union bit set");
new = (struct nextfield *) alloca (sizeof (struct nextfield));
new->next = list;
list = new;
list->field.name = VT (objfile) + fn_fieldp->ddvar.name;
FIELD_BITPOS (list->field) = 0;
FIELD_BITSIZE (list->field) = 0;
FIELD_STATIC_KIND (list->field) = 0;
memtype = hpread_type_lookup (fn_fieldp->ddvar.type, objfile);
list->field.type = memtype;
list->attributes = 0;
nfields++;
}
else
{
if ((fn_fieldp->dblock.kind != DNTT_TYPE_MEMACCESS) &&
(fn_fieldp->dblock.kind != DNTT_TYPE_MEMENUM) &&
(fn_fieldp->dblock.kind != DNTT_TYPE_FUNC_TEMPLATE))
warning ("Internal error: Unexpected debug record kind %d found following DNTT_GENFIELD",
fn_fieldp->dblock.kind);
}
field = fieldp->dgenfield.nextfield;
}
else if (fieldp->dblock.kind == DNTT_TYPE_FIELD)
{
struct type *anon_union_type;
new = (struct nextfield *) alloca (sizeof (struct nextfield));
new->next = list;
list = new;
list->field.name = VT (objfile) + fieldp->dfield.name;
if (fieldp->dfield.staticmem)
{
SET_FIELD_PHYSNAME (list->field, NULL);
FIELD_BITPOS (list->field) = 0;
FIELD_BITSIZE (list->field) = 0;
}
else
{
FIELD_STATIC_KIND (list->field) = 0;
FIELD_BITPOS (list->field) = fieldp->dfield.bitoffset;
if (fieldp->dfield.bitlength % 8)
FIELD_BITSIZE (list->field) = fieldp->dfield.bitlength;
else
FIELD_BITSIZE (list->field) = 0;
}
memtype = hpread_type_lookup (fieldp->dfield.type, objfile);
FIELD_TYPE (list->field) = memtype;
list->attributes = 0;
switch (fieldp->dfield.visibility)
{
case 1:
B_SET (&(list->attributes), ATTR_PROTECT);
break;
case 2:
B_SET (&(list->attributes), ATTR_PRIVATE);
break;
}
nfields++;
field = hpread_get_next_skip_over_anon_unions (1, field, &fieldp, objfile);
}
else
{
warning ("Internal error: unexpected DNTT kind %d encountered as field of struct",
fieldp->dblock.kind);
warning ("Skipping remaining fields of struct");
break;
}
}
if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
{
ninstantiations = 0;
field = dn_bufp->dtemplate.expansions;
while (field.word && field.word != DNTTNIL)
{
fieldp = hpread_get_lntt (field.dnttp.index, objfile);
if (fieldp->dblock.kind != DNTT_TYPE_TAGDEF)
break;
i_new = (struct next_instantiation *) alloca (sizeof (struct next_instantiation));
i_new->next = i_list;
i_list = i_new;
i_list->t = hpread_type_lookup (field, objfile);
ninstantiations++;
field = fieldp->dtag.type;
fieldp = hpread_get_lntt (field.dnttp.index, objfile);
if (fieldp->dblock.kind != DNTT_TYPE_CLASS)
break;
field = fieldp->dclass.nextexp;
}
}
TYPE_NINSTANTIATIONS (type) = ninstantiations;
if (ninstantiations > 0)
TYPE_INSTANTIATIONS (type) = (struct type **)
obstack_alloc (&objfile->objfile_obstack, sizeof (struct type *) * ninstantiations);
for (n = ninstantiations; i_list; i_list = i_list->next)
{
n -= 1;
TYPE_INSTANTIATION (type, n) = i_list->t;
}
TYPE_NFIELDS (type) = nfields;
TYPE_N_BASECLASSES (type) = n_base_classes;
TYPE_FIELDS (type) = (struct field *)
obstack_alloc (&objfile->objfile_obstack, sizeof (struct field) * nfields);
for (n = nfields, tmp_list = list; tmp_list; tmp_list = tmp_list->next)
{
n -= 1;
TYPE_FIELD (type, n) = tmp_list->field;
}
TYPE_NFN_FIELDS (type) = n_fn_fields;
TYPE_NFN_FIELDS_TOTAL (type) = n_fn_fields_total;
TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *)
obstack_alloc (&objfile->objfile_obstack, sizeof (struct fn_fieldlist) * n_fn_fields);
for (n = n_fn_fields; fn_list; fn_list = fn_list->next)
{
n -= 1;
TYPE_FN_FIELDLIST (type, n) = fn_list->field;
}
for (n = nfields, tmp_list = list; tmp_list; tmp_list = tmp_list->next)
{
n -= 1;
if (tmp_list->attributes)
{
need_bitvectors = 1;
break;
}
}
if (need_bitvectors)
{
ALLOCATE_CPLUS_STRUCT_TYPE (type);
TYPE_FIELD_VIRTUAL_BITS (type) =
(B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), nfields);
TYPE_FIELD_PRIVATE_BITS (type) =
(B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields);
TYPE_FIELD_PROTECTED_BITS (type) =
(B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields);
TYPE_FIELD_IGNORE_BITS (type) =
(B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields));
B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields);
while (nfields-- > 0)
{
if (B_TST (&(list->attributes), ATTR_VIRTUAL))
SET_TYPE_FIELD_VIRTUAL (type, nfields);
if (B_TST (&(list->attributes), ATTR_PRIVATE))
SET_TYPE_FIELD_PRIVATE (type, nfields);
if (B_TST (&(list->attributes), ATTR_PROTECT))
SET_TYPE_FIELD_PROTECTED (type, nfields);
list = list->next;
}
}
else
{
TYPE_FIELD_VIRTUAL_BITS (type) = NULL;
TYPE_FIELD_PROTECTED_BITS (type) = NULL;
TYPE_FIELD_PRIVATE_BITS (type) = NULL;
}
if (has_vtable (type))
{
TYPE_RUNTIME_PTR (type) = (struct runtime_info *) xmalloc (sizeof (struct runtime_info));
TYPE_VTABLE (type) = 1;
TYPE_PRIMARY_BASE (type) = primary_base_class (type);
TYPE_VIRTUAL_BASE_LIST (type) = virtual_base_list (type);
}
else
TYPE_RUNTIME_PTR (type) = NULL;
if (hpread_get_scope_depth (dn_bufp, objfile, 1 ))
{
TYPE_LOCALTYPE_PTR (type) = (struct local_type_info *) xmalloc (sizeof (struct local_type_info));
TYPE_LOCALTYPE_FILE (type) = (char *) xmalloc (strlen (current_subfile->name) + 1);
strcpy (TYPE_LOCALTYPE_FILE (type), current_subfile->name);
if (current_subfile->line_vector && (current_subfile->line_vector->nitems > 0))
TYPE_LOCALTYPE_LINE (type) = current_subfile->line_vector->item[current_subfile->line_vector->nitems - 1].line;
else
TYPE_LOCALTYPE_LINE (type) = 0;
}
else
TYPE_LOCALTYPE_PTR (type) = NULL;
current_template = NULL;
return type;
}
static void
fix_static_member_physnames (struct type *type, char *class_name,
struct objfile *objfile)
{
int i;
if (TYPE_CODE (type) != TYPE_CODE_STRUCT)
return;
for (i = 0; i < TYPE_NFIELDS (type); i++)
if (TYPE_FIELD_STATIC (type, i))
{
if (TYPE_FIELD_STATIC_PHYSNAME (type, i))
return;
SET_FIELD_PHYSNAME (TYPE_FIELDS (type)[i],
obstack_alloc (&objfile->objfile_obstack,
strlen (class_name) + strlen (TYPE_FIELD_NAME (type, i)) + 3));
strcpy (TYPE_FIELD_STATIC_PHYSNAME (type, i), class_name);
strcat (TYPE_FIELD_STATIC_PHYSNAME (type, i), "::");
strcat (TYPE_FIELD_STATIC_PHYSNAME (type, i), TYPE_FIELD_NAME (type, i));
}
}
static void
fixup_class_method_type (struct type *class, struct type *method,
struct objfile *objfile)
{
int i, j, k;
if (!class || !method || !objfile)
return;
if ((TYPE_CODE (class) != TYPE_CODE_CLASS) &&
(TYPE_CODE (class) != TYPE_CODE_UNION))
return;
for (i = 0; i < TYPE_NFN_FIELDS (class); i++)
for (j = 0; j < TYPE_FN_FIELDLIST_LENGTH (class, i); j++)
if (TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j) == NULL)
{
TYPE_FN_FIELD_TYPE (TYPE_FN_FIELDLIST1 (class, i), j) = method;
goto finish;
}
finish:
TYPE_FLAGS (class) &= ~TYPE_FLAG_INCOMPLETE;
}
static struct type *
hpread_get_nth_template_arg (struct objfile *objfile, int n)
{
if (current_template != NULL)
return TYPE_TEMPLATE_ARG (current_template, n).type;
else
return lookup_fundamental_type (objfile, FT_TEMPLATE_ARG);
}
static struct type *
hpread_read_templ_arg_type (dnttpointer hp_type, union dnttentry *dn_bufp,
struct objfile *objfile, char *name)
{
struct type *type;
type = hpread_alloc_type (hp_type, objfile);
if (TYPE_CODE (type) == TYPE_CODE_TEMPLATE_ARG)
return type;
TYPE_CODE (type) = TYPE_CODE_TEMPLATE_ARG;
TYPE_LENGTH (type) = 0;
TYPE_NFIELDS (type) = 0;
TYPE_NAME (type) = name;
return type;
}
static struct type *
hpread_read_set_type (dnttpointer hp_type, union dnttentry *dn_bufp,
struct objfile *objfile)
{
struct type *type;
type = hpread_alloc_type (hp_type, objfile);
if (TYPE_CODE (type) == TYPE_CODE_SET)
return type;
TYPE_CODE (type) = TYPE_CODE_SET;
TYPE_LENGTH (type) = dn_bufp->dset.bitlength / 8;
TYPE_NFIELDS (type) = 0;
TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->dset.subtype,
objfile);
return type;
}
static struct type *
hpread_read_array_type (dnttpointer hp_type, union dnttentry *dn_bufp,
struct objfile *objfile)
{
struct type *type;
type = hpread_alloc_type (hp_type, objfile);
TYPE_CODE (type) = TYPE_CODE_ARRAY;
if (!((dn_bufp->darray.arrayisbytes && dn_bufp->darray.elemisbytes) ||
(!dn_bufp->darray.arrayisbytes && !dn_bufp->darray.elemisbytes)))
{
warning ("error in hpread_array_type.\n");
return NULL;
}
else if (dn_bufp->darray.arraylength == 0x7fffffff)
{
TYPE_LENGTH (type) = 0;
}
else if (dn_bufp->darray.arrayisbytes)
TYPE_LENGTH (type) = dn_bufp->darray.arraylength;
else
TYPE_LENGTH (type) = dn_bufp->darray.arraylength / 8;
TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->darray.elemtype,
objfile);
TYPE_NFIELDS (type) = 1;
TYPE_FIELDS (type) = (struct field *)
obstack_alloc (&objfile->objfile_obstack, sizeof (struct field));
TYPE_FIELD_TYPE (type, 0) = hpread_type_lookup (dn_bufp->darray.indextype,
objfile);
return type;
}
static struct type *
hpread_read_subrange_type (dnttpointer hp_type, union dnttentry *dn_bufp,
struct objfile *objfile)
{
struct type *type;
type = hpread_alloc_type (hp_type, objfile);
if (TYPE_CODE (type) == TYPE_CODE_RANGE)
return type;
TYPE_CODE (type) = TYPE_CODE_RANGE;
TYPE_LENGTH (type) = dn_bufp->dsubr.bitlength / 8;
TYPE_NFIELDS (type) = 2;
TYPE_FIELDS (type)
= (struct field *) obstack_alloc (&objfile->objfile_obstack,
2 * sizeof (struct field));
if (dn_bufp->dsubr.dyn_low)
TYPE_FIELD_BITPOS (type, 0) = 0;
else
TYPE_FIELD_BITPOS (type, 0) = dn_bufp->dsubr.lowbound;
if (dn_bufp->dsubr.dyn_high)
TYPE_FIELD_BITPOS (type, 1) = -1;
else
TYPE_FIELD_BITPOS (type, 1) = dn_bufp->dsubr.highbound;
TYPE_TARGET_TYPE (type) = hpread_type_lookup (dn_bufp->dsubr.subtype,
objfile);
return type;
}
static struct type *
hpread_type_lookup (dnttpointer hp_type, struct objfile *objfile)
{
union dnttentry *dn_bufp;
struct type *tmp_type;
if (hp_type.dntti.immediate)
{
if (hp_type.dntti.type == HP_TYPE_TEMPLATE_ARG)
return hpread_get_nth_template_arg (objfile, hp_type.dntti.bitlength);
else
return lookup_fundamental_type (objfile,
hpread_type_translate (hp_type));
}
if (hp_type.dnttp.index < LNTT_SYMCOUNT (objfile))
dn_bufp = hpread_get_lntt (hp_type.dnttp.index, objfile);
else
return lookup_fundamental_type (objfile, FT_VOID);
switch (dn_bufp->dblock.kind)
{
case DNTT_TYPE_SRCFILE:
case DNTT_TYPE_MODULE:
case DNTT_TYPE_ENTRY:
case DNTT_TYPE_BEGIN:
case DNTT_TYPE_END:
case DNTT_TYPE_IMPORT:
case DNTT_TYPE_LABEL:
case DNTT_TYPE_FPARAM:
case DNTT_TYPE_SVAR:
case DNTT_TYPE_DVAR:
case DNTT_TYPE_CONST:
case DNTT_TYPE_MEMENUM:
case DNTT_TYPE_VARIANT:
case DNTT_TYPE_FILE:
case DNTT_TYPE_WITH:
case DNTT_TYPE_COMMON:
case DNTT_TYPE_COBSTRUCT:
case DNTT_TYPE_XREF:
case DNTT_TYPE_SA:
case DNTT_TYPE_MACRO:
case DNTT_TYPE_BLOCKDATA:
case DNTT_TYPE_CLASS_SCOPE:
case DNTT_TYPE_MEMACCESS:
case DNTT_TYPE_INHERITANCE:
case DNTT_TYPE_OBJECT_ID:
case DNTT_TYPE_FRIEND_CLASS:
case DNTT_TYPE_FRIEND_FUNC:
return lookup_fundamental_type (objfile, FT_VOID);
case DNTT_TYPE_FUNCTION:
return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
case DNTT_TYPE_DOC_FUNCTION:
return hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 0);
case DNTT_TYPE_TYPEDEF:
{
struct type *structtype = hpread_type_lookup (dn_bufp->dtype.type,
objfile);
return structtype;
}
case DNTT_TYPE_TAGDEF:
{
struct type *structtype = hpread_type_lookup (dn_bufp->dtype.type,
objfile);
char *prefix, *suffix;
suffix = VT (objfile) + dn_bufp->dtype.name;
if (dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile))
dn_bufp = hpread_get_lntt (dn_bufp->dtype.type.dnttp.index, objfile);
else
{
complaint (&symfile_complaints, "error in hpread_type_lookup().");
return NULL;
}
if (dn_bufp->dblock.kind == DNTT_TYPE_STRUCT)
{
prefix = "struct ";
}
else if (dn_bufp->dblock.kind == DNTT_TYPE_UNION)
{
prefix = "union ";
}
else if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS)
{
if (dn_bufp->dclass.class_decl == 0)
prefix = "class ";
else if (dn_bufp->dclass.class_decl == 1)
prefix = "union ";
else if (dn_bufp->dclass.class_decl == 2)
prefix = "struct ";
else
prefix = "";
}
else if (dn_bufp->dblock.kind == DNTT_TYPE_ENUM)
{
prefix = "enum ";
}
else if (dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
{
prefix = "template ";
}
else
{
prefix = "";
}
TYPE_NAME (structtype)
= (char *) obstack_alloc (&objfile->objfile_obstack,
strlen (prefix) + strlen (suffix) + 1);
TYPE_NAME (structtype) = strcpy (TYPE_NAME (structtype), prefix);
TYPE_NAME (structtype) = strcat (TYPE_NAME (structtype), suffix);
TYPE_TAG_NAME (structtype) = suffix;
if (TYPE_CODE (structtype) == TYPE_CODE_STRUCT)
fix_static_member_physnames (structtype, suffix, objfile);
return structtype;
}
case DNTT_TYPE_POINTER:
return make_pointer_type (
hpread_type_lookup (dn_bufp->dptr.pointsto,
objfile),
NULL);
case DNTT_TYPE_REFERENCE:
return make_reference_type (
hpread_type_lookup (dn_bufp->dreference.pointsto,
objfile),
NULL);
case DNTT_TYPE_ENUM:
return hpread_read_enum_type (hp_type, dn_bufp, objfile);
case DNTT_TYPE_SET:
return hpread_read_set_type (hp_type, dn_bufp, objfile);
case DNTT_TYPE_SUBRANGE:
return hpread_read_subrange_type (hp_type, dn_bufp, objfile);
case DNTT_TYPE_ARRAY:
return hpread_read_array_type (hp_type, dn_bufp, objfile);
case DNTT_TYPE_STRUCT:
case DNTT_TYPE_UNION:
return hpread_read_struct_type (hp_type, dn_bufp, objfile);
case DNTT_TYPE_FIELD:
return hpread_type_lookup (dn_bufp->dfield.type, objfile);
case DNTT_TYPE_FUNCTYPE:
return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
case DNTT_TYPE_PTRMEM:
{
struct type *ptrmemtype;
struct type *class_type;
struct type *memtype;
memtype = hpread_type_lookup (dn_bufp->dptrmem.memtype,
objfile),
class_type = hpread_type_lookup (dn_bufp->dptrmem.pointsto,
objfile),
ptrmemtype = alloc_type (objfile);
smash_to_member_type (ptrmemtype, class_type, memtype);
return make_pointer_type (ptrmemtype, NULL);
}
break;
case DNTT_TYPE_PTRMEMFUNC:
{
struct type *ptrmemtype;
struct type *class_type;
struct type *functype;
struct type *retvaltype;
int nargs;
int i;
class_type = hpread_type_lookup (dn_bufp->dptrmem.pointsto,
objfile);
functype = hpread_type_lookup (dn_bufp->dptrmem.memtype,
objfile);
retvaltype = TYPE_TARGET_TYPE (functype);
nargs = TYPE_NFIELDS (functype);
ptrmemtype = alloc_type (objfile);
smash_to_method_type (ptrmemtype, class_type, retvaltype,
TYPE_FIELDS (functype),
TYPE_NFIELDS (functype),
0);
return make_pointer_type (ptrmemtype, NULL);
}
break;
case DNTT_TYPE_CLASS:
return hpread_read_struct_type (hp_type, dn_bufp, objfile);
case DNTT_TYPE_GENFIELD:
return hpread_type_lookup (dn_bufp->dgenfield.field, objfile);
case DNTT_TYPE_VFUNC:
return hpread_type_lookup (dn_bufp->dvfunc.funcptr, objfile);
case DNTT_TYPE_MODIFIER:
tmp_type = make_cv_type (dn_bufp->dmodifier.m_const,
dn_bufp->dmodifier.m_volatile,
hpread_type_lookup (dn_bufp->dmodifier.type, objfile),
0);
return tmp_type;
case DNTT_TYPE_MEMFUNC:
return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
case DNTT_TYPE_DOC_MEMFUNC:
return hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 0);
case DNTT_TYPE_TEMPLATE:
return hpread_read_struct_type (hp_type, dn_bufp, objfile);
case DNTT_TYPE_TEMPLATE_ARG:
{
char *name;
name = VT (objfile) + dn_bufp->dtempl_arg.name;
return hpread_read_templ_arg_type (hp_type, dn_bufp, objfile, name);
}
case DNTT_TYPE_FUNC_TEMPLATE:
return hpread_read_function_type (hp_type, dn_bufp, objfile, 0);
case DNTT_TYPE_LINK:
return lookup_fundamental_type (objfile, FT_VOID);
default:
return lookup_fundamental_type (objfile, FT_VOID);
}
}
static sltpointer
hpread_record_lines (struct subfile *subfile, sltpointer s_idx,
sltpointer e_idx, struct objfile *objfile,
CORE_ADDR offset)
{
union sltentry *sl_bufp;
while (s_idx <= e_idx)
{
sl_bufp = hpread_get_slt (s_idx, objfile);
if (sl_bufp->snorm.sltdesc == SLT_NORMAL
|| sl_bufp->snorm.sltdesc == SLT_EXIT)
record_line (subfile, sl_bufp->snorm.line,
sl_bufp->snorm.address + offset);
else if (sl_bufp->snorm.sltdesc == SLT_NORMAL_OFFSET)
record_line (subfile, sl_bufp->snormoff.line,
sl_bufp->snormoff.address + offset);
s_idx++;
}
return e_idx;
}
static char *
class_of (struct type *functype)
{
struct type *first_param_type;
char *first_param_name;
struct type *pointed_to_type;
char *class_name;
if (TYPE_NFIELDS (functype) == 0)
return NULL;
first_param_name = TYPE_FIELD_NAME (functype, 0);
if (first_param_name == NULL)
return NULL;
if (strcmp (first_param_name, "this"))
return NULL;
first_param_type = TYPE_FIELD_TYPE (functype, 0);
if (first_param_type == NULL)
return NULL;
if (TYPE_CODE (first_param_type) != TYPE_CODE_PTR)
return NULL;
pointed_to_type = TYPE_TARGET_TYPE (first_param_type);
if (pointed_to_type == NULL)
return NULL;
if (TYPE_CODE (pointed_to_type) != TYPE_CODE_CLASS)
return NULL;
class_name = TYPE_NAME (pointed_to_type);
if (class_name == NULL)
return NULL;
if (strncmp (class_name, "class ", 6) == 0)
class_name += 6;
return class_name;
}
static void
hpread_process_one_debug_symbol (union dnttentry *dn_bufp, char *name,
struct section_offsets *section_offsets,
struct objfile *objfile, CORE_ADDR text_offset,
int text_size, char *filename, int index,
int *at_module_boundary_p)
{
unsigned long desc;
int type;
CORE_ADDR valu;
int offset = ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
int data_offset = ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
union dnttentry *dn_temp;
dnttpointer hp_type;
struct symbol *sym;
struct context_stack *new;
char *class_scope_name;
sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
sizeof (struct symbol));
memset (sym, 0, sizeof (struct symbol));
DEPRECATED_SYMBOL_NAME (sym) = obsavestring (name, strlen (name), &objfile->objfile_obstack);
SYMBOL_LANGUAGE (sym) = language_auto;
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
SYMBOL_LINE (sym) = 0;
SYMBOL_VALUE (sym) = 0;
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
hp_type.dnttp.extension = 1;
hp_type.dnttp.immediate = 0;
hp_type.dnttp.global = 0;
hp_type.dnttp.index = index;
type = dn_bufp->dblock.kind;
switch (type)
{
case DNTT_TYPE_SRCFILE:
valu = text_offset;
if (!last_source_file)
{
start_symtab (name, NULL, valu);
record_debugformat ("HP");
SL_INDEX (objfile) = dn_bufp->dsfile.address;
}
else
{
SL_INDEX (objfile) = hpread_record_lines (current_subfile,
SL_INDEX (objfile),
dn_bufp->dsfile.address,
objfile, offset);
}
start_subfile (name, NULL);
break;
case DNTT_TYPE_MODULE:
valu = text_offset;
if (!last_source_file)
{
start_symtab (name, NULL, valu);
SL_INDEX (objfile) = dn_bufp->dmodule.address;
}
else
{
*at_module_boundary_p = -1;
}
start_subfile (name, NULL);
break;
case DNTT_TYPE_FUNCTION:
case DNTT_TYPE_ENTRY:
valu = dn_bufp->dfunc.lowaddr + offset;
SL_INDEX (objfile) = hpread_record_lines (current_subfile,
SL_INDEX (objfile),
dn_bufp->dfunc.address,
objfile, offset);
WITHIN_FUNCTION (objfile) = 1;
CURRENT_FUNCTION_VALUE (objfile) = valu;
if (context_stack_depth != 0)
lbrac_unmatched_complaint (symnum);
new = push_context (0, valu);
SYMBOL_CLASS (sym) = LOC_BLOCK;
SYMBOL_TYPE (sym) = hpread_read_function_type (hp_type, dn_bufp, objfile, 1);
if (SYMBOL_LANGUAGE (sym) == language_cplus)
TYPE_FLAGS (SYMBOL_TYPE (sym)) |= TYPE_FLAG_PROTOTYPED;
if ((dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS) &&
dn_bufp->dfunc.alias &&
*(char *) (VT (objfile) + dn_bufp->dfunc.alias))
DEPRECATED_SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.alias;
else
DEPRECATED_SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.name;
if ((strcmp (DEPRECATED_SYMBOL_NAME (sym), "_MAIN_") == 0) &&
(strcmp (VT (objfile) + dn_bufp->dfunc.name, "main") == 0))
DEPRECATED_SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->dfunc.name;
if (dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS)
{
SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->objfile_obstack);
if ((DEPRECATED_SYMBOL_NAME (sym) == VT (objfile) + dn_bufp->dfunc.alias) &&
(!SYMBOL_CPLUS_DEMANGLED_NAME (sym)))
{
char *basename;
char *classname;
char *dem_name;
basename = VT (objfile) + dn_bufp->dfunc.name;
classname = class_of (SYMBOL_TYPE (sym));
if (classname)
{
dem_name = xmalloc (strlen (basename) + strlen (classname) + 3);
strcpy (dem_name, classname);
strcat (dem_name, "::");
strcat (dem_name, basename);
SYMBOL_CPLUS_DEMANGLED_NAME (sym) = dem_name;
SYMBOL_LANGUAGE (sym) = language_cplus;
}
}
}
if (dn_bufp->dfunc.global)
add_symbol_to_list (sym, &global_symbols);
else
add_symbol_to_list (sym, &file_symbols);
new->name = sym;
if (dn_bufp->dfunc.language == HP_LANGUAGE_C ||
dn_bufp->dfunc.language == HP_LANGUAGE_CPLUSPLUS)
{
while (dn_bufp->dblock.kind != DNTT_TYPE_BEGIN)
{
dn_bufp = hpread_get_lntt (++index, objfile);
if (dn_bufp->dblock.extension)
continue;
}
SL_INDEX (objfile) = hpread_record_lines (current_subfile,
SL_INDEX (objfile),
dn_bufp->dbegin.address,
objfile, offset);
SYMBOL_LINE (sym) = hpread_get_line (dn_bufp->dbegin.address, objfile);
}
record_line (current_subfile, SYMBOL_LINE (sym), valu);
break;
case DNTT_TYPE_DOC_FUNCTION:
valu = dn_bufp->ddocfunc.lowaddr + offset;
SL_INDEX (objfile) = hpread_record_lines (current_subfile,
SL_INDEX (objfile),
dn_bufp->ddocfunc.address,
objfile, offset);
WITHIN_FUNCTION (objfile) = 1;
CURRENT_FUNCTION_VALUE (objfile) = valu;
if (context_stack_depth != 0)
lbrac_unmatched_complaint (symnum);
new = push_context (0, valu);
SYMBOL_CLASS (sym) = LOC_BLOCK;
SYMBOL_TYPE (sym) = hpread_read_doc_function_type (hp_type, dn_bufp, objfile, 1);
if ((dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS) &&
dn_bufp->ddocfunc.alias &&
*(char *) (VT (objfile) + dn_bufp->ddocfunc.alias))
DEPRECATED_SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.alias;
else
DEPRECATED_SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.name;
if ((strcmp (DEPRECATED_SYMBOL_NAME (sym), "_MAIN_") == 0) &&
(strcmp (VT (objfile) + dn_bufp->ddocfunc.name, "main") == 0))
DEPRECATED_SYMBOL_NAME (sym) = VT (objfile) + dn_bufp->ddocfunc.name;
if (dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS)
{
SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->objfile_obstack);
if ((DEPRECATED_SYMBOL_NAME (sym) == VT (objfile) + dn_bufp->ddocfunc.alias) &&
(!SYMBOL_CPLUS_DEMANGLED_NAME (sym)))
{
char *basename;
char *classname;
char *dem_name;
basename = VT (objfile) + dn_bufp->ddocfunc.name;
classname = class_of (SYMBOL_TYPE (sym));
if (classname)
{
dem_name = xmalloc (strlen (basename) + strlen (classname) + 3);
strcpy (dem_name, classname);
strcat (dem_name, "::");
strcat (dem_name, basename);
SYMBOL_CPLUS_DEMANGLED_NAME (sym) = dem_name;
SYMBOL_LANGUAGE (sym) = language_cplus;
}
}
}
if (dn_bufp->ddocfunc.global)
add_symbol_to_list (sym, &global_symbols);
else
add_symbol_to_list (sym, &file_symbols);
new->name = sym;
if (dn_bufp->ddocfunc.language == HP_LANGUAGE_C ||
dn_bufp->ddocfunc.language == HP_LANGUAGE_CPLUSPLUS)
{
while (dn_bufp->dblock.kind != DNTT_TYPE_BEGIN)
{
dn_bufp = hpread_get_lntt (++index, objfile);
if (dn_bufp->dblock.extension)
continue;
}
SL_INDEX (objfile) = hpread_record_lines (current_subfile,
SL_INDEX (objfile),
dn_bufp->dbegin.address,
objfile, offset);
SYMBOL_LINE (sym) = hpread_get_line (dn_bufp->dbegin.address, objfile);
}
record_line (current_subfile, SYMBOL_LINE (sym), valu);
break;
case DNTT_TYPE_BEGIN:
if (context_stack_depth == 1 &&
context_stack[0].name != NULL &&
context_stack[0].depth == 0
)
{
context_stack[0].depth++;
}
else
{
SL_INDEX (objfile) = hpread_record_lines (current_subfile,
SL_INDEX (objfile),
dn_bufp->dbegin.address,
objfile, offset);
valu = hpread_get_location (dn_bufp->dbegin.address, objfile);
valu += offset;
desc = hpread_get_scope_start (dn_bufp->dbegin.address, objfile);
new = push_context (desc, valu);
}
break;
case DNTT_TYPE_END:
SL_INDEX (objfile) = hpread_record_lines (current_subfile,
SL_INDEX (objfile),
dn_bufp->dend.address,
objfile, offset);
switch (dn_bufp->dend.endkind)
{
case DNTT_TYPE_MODULE:
valu = text_offset + text_size + offset;
*at_module_boundary_p = 1;
break;
case DNTT_TYPE_FUNCTION:
dn_temp = hpread_get_lntt (dn_bufp->dend.beginscope.dnttp.index,
objfile);
valu = dn_temp->dfunc.hiaddr + offset;
merge_symbol_lists (¶m_symbols, &local_symbols);
new = pop_context ();
finish_block (new->name, &local_symbols, new->old_blocks,
new->start_addr, valu, objfile);
WITHIN_FUNCTION (objfile) = 0;
local_symbols = new->locals;
param_symbols = new->params;
break;
case DNTT_TYPE_BEGIN:
if (context_stack_depth == 1 &&
context_stack[0].name != NULL &&
context_stack[0].depth == 1)
{
context_stack[0].depth--;
}
else
{
valu = hpread_get_location (dn_bufp->dend.address, objfile);
valu += offset + 9;
new = pop_context ();
desc = dn_bufp->dend.beginscope.dnttp.index;
if (desc != new->depth)
lbrac_mismatch_complaint (symnum);
finish_block (new->name, &local_symbols, new->old_blocks,
new->start_addr, valu, objfile);
local_symbols = new->locals;
param_symbols = new->params;
}
break;
case DNTT_TYPE_WITH:
break;
case DNTT_TYPE_COMMON:
complaint (&symfile_complaints,
"unhandled symbol in hp-symtab-read.c: DNTT_TYPE_COMMON/DNTT_TYPE_END.\n");
break;
case DNTT_TYPE_CLASS_SCOPE:
class_scope_name = NULL;
#if 0
valu = hpread_get_location (dn_bufp->dend.address, objfile);
valu += offset + 9;
new = pop_context ();
desc = dn_bufp->dend.beginscope.dnttp.index;
if (desc != new->depth)
lbrac_mismatch_complaint ((char *) symnum);
finish_block (new->name, &local_symbols, new->old_blocks,
new->start_addr, valu, objfile);
local_symbols = new->locals;
param_symbols = new->params;
#endif
break;
default:
complaint (&symfile_complaints,
"internal error in hp-symtab-read.c: Unexpected DNTT_TYPE_END kind.");
break;
}
break;
case DNTT_TYPE_LABEL:
SYMBOL_DOMAIN (sym) = LABEL_DOMAIN;
break;
case DNTT_TYPE_FPARAM:
break;
#if 0
if (dn_bufp->dfparam.regparam)
SYMBOL_CLASS (sym) = LOC_REGISTER;
else if (dn_bufp->dfparam.indirect)
SYMBOL_CLASS (sym) = LOC_REF_ARG;
else
SYMBOL_CLASS (sym) = LOC_ARG;
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
if (dn_bufp->dfparam.copyparam)
{
SYMBOL_VALUE (sym) = dn_bufp->dfparam.location;
#ifdef HPREAD_ADJUST_STACK_ADDRESS
SYMBOL_VALUE (sym)
+= HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
#endif
}
else
SYMBOL_VALUE (sym) = dn_bufp->dfparam.location;
SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dfparam.type, objfile);
add_symbol_to_list (sym, &fparam_symbols);
break;
#endif
case DNTT_TYPE_SVAR:
SYMBOL_CLASS (sym) = LOC_STATIC;
if (is_in_import_list (DEPRECATED_SYMBOL_NAME (sym), objfile))
SYMBOL_CLASS (sym) = LOC_INDIRECT;
SYMBOL_VALUE_ADDRESS (sym) = dn_bufp->dsvar.location + data_offset;
SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dsvar.type, objfile);
if (dn_bufp->dsvar.global)
add_symbol_to_list (sym, &global_symbols);
else if (WITHIN_FUNCTION (objfile))
add_symbol_to_list (sym, &local_symbols);
else
add_symbol_to_list (sym, &file_symbols);
if (dn_bufp->dsvar.thread_specific)
{
SYMBOL_CLASS (sym) = LOC_HP_THREAD_LOCAL_STATIC;
SYMBOL_BASEREG (sym) = CR27_REGNUM;
if (objfile->flags & OBJF_SHARED)
{
struct so_list *so;
if (objfile->obj_private == NULL)
error ("Internal error in reading shared library information.");
so = ((obj_private_data_t *) (objfile->obj_private))->so_info;
if (so == NULL)
error ("Internal error in reading shared library information.");
SYMBOL_VALUE_ADDRESS (sym) = dn_bufp->dsvar.location +
so_lib_thread_start_addr (so);
}
}
break;
case DNTT_TYPE_DVAR:
if (dn_bufp->ddvar.regvar)
SYMBOL_CLASS (sym) = LOC_REGISTER;
else
SYMBOL_CLASS (sym) = LOC_LOCAL;
SYMBOL_VALUE (sym) = dn_bufp->ddvar.location;
#ifdef HPREAD_ADJUST_STACK_ADDRESS
SYMBOL_VALUE (sym)
+= HPREAD_ADJUST_STACK_ADDRESS (CURRENT_FUNCTION_VALUE (objfile));
#endif
SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->ddvar.type, objfile);
if (dn_bufp->ddvar.global)
add_symbol_to_list (sym, &global_symbols);
else if (WITHIN_FUNCTION (objfile))
add_symbol_to_list (sym, &local_symbols);
else
add_symbol_to_list (sym, &file_symbols);
break;
case DNTT_TYPE_CONST:
SYMBOL_CLASS (sym) = LOC_CONST;
SYMBOL_VALUE (sym) = dn_bufp->dconst.location;
SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dconst.type, objfile);
if (dn_bufp->dconst.global)
add_symbol_to_list (sym, &global_symbols);
else if (WITHIN_FUNCTION (objfile))
add_symbol_to_list (sym, &local_symbols);
else
add_symbol_to_list (sym, &file_symbols);
break;
case DNTT_TYPE_TYPEDEF:
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dtype.type, objfile);
if (dn_bufp->dtype.global)
add_symbol_to_list (sym, &global_symbols);
else if (WITHIN_FUNCTION (objfile))
add_symbol_to_list (sym, &local_symbols);
else
add_symbol_to_list (sym, &file_symbols);
break;
case DNTT_TYPE_TAGDEF:
{
int global = dn_bufp->dtag.global;
SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
SYMBOL_TYPE (sym) = hpread_type_lookup (dn_bufp->dtype.type, objfile);
TYPE_NAME (sym->type) = DEPRECATED_SYMBOL_NAME (sym);
TYPE_TAG_NAME (sym->type) = DEPRECATED_SYMBOL_NAME (sym);
if (dn_bufp->dtag.global)
add_symbol_to_list (sym, &global_symbols);
else if (WITHIN_FUNCTION (objfile))
add_symbol_to_list (sym, &local_symbols);
else
add_symbol_to_list (sym, &file_symbols);
if (dn_bufp->dtype.type.dnttp.index < LNTT_SYMCOUNT (objfile))
dn_bufp = hpread_get_lntt (dn_bufp->dtag.type.dnttp.index, objfile);
else
{
complaint (&symfile_complaints, "error processing class tagdef");
return;
}
if (dn_bufp->dblock.kind == DNTT_TYPE_CLASS ||
dn_bufp->dblock.kind == DNTT_TYPE_ENUM ||
dn_bufp->dblock.kind == DNTT_TYPE_TEMPLATE)
{
struct symbol *newsym;
newsym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
sizeof (struct symbol));
memset (newsym, 0, sizeof (struct symbol));
DEPRECATED_SYMBOL_NAME (newsym) = name;
SYMBOL_LANGUAGE (newsym) = language_auto;
SYMBOL_DOMAIN (newsym) = VAR_DOMAIN;
SYMBOL_LINE (newsym) = 0;
SYMBOL_VALUE (newsym) = 0;
SYMBOL_CLASS (newsym) = LOC_TYPEDEF;
SYMBOL_TYPE (newsym) = sym->type;
if (global)
add_symbol_to_list (newsym, &global_symbols);
else if (WITHIN_FUNCTION (objfile))
add_symbol_to_list (newsym, &local_symbols);
else
add_symbol_to_list (newsym, &file_symbols);
}
}
break;
case DNTT_TYPE_POINTER:
break;
case DNTT_TYPE_ENUM:
break;
case DNTT_TYPE_MEMENUM:
break;
case DNTT_TYPE_SET:
break;
case DNTT_TYPE_SUBRANGE:
break;
case DNTT_TYPE_ARRAY:
break;
case DNTT_TYPE_STRUCT:
case DNTT_TYPE_UNION:
break;
case DNTT_TYPE_FIELD:
break;
case DNTT_TYPE_FUNCTYPE:
break;
case DNTT_TYPE_WITH:
break;
case DNTT_TYPE_COMMON:
complaint (&symfile_complaints,
"unhandled symbol in hp-symtab-read.c: DNTT_TYPE_COMMON.");
break;
case DNTT_TYPE_BLOCKDATA:
complaint (&symfile_complaints,
"unhandled symbol in hp-symtab-read.c: DNTT_TYPE_BLOCKDATA.");
break;
case DNTT_TYPE_CLASS_SCOPE:
dn_temp = hpread_get_lntt (dn_bufp->dclass_scope.type.dnttp.index, objfile);
if (dn_temp->dblock.kind == DNTT_TYPE_TAGDEF)
class_scope_name = VT (objfile) + dn_temp->dtag.name;
else
class_scope_name = NULL;
#if 0
SL_INDEX (objfile) = hpread_record_lines (current_subfile,
SL_INDEX (objfile),
dn_bufp->dclass_scope.address,
objfile, offset);
valu = hpread_get_location (dn_bufp->dclass_scope.address, objfile);
valu += offset;
desc = hpread_get_scope_start (dn_bufp->dclass_scope.address, objfile);
new = push_context (desc, valu);
#endif
break;
case DNTT_TYPE_REFERENCE:
break;
case DNTT_TYPE_PTRMEM:
break;
case DNTT_TYPE_PTRMEMFUNC:
break;
case DNTT_TYPE_CLASS:
break;
case DNTT_TYPE_GENFIELD:
break;
case DNTT_TYPE_VFUNC:
break;
case DNTT_TYPE_MEMACCESS:
break;
case DNTT_TYPE_INHERITANCE:
break;
case DNTT_TYPE_FRIEND_CLASS:
case DNTT_TYPE_FRIEND_FUNC:
break;
case DNTT_TYPE_MODIFIER:
break;
case DNTT_TYPE_OBJECT_ID:
break;
case DNTT_TYPE_MEMFUNC:
break;
case DNTT_TYPE_DOC_MEMFUNC:
break;
case DNTT_TYPE_TEMPLATE:
break;
case DNTT_TYPE_TEMPLATE_ARG:
break;
case DNTT_TYPE_FUNC_TEMPLATE:
break;
case DNTT_TYPE_LINK:
break;
default:
break;
}
}
static int
hpread_get_scope_depth (union dnttentry *dn_bufp, struct objfile *objfile,
int report_nested)
{
int index;
union dnttentry *dn_tmp;
short depth = 0;
return 0;
index = (((char *) dn_bufp) - LNTT (objfile)) / (sizeof (struct dntt_type_block));
while (--index >= 0)
{
dn_tmp = hpread_get_lntt (index, objfile);
switch (dn_tmp->dblock.kind)
{
case DNTT_TYPE_MODULE:
return depth;
case DNTT_TYPE_END:
index = (int) dn_tmp->dend.beginscope.dnttp.index;
break;
case DNTT_TYPE_BEGIN:
case DNTT_TYPE_FUNCTION:
case DNTT_TYPE_DOC_FUNCTION:
case DNTT_TYPE_WITH:
case DNTT_TYPE_COMMON:
case DNTT_TYPE_CLASS_SCOPE:
depth++;
if (report_nested)
return 1;
break;
default:
break;
}
}
return depth;
}
static void
hpread_adjust_bitoffsets (struct type *type, int bits)
{
int i;
if (TYPE_CODE (type) != TYPE_CODE_UNION)
return;
for (i = 0; i < TYPE_NFIELDS (type); i++)
TYPE_FIELD_BITPOS (type, i) -= bits;
}
static dnttpointer
hpread_get_next_skip_over_anon_unions (int skip_fields, dnttpointer field,
union dnttentry **fieldp,
struct objfile *objfile)
{
struct type *anon_type;
int i;
int bitoffset;
char *name;
for (i = 0; i < skip_fields; i++)
{
anon_type = hpread_type_lookup ((*fieldp)->dfield.type, objfile);
anon_type = CHECK_TYPEDEF (anon_type);
bitoffset = (*fieldp)->dfield.bitoffset;
name = VT (objfile) + (*fieldp)->dfield.name;
field = (*fieldp)->dfield.nextfield;
*fieldp = hpread_get_lntt (field.dnttp.index, objfile);
if ((TYPE_CODE (anon_type) == TYPE_CODE_UNION) &&
(!name || DEPRECATED_STREQ (name, "")))
{
hpread_adjust_bitoffsets (anon_type, bitoffset);
field = hpread_get_next_skip_over_anon_unions (TYPE_NFIELDS (anon_type), field, fieldp, objfile);
}
}
return field;
}