X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fcoffread.c;h=1008f6d777e37792596e83cc25b7bef0d5711bf2;hb=4262abfb982e7afb257203a2dbdb921b57f5e39b;hp=cf8fb54a0172d20fb01d2065964acf5370f15e1f;hpb=dd707e8e619a4ef27a2a11fc25dbe166d29b742d;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/coffread.c b/gdb/coffread.c index cf8fb54a01..1008f6d777 100644 --- a/gdb/coffread.c +++ b/gdb/coffread.c @@ -1,7 +1,5 @@ /* Read coff symbol tables and convert to internal format, for GDB. - Copyright (C) 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, - 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, - 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 1987-2013 Free Software Foundation, Inc. Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu). This file is part of GDB. @@ -49,6 +47,10 @@ 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; @@ -144,6 +146,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, @@ -295,7 +310,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. */ @@ -313,7 +328,7 @@ cs_section_address (struct coff_symbol *cs, bfd *abfd) args.resultp = § bfd_map_over_sections (abfd, find_targ_sec, &args); if (sect != NULL) - addr = bfd_get_section_vma (objfile->obfd, sect); + addr = bfd_get_section_vma (abfd, sect); return addr; } @@ -394,9 +409,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; } @@ -415,24 +428,63 @@ coff_end_symtab (struct objfile *objfile) 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 (strncmp (cs->c_name, "__fu", 4) != 0) + 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, 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); + 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 prim_record_minimal_symbol_and_info (cs->c_name, address, - type, section, - bfd_section, objfile); + type, section, objfile); } /* coff_symfile_init () @@ -452,26 +504,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 @@ -529,8 +576,8 @@ coff_symfile_read (struct objfile *objfile, int symfile_flags) struct cleanup *back_to, *cleanup_minimal_symbols; int stabstrsize; - info = (struct coff_symfile_info *) objfile->deprecated_sym_private; - dbxinfo = objfile->deprecated_sym_stab_info; + info = objfile_data (objfile, coff_objfile_data_key); + dbxinfo = DBX_SYMFILE_INFO (objfile); symfile_bfd = abfd; /* Kludge for swap routines. */ /* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */ @@ -616,6 +663,35 @@ coff_symfile_read (struct objfile *objfile, int symfile_flags) install_minimal_symbols (objfile); + if (pe_file) + { + struct minimal_symbol *msym; + + ALL_OBJFILE_MSYMBOLS (objfile, msym) + { + const char *name = SYMBOL_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 + && (strncmp (name, "__imp_", 6) == 0 + || strncmp (name, "_imp_", 5) == 0)) + { + const char *name1 = (name[1] == '_' ? &name[7] : &name[6]); + struct minimal_symbol *found; + + 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 != NULL && MSYMBOL_TYPE (found) == mst_text) + MSYMBOL_TYPE (found) = mst_solib_trampoline; + } + } + } + /* Free the installed minimal symbol data. */ do_cleanups (cleanup_minimal_symbols); @@ -655,13 +731,14 @@ coff_symfile_read (struct objfile *objfile, int symfile_flags) char *debugfile; debugfile = find_separate_debug_file_by_debuglink (objfile); + make_cleanup (xfree, debugfile); if (debugfile) { bfd *abfd = symfile_bfd_open (debugfile); + make_cleanup_bfd_unref (abfd); symbol_file_add_separate (abfd, symfile_flags, objfile); - xfree (debugfile); } } @@ -682,11 +759,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 (); @@ -747,17 +819,17 @@ 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_length = INITIAL_TYPE_VECTOR_LENGTH; type_vector = (struct type **) xmalloc (type_vector_length * sizeof (struct type *)); memset (type_vector, 0, type_vector_length * sizeof (struct type *)); @@ -773,7 +845,7 @@ 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_"); @@ -789,7 +861,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); @@ -838,7 +910,7 @@ 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); @@ -942,7 +1014,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) @@ -1128,7 +1200,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms, read_pe_exported_syms (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 @@ -1157,14 +1229,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); @@ -1174,7 +1246,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); @@ -1308,7 +1381,6 @@ static const char * coff_getfilename (union internal_auxent *aux_entry) { static char buffer[BUFSIZ]; - char *temp; const char *result; if (aux_entry->x_file.x_n.x_zeroes == 0) @@ -1457,10 +1529,11 @@ patch_type (struct type *type, struct type *real_type) if (TYPE_NAME (real_target)) { + /* The previous copy of TYPE_NAME is allocated by + process_coff_symbol. */ if (TYPE_NAME (target)) - xfree (TYPE_NAME (target)); - TYPE_NAME (target) = concat (TYPE_NAME (real_target), - (char *) NULL); + xfree ((char*) TYPE_NAME (target)); + TYPE_NAME (target) = xstrdup (TYPE_NAME (real_target)); } } @@ -1472,7 +1545,7 @@ static void patch_opaque_types (struct symtab *s) { struct block *b; - struct dict_iterator iter; + struct block_iterator iter; struct symbol *real_sym; /* Go through the per-file symbols only. */ @@ -1488,7 +1561,7 @@ patch_opaque_types (struct symtab *s) && TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR && TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (real_sym))) != 0) { - char *name = SYMBOL_LINKAGE_NAME (real_sym); + const char *name = SYMBOL_LINKAGE_NAME (real_sym); int hash = hashname (name); struct symbol *sym, *prev; @@ -1538,20 +1611,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 */ @@ -1567,7 +1642,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); @@ -1584,14 +1659,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)); @@ -1601,7 +1676,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)); @@ -1621,8 +1696,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; @@ -1632,21 +1706,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. */ @@ -1677,7 +1750,7 @@ process_coff_symbol (struct coff_symbol *cs, } else TYPE_NAME (SYMBOL_TYPE (sym)) = - concat (SYMBOL_LINKAGE_NAME (sym), (char *) NULL); + xstrdup (SYMBOL_LINKAGE_NAME (sym)); } /* Keep track of any type which points to empty structured @@ -1702,7 +1775,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" @@ -2020,8 +2093,8 @@ coff_read_struct_type (int index, int length, int lastsym, list = new; /* Save the data. */ - list->field.name = obsavestring (name, strlen (name), - &objfile->objfile_obstack); + list->field.name = 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); @@ -2037,8 +2110,8 @@ coff_read_struct_type (int index, int length, int lastsym, list = new; /* Save the data. */ - list->field.name = obsavestring (name, strlen (name), - &objfile->objfile_obstack); + list->field.name = 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); @@ -2106,14 +2179,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)); + sym = allocate_symbol (objfile); SYMBOL_SET_LINKAGE_NAME (sym, - obsavestring (name, strlen (name), - &objfile->objfile_obstack)); - SYMBOL_CLASS (sym) = LOC_CONST; + obstack_copy0 (&objfile->objfile_obstack, + name, strlen (name))); + SYMBOL_ACLASS_INDEX (sym) = LOC_CONST; SYMBOL_DOMAIN (sym) = VAR_DOMAIN; SYMBOL_VALUE (sym) = ms->c_value; add_symbol_to_list (sym, symlist); @@ -2160,7 +2231,7 @@ coff_read_enum_type (int index, int length, int lastsym, SYMBOL_TYPE (xsym) = type; TYPE_FIELD_NAME (type, n) = SYMBOL_LINKAGE_NAME (xsym); - SET_FIELD_BITPOS (TYPE_FIELD (type, n), SYMBOL_VALUE (xsym)); + SET_FIELD_ENUMVAL (TYPE_FIELD (type, n), SYMBOL_VALUE (xsym)); if (SYMBOL_VALUE (xsym) < 0) unsigned_enum = 0; TYPE_FIELD_BITSIZE (type, n) = 0; @@ -2197,11 +2268,26 @@ static const struct sym_fns coff_sym_fns = default_symfile_relocate, /* sym_relocate: Relocate a debug section. */ + NULL, /* sym_probe_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); + + 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); }