X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fcoffread.c;h=501e9011222b451c632806a336908da6652f4a5f;hb=b15cc25cbe7c13e450f77b4a309223b9b3da3936;hp=b0a8b8202995186f5a99c737612fe7d56b70c96d;hpb=22e048c9ddfdfd4e4580998f543f80e70f9770f7;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/coffread.c b/gdb/coffread.c index b0a8b82029..501e901122 100644 --- a/gdb/coffread.c +++ b/gdb/coffread.c @@ -1,5 +1,5 @@ /* Read coff symbol tables and convert to internal format, for GDB. - Copyright (C) 1987-2005, 2007-2012 Free Software Foundation, Inc. + Copyright (C) 1987-2016 Free Software Foundation, Inc. Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu). This file is part of GDB. @@ -25,8 +25,6 @@ #include "bfd.h" #include "gdb_obstack.h" - -#include "gdb_string.h" #include #include "coff/internal.h" /* Internal format of COFF symbols in BFD */ @@ -37,16 +35,20 @@ #include "stabsread.h" #include "complaints.h" #include "target.h" -#include "gdb_assert.h" #include "block.h" #include "dictionary.h" #include "coff-pe-read.h" #include "psymtab.h" +#include "build-id.h" extern void _initialize_coffread (void); +/* Key for COFF-associated data. */ + +static const struct objfile_data *coff_objfile_data_key; + /* The objfile we are currently reading. */ static struct objfile *coffread_objfile; @@ -142,6 +144,19 @@ struct coff_symbol unsigned int c_type; }; +/* Vector of types defined so far, indexed by their type numbers. */ + +static struct type **type_vector; + +/* Number of elements allocated for type_vector currently. */ + +static int type_vector_length; + +/* Initial size of type vector. Is realloc'd larger if needed, and + realloc'd down to the size actually used, when completed. */ + +#define INITIAL_TYPE_VECTOR_LENGTH 160 + extern void stabsread_clear_cache (void); static struct type *coff_read_struct_type (int, int, int, @@ -192,7 +207,8 @@ static void read_one_sym (struct coff_symbol *, struct internal_syment *, union internal_auxent *); -static void coff_symtab_read (long, unsigned int, struct objfile *); +static void coff_symtab_read (minimal_symbol_reader &, + long, unsigned int, struct objfile *); /* We are called once per section from coff_symfile_read. We need to examine each section we are passed, check to see @@ -217,7 +233,7 @@ coff_locate_sections (bfd *abfd, asection *sectp, void *csip) csi->textaddr = bfd_section_vma (abfd, sectp); csi->textsize += bfd_section_size (abfd, sectp); } - else if (strncmp (name, ".text", sizeof ".text" - 1) == 0) + else if (startswith (name, ".text")) { csi->textsize += bfd_section_size (abfd, sectp); } @@ -225,7 +241,7 @@ coff_locate_sections (bfd *abfd, asection *sectp, void *csip) { csi->stabstrsect = sectp; } - else if (strncmp (name, ".stab", sizeof ".stab" - 1) == 0) + else if (startswith (name, ".stab")) { const char *s; @@ -238,8 +254,7 @@ coff_locate_sections (bfd *abfd, asection *sectp, void *csip) { struct stab_section_list *n, **pn; - n = ((struct stab_section_list *) - xmalloc (sizeof (struct stab_section_list))); + n = XNEW (struct stab_section_list); n->section = sectp; n->next = NULL; for (pn = &csi->stabsects; *pn != NULL; pn = &(*pn)->next) @@ -293,7 +308,7 @@ cs_to_section (struct coff_symbol *cs, struct objfile *objfile) if (sect == NULL) return SECT_OFF_TEXT (objfile); - return sect->index; + return gdb_bfd_section_index (objfile->obfd, sect); } /* Return the address of the section of a COFF symbol. */ @@ -368,9 +383,9 @@ coff_alloc_type (int index) it indicates the start of data for one original source file. */ static void -coff_start_symtab (const char *name) +coff_start_symtab (struct objfile *objfile, const char *name) { - start_symtab ( + start_symtab (objfile, /* We fill in the filename later. start_symtab puts this pointer into last_source_file and we put it in subfiles->name, which end_symtab frees; that's why it must be malloc'd. */ @@ -392,9 +407,7 @@ coff_start_symtab (const char *name) static void complete_symtab (const char *name, CORE_ADDR start_addr, unsigned int size) { - if (last_source_file != NULL) - xfree (last_source_file); - last_source_file = xstrdup (name); + set_last_source_file (name); current_source_start_addr = start_addr; current_source_end_addr = start_addr + size; } @@ -409,28 +422,66 @@ coff_end_symtab (struct objfile *objfile) { last_source_start_addr = current_source_start_addr; - end_symtab (current_source_end_addr, objfile, - SECT_OFF_TEXT (objfile)); + end_symtab (current_source_end_addr, SECT_OFF_TEXT (objfile)); /* Reinitialize for beginning of new file. */ - last_source_file = NULL; + set_last_source_file (NULL); } +/* The linker sometimes generates some non-function symbols inside + functions referencing variables imported from another DLL. + Return nonzero if the given symbol corresponds to one of them. */ + +static int +is_import_fixup_symbol (struct coff_symbol *cs, + enum minimal_symbol_type type) +{ + /* The following is a bit of a heuristic using the characterictics + of these fixup symbols, but should work well in practice... */ + int i; + + /* Must be a non-static text symbol. */ + if (type != mst_text) + return 0; + + /* Must be a non-function symbol. */ + if (ISFCN (cs->c_type)) + return 0; + + /* The name must start with "__fu__". */ + if (!startswith (cs->c_name, "__fu")) + return 0; + if (! isdigit (cs->c_name[4])) + return 0; + for (i = 5; cs->c_name[i] != '\0' && isdigit (cs->c_name[i]); i++) + /* Nothing, just incrementing index past all digits. */; + if (cs->c_name[i] != '_' || cs->c_name[i + 1] != '_') + return 0; + + return 1; +} + static struct minimal_symbol * -record_minimal_symbol (struct coff_symbol *cs, CORE_ADDR address, +record_minimal_symbol (minimal_symbol_reader &reader, + struct coff_symbol *cs, CORE_ADDR address, enum minimal_symbol_type type, int section, struct objfile *objfile) { - struct bfd_section *bfd_section; - /* We don't want TDESC entry points in the minimal symbol table. */ if (cs->c_name[0] == '@') return NULL; - bfd_section = cs_to_bfd_section (cs, objfile); - return prim_record_minimal_symbol_and_info (cs->c_name, address, - type, section, - bfd_section, objfile); + if (is_import_fixup_symbol (cs, type)) + { + /* Because the value of these symbols is within a function code + range, these symbols interfere with the symbol-from-address + reverse lookup; this manifests itselfs in backtraces, or any + other commands that prints symbolic addresses. Just pretend + these symbols do not exist. */ + return NULL; + } + + return reader.record_with_info (cs->c_name, address, type, section); } /* coff_symfile_init () @@ -450,26 +501,21 @@ record_minimal_symbol (struct coff_symbol *cs, CORE_ADDR address, static void coff_symfile_init (struct objfile *objfile) { - /* Allocate struct to keep track of stab reading. */ - objfile->deprecated_sym_stab_info = (struct dbx_symfile_info *) - xmalloc (sizeof (struct dbx_symfile_info)); + struct dbx_symfile_info *dbx; + struct coff_symfile_info *coff; - memset (objfile->deprecated_sym_stab_info, 0, - sizeof (struct dbx_symfile_info)); + /* Allocate struct to keep track of stab reading. */ + dbx = XCNEW (struct dbx_symfile_info); + set_objfile_data (objfile, dbx_objfile_data_key, dbx); /* Allocate struct to keep track of the symfile. */ - objfile->deprecated_sym_private - = xmalloc (sizeof (struct coff_symfile_info)); - - memset (objfile->deprecated_sym_private, 0, - sizeof (struct coff_symfile_info)); + coff = XCNEW (struct coff_symfile_info); + set_objfile_data (objfile, coff_objfile_data_key, coff); /* COFF objects may be reordered, so set OBJF_REORDERED. If we find this causes a significant slowdown in gdb then we could set it in the debug symbol readers only when necessary. */ objfile->flags |= OBJF_REORDERED; - - init_entry_point_info (objfile); } /* This function is called for every section; it finds the outer @@ -513,10 +559,9 @@ static bfd *symfile_bfd; /* Read a symbol file, after initialization by coff_symfile_init. */ static void -coff_symfile_read (struct objfile *objfile, int symfile_flags) +coff_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) { struct coff_symfile_info *info; - struct dbx_symfile_info *dbxinfo; bfd *abfd = objfile->obfd; coff_data_type *cdata = coff_data (abfd); char *name = bfd_get_filename (abfd); @@ -524,11 +569,11 @@ coff_symfile_read (struct objfile *objfile, int symfile_flags) unsigned int num_symbols; int symtab_offset; int stringtab_offset; - struct cleanup *back_to, *cleanup_minimal_symbols; + struct cleanup *back_to; int stabstrsize; - info = (struct coff_symfile_info *) objfile->deprecated_sym_private; - dbxinfo = objfile->deprecated_sym_stab_info; + info = (struct coff_symfile_info *) objfile_data (objfile, + coff_objfile_data_key); symfile_bfd = abfd; /* Kludge for swap routines. */ /* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */ @@ -560,8 +605,8 @@ coff_symfile_read (struct objfile *objfile, int symfile_flags) FIXME: We should use BFD to read the symbol table, and thus avoid this problem. */ pe_file = - strncmp (bfd_get_target (objfile->obfd), "pe", 2) == 0 - || strncmp (bfd_get_target (objfile->obfd), "epoc-pe", 7) == 0; + startswith (bfd_get_target (objfile->obfd), "pe") + || startswith (bfd_get_target (objfile->obfd), "epoc-pe"); /* End of warning. */ @@ -601,21 +646,58 @@ coff_symfile_read (struct objfile *objfile, int symfile_flags) if (val < 0) error (_("\"%s\": can't get string table"), name); - init_minimal_symbol_collection (); - cleanup_minimal_symbols = make_cleanup_discard_minimal_symbols (); + minimal_symbol_reader reader (objfile); /* Now that the executable file is positioned at symbol table, process it and define symbols accordingly. */ - coff_symtab_read ((long) symtab_offset, num_symbols, objfile); + coff_symtab_read (reader, (long) symtab_offset, num_symbols, objfile); /* Install any minimal symbols that have been collected as the current minimal symbols for this objfile. */ - install_minimal_symbols (objfile); + reader.install (); - /* Free the installed minimal symbol data. */ - do_cleanups (cleanup_minimal_symbols); + if (pe_file) + { + struct minimal_symbol *msym; + + ALL_OBJFILE_MSYMBOLS (objfile, msym) + { + const char *name = MSYMBOL_LINKAGE_NAME (msym); + + /* If the minimal symbols whose name are prefixed by "__imp_" + or "_imp_", get rid of the prefix, and search the minimal + symbol in OBJFILE. Note that 'maintenance print msymbols' + shows that type of these "_imp_XXXX" symbols is mst_data. */ + if (MSYMBOL_TYPE (msym) == mst_data) + { + const char *name1 = NULL; + + if (startswith (name, "_imp_")) + name1 = name + 5; + else if (startswith (name, "__imp_")) + name1 = name + 6; + if (name1 != NULL) + { + int lead = bfd_get_symbol_leading_char (objfile->obfd); + struct bound_minimal_symbol found; + + if (lead != '\0' && *name1 == lead) + name1 += 1; + + found = lookup_minimal_symbol (name1, NULL, objfile); + + /* If found, there are symbols named "_imp_foo" and "foo" + respectively in OBJFILE. Set the type of symbol "foo" + as 'mst_solib_trampoline'. */ + if (found.minsym != NULL + && MSYMBOL_TYPE (found.minsym) == mst_text) + MSYMBOL_TYPE (found.minsym) = mst_solib_trampoline; + } + } + } + } bfd_map_over_sections (abfd, coff_locate_sections, (void *) info); @@ -652,14 +734,18 @@ coff_symfile_read (struct objfile *objfile, int symfile_flags) { char *debugfile; - debugfile = find_separate_debug_file_by_debuglink (objfile); + debugfile = find_separate_debug_file_by_buildid (objfile); + + if (debugfile == NULL) + debugfile = find_separate_debug_file_by_debuglink (objfile); + make_cleanup (xfree, debugfile); if (debugfile) { bfd *abfd = symfile_bfd_open (debugfile); - symbol_file_add_separate (abfd, symfile_flags, objfile); - xfree (debugfile); + make_cleanup_bfd_unref (abfd); + symbol_file_add_separate (abfd, debugfile, symfile_flags, objfile); } } @@ -680,11 +766,6 @@ coff_new_init (struct objfile *ignore) static void coff_symfile_finish (struct objfile *objfile) { - if (objfile->deprecated_sym_private != NULL) - { - xfree (objfile->deprecated_sym_private); - } - /* Let stabs reader clean up. */ stabsread_clear_cache (); @@ -698,11 +779,12 @@ coff_symfile_finish (struct objfile *objfile) We read them one at a time using read_one_sym (). */ static void -coff_symtab_read (long symtab_offset, unsigned int nsyms, +coff_symtab_read (minimal_symbol_reader &reader, + long symtab_offset, unsigned int nsyms, struct objfile *objfile) { struct gdbarch *gdbarch = get_objfile_arch (objfile); - struct context_stack *new; + struct context_stack *newobj; struct coff_symbol coff_symbol; struct coff_symbol *cs = &coff_symbol; static struct internal_syment main_sym; @@ -710,7 +792,6 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, struct coff_symbol fcn_cs_saved; static struct internal_syment fcn_sym_saved; static union internal_auxent fcn_aux_saved; - struct symtab *s; /* A .file is open. */ int in_source_file = 0; int next_file_symnum = -1; @@ -745,22 +826,20 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, /* Position to read the symbol table. */ val = bfd_seek (objfile->obfd, (long) symtab_offset, 0); if (val < 0) - perror_with_name (objfile->name); + perror_with_name (objfile_name (objfile)); coffread_objfile = objfile; nlist_bfd_global = objfile->obfd; nlist_nsyms_global = nsyms; - last_source_file = NULL; + set_last_source_file (NULL); memset (opaque_type_chain, 0, sizeof opaque_type_chain); if (type_vector) /* Get rid of previous one. */ xfree (type_vector); - type_vector_length = 160; - type_vector = (struct type **) - xmalloc (type_vector_length * sizeof (struct type *)); - memset (type_vector, 0, type_vector_length * sizeof (struct type *)); + type_vector_length = INITIAL_TYPE_VECTOR_LENGTH; + type_vector = XCNEWVEC (struct type *, type_vector_length); - coff_start_symtab (""); + coff_start_symtab (objfile, ""); symnum = 0; while (symnum < nsyms) @@ -771,10 +850,10 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE) { - if (last_source_file) + if (get_last_source_file ()) coff_end_symtab (objfile); - coff_start_symtab ("_globals_"); + coff_start_symtab (objfile, "_globals_"); /* coff_start_symtab will set the language of this symtab to language_unknown, since such a ``file name'' is not recognized. Override that with the minimal language to @@ -787,7 +866,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, /* Special case for file with type declarations only, no text. */ - if (!last_source_file && SDB_TYPE (cs->c_type) + if (!get_last_source_file () && SDB_TYPE (cs->c_type) && cs->c_secnum == N_DEBUG) complete_symtab (filestring, 0, 0); @@ -798,9 +877,8 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, minsyms. */ int section = cs_to_section (cs, objfile); - tmpaddr = cs->c_value + ANOFFSET (objfile->section_offsets, - SECT_OFF_TEXT (objfile)); - record_minimal_symbol (cs, tmpaddr, mst_text, + tmpaddr = cs->c_value; + record_minimal_symbol (reader, cs, tmpaddr, mst_text, section, objfile); fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr; @@ -836,10 +914,10 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, /* Complete symbol table for last object file containing debugging information. */ - if (last_source_file) + if (get_last_source_file ()) { coff_end_symtab (objfile); - coff_start_symtab (filestring); + coff_start_symtab (objfile, filestring); } in_source_file = 1; break; @@ -877,14 +955,14 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, } else if (!SDB_TYPE (cs->c_type) && cs->c_name[0] == 'L' - && (strncmp (cs->c_name, "LI%", 3) == 0 - || strncmp (cs->c_name, "LF%", 3) == 0 - || strncmp (cs->c_name, "LC%", 3) == 0 - || strncmp (cs->c_name, "LP%", 3) == 0 - || strncmp (cs->c_name, "LPB%", 4) == 0 - || strncmp (cs->c_name, "LBB%", 4) == 0 - || strncmp (cs->c_name, "LBE%", 4) == 0 - || strncmp (cs->c_name, "LPBX%", 5) == 0)) + && (startswith (cs->c_name, "LI%") + || startswith (cs->c_name, "LF%") + || startswith (cs->c_name, "LC%") + || startswith (cs->c_name, "LP%") + || startswith (cs->c_name, "LPB%") + || startswith (cs->c_name, "LBB%") + || startswith (cs->c_name, "LBE%") + || startswith (cs->c_name, "LPBX%"))) /* At least on a 3b1, gcc generates swbeg and string labels that look like this. Ignore them. */ break; @@ -901,6 +979,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, enum minimal_symbol_type ms_type; int sec; + CORE_ADDR offset = 0; if (cs->c_secnum == N_UNDEF) { @@ -932,7 +1011,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, || cs->c_sclass == C_THUMBEXTFUNC || cs->c_sclass == C_THUMBEXT || (pe_file && (cs->c_sclass == C_STAT))) - tmpaddr += ANOFFSET (objfile->section_offsets, sec); + offset = ANOFFSET (objfile->section_offsets, sec); if (bfd_section->flags & SEC_CODE) { @@ -940,7 +1019,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC || cs->c_sclass == C_THUMBEXT ? mst_text : mst_file_text; - tmpaddr = gdbarch_smash_text_address (gdbarch, tmpaddr); + tmpaddr = gdbarch_addr_bits_remove (gdbarch, tmpaddr); } else if (bfd_section->flags & SEC_ALLOC && bfd_section->flags & SEC_LOAD) @@ -959,7 +1038,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, ms_type = mst_unknown; } - msym = record_minimal_symbol (cs, tmpaddr, ms_type, + msym = record_minimal_symbol (reader, cs, tmpaddr, ms_type, sec, objfile); if (msym) gdbarch_coff_make_msymbol_special (gdbarch, @@ -971,7 +1050,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, sym = process_coff_symbol (cs, &main_aux, objfile); - SYMBOL_VALUE (sym) = tmpaddr; + SYMBOL_VALUE (sym) = tmpaddr + offset; SYMBOL_SECTION (sym) = sec; } } @@ -997,9 +1076,9 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, context_stack_depth is zero, and complain if not. */ depth = 0; - new = push_context (depth, fcn_start_addr); + newobj = push_context (depth, fcn_start_addr); fcn_cs_saved.c_name = getsymname (&fcn_sym_saved); - new->name = + newobj->name = process_coff_symbol (&fcn_cs_saved, &fcn_aux_saved, objfile); } @@ -1022,9 +1101,9 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, break; } - new = pop_context (); + newobj = pop_context (); /* Stack must be empty now. */ - if (context_stack_depth > 0 || new == NULL) + if (context_stack_depth > 0 || newobj == NULL) { complaint (&symfile_complaints, _("Unmatched .ef symbol(s) ignored " @@ -1059,14 +1138,12 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, enter_linenos (fcn_line_ptr, fcn_first_line, fcn_last_line, objfile); - finish_block (new->name, &local_symbols, - new->old_blocks, new->start_addr, + finish_block (newobj->name, &local_symbols, newobj->old_blocks, + NULL, newobj->start_addr, fcn_cs_saved.c_value + fcn_aux_saved.x_sym.x_misc.x_fsize + ANOFFSET (objfile->section_offsets, - SECT_OFF_TEXT (objfile)), - objfile - ); + SECT_OFF_TEXT (objfile))); within_function = 0; } break; @@ -1090,8 +1167,8 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, break; } - new = pop_context (); - if (depth-- != new->depth) + newobj = pop_context (); + if (depth-- != newobj->depth) { complaint (&symfile_complaints, _("Mismatched .eb symbol ignored " @@ -1105,11 +1182,11 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); /* Make a block for the local symbols within. */ - finish_block (0, &local_symbols, new->old_blocks, - new->start_addr, tmpaddr, objfile); + finish_block (0, &local_symbols, newobj->old_blocks, NULL, + newobj->start_addr, tmpaddr); } /* Now pop locals of block just finished. */ - local_symbols = new->locals; + local_symbols = newobj->locals; } break; @@ -1123,16 +1200,21 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, { /* We've got no debugging symbols, but it's a portable executable, so try to read the export table. */ - read_pe_exported_syms (objfile); + read_pe_exported_syms (reader, objfile); } - if (last_source_file) + if (get_last_source_file ()) coff_end_symtab (objfile); /* Patch up any opaque types (references to types that are not defined in the file where they are referenced, e.g. "struct foo *bar"). */ - ALL_OBJFILE_SYMTABS (objfile, s) - patch_opaque_types (s); + { + struct compunit_symtab *cu; + struct symtab *s; + + ALL_OBJFILE_FILETABS (objfile, cu, s) + patch_opaque_types (s); + } coffread_objfile = NULL; } @@ -1155,14 +1237,14 @@ read_one_sym (struct coff_symbol *cs, cs->c_symnum = symnum; bytes = bfd_bread (temp_sym, local_symesz, nlist_bfd_global); if (bytes != local_symesz) - error (_("%s: error reading symbols"), coffread_objfile->name); + error (_("%s: error reading symbols"), objfile_name (coffread_objfile)); bfd_coff_swap_sym_in (symfile_bfd, temp_sym, (char *) sym); cs->c_naux = sym->n_numaux & 0xff; if (cs->c_naux >= 1) { bytes = bfd_bread (temp_aux, local_auxesz, nlist_bfd_global); if (bytes != local_auxesz) - error (_("%s: error reading symbols"), coffread_objfile->name); + error (_("%s: error reading symbols"), objfile_name (coffread_objfile)); bfd_coff_swap_aux_in (symfile_bfd, temp_aux, sym->n_type, sym->n_sclass, 0, cs->c_naux, (char *) aux); @@ -1172,7 +1254,8 @@ read_one_sym (struct coff_symbol *cs, { bytes = bfd_bread (temp_aux, local_auxesz, nlist_bfd_global); if (bytes != local_auxesz) - error (_("%s: error reading symbols"), coffread_objfile->name); + error (_("%s: error reading symbols"), + objfile_name (coffread_objfile)); } } cs->c_name = getsymname (sym); @@ -1474,7 +1557,7 @@ patch_opaque_types (struct symtab *s) struct symbol *real_sym; /* Go through the per-file symbols only. */ - b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK); + b = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (s), STATIC_BLOCK); ALL_BLOCK_SYMBOLS (b, iter, real_sym) { /* Find completed typedefs to use to fix opaque ones. @@ -1536,20 +1619,22 @@ static const struct symbol_register_ops coff_register_funcs = { coff_reg_to_regnum }; +/* The "aclass" index for computed COFF symbols. */ + +static int coff_register_index; + static struct symbol * process_coff_symbol (struct coff_symbol *cs, union internal_auxent *aux, struct objfile *objfile) { - struct symbol *sym - = (struct symbol *) obstack_alloc (&objfile->objfile_obstack, - sizeof (struct symbol)); + struct symbol *sym = allocate_symbol (objfile); char *name; - memset (sym, 0, sizeof (struct symbol)); name = cs->c_name; name = EXTERNAL_NAME (name, objfile->obfd); - SYMBOL_SET_LANGUAGE (sym, current_subfile->language); + SYMBOL_SET_LANGUAGE (sym, current_subfile->language, + &objfile->objfile_obstack); SYMBOL_SET_NAMES (sym, name, strlen (name), 1, objfile); /* default assumptions */ @@ -1565,7 +1650,7 @@ process_coff_symbol (struct coff_symbol *cs, lookup_function_type (decode_function_type (cs, cs->c_type, aux, objfile)); - SYMBOL_CLASS (sym) = LOC_BLOCK; + SYMBOL_ACLASS_INDEX (sym) = LOC_BLOCK; if (cs->c_sclass == C_STAT || cs->c_sclass == C_THUMBSTAT || cs->c_sclass == C_THUMBSTATFUNC) add_symbol_to_list (sym, &file_symbols); @@ -1582,14 +1667,14 @@ process_coff_symbol (struct coff_symbol *cs, break; case C_AUTO: - SYMBOL_CLASS (sym) = LOC_LOCAL; + SYMBOL_ACLASS_INDEX (sym) = LOC_LOCAL; add_symbol_to_list (sym, &local_symbols); break; case C_THUMBEXT: case C_THUMBEXTFUNC: case C_EXT: - SYMBOL_CLASS (sym) = LOC_STATIC; + SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC; SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value; SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); @@ -1599,7 +1684,7 @@ process_coff_symbol (struct coff_symbol *cs, case C_THUMBSTAT: case C_THUMBSTATFUNC: case C_STAT: - SYMBOL_CLASS (sym) = LOC_STATIC; + SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC; SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value; SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); @@ -1619,8 +1704,7 @@ process_coff_symbol (struct coff_symbol *cs, case C_GLBLREG: #endif case C_REG: - SYMBOL_CLASS (sym) = LOC_REGISTER; - SYMBOL_REGISTER_OPS (sym) = &coff_register_funcs; + SYMBOL_ACLASS_INDEX (sym) = coff_register_index; SYMBOL_VALUE (sym) = cs->c_value; add_symbol_to_list (sym, &local_symbols); break; @@ -1630,21 +1714,20 @@ process_coff_symbol (struct coff_symbol *cs, break; case C_ARG: - SYMBOL_CLASS (sym) = LOC_ARG; + SYMBOL_ACLASS_INDEX (sym) = LOC_ARG; SYMBOL_IS_ARGUMENT (sym) = 1; add_symbol_to_list (sym, &local_symbols); break; case C_REGPARM: - SYMBOL_CLASS (sym) = LOC_REGISTER; - SYMBOL_REGISTER_OPS (sym) = &coff_register_funcs; + SYMBOL_ACLASS_INDEX (sym) = coff_register_index; SYMBOL_IS_ARGUMENT (sym) = 1; SYMBOL_VALUE (sym) = cs->c_value; add_symbol_to_list (sym, &local_symbols); break; case C_TPDEF: - SYMBOL_CLASS (sym) = LOC_TYPEDEF; + SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF; SYMBOL_DOMAIN (sym) = VAR_DOMAIN; /* If type has no name, give it one. */ @@ -1700,7 +1783,7 @@ process_coff_symbol (struct coff_symbol *cs, case C_STRTAG: case C_UNTAG: case C_ENTAG: - SYMBOL_CLASS (sym) = LOC_TYPEDEF; + SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF; SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN; /* Some compilers try to be helpful by inventing "fake" @@ -1766,9 +1849,9 @@ decode_type (struct coff_symbol *cs, unsigned int c_type, base_type = decode_type (cs, new_c_type, aux, objfile); index_type = objfile_type (objfile)->builtin_int; - range_type = - create_range_type ((struct type *) NULL, - index_type, 0, n - 1); + range_type + = create_static_range_type ((struct type *) NULL, + index_type, 0, n - 1); type = create_array_type ((struct type *) NULL, base_type, range_type); @@ -1986,7 +2069,7 @@ coff_read_struct_type (int index, int length, int lastsym, struct type *type; struct nextfield *list = 0; - struct nextfield *new; + struct nextfield *newobj; int nfields = 0; int n; char *name; @@ -2013,13 +2096,14 @@ coff_read_struct_type (int index, int length, int lastsym, case C_MOU: /* Get space to record the next field's data. */ - new = (struct nextfield *) alloca (sizeof (struct nextfield)); - new->next = list; - list = new; + newobj = XALLOCA (struct nextfield); + newobj->next = list; + list = newobj; /* Save the data. */ - list->field.name = obsavestring (name, strlen (name), - &objfile->objfile_obstack); + list->field.name + = (const char *) obstack_copy0 (&objfile->objfile_obstack, + name, strlen (name)); FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux, objfile); SET_FIELD_BITPOS (list->field, 8 * ms->c_value); @@ -2030,13 +2114,14 @@ coff_read_struct_type (int index, int length, int lastsym, case C_FIELD: /* Get space to record the next field's data. */ - new = (struct nextfield *) alloca (sizeof (struct nextfield)); - new->next = list; - list = new; + newobj = XALLOCA (struct nextfield); + newobj->next = list; + list = newobj; /* Save the data. */ - list->field.name = obsavestring (name, strlen (name), - &objfile->objfile_obstack); + list->field.name + = (const char *) obstack_copy0 (&objfile->objfile_obstack, + name, strlen (name)); FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux, objfile); SET_FIELD_BITPOS (list->field, ms->c_value); @@ -2104,14 +2189,12 @@ coff_read_enum_type (int index, int length, int lastsym, switch (ms->c_sclass) { case C_MOE: - sym = (struct symbol *) obstack_alloc - (&objfile->objfile_obstack, sizeof (struct symbol)); - memset (sym, 0, sizeof (struct symbol)); - - SYMBOL_SET_LINKAGE_NAME (sym, - obsavestring (name, strlen (name), - &objfile->objfile_obstack)); - SYMBOL_CLASS (sym) = LOC_CONST; + sym = allocate_symbol (objfile); + + name = (char *) obstack_copy0 (&objfile->objfile_obstack, name, + strlen (name)); + SYMBOL_SET_LINKAGE_NAME (sym, name); + SYMBOL_ACLASS_INDEX (sym) = LOC_CONST; SYMBOL_DOMAIN (sym) = VAR_DOMAIN; SYMBOL_VALUE (sym) = ms->c_value; add_symbol_to_list (sym, symlist); @@ -2177,7 +2260,6 @@ coff_read_enum_type (int index, int length, int lastsym, static const struct sym_fns coff_sym_fns = { - bfd_target_coff_flavour, coff_new_init, /* sym_new_init: init anything gbl to entire symtab */ coff_symfile_init, /* sym_init: read initial info, setup @@ -2199,8 +2281,22 @@ static const struct sym_fns coff_sym_fns = &psym_functions }; +/* Free the per-objfile COFF data. */ + +static void +coff_free_info (struct objfile *objfile, void *arg) +{ + xfree (arg); +} + void _initialize_coffread (void) { - add_symtab_fns (&coff_sym_fns); + add_symtab_fns (bfd_target_coff_flavour, &coff_sym_fns); + + coff_objfile_data_key = register_objfile_data_with_cleanup (NULL, + coff_free_info); + + coff_register_index + = register_symbol_register_impl (LOC_REGISTER, &coff_register_funcs); }