X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fsymfile.c;h=efa341dfe32d7127180b73f0a52a116bbc6e9b28;hb=3c83b96e241336be0c3e26c06f2bf901d0fe8edd;hp=1e57c69ebde6f343312254b4fd0dee253ccdbdc5;hpb=24ddea6286ad7c1915e833ca5009238724ff9299;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/symfile.c b/gdb/symfile.c index 1e57c69ebd..efa341dfe3 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -1,7 +1,7 @@ /* Generic symbol file reading for the GNU debugger, GDB. Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Cygnus Support, using pieces from other GDB modules. @@ -97,10 +97,6 @@ static void symbol_file_add_main_1 (char *args, int from_tty, int flags); static void add_symbol_file_command (char *, int); -static void reread_separate_symbols (struct objfile *objfile); - -static void cashier_psymtab (struct partial_symtab *); - bfd *symfile_bfd_open (char *); int get_section_index (struct objfile *, char *); @@ -140,8 +136,6 @@ static void add_filename_language (char *ext, enum language lang); static void info_ext_lang_command (char *args, int from_tty); -static char *find_separate_debug_file (struct objfile *objfile); - static void init_filename_language_table (void); static void symfile_find_segment_sections (struct objfile *objfile); @@ -332,32 +326,6 @@ alloc_section_addr_info (size_t num_sections) return sap; } - -/* Return a freshly allocated copy of ADDRS. The section names, if - any, are also freshly allocated copies of those in ADDRS. */ -struct section_addr_info * -copy_section_addr_info (struct section_addr_info *addrs) -{ - struct section_addr_info *copy - = alloc_section_addr_info (addrs->num_sections); - int i; - - copy->num_sections = addrs->num_sections; - for (i = 0; i < addrs->num_sections; i++) - { - copy->other[i].addr = addrs->other[i].addr; - if (addrs->other[i].name) - copy->other[i].name = xstrdup (addrs->other[i].name); - else - copy->other[i].name = NULL; - copy->other[i].sectindex = addrs->other[i].sectindex; - } - - return copy; -} - - - /* Build (allocate and populate) a section_addr_info struct from an existing section table. */ @@ -388,6 +356,34 @@ build_section_addr_info_from_section_table (const struct target_section *start, return sap; } +/* Create a section_addr_info from section offsets in OBJFILE. */ + +struct section_addr_info * +build_section_addr_info_from_objfile (const struct objfile *objfile) +{ + struct section_addr_info *sap; + int i; + struct bfd_section *sec; + int addr_bit = gdbarch_addr_bit (objfile->gdbarch); + CORE_ADDR mask = CORE_ADDR_MAX; + + if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT)) + mask = ((CORE_ADDR) 1 << addr_bit) - 1; + + sap = alloc_section_addr_info (objfile->num_sections); + for (i = 0, sec = objfile->obfd->sections; + i < objfile->num_sections; + i++, sec = sec->next) + { + gdb_assert (sec != NULL); + sap->other[i].addr = (bfd_get_section_vma (objfile->obfd, sec) + + objfile->section_offsets->offsets[i]) & mask; + sap->other[i].name = xstrdup (bfd_get_section_name (objfile->obfd, sec)); + sap->other[i].sectindex = sec->index; + } + return sap; +} + /* Free all memory allocated by build_section_addr_info_from_section_table. */ @@ -536,40 +532,111 @@ place_section (bfd *abfd, asection *sect, void *obj) arg->lowest = start_addr + bfd_get_section_size (sect); } -/* Parse the user's idea of an offset for dynamic linking, into our idea - of how to represent it for fast symbol reading. This is the default - version of the sym_fns.sym_offsets function for symbol readers that - don't need to do anything special. It allocates a section_offsets table - for the objectfile OBJFILE and stuffs ADDR into all of the offsets. */ +/* Store struct section_addr_info as prepared (made relative and with SECTINDEX + filled-in) by addr_info_make_relative into SECTION_OFFSETS of NUM_SECTIONS + entries. */ void -default_symfile_offsets (struct objfile *objfile, - struct section_addr_info *addrs) +relative_addr_info_to_section_offsets (struct section_offsets *section_offsets, + int num_sections, + struct section_addr_info *addrs) { int i; - objfile->num_sections = bfd_count_sections (objfile->obfd); - objfile->section_offsets = (struct section_offsets *) - obstack_alloc (&objfile->objfile_obstack, - SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)); - memset (objfile->section_offsets, 0, - SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)); + memset (section_offsets, 0, SIZEOF_N_SECTION_OFFSETS (num_sections)); - /* Now calculate offsets for section that were specified by the - caller. */ + /* Now calculate offsets for section that were specified by the caller. */ for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++) { - struct other_sections *osp ; + struct other_sections *osp; - osp = &addrs->other[i] ; + osp = &addrs->other[i]; if (osp->addr == 0) continue; /* Record all sections in offsets */ /* The section_offsets in the objfile are here filled in using the BFD index. */ - (objfile->section_offsets)->offsets[osp->sectindex] = osp->addr; + section_offsets->offsets[osp->sectindex] = osp->addr; + } +} + +/* Relativize absolute addresses in ADDRS into offsets based on ABFD. Fill-in + also SECTINDEXes there. */ + +void +addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd) +{ + asection *lower_sect; + asection *sect; + CORE_ADDR lower_offset; + int i; + + /* Find lowest loadable section to be used as starting point for + continguous sections. FIXME!! won't work without call to find + .text first, but this assumes text is lowest section. */ + lower_sect = bfd_get_section_by_name (abfd, ".text"); + if (lower_sect == NULL) + bfd_map_over_sections (abfd, find_lowest_section, &lower_sect); + if (lower_sect == NULL) + { + warning (_("no loadable sections found in added symbol-file %s"), + bfd_get_filename (abfd)); + lower_offset = 0; + } + else + lower_offset = bfd_section_vma (bfd_get_filename (abfd), lower_sect); + + /* Calculate offsets for the loadable sections. + FIXME! Sections must be in order of increasing loadable section + so that contiguous sections can use the lower-offset!!! + + Adjust offsets if the segments are not contiguous. + If the section is contiguous, its offset should be set to + the offset of the highest loadable section lower than it + (the loadable section directly below it in memory). + this_offset = lower_offset = lower_addr - lower_orig_addr */ + + for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++) + { + if (addrs->other[i].addr != 0) + { + sect = bfd_get_section_by_name (abfd, addrs->other[i].name); + if (sect) + { + addrs->other[i].addr -= bfd_section_vma (abfd, sect); + lower_offset = addrs->other[i].addr; + /* This is the index used by BFD. */ + addrs->other[i].sectindex = sect->index; + } + else + { + warning (_("section %s not found in %s"), addrs->other[i].name, + bfd_get_filename (abfd)); + addrs->other[i].addr = 0; + } + } + else + addrs->other[i].addr = lower_offset; } +} + +/* Parse the user's idea of an offset for dynamic linking, into our idea + of how to represent it for fast symbol reading. This is the default + version of the sym_fns.sym_offsets function for symbol readers that + don't need to do anything special. It allocates a section_offsets table + for the objectfile OBJFILE and stuffs ADDR into all of the offsets. */ + +void +default_symfile_offsets (struct objfile *objfile, + struct section_addr_info *addrs) +{ + objfile->num_sections = bfd_count_sections (objfile->obfd); + objfile->section_offsets = (struct section_offsets *) + obstack_alloc (&objfile->objfile_obstack, + SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)); + relative_addr_info_to_section_offsets (objfile->section_offsets, + objfile->num_sections, addrs); /* For relocatable files, all loadable sections will start at zero. The zero is meaningless, so try to pick arbitrary addresses such @@ -803,65 +870,8 @@ syms_from_objfile (struct objfile *objfile, We no longer warn if the lowest section is not a text segment (as happens for the PA64 port. */ - if (!mainline && addrs && addrs->other[0].name) - { - asection *lower_sect; - asection *sect; - CORE_ADDR lower_offset; - int i; - - /* Find lowest loadable section to be used as starting point for - continguous sections. FIXME!! won't work without call to find - .text first, but this assumes text is lowest section. */ - lower_sect = bfd_get_section_by_name (objfile->obfd, ".text"); - if (lower_sect == NULL) - bfd_map_over_sections (objfile->obfd, find_lowest_section, - &lower_sect); - if (lower_sect == NULL) - { - warning (_("no loadable sections found in added symbol-file %s"), - objfile->name); - lower_offset = 0; - } - else - lower_offset = bfd_section_vma (objfile->obfd, lower_sect); - - /* Calculate offsets for the loadable sections. - FIXME! Sections must be in order of increasing loadable section - so that contiguous sections can use the lower-offset!!! - - Adjust offsets if the segments are not contiguous. - If the section is contiguous, its offset should be set to - the offset of the highest loadable section lower than it - (the loadable section directly below it in memory). - this_offset = lower_offset = lower_addr - lower_orig_addr */ - - for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++) - { - if (addrs->other[i].addr != 0) - { - sect = bfd_get_section_by_name (objfile->obfd, - addrs->other[i].name); - if (sect) - { - addrs->other[i].addr - -= bfd_section_vma (objfile->obfd, sect); - lower_offset = addrs->other[i].addr; - /* This is the index used by BFD. */ - addrs->other[i].sectindex = sect->index ; - } - else - { - warning (_("section %s not found in %s"), - addrs->other[i].name, - objfile->name); - addrs->other[i].addr = 0; - } - } - else - addrs->other[i].addr = lower_offset; - } - } + if (addrs && addrs->other[0].name) + addr_info_make_relative (addrs, objfile->obfd); /* Initialize symbol reading routines for this objfile, allow complaints to appear for this new file, and record how verbose to be, then do the @@ -886,7 +896,7 @@ syms_from_objfile (struct objfile *objfile, init_objfile_sect_indices (objfile); } - (*objfile->sf->sym_read) (objfile, mainline); + (*objfile->sf->sym_read) (objfile, add_flags); /* Discard cleanups as symbol reading was successful. */ @@ -947,8 +957,6 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, { struct objfile *objfile; struct partial_symtab *psymtab; - char *debugfile = NULL; - struct section_addr_info *orig_addrs = NULL; struct cleanup *my_cleanups; const char *name = bfd_get_filename (abfd); const int from_tty = add_flags & SYMFILE_VERBOSE; @@ -967,12 +975,6 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, objfile = allocate_objfile (abfd, flags); discard_cleanups (my_cleanups); - if (addrs) - { - orig_addrs = copy_section_addr_info (addrs); - make_cleanup_free_section_addr_info (orig_addrs); - } - /* We either created a new mapped symbol table, mapped an existing symbol table file which has not had initial symbol reading performed, or need to read an unmapped symbol table. */ @@ -1012,33 +1014,6 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, } } - /* If the file has its own symbol tables it has no separate debug info. - `.dynsym'/`.symtab' go to MSYMBOLS, `.debug_info' goes to SYMTABS/PSYMTABS. - `.gnu_debuglink' may no longer be present with `.note.gnu.build-id'. */ - if (objfile->psymtabs == NULL) - debugfile = find_separate_debug_file (objfile); - if (debugfile) - { - if (addrs != NULL) - { - objfile->separate_debug_objfile - = symbol_file_add (debugfile, add_flags, orig_addrs, flags); - } - else - { - objfile->separate_debug_objfile - = symbol_file_add (debugfile, add_flags, NULL, flags); - } - objfile->separate_debug_objfile->separate_debug_objfile_backlink - = objfile; - - /* Put the separate debug object before the normal one, this is so that - usage of the ALL_OBJFILES_SAFE macro will stay safe. */ - put_objfile_before (objfile->separate_debug_objfile, objfile); - - xfree (debugfile); - } - if ((from_tty || info_verbose) && !objfile_has_symbols (objfile)) { @@ -1076,6 +1051,31 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, return (objfile); } +/* Add BFD as a separate debug file for OBJFILE. */ + +void +symbol_file_add_separate (bfd *bfd, int symfile_flags, struct objfile *objfile) +{ + struct objfile *new_objfile; + struct section_addr_info *sap; + struct cleanup *my_cleanup; + + /* Create section_addr_info. We can't directly use offsets from OBJFILE + because sections of BFD may not match sections of OBJFILE and because + vma may have been modified by tools such as prelink. */ + sap = build_section_addr_info_from_objfile (objfile); + my_cleanup = make_cleanup_free_section_addr_info (sap); + + new_objfile = symbol_file_add_with_addrs_or_offsets + (bfd, symfile_flags, + sap, NULL, 0, + objfile->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW + | OBJF_USERLOADED)); + + do_cleanups (my_cleanup); + + add_separate_debug_objfile (new_objfile, objfile); +} /* Process the symbol file ABFD, as either the main file or as a dynamically loaded file. @@ -1154,127 +1154,6 @@ symbol_file_clear (int from_tty) printf_unfiltered (_("No symbol file now.\n")); } -struct build_id - { - size_t size; - gdb_byte data[1]; - }; - -/* Locate NT_GNU_BUILD_ID from ABFD and return its content. */ - -static struct build_id * -build_id_bfd_get (bfd *abfd) -{ - struct build_id *retval; - - if (!bfd_check_format (abfd, bfd_object) - || bfd_get_flavour (abfd) != bfd_target_elf_flavour - || elf_tdata (abfd)->build_id == NULL) - return NULL; - - retval = xmalloc (sizeof *retval - 1 + elf_tdata (abfd)->build_id_size); - retval->size = elf_tdata (abfd)->build_id_size; - memcpy (retval->data, elf_tdata (abfd)->build_id, retval->size); - - return retval; -} - -/* Return if FILENAME has NT_GNU_BUILD_ID matching the CHECK value. */ - -static int -build_id_verify (const char *filename, struct build_id *check) -{ - bfd *abfd; - struct build_id *found = NULL; - int retval = 0; - - /* We expect to be silent on the non-existing files. */ - if (remote_filename_p (filename)) - abfd = remote_bfd_open (filename, gnutarget); - else - abfd = bfd_openr (filename, gnutarget); - if (abfd == NULL) - return 0; - - found = build_id_bfd_get (abfd); - - if (found == NULL) - warning (_("File \"%s\" has no build-id, file skipped"), filename); - else if (found->size != check->size - || memcmp (found->data, check->data, found->size) != 0) - warning (_("File \"%s\" has a different build-id, file skipped"), filename); - else - retval = 1; - - if (!bfd_close (abfd)) - warning (_("cannot close \"%s\": %s"), filename, - bfd_errmsg (bfd_get_error ())); - - xfree (found); - - return retval; -} - -static char * -build_id_to_debug_filename (struct build_id *build_id) -{ - char *link, *debugdir, *retval = NULL; - - /* DEBUG_FILE_DIRECTORY/.build-id/ab/cdef */ - link = alloca (strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1 - + 2 * build_id->size + (sizeof ".debug" - 1) + 1); - - /* Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will - cause "/.build-id/..." lookups. */ - - debugdir = debug_file_directory; - do - { - char *s, *debugdir_end; - gdb_byte *data = build_id->data; - size_t size = build_id->size; - - while (*debugdir == DIRNAME_SEPARATOR) - debugdir++; - - debugdir_end = strchr (debugdir, DIRNAME_SEPARATOR); - if (debugdir_end == NULL) - debugdir_end = &debugdir[strlen (debugdir)]; - - memcpy (link, debugdir, debugdir_end - debugdir); - s = &link[debugdir_end - debugdir]; - s += sprintf (s, "/.build-id/"); - if (size > 0) - { - size--; - s += sprintf (s, "%02x", (unsigned) *data++); - } - if (size > 0) - *s++ = '/'; - while (size-- > 0) - s += sprintf (s, "%02x", (unsigned) *data++); - strcpy (s, ".debug"); - - /* lrealpath() is expensive even for the usually non-existent files. */ - if (access (link, F_OK) == 0) - retval = lrealpath (link); - - if (retval != NULL && !build_id_verify (retval, build_id)) - { - xfree (retval); - retval = NULL; - } - - if (retval != NULL) - break; - - debugdir = debugdir_end; - } - while (*debugdir != 0); - - return retval; -} - static char * get_debug_link_info (struct objfile *objfile, unsigned long *crc32_out) { @@ -1308,21 +1187,48 @@ get_debug_link_info (struct objfile *objfile, unsigned long *crc32_out) static int separate_debug_file_exists (const char *name, unsigned long crc, - const char *parent_name) + struct objfile *parent_objfile) { unsigned long file_crc = 0; bfd *abfd; gdb_byte buffer[8*1024]; int count; + struct stat parent_stat, abfd_stat; - if (remote_filename_p (name)) - abfd = remote_bfd_open (name, gnutarget); - else - abfd = bfd_openr (name, gnutarget); + /* Find a separate debug info file as if symbols would be present in + PARENT_OBJFILE itself this function would not be called. .gnu_debuglink + section can contain just the basename of PARENT_OBJFILE without any + ".debug" suffix as "/usr/lib/debug/path/to/file" is a separate tree where + the separate debug infos with the same basename can exist. */ + + if (strcmp (name, parent_objfile->name) == 0) + return 0; + + abfd = bfd_open_maybe_remote (name); if (!abfd) return 0; + /* Verify symlinks were not the cause of strcmp name difference above. + + Some operating systems, e.g. Windows, do not provide a meaningful + st_ino; they always set it to zero. (Windows does provide a + meaningful st_dev.) Do not indicate a duplicate library in that + case. While there is no guarantee that a system that provides + meaningful inode numbers will never set st_ino to zero, this is + merely an optimization, so we do not need to worry about false + negatives. */ + + if (bfd_stat (abfd, &abfd_stat) == 0 + && bfd_stat (parent_objfile->obfd, &parent_stat) == 0 + && abfd_stat.st_dev == parent_stat.st_dev + && abfd_stat.st_ino == parent_stat.st_ino + && abfd_stat.st_ino != 0) + { + bfd_close (abfd); + return 0; + } + while ((count = bfd_bread (buffer, sizeof (buffer), abfd)) > 0) file_crc = gnu_debuglink_crc32 (file_crc, buffer, count); @@ -1332,7 +1238,7 @@ separate_debug_file_exists (const char *name, unsigned long crc, { warning (_("the debug information found in \"%s\"" " does not match \"%s\" (CRC mismatch).\n"), - name, parent_name); + name, parent_objfile->name); return 0; } @@ -1353,8 +1259,8 @@ The directory where separate debug symbols are searched for is \"%s\".\n"), #define DEBUG_SUBDIRECTORY ".debug" #endif -static char * -find_separate_debug_file (struct objfile *objfile) +char * +find_separate_debug_file_by_debuglink (struct objfile *objfile) { asection *sect; char *basename, *name_copy, *debugdir; @@ -1364,25 +1270,6 @@ find_separate_debug_file (struct objfile *objfile) bfd_size_type debuglink_size; unsigned long crc32; int i; - struct build_id *build_id; - - build_id = build_id_bfd_get (objfile->obfd); - if (build_id != NULL) - { - char *build_id_name; - - build_id_name = build_id_to_debug_filename (build_id); - xfree (build_id); - /* Prevent looping on a stripped .debug file. */ - if (build_id_name != NULL && strcmp (build_id_name, objfile->name) == 0) - { - warning (_("\"%s\": separate debug info file has no debug info"), - build_id_name); - xfree (build_id_name); - } - else if (build_id_name != NULL) - return build_id_name; - } basename = get_debug_link_info (objfile, &crc32); @@ -1422,7 +1309,7 @@ find_separate_debug_file (struct objfile *objfile) strcpy (debugfile, dir); strcat (debugfile, basename); - if (separate_debug_file_exists (debugfile, crc32, objfile->name)) + if (separate_debug_file_exists (debugfile, crc32, objfile)) goto cleanup_return_debugfile; /* Then try in the subdirectory named DEBUG_SUBDIRECTORY. */ @@ -1431,7 +1318,7 @@ find_separate_debug_file (struct objfile *objfile) strcat (debugfile, "/"); strcat (debugfile, basename); - if (separate_debug_file_exists (debugfile, crc32, objfile->name)) + if (separate_debug_file_exists (debugfile, crc32, objfile)) goto cleanup_return_debugfile; /* Then try in the global debugfile directories. @@ -1457,7 +1344,7 @@ find_separate_debug_file (struct objfile *objfile) strcat (debugfile, dir); strcat (debugfile, basename); - if (separate_debug_file_exists (debugfile, crc32, objfile->name)) + if (separate_debug_file_exists (debugfile, crc32, objfile)) goto cleanup_return_debugfile; /* If the file is in the sysroot, try using its base path in the @@ -1472,7 +1359,7 @@ find_separate_debug_file (struct objfile *objfile) strcat (debugfile, "/"); strcat (debugfile, basename); - if (separate_debug_file_exists (debugfile, crc32, objfile->name)) + if (separate_debug_file_exists (debugfile, crc32, objfile)) goto cleanup_return_debugfile; } @@ -1578,6 +1465,19 @@ set_initial_language (void) } } +/* If NAME is a remote name open the file using remote protocol, otherwise + open it normally. */ + +bfd * +bfd_open_maybe_remote (const char *name) +{ + if (remote_filename_p (name)) + return remote_bfd_open (name, gnutarget); + else + return bfd_openr (name, gnutarget); +} + + /* Open the file specified by NAME and hand it off to BFD for preliminary analysis. Return a newly initialized bfd *, which includes a newly malloc'd` copy of NAME (tilde-expanded and made @@ -2290,201 +2190,208 @@ reread_symbols (void) for (objfile = object_files; objfile; objfile = objfile->next) { - if (objfile->obfd) - { + /* solib-sunos.c creates one objfile with obfd. */ + if (objfile->obfd == NULL) + continue; + + /* Separate debug objfiles are handled in the main objfile. */ + if (objfile->separate_debug_objfile_backlink) + continue; + #ifdef DEPRECATED_IBM6000_TARGET - /* If this object is from a shared library, then you should - stat on the library name, not member name. */ + /* If this object is from a shared library, then you should + stat on the library name, not member name. */ - if (objfile->obfd->my_archive) - res = stat (objfile->obfd->my_archive->filename, &new_statbuf); - else + if (objfile->obfd->my_archive) + res = stat (objfile->obfd->my_archive->filename, &new_statbuf); + else #endif - res = stat (objfile->name, &new_statbuf); - if (res != 0) + res = stat (objfile->name, &new_statbuf); + if (res != 0) + { + /* FIXME, should use print_sys_errmsg but it's not filtered. */ + printf_unfiltered (_("`%s' has disappeared; keeping its symbols.\n"), + objfile->name); + continue; + } + new_modtime = new_statbuf.st_mtime; + if (new_modtime != objfile->mtime) + { + struct cleanup *old_cleanups; + struct section_offsets *offsets; + int num_offsets; + char *obfd_filename; + + printf_unfiltered (_("`%s' has changed; re-reading symbols.\n"), + objfile->name); + + /* There are various functions like symbol_file_add, + symfile_bfd_open, syms_from_objfile, etc., which might + appear to do what we want. But they have various other + effects which we *don't* want. So we just do stuff + ourselves. We don't worry about mapped files (for one thing, + any mapped file will be out of date). */ + + /* If we get an error, blow away this objfile (not sure if + that is the correct response for things like shared + libraries). */ + old_cleanups = make_cleanup_free_objfile (objfile); + /* We need to do this whenever any symbols go away. */ + make_cleanup (clear_symtab_users_cleanup, 0 /*ignore*/); + + if (exec_bfd != NULL && strcmp (bfd_get_filename (objfile->obfd), + bfd_get_filename (exec_bfd)) == 0) + { + /* Reload EXEC_BFD without asking anything. */ + + exec_file_attach (bfd_get_filename (objfile->obfd), 0); + } + + /* Clean up any state BFD has sitting around. We don't need + to close the descriptor but BFD lacks a way of closing the + BFD without closing the descriptor. */ + obfd_filename = bfd_get_filename (objfile->obfd); + if (!bfd_close (objfile->obfd)) + error (_("Can't close BFD for %s: %s"), objfile->name, + bfd_errmsg (bfd_get_error ())); + objfile->obfd = bfd_open_maybe_remote (obfd_filename); + if (objfile->obfd == NULL) + error (_("Can't open %s to read symbols."), objfile->name); + else + objfile->obfd = gdb_bfd_ref (objfile->obfd); + /* bfd_openr sets cacheable to true, which is what we want. */ + if (!bfd_check_format (objfile->obfd, bfd_object)) + error (_("Can't read symbols from %s: %s."), objfile->name, + bfd_errmsg (bfd_get_error ())); + + /* Save the offsets, we will nuke them with the rest of the + objfile_obstack. */ + num_offsets = objfile->num_sections; + offsets = ((struct section_offsets *) + alloca (SIZEOF_N_SECTION_OFFSETS (num_offsets))); + memcpy (offsets, objfile->section_offsets, + SIZEOF_N_SECTION_OFFSETS (num_offsets)); + + /* Remove any references to this objfile in the global + value lists. */ + preserve_values (objfile); + + /* Nuke all the state that we will re-read. Much of the following + code which sets things to NULL really is necessary to tell + other parts of GDB that there is nothing currently there. + + Try to keep the freeing order compatible with free_objfile. */ + + if (objfile->sf != NULL) + { + (*objfile->sf->sym_finish) (objfile); + } + + clear_objfile_data (objfile); + + /* Free the separate debug objfiles. It will be + automatically recreated by sym_read. */ + free_objfile_separate_debug (objfile); + + /* FIXME: Do we have to free a whole linked list, or is this + enough? */ + if (objfile->global_psymbols.list) + xfree (objfile->global_psymbols.list); + memset (&objfile->global_psymbols, 0, + sizeof (objfile->global_psymbols)); + if (objfile->static_psymbols.list) + xfree (objfile->static_psymbols.list); + memset (&objfile->static_psymbols, 0, + sizeof (objfile->static_psymbols)); + + /* Free the obstacks for non-reusable objfiles */ + bcache_xfree (objfile->psymbol_cache); + objfile->psymbol_cache = bcache_xmalloc (); + bcache_xfree (objfile->macro_cache); + objfile->macro_cache = bcache_xmalloc (); + bcache_xfree (objfile->filename_cache); + objfile->filename_cache = bcache_xmalloc (); + if (objfile->demangled_names_hash != NULL) + { + htab_delete (objfile->demangled_names_hash); + objfile->demangled_names_hash = NULL; + } + obstack_free (&objfile->objfile_obstack, 0); + objfile->sections = NULL; + objfile->symtabs = NULL; + objfile->psymtabs = NULL; + objfile->psymtabs_addrmap = NULL; + objfile->free_psymtabs = NULL; + objfile->cp_namespace_symtab = NULL; + objfile->msymbols = NULL; + objfile->deprecated_sym_private = NULL; + objfile->minimal_symbol_count = 0; + memset (&objfile->msymbol_hash, 0, + sizeof (objfile->msymbol_hash)); + memset (&objfile->msymbol_demangled_hash, 0, + sizeof (objfile->msymbol_demangled_hash)); + + objfile->psymbol_cache = bcache_xmalloc (); + objfile->macro_cache = bcache_xmalloc (); + objfile->filename_cache = bcache_xmalloc (); + /* obstack_init also initializes the obstack so it is + empty. We could use obstack_specify_allocation but + gdb_obstack.h specifies the alloc/dealloc + functions. */ + obstack_init (&objfile->objfile_obstack); + if (build_objfile_section_table (objfile)) { - /* FIXME, should use print_sys_errmsg but it's not filtered. */ - printf_unfiltered (_("`%s' has disappeared; keeping its symbols.\n"), - objfile->name); - continue; + error (_("Can't find the file sections in `%s': %s"), + objfile->name, bfd_errmsg (bfd_get_error ())); } - new_modtime = new_statbuf.st_mtime; - if (new_modtime != objfile->mtime) + terminate_minimal_symbol_table (objfile); + + /* We use the same section offsets as from last time. I'm not + sure whether that is always correct for shared libraries. */ + objfile->section_offsets = (struct section_offsets *) + obstack_alloc (&objfile->objfile_obstack, + SIZEOF_N_SECTION_OFFSETS (num_offsets)); + memcpy (objfile->section_offsets, offsets, + SIZEOF_N_SECTION_OFFSETS (num_offsets)); + objfile->num_sections = num_offsets; + + /* What the hell is sym_new_init for, anyway? The concept of + distinguishing between the main file and additional files + in this way seems rather dubious. */ + if (objfile == symfile_objfile) + { + (*objfile->sf->sym_new_init) (objfile); + } + + (*objfile->sf->sym_init) (objfile); + clear_complaints (&symfile_complaints, 1, 1); + /* Do not set flags as this is safe and we don't want to be + verbose. */ + (*objfile->sf->sym_read) (objfile, 0); + if (!objfile_has_symbols (objfile)) { - struct cleanup *old_cleanups; - struct section_offsets *offsets; - int num_offsets; - char *obfd_filename; - - printf_unfiltered (_("`%s' has changed; re-reading symbols.\n"), - objfile->name); - - /* There are various functions like symbol_file_add, - symfile_bfd_open, syms_from_objfile, etc., which might - appear to do what we want. But they have various other - effects which we *don't* want. So we just do stuff - ourselves. We don't worry about mapped files (for one thing, - any mapped file will be out of date). */ - - /* If we get an error, blow away this objfile (not sure if - that is the correct response for things like shared - libraries). */ - old_cleanups = make_cleanup_free_objfile (objfile); - /* We need to do this whenever any symbols go away. */ - make_cleanup (clear_symtab_users_cleanup, 0 /*ignore*/); - - if (exec_bfd != NULL && strcmp (bfd_get_filename (objfile->obfd), - bfd_get_filename (exec_bfd)) == 0) - { - /* Reload EXEC_BFD without asking anything. */ - - exec_file_attach (bfd_get_filename (objfile->obfd), 0); - } - - /* Clean up any state BFD has sitting around. We don't need - to close the descriptor but BFD lacks a way of closing the - BFD without closing the descriptor. */ - obfd_filename = bfd_get_filename (objfile->obfd); - if (!bfd_close (objfile->obfd)) - error (_("Can't close BFD for %s: %s"), objfile->name, - bfd_errmsg (bfd_get_error ())); - if (remote_filename_p (obfd_filename)) - objfile->obfd = remote_bfd_open (obfd_filename, gnutarget); - else - objfile->obfd = bfd_openr (obfd_filename, gnutarget); - if (objfile->obfd == NULL) - error (_("Can't open %s to read symbols."), objfile->name); - else - objfile->obfd = gdb_bfd_ref (objfile->obfd); - /* bfd_openr sets cacheable to true, which is what we want. */ - if (!bfd_check_format (objfile->obfd, bfd_object)) - error (_("Can't read symbols from %s: %s."), objfile->name, - bfd_errmsg (bfd_get_error ())); - - /* Save the offsets, we will nuke them with the rest of the - objfile_obstack. */ - num_offsets = objfile->num_sections; - offsets = ((struct section_offsets *) - alloca (SIZEOF_N_SECTION_OFFSETS (num_offsets))); - memcpy (offsets, objfile->section_offsets, - SIZEOF_N_SECTION_OFFSETS (num_offsets)); - - /* Remove any references to this objfile in the global - value lists. */ - preserve_values (objfile); - - /* Nuke all the state that we will re-read. Much of the following - code which sets things to NULL really is necessary to tell - other parts of GDB that there is nothing currently there. - - Try to keep the freeing order compatible with free_objfile. */ - - if (objfile->sf != NULL) - { - (*objfile->sf->sym_finish) (objfile); - } - - clear_objfile_data (objfile); - - /* FIXME: Do we have to free a whole linked list, or is this - enough? */ - if (objfile->global_psymbols.list) - xfree (objfile->global_psymbols.list); - memset (&objfile->global_psymbols, 0, - sizeof (objfile->global_psymbols)); - if (objfile->static_psymbols.list) - xfree (objfile->static_psymbols.list); - memset (&objfile->static_psymbols, 0, - sizeof (objfile->static_psymbols)); - - /* Free the obstacks for non-reusable objfiles */ - bcache_xfree (objfile->psymbol_cache); - objfile->psymbol_cache = bcache_xmalloc (); - bcache_xfree (objfile->macro_cache); - objfile->macro_cache = bcache_xmalloc (); - if (objfile->demangled_names_hash != NULL) - { - htab_delete (objfile->demangled_names_hash); - objfile->demangled_names_hash = NULL; - } - obstack_free (&objfile->objfile_obstack, 0); - objfile->sections = NULL; - objfile->symtabs = NULL; - objfile->psymtabs = NULL; - objfile->psymtabs_addrmap = NULL; - objfile->free_psymtabs = NULL; - objfile->cp_namespace_symtab = NULL; - objfile->msymbols = NULL; - objfile->deprecated_sym_private = NULL; - objfile->minimal_symbol_count = 0; - memset (&objfile->msymbol_hash, 0, - sizeof (objfile->msymbol_hash)); - memset (&objfile->msymbol_demangled_hash, 0, - sizeof (objfile->msymbol_demangled_hash)); - - objfile->psymbol_cache = bcache_xmalloc (); - objfile->macro_cache = bcache_xmalloc (); - /* obstack_init also initializes the obstack so it is - empty. We could use obstack_specify_allocation but - gdb_obstack.h specifies the alloc/dealloc - functions. */ - obstack_init (&objfile->objfile_obstack); - if (build_objfile_section_table (objfile)) - { - error (_("Can't find the file sections in `%s': %s"), - objfile->name, bfd_errmsg (bfd_get_error ())); - } - terminate_minimal_symbol_table (objfile); - - /* We use the same section offsets as from last time. I'm not - sure whether that is always correct for shared libraries. */ - objfile->section_offsets = (struct section_offsets *) - obstack_alloc (&objfile->objfile_obstack, - SIZEOF_N_SECTION_OFFSETS (num_offsets)); - memcpy (objfile->section_offsets, offsets, - SIZEOF_N_SECTION_OFFSETS (num_offsets)); - objfile->num_sections = num_offsets; - - /* What the hell is sym_new_init for, anyway? The concept of - distinguishing between the main file and additional files - in this way seems rather dubious. */ - if (objfile == symfile_objfile) - { - (*objfile->sf->sym_new_init) (objfile); - } - - (*objfile->sf->sym_init) (objfile); - clear_complaints (&symfile_complaints, 1, 1); - /* The "mainline" parameter is a hideous hack; I think leaving it - zero is OK since dbxread.c also does what it needs to do if - objfile->global_psymbols.size is 0. */ - (*objfile->sf->sym_read) (objfile, 0); - if (!objfile_has_symbols (objfile)) - { - wrap_here (""); - printf_unfiltered (_("(no debugging symbols found)\n")); - wrap_here (""); - } - - /* We're done reading the symbol file; finish off complaints. */ - clear_complaints (&symfile_complaints, 0, 1); - - /* Getting new symbols may change our opinion about what is - frameless. */ - - reinit_frame_cache (); - - /* Discard cleanups as symbol reading was successful. */ - discard_cleanups (old_cleanups); - - /* If the mtime has changed between the time we set new_modtime - and now, we *want* this to be out of date, so don't call stat - again now. */ - objfile->mtime = new_modtime; - reread_one = 1; - reread_separate_symbols (objfile); - init_entry_point_info (objfile); + wrap_here (""); + printf_unfiltered (_("(no debugging symbols found)\n")); + wrap_here (""); } + + /* We're done reading the symbol file; finish off complaints. */ + clear_complaints (&symfile_complaints, 0, 1); + + /* Getting new symbols may change our opinion about what is + frameless. */ + + reinit_frame_cache (); + + /* Discard cleanups as symbol reading was successful. */ + discard_cleanups (old_cleanups); + + /* If the mtime has changed between the time we set new_modtime + and now, we *want* this to be out of date, so don't call stat + again now. */ + objfile->mtime = new_modtime; + reread_one = 1; + init_entry_point_info (objfile); } } @@ -2499,73 +2406,6 @@ reread_symbols (void) observer_notify_executable_changed (); } } - - -/* Handle separate debug info for OBJFILE, which has just been - re-read: - - If we had separate debug info before, but now we don't, get rid - of the separated objfile. - - If we didn't have separated debug info before, but now we do, - read in the new separated debug info file. - - If the debug link points to a different file, toss the old one - and read the new one. - This function does *not* handle the case where objfile is still - using the same separate debug info file, but that file's timestamp - has changed. That case should be handled by the loop in - reread_symbols already. */ -static void -reread_separate_symbols (struct objfile *objfile) -{ - char *debug_file; - unsigned long crc32; - - /* Does the updated objfile's debug info live in a - separate file? */ - debug_file = find_separate_debug_file (objfile); - - if (objfile->separate_debug_objfile) - { - /* There are two cases where we need to get rid of - the old separated debug info objfile: - - if the new primary objfile doesn't have - separated debug info, or - - if the new primary objfile has separate debug - info, but it's under a different filename. - - If the old and new objfiles both have separate - debug info, under the same filename, then we're - okay --- if the separated file's contents have - changed, we will have caught that when we - visited it in this function's outermost - loop. */ - if (! debug_file - || strcmp (debug_file, objfile->separate_debug_objfile->name) != 0) - free_objfile (objfile->separate_debug_objfile); - } - - /* If the new objfile has separate debug info, and we - haven't loaded it already, do so now. */ - if (debug_file - && ! objfile->separate_debug_objfile) - { - /* Use the same section offset table as objfile itself. - Preserve the flags from objfile that make sense. */ - objfile->separate_debug_objfile - = (symbol_file_add_with_addrs_or_offsets - (symfile_bfd_open (debug_file), - info_verbose ? SYMFILE_VERBOSE : 0, - 0, /* No addr table. */ - objfile->section_offsets, objfile->num_sections, - objfile->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW - | OBJF_USERLOADED))); - objfile->separate_debug_objfile->separate_debug_objfile_backlink - = objfile; - } - if (debug_file) - xfree (debug_file); -} - - @@ -2735,7 +2575,6 @@ deduce_language_from_filename (char *filename) symtab->dirname symtab->free_code symtab->free_ptr - possibly free_named_symtabs (symtab->filename); */ struct symtab * @@ -2746,12 +2585,11 @@ allocate_symtab (char *filename, struct objfile *objfile) symtab = (struct symtab *) obstack_alloc (&objfile->objfile_obstack, sizeof (struct symtab)); memset (symtab, 0, sizeof (*symtab)); - symtab->filename = obsavestring (filename, strlen (filename), - &objfile->objfile_obstack); + symtab->filename = (char *) bcache (filename, strlen (filename) + 1, + objfile->filename_cache); symtab->fullname = NULL; symtab->language = deduce_language_from_filename (filename); - symtab->debugformat = obsavestring ("unknown", 7, - &objfile->objfile_obstack); + symtab->debugformat = "unknown"; /* Hook it to the objfile it comes from */ @@ -2763,7 +2601,7 @@ allocate_symtab (char *filename, struct objfile *objfile) } struct partial_symtab * -allocate_psymtab (char *filename, struct objfile *objfile) +allocate_psymtab (const char *filename, struct objfile *objfile) { struct partial_symtab *psymtab; @@ -2778,8 +2616,8 @@ allocate_psymtab (char *filename, struct objfile *objfile) sizeof (struct partial_symtab)); memset (psymtab, 0, sizeof (struct partial_symtab)); - psymtab->filename = obsavestring (filename, strlen (filename), - &objfile->objfile_obstack); + psymtab->filename = (char *) bcache (filename, strlen (filename) + 1, + objfile->filename_cache); psymtab->symtab = NULL; /* Prepend it to the psymtab list for the objfile it belongs to. @@ -2865,210 +2703,6 @@ clear_symtab_users_cleanup (void *ignore) { clear_symtab_users (); } - -/* clear_symtab_users_once: - - This function is run after symbol reading, or from a cleanup. - If an old symbol table was obsoleted, the old symbol table - has been blown away, but the other GDB data structures that may - reference it have not yet been cleared or re-directed. (The old - symtab was zapped, and the cleanup queued, in free_named_symtab() - below.) - - This function can be queued N times as a cleanup, or called - directly; it will do all the work the first time, and then will be a - no-op until the next time it is queued. This works by bumping a - counter at queueing time. Much later when the cleanup is run, or at - the end of symbol processing (in case the cleanup is discarded), if - the queued count is greater than the "done-count", we do the work - and set the done-count to the queued count. If the queued count is - less than or equal to the done-count, we just ignore the call. This - is needed because reading a single .o file will often replace many - symtabs (one per .h file, for example), and we don't want to reset - the breakpoints N times in the user's face. - - The reason we both queue a cleanup, and call it directly after symbol - reading, is because the cleanup protects us in case of errors, but is - discarded if symbol reading is successful. */ - -#if 0 -/* FIXME: As free_named_symtabs is currently a big noop this function - is no longer needed. */ -static void clear_symtab_users_once (void); - -static int clear_symtab_users_queued; -static int clear_symtab_users_done; - -static void -clear_symtab_users_once (void) -{ - /* Enforce once-per-`do_cleanups'-semantics */ - if (clear_symtab_users_queued <= clear_symtab_users_done) - return; - clear_symtab_users_done = clear_symtab_users_queued; - - clear_symtab_users (); -} -#endif - -/* Delete the specified psymtab, and any others that reference it. */ - -static void -cashier_psymtab (struct partial_symtab *pst) -{ - struct partial_symtab *ps, *pprev = NULL; - int i; - - /* Find its previous psymtab in the chain */ - for (ps = pst->objfile->psymtabs; ps; ps = ps->next) - { - if (ps == pst) - break; - pprev = ps; - } - - if (ps) - { - /* Unhook it from the chain. */ - if (ps == pst->objfile->psymtabs) - pst->objfile->psymtabs = ps->next; - else - pprev->next = ps->next; - - /* FIXME, we can't conveniently deallocate the entries in the - partial_symbol lists (global_psymbols/static_psymbols) that - this psymtab points to. These just take up space until all - the psymtabs are reclaimed. Ditto the dependencies list and - filename, which are all in the objfile_obstack. */ - - /* We need to cashier any psymtab that has this one as a dependency... */ - again: - for (ps = pst->objfile->psymtabs; ps; ps = ps->next) - { - for (i = 0; i < ps->number_of_dependencies; i++) - { - if (ps->dependencies[i] == pst) - { - cashier_psymtab (ps); - goto again; /* Must restart, chain has been munged. */ - } - } - } - } -} - -/* If a symtab or psymtab for filename NAME is found, free it along - with any dependent breakpoints, displays, etc. - Used when loading new versions of object modules with the "add-file" - command. This is only called on the top-level symtab or psymtab's name; - it is not called for subsidiary files such as .h files. - - Return value is 1 if we blew away the environment, 0 if not. - FIXME. The return value appears to never be used. - - FIXME. I think this is not the best way to do this. We should - work on being gentler to the environment while still cleaning up - all stray pointers into the freed symtab. */ - -int -free_named_symtabs (char *name) -{ -#if 0 - /* FIXME: With the new method of each objfile having it's own - psymtab list, this function needs serious rethinking. In particular, - why was it ever necessary to toss psymtabs with specific compilation - unit filenames, as opposed to all psymtabs from a particular symbol - file? -- fnf - Well, the answer is that some systems permit reloading of particular - compilation units. We want to blow away any old info about these - compilation units, regardless of which objfiles they arrived in. --gnu. */ - - struct symtab *s; - struct symtab *prev; - struct partial_symtab *ps; - struct blockvector *bv; - int blewit = 0; - - /* We only wack things if the symbol-reload switch is set. */ - if (!symbol_reloading) - return 0; - - /* Some symbol formats have trouble providing file names... */ - if (name == 0 || *name == '\0') - return 0; - - /* Look for a psymtab with the specified name. */ - -again2: - for (ps = partial_symtab_list; ps; ps = ps->next) - { - if (strcmp (name, ps->filename) == 0) - { - cashier_psymtab (ps); /* Blow it away...and its little dog, too. */ - goto again2; /* Must restart, chain has been munged */ - } - } - - /* Look for a symtab with the specified name. */ - - for (s = symtab_list; s; s = s->next) - { - if (strcmp (name, s->filename) == 0) - break; - prev = s; - } - - if (s) - { - if (s == symtab_list) - symtab_list = s->next; - else - prev->next = s->next; - - /* For now, queue a delete for all breakpoints, displays, etc., whether - or not they depend on the symtab being freed. This should be - changed so that only those data structures affected are deleted. */ - - /* But don't delete anything if the symtab is empty. - This test is necessary due to a bug in "dbxread.c" that - causes empty symtabs to be created for N_SO symbols that - contain the pathname of the object file. (This problem - has been fixed in GDB 3.9x). */ - - bv = BLOCKVECTOR (s); - if (BLOCKVECTOR_NBLOCKS (bv) > 2 - || BLOCK_NSYMS (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)) - || BLOCK_NSYMS (BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK))) - { - complaint (&symfile_complaints, _("Replacing old symbols for `%s'"), - name); - clear_symtab_users_queued++; - make_cleanup (clear_symtab_users_once, 0); - blewit = 1; - } - else - complaint (&symfile_complaints, _("Empty symbol table found for `%s'"), - name); - - free_symtab (s); - } - else - { - /* It is still possible that some breakpoints will be affected - even though no symtab was found, since the file might have - been compiled without debugging, and hence not be associated - with a symtab. In order to handle this correctly, we would need - to keep a list of text address ranges for undebuggable files. - For now, we do nothing, since this is a fairly obscure case. */ - ; - } - - /* FIXME, what about the minimal symbol table? */ - return blewit; -#else - return (0); -#endif -} /* Allocate and partially fill a partial symtab. It will be completely filled at the end of the symbol list. @@ -3077,7 +2711,8 @@ again2: struct partial_symtab * start_psymtab_common (struct objfile *objfile, - struct section_offsets *section_offsets, char *filename, + struct section_offsets *section_offsets, + const char *filename, CORE_ADDR textlow, struct partial_symbol **global_syms, struct partial_symbol **static_syms) { @@ -3099,26 +2734,23 @@ start_psymtab_common (struct objfile *objfile, different domain (or address) is possible and correct. */ static const struct partial_symbol * -add_psymbol_to_bcache (char *name, int namelength, domain_enum domain, +add_psymbol_to_bcache (char *name, int namelength, int copy_name, + domain_enum domain, enum address_class class, long val, /* Value as a long */ CORE_ADDR coreaddr, /* Value as a CORE_ADDR */ enum language language, struct objfile *objfile, int *added) { - char *buf = name; /* psymbol is static so that there will be no uninitialized gaps in the structure which might contain random data, causing cache misses in bcache. */ static struct partial_symbol psymbol; - - if (name[namelength] != '\0') - { - buf = alloca (namelength + 1); - /* Create local copy of the partial symbol */ - memcpy (buf, name, namelength); - buf[namelength] = '\0'; - } + + /* However, we must ensure that the entire 'value' field has been + zeroed before assigning to it, because an assignment may not + write the entire field. */ + memset (&psymbol.ginfo.value, 0, sizeof (psymbol.ginfo.value)); /* val and coreaddr are mutually exclusive, one of them *will* be zero */ if (val != 0) { @@ -3133,7 +2765,7 @@ add_psymbol_to_bcache (char *name, int namelength, domain_enum domain, PSYMBOL_DOMAIN (&psymbol) = domain; PSYMBOL_CLASS (&psymbol) = class; - SYMBOL_SET_NAMES (&psymbol, buf, namelength, objfile); + SYMBOL_SET_NAMES (&psymbol, name, namelength, copy_name, objfile); /* Stash the partial symbol away in the cache */ return bcache_full (&psymbol, sizeof (struct partial_symbol), @@ -3170,7 +2802,8 @@ append_psymbol_to_list (struct psymbol_allocation_list *list, cache. */ const struct partial_symbol * -add_psymbol_to_list (char *name, int namelength, domain_enum domain, +add_psymbol_to_list (char *name, int namelength, int copy_name, + domain_enum domain, enum address_class class, struct psymbol_allocation_list *list, long val, /* Value as a long */ @@ -3182,7 +2815,7 @@ add_psymbol_to_list (char *name, int namelength, domain_enum domain, int added; /* Stash the partial symbol away in the cache */ - psym = add_psymbol_to_bcache (name, namelength, domain, class, + psym = add_psymbol_to_bcache (name, namelength, copy_name, domain, class, val, coreaddr, language, objfile, &added); /* Do not duplicate global partial symbols. */ @@ -3994,6 +3627,27 @@ symfile_dummy_outputs (bfd *abfd, asection *sectp, void *dummy) sectp->output_offset = 0; } +/* Default implementation for sym_relocate. */ + + +bfd_byte * +default_symfile_relocate (struct objfile *objfile, asection *sectp, + bfd_byte *buf) +{ + bfd *abfd = objfile->obfd; + + /* We're only interested in sections with relocation + information. */ + if ((sectp->flags & SEC_RELOC) == 0) + return NULL; + + /* We will handle section offsets properly elsewhere, so relocate as if + all sections begin at 0. */ + bfd_map_over_sections (abfd, symfile_dummy_outputs, NULL); + + return bfd_simple_get_relocated_section_contents (abfd, sectp, buf, NULL); +} + /* Relocate the contents of a debug section SECTP in ABFD. The contents are stored in BUF if it is non-NULL, or returned in a malloc'd buffer otherwise. @@ -4009,18 +3663,12 @@ symfile_dummy_outputs (bfd *abfd, asection *sectp, void *dummy) debug section. */ bfd_byte * -symfile_relocate_debug_section (bfd *abfd, asection *sectp, bfd_byte *buf) +symfile_relocate_debug_section (struct objfile *objfile, + asection *sectp, bfd_byte *buf) { - /* We're only interested in sections with relocation - information. */ - if ((sectp->flags & SEC_RELOC) == 0) - return NULL; + gdb_assert (objfile->sf->sym_relocate); - /* We will handle section offsets properly elsewhere, so relocate as if - all sections begin at 0. */ - bfd_map_over_sections (abfd, symfile_dummy_outputs, NULL); - - return bfd_simple_get_relocated_section_contents (abfd, sectp, buf, NULL); + return (*objfile->sf->sym_relocate) (objfile, sectp, buf); } struct symfile_segment_data *