X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fsymfile.c;h=d94db48dfa1e7e5324eb7933a1cb266491f74218;hb=635c7e8a0521e985921ea3189ab2db5e05fdd41f;hp=5ed25913cb6ff4316a60413647a2645124d93c4b;hpb=529480d058a17512a1cff27c682d340f8ea3ab33;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/symfile.c b/gdb/symfile.c index 5ed25913cb..d94db48dfa 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -1,6 +1,6 @@ /* Generic symbol file reading for the GNU debugger, GDB. - Copyright (C) 1990-2013 Free Software Foundation, Inc. + Copyright (C) 1990-2014 Free Software Foundation, Inc. Contributed by Cygnus Support, using pieces from other GDB modules. @@ -60,8 +60,8 @@ #include #include -#include "gdb_string.h" -#include "gdb_stat.h" +#include +#include #include #include #include @@ -87,14 +87,10 @@ int readnow_symbol_files; /* Read full symbols immediately. */ static void load_command (char *, int); -static void symbol_file_add_main_1 (char *args, int from_tty, int flags); +static void symbol_file_add_main_1 (const char *args, int from_tty, int flags); static void add_symbol_file_command (char *, int); -bfd *symfile_bfd_open (char *); - -int get_section_index (struct objfile *, char *); - static const struct sym_fns *find_sym_fns (bfd *); static void decrement_reading_symtab (void *); @@ -134,10 +130,32 @@ void _initialize_symfile (void); calls add_symtab_fns() to register information on each format it is prepared to read. */ -typedef const struct sym_fns *sym_fns_ptr; -DEF_VEC_P (sym_fns_ptr); +typedef struct +{ + /* BFD flavour that we handle. */ + enum bfd_flavour sym_flavour; + + /* The "vtable" of symbol functions. */ + const struct sym_fns *sym_fns; +} registered_sym_fns; + +DEF_VEC_O (registered_sym_fns); -static VEC (sym_fns_ptr) *symtab_fns = NULL; +static VEC (registered_sym_fns) *symtab_fns = NULL; + +/* Values for "set print symbol-loading". */ + +const char print_symbol_loading_off[] = "off"; +const char print_symbol_loading_brief[] = "brief"; +const char print_symbol_loading_full[] = "full"; +static const char *print_symbol_loading_enums[] = +{ + print_symbol_loading_off, + print_symbol_loading_brief, + print_symbol_loading_full, + NULL +}; +static const char *print_symbol_loading = print_symbol_loading_full; /* If non-zero, shared library symbols will be added automatically when the inferior is created, new libraries are loaded, or when @@ -152,6 +170,31 @@ static VEC (sym_fns_ptr) *symtab_fns = NULL; int auto_solib_add = 1; +/* Return non-zero if symbol-loading messages should be printed. + FROM_TTY is the standard from_tty argument to gdb commands. + If EXEC is non-zero the messages are for the executable. + Otherwise, messages are for shared libraries. + If FULL is non-zero then the caller is printing a detailed message. + E.g., the message includes the shared library name. + Otherwise, the caller is printing a brief "summary" message. */ + +int +print_symbol_loading_p (int from_tty, int exec, int full) +{ + if (!from_tty && !info_verbose) + return 0; + + if (exec) + { + /* We don't check FULL for executables, there are few such + messages, therefore brief == full. */ + return print_symbol_loading != print_symbol_loading_off; + } + if (full) + return print_symbol_loading == print_symbol_loading_full; + return print_symbol_loading == print_symbol_loading_brief; +} + /* True if we are reading a symbol table. */ int currently_reading_symtab = 0; @@ -160,14 +203,17 @@ static void decrement_reading_symtab (void *dummy) { currently_reading_symtab--; + gdb_assert (currently_reading_symtab >= 0); } /* Increment currently_reading_symtab and return a cleanup that can be used to decrement it. */ + struct cleanup * increment_reading_symtab (void) { ++currently_reading_symtab; + gdb_assert (currently_reading_symtab > 0); return make_cleanup (decrement_reading_symtab, NULL); } @@ -197,7 +243,9 @@ find_lowest_section (bfd *abfd, asection *sect, void *obj) *lowest = sect; } -/* Create a new section_addr_info, with room for NUM_SECTIONS. */ +/* Create a new section_addr_info, with room for NUM_SECTIONS. The + new object's 'num_sections' field is set to 0; it must be updated + by the caller. */ struct section_addr_info * alloc_section_addr_info (size_t num_sections) @@ -209,7 +257,6 @@ alloc_section_addr_info (size_t num_sections) + sizeof (struct other_sections) * (num_sections - 1)); sap = (struct section_addr_info *) xmalloc (size); memset (sap, 0, size); - sap->num_sections = num_sections; return sap; } @@ -229,18 +276,21 @@ build_section_addr_info_from_section_table (const struct target_section *start, for (stp = start, oidx = 0; stp != end; stp++) { - if (bfd_get_section_flags (stp->bfd, - stp->the_bfd_section) & (SEC_ALLOC | SEC_LOAD) + struct bfd_section *asect = stp->the_bfd_section; + bfd *abfd = asect->owner; + + if (bfd_get_section_flags (abfd, asect) & (SEC_ALLOC | SEC_LOAD) && oidx < end - start) { sap->other[oidx].addr = stp->addr; - sap->other[oidx].name - = xstrdup (bfd_section_name (stp->bfd, stp->the_bfd_section)); - sap->other[oidx].sectindex = stp->the_bfd_section->index; + sap->other[oidx].name = xstrdup (bfd_section_name (abfd, asect)); + sap->other[oidx].sectindex = gdb_bfd_section_index (abfd, asect); oidx++; } } + sap->num_sections = oidx; + return sap; } @@ -259,9 +309,12 @@ build_section_addr_info_from_bfd (bfd *abfd) { sap->other[i].addr = bfd_get_section_vma (abfd, sec); sap->other[i].name = xstrdup (bfd_get_section_name (abfd, sec)); - sap->other[i].sectindex = sec->index; + sap->other[i].sectindex = gdb_bfd_section_index (abfd, sec); i++; } + + sap->num_sections = i; + return sap; } @@ -277,7 +330,7 @@ build_section_addr_info_from_objfile (const struct objfile *objfile) gdb_assert (objfile->num_sections == bfd_count_sections (objfile->obfd)); */ sap = build_section_addr_info_from_bfd (objfile->obfd); - for (i = 0; i < sap->num_sections && sap->other[i].name; i++) + for (i = 0; i < sap->num_sections; i++) { int sectindex = sap->other[i].sectindex; @@ -294,13 +347,12 @@ free_section_addr_info (struct section_addr_info *sap) int idx; for (idx = 0; idx < sap->num_sections; idx++) - if (sap->other[idx].name) - xfree (sap->other[idx].name); + xfree (sap->other[idx].name); xfree (sap); } - /* Initialize OBJFILE's sect_index_* members. */ + static void init_objfile_sect_indices (struct objfile *objfile) { @@ -384,7 +436,7 @@ place_section (bfd *abfd, asection *sect, void *obj) return; /* If the user specified an offset, honor it. */ - if (offsets[sect->index] != 0) + if (offsets[gdb_bfd_section_index (abfd, sect)] != 0) return; /* Otherwise, let's try to find a place for the section. */ @@ -428,7 +480,7 @@ place_section (bfd *abfd, asection *sect, void *obj) } while (!done); - offsets[sect->index] = start_addr; + offsets[gdb_bfd_section_index (abfd, sect)] = start_addr; arg->lowest = start_addr + bfd_get_section_size (sect); } @@ -439,16 +491,16 @@ place_section (bfd *abfd, asection *sect, void *obj) void relative_addr_info_to_section_offsets (struct section_offsets *section_offsets, int num_sections, - struct section_addr_info *addrs) + const struct section_addr_info *addrs) { int i; memset (section_offsets, 0, SIZEOF_N_SECTION_OFFSETS (num_sections)); /* Now calculate offsets for section that were specified by the caller. */ - for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++) + for (i = 0; i < addrs->num_sections; i++) { - struct other_sections *osp; + const struct other_sections *osp; osp = &addrs->other[i]; if (osp->sectindex == -1) @@ -506,7 +558,7 @@ addrs_section_sort (struct section_addr_info *addrs) /* `+ 1' for the NULL terminator. */ array = xmalloc (sizeof (*array) * (addrs->num_sections + 1)); - for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++) + for (i = 0; i < addrs->num_sections; i++) array[i] = &addrs->other[i]; array[i] = NULL; @@ -605,7 +657,7 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd) (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++) + for (i = 0; i < addrs->num_sections; i++) { struct other_sections *sect = addrs_to_abfd_addrs[i]; @@ -670,9 +722,9 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd) void default_symfile_offsets (struct objfile *objfile, - struct section_addr_info *addrs) + const struct section_addr_info *addrs) { - objfile->num_sections = bfd_count_sections (objfile->obfd); + objfile->num_sections = gdb_bfd_count_sections (objfile->obfd); objfile->section_offsets = (struct section_offsets *) obstack_alloc (&objfile->objfile_obstack, SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)); @@ -752,7 +804,6 @@ default_symfile_offsets (struct objfile *objfile, init_objfile_sect_indices (objfile); } - /* Divide the file into segments, which are individual relocatable units. This is the default version of the sym_fns.sym_segments function for symbol readers that do not have an explicit representation of segments. @@ -787,13 +838,13 @@ default_symfile_segments (bfd *abfd) low = bfd_get_section_vma (abfd, sect); high = low + bfd_get_section_size (sect); - data = XZALLOC (struct symfile_segment_data); + data = XCNEW (struct symfile_segment_data); data->num_segments = 1; - data->segment_bases = XCALLOC (1, CORE_ADDR); - data->segment_sizes = XCALLOC (1, CORE_ADDR); + data->segment_bases = XCNEW (CORE_ADDR); + data->segment_sizes = XCNEW (CORE_ADDR); num_sections = bfd_count_sections (abfd); - data->segment_info = XCALLOC (num_sections, int); + data->segment_info = XCNEWVEC (int, num_sections); for (i = 0, sect = abfd->sections; sect != NULL; i++, sect = sect->next) { @@ -824,6 +875,7 @@ static void read_symbols (struct objfile *objfile, int add_flags) { (*objfile->sf->sym_read) (objfile, add_flags); + objfile->per_bfd->minsyms_read = 1; /* find_separate_debug_file_in_section should be called only if there is single binary with no existing separate debug info file. */ @@ -835,7 +887,14 @@ read_symbols (struct objfile *objfile, int add_flags) struct cleanup *cleanup = make_cleanup_bfd_unref (abfd); if (abfd != NULL) - symbol_file_add_separate (abfd, add_flags, objfile); + { + /* find_separate_debug_file_in_section uses the same filename for the + virtual section-as-bfd like the bfd filename containing the + section. Therefore use also non-canonical name form for the same + file containing the section. */ + symbol_file_add_separate (abfd, objfile->original_name, add_flags, + objfile); + } do_cleanups (cleanup); } @@ -848,6 +907,12 @@ read_symbols (struct objfile *objfile, int add_flags) static void init_entry_point_info (struct objfile *objfile) { + struct entry_info *ei = &objfile->per_bfd->ei; + + if (ei->initialized) + return; + ei->initialized = 1; + /* Save startup file's range of PC addresses to help blockframe.c decide where the bottom of the stack is. */ @@ -855,8 +920,8 @@ init_entry_point_info (struct objfile *objfile) { /* Executable file -- record its entry point so we'll recognize the startup file because it contains the entry point. */ - objfile->ei.entry_point = bfd_get_start_address (objfile->obfd); - objfile->ei.entry_point_p = 1; + ei->entry_point = bfd_get_start_address (objfile->obfd); + ei->entry_point_p = 1; } else if (bfd_get_file_flags (objfile->obfd) & DYNAMIC && bfd_get_start_address (objfile->obfd) != 0) @@ -864,30 +929,51 @@ init_entry_point_info (struct objfile *objfile) /* Some shared libraries may have entry points set and be runnable. There's no clear way to indicate this, so just check for values other than zero. */ - objfile->ei.entry_point = bfd_get_start_address (objfile->obfd); - objfile->ei.entry_point_p = 1; + ei->entry_point = bfd_get_start_address (objfile->obfd); + ei->entry_point_p = 1; } else { /* Examination of non-executable.o files. Short-circuit this stuff. */ - objfile->ei.entry_point_p = 0; + ei->entry_point_p = 0; } - if (objfile->ei.entry_point_p) + if (ei->entry_point_p) { - CORE_ADDR entry_point = objfile->ei.entry_point; + struct obj_section *osect; + CORE_ADDR entry_point = ei->entry_point; + int found; /* Make certain that the address points at real code, and not a function descriptor. */ entry_point - = gdbarch_convert_from_func_ptr_addr (objfile->gdbarch, + = gdbarch_convert_from_func_ptr_addr (get_objfile_arch (objfile), entry_point, ¤t_target); /* Remove any ISA markers, so that this matches entries in the symbol table. */ - objfile->ei.entry_point - = gdbarch_addr_bits_remove (objfile->gdbarch, entry_point); + ei->entry_point + = gdbarch_addr_bits_remove (get_objfile_arch (objfile), entry_point); + + found = 0; + ALL_OBJFILE_OSECTIONS (objfile, osect) + { + struct bfd_section *sect = osect->the_bfd_section; + + if (entry_point >= bfd_get_section_vma (objfile->obfd, sect) + && entry_point < (bfd_get_section_vma (objfile->obfd, sect) + + bfd_get_section_size (sect))) + { + ei->the_bfd_section_index + = gdb_bfd_section_index (objfile->obfd, sect); + found = 1; + break; + } + } + + if (!found) + ei->the_bfd_section_index = SECT_OFF_TEXT (objfile); } } @@ -907,17 +993,6 @@ init_entry_point_info (struct objfile *objfile) into an offset from the section VMA's as it appears in the object file, and then call the file's sym_offsets function to convert this into a format-specific offset table --- a `struct section_offsets'. - If ADDRS is non-zero, OFFSETS must be zero. - - OFFSETS is a table of section offsets already in the right - format-specific representation. NUM_OFFSETS is the number of - elements present in OFFSETS->offsets. If OFFSETS is non-zero, we - assume this is the proper table the call to sym_offsets described - above would produce. Instead of calling sym_offsets, we just dump - it right into objfile->section_offsets. (When we're re-reading - symbols from an objfile, we don't have the original load address - list any more; all we have is the section offset table.) If - OFFSETS is non-zero, ADDRS must be zero. ADD_FLAGS encodes verbosity level, whether this is main symbol or an extra symbol file such as dynamically loaded code, and wether @@ -926,24 +1001,20 @@ init_entry_point_info (struct objfile *objfile) static void syms_from_objfile_1 (struct objfile *objfile, struct section_addr_info *addrs, - struct section_offsets *offsets, - int num_offsets, int add_flags) { struct section_addr_info *local_addr = NULL; struct cleanup *old_chain; const int mainline = add_flags & SYMFILE_MAINLINE; - gdb_assert (! (addrs && offsets)); - - objfile->sf = find_sym_fns (objfile->obfd); + objfile_set_sym_fns (objfile, find_sym_fns (objfile->obfd)); if (objfile->sf == NULL) { /* No symbols to load, but we still need to make sure that the section_offsets table is allocated. */ - int num_sections = bfd_count_sections (objfile->obfd); - size_t size = SIZEOF_N_SECTION_OFFSETS (num_offsets); + int num_sections = gdb_bfd_count_sections (objfile->obfd); + size_t size = SIZEOF_N_SECTION_OFFSETS (num_sections); objfile->num_sections = num_sections; objfile->section_offsets @@ -956,19 +1027,16 @@ syms_from_objfile_1 (struct objfile *objfile, if an error occurs during symbol reading. */ old_chain = make_cleanup_free_objfile (objfile); - /* If ADDRS and OFFSETS are both NULL, put together a dummy address - list. We now establish the convention that an addr of zero means + /* If ADDRS is NULL, put together a dummy address list. + We now establish the convention that an addr of zero means no load address was specified. */ - if (! addrs && ! offsets) + if (! addrs) { - local_addr - = alloc_section_addr_info (bfd_count_sections (objfile->obfd)); + local_addr = alloc_section_addr_info (1); make_cleanup (xfree, local_addr); addrs = local_addr; } - /* Now either addrs or offsets is non-zero. */ - if (mainline) { /* We will modify the main symbol table, make sure that all its users @@ -997,7 +1065,7 @@ syms_from_objfile_1 (struct objfile *objfile, We no longer warn if the lowest section is not a text segment (as happens for the PA64 port. */ - if (addrs && addrs->other[0].name) + if (addrs->num_sections > 0) addr_info_make_relative (addrs, objfile->obfd); /* Initialize symbol reading routines for this objfile, allow complaints to @@ -1007,21 +1075,7 @@ syms_from_objfile_1 (struct objfile *objfile, (*objfile->sf->sym_init) (objfile); clear_complaints (&symfile_complaints, 1, add_flags & SYMFILE_VERBOSE); - if (addrs) - (*objfile->sf->sym_offsets) (objfile, addrs); - else - { - size_t size = SIZEOF_N_SECTION_OFFSETS (num_offsets); - - /* Just copy in the offset table directly as given to us. */ - objfile->num_sections = num_offsets; - objfile->section_offsets - = ((struct section_offsets *) - obstack_alloc (&objfile->objfile_obstack, size)); - memcpy (objfile->section_offsets, offsets, size); - - init_objfile_sect_indices (objfile); - } + (*objfile->sf->sym_offsets) (objfile, addrs); read_symbols (objfile, add_flags); @@ -1034,14 +1088,12 @@ syms_from_objfile_1 (struct objfile *objfile, /* Same as syms_from_objfile_1, but also initializes the objfile entry-point info. */ -void +static void syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs, - struct section_offsets *offsets, - int num_offsets, int add_flags) { - syms_from_objfile_1 (objfile, addrs, offsets, num_offsets, add_flags); + syms_from_objfile_1 (objfile, addrs, add_flags); init_entry_point_info (objfile); } @@ -1077,11 +1129,12 @@ new_symfile_objfile (struct objfile *objfile, int add_flags) ABFD is a BFD already open on the file, as from symfile_bfd_open. A new reference is acquired by this function. + For NAME description see allocate_objfile's definition. + ADD_FLAGS encodes verbosity, whether this is main symbol file or extra, such as dynamically loaded code, and what to do with breakpoins. - ADDRS, OFFSETS, and NUM_OFFSETS are as described for - syms_from_objfile, above. + ADDRS is as described for syms_from_objfile_1, above. ADDRS is ignored when SYMFILE_MAINLINE bit is set in ADD_FLAGS. PARENT is the original objfile if ABFD is a separate debug info file. @@ -1091,18 +1144,14 @@ new_symfile_objfile (struct objfile *objfile, int add_flags) Upon failure, jumps back to command level (never returns). */ static struct objfile * -symbol_file_add_with_addrs_or_offsets (bfd *abfd, - int add_flags, - struct section_addr_info *addrs, - struct section_offsets *offsets, - int num_offsets, - int flags, struct objfile *parent) +symbol_file_add_with_addrs (bfd *abfd, const char *name, int add_flags, + struct section_addr_info *addrs, + int flags, struct objfile *parent) { struct objfile *objfile; - const char *name = bfd_get_filename (abfd); const int from_tty = add_flags & SYMFILE_VERBOSE; const int mainline = add_flags & SYMFILE_MAINLINE; - const int should_print = ((from_tty || info_verbose) + const int should_print = (print_symbol_loading_p (from_tty, mainline, 1) && (readnow_symbol_files || (add_flags & SYMFILE_NO_READ) == 0)); @@ -1121,7 +1170,8 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, && !query (_("Load new symbol table from \"%s\"? "), name)) error (_("Not confirmed.")); - objfile = allocate_objfile (abfd, flags | (mainline ? OBJF_MAINLINE : 0)); + objfile = allocate_objfile (abfd, name, + flags | (mainline ? OBJF_MAINLINE : 0)); if (parent) add_separate_debug_objfile (objfile, parent); @@ -1140,8 +1190,7 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, gdb_flush (gdb_stdout); } } - syms_from_objfile (objfile, addrs, offsets, num_offsets, - add_flags); + syms_from_objfile (objfile, addrs, add_flags); /* We now have at least a partial symbol table. Check to see if the user requested that all symbols be read on initial access via either @@ -1195,10 +1244,12 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, return (objfile); } -/* Add BFD as a separate debug file for OBJFILE. */ +/* Add BFD as a separate debug file for OBJFILE. For NAME description + see allocate_objfile's definition. */ void -symbol_file_add_separate (bfd *bfd, int symfile_flags, struct objfile *objfile) +symbol_file_add_separate (bfd *bfd, const char *name, int symfile_flags, + struct objfile *objfile) { struct objfile *new_objfile; struct section_addr_info *sap; @@ -1210,9 +1261,8 @@ symbol_file_add_separate (bfd *bfd, int symfile_flags, struct objfile *objfile) 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, + new_objfile = symbol_file_add_with_addrs + (bfd, name, symfile_flags, sap, objfile->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW | OBJF_USERLOADED), objfile); @@ -1222,36 +1272,33 @@ symbol_file_add_separate (bfd *bfd, int symfile_flags, struct objfile *objfile) /* Process the symbol file ABFD, as either the main file or as a dynamically loaded file. + See symbol_file_add_with_addrs's comments for details. */ - See symbol_file_add_with_addrs_or_offsets's comments for - details. */ struct objfile * -symbol_file_add_from_bfd (bfd *abfd, int add_flags, +symbol_file_add_from_bfd (bfd *abfd, const char *name, int add_flags, struct section_addr_info *addrs, int flags, struct objfile *parent) { - return symbol_file_add_with_addrs_or_offsets (abfd, add_flags, addrs, 0, 0, - flags, parent); + return symbol_file_add_with_addrs (abfd, name, add_flags, addrs, flags, + parent); } - /* Process a symbol file, as either the main file or as a dynamically - loaded file. See symbol_file_add_with_addrs_or_offsets's comments - for details. */ + loaded file. See symbol_file_add_with_addrs's comments for details. */ + struct objfile * -symbol_file_add (char *name, int add_flags, struct section_addr_info *addrs, - int flags) +symbol_file_add (const char *name, int add_flags, + struct section_addr_info *addrs, int flags) { bfd *bfd = symfile_bfd_open (name); struct cleanup *cleanup = make_cleanup_bfd_unref (bfd); struct objfile *objf; - objf = symbol_file_add_from_bfd (bfd, add_flags, addrs, flags, NULL); + objf = symbol_file_add_from_bfd (bfd, name, add_flags, addrs, flags, NULL); do_cleanups (cleanup); return objf; } - /* Call symbol_file_add() with default values and update whatever is affected by the loading of a new main(). Used when the file is supplied in the gdb command line @@ -1261,13 +1308,13 @@ symbol_file_add (char *name, int add_flags, struct section_addr_info *addrs, command itself. */ void -symbol_file_add_main (char *args, int from_tty) +symbol_file_add_main (const char *args, int from_tty) { symbol_file_add_main_1 (args, from_tty, 0); } static void -symbol_file_add_main_1 (char *args, int from_tty, int flags) +symbol_file_add_main_1 (const char *args, int from_tty, int flags) { const int add_flags = (current_inferior ()->symfile_flags | SYMFILE_MAINLINE | (from_tty ? SYMFILE_VERBOSE : 0)); @@ -1289,7 +1336,7 @@ symbol_file_clear (int from_tty) && from_tty && (symfile_objfile ? !query (_("Discard symbol table from `%s'? "), - symfile_objfile->name) + objfile_name (symfile_objfile)) : !query (_("Discard symbol table? ")))) error (_("Not confirmed.")); @@ -1304,73 +1351,6 @@ symbol_file_clear (int from_tty) printf_unfiltered (_("No symbol file now.\n")); } -static char * -get_debug_link_info (struct objfile *objfile, unsigned long *crc32_out) -{ - asection *sect; - bfd_size_type debuglink_size; - unsigned long crc32; - char *contents; - int crc_offset; - - sect = bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink"); - - if (sect == NULL) - return NULL; - - debuglink_size = bfd_section_size (objfile->obfd, sect); - - contents = xmalloc (debuglink_size); - bfd_get_section_contents (objfile->obfd, sect, contents, - (file_ptr)0, (bfd_size_type)debuglink_size); - - /* Crc value is stored after the filename, aligned up to 4 bytes. */ - crc_offset = strlen (contents) + 1; - crc_offset = (crc_offset + 3) & ~3; - - crc32 = bfd_get_32 (objfile->obfd, (bfd_byte *) (contents + crc_offset)); - - *crc32_out = crc32; - return contents; -} - -/* Return 32-bit CRC for ABFD. If successful store it to *FILE_CRC_RETURN and - return 1. Otherwise print a warning and return 0. ABFD seek position is - not preserved. */ - -static int -get_file_crc (bfd *abfd, unsigned long *file_crc_return) -{ - unsigned long file_crc = 0; - - if (bfd_seek (abfd, 0, SEEK_SET) != 0) - { - warning (_("Problem reading \"%s\" for CRC: %s"), - bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ())); - return 0; - } - - for (;;) - { - gdb_byte buffer[8 * 1024]; - bfd_size_type count; - - count = bfd_bread (buffer, sizeof (buffer), abfd); - if (count == (bfd_size_type) -1) - { - warning (_("Problem reading \"%s\" for CRC: %s"), - bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ())); - return 0; - } - if (count == 0) - break; - file_crc = bfd_calc_gnu_debuglink_crc32 (file_crc, buffer, count); - } - - *file_crc_return = file_crc; - return 1; -} - static int separate_debug_file_exists (const char *name, unsigned long crc, struct objfile *parent_objfile) @@ -1387,7 +1367,7 @@ separate_debug_file_exists (const char *name, unsigned long crc, ".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 (filename_cmp (name, parent_objfile->name) == 0) + if (filename_cmp (name, objfile_name (parent_objfile)) == 0) return 0; abfd = gdb_bfd_open_maybe_remote (name); @@ -1420,7 +1400,7 @@ separate_debug_file_exists (const char *name, unsigned long crc, else verified_as_different = 0; - file_crc_p = get_file_crc (abfd, &file_crc); + file_crc_p = gdb_bfd_crc (abfd, &file_crc); gdb_bfd_unref (abfd); @@ -1429,22 +1409,22 @@ separate_debug_file_exists (const char *name, unsigned long crc, if (crc != file_crc) { + unsigned long parent_crc; + /* If one (or both) the files are accessed for example the via "remote:" gdbserver way it does not support the bfd_stat operation. Verify whether those two files are not the same manually. */ - if (!verified_as_different && !parent_objfile->crc32_p) + if (!verified_as_different) { - parent_objfile->crc32_p = get_file_crc (parent_objfile->obfd, - &parent_objfile->crc32); - if (!parent_objfile->crc32_p) + if (!gdb_bfd_crc (parent_objfile->obfd, &parent_crc)) return 0; } - if (verified_as_different || parent_objfile->crc32 != file_crc) + if (verified_as_different || parent_crc != file_crc) warning (_("the debug information found in \"%s\"" " does not match \"%s\" (CRC mismatch).\n"), - name, parent_objfile->name); + name, objfile_name (parent_objfile)); return 0; } @@ -1470,7 +1450,9 @@ show_debug_file_directory (struct ui_file *file, int from_tty, /* Find a separate debuginfo file for OBJFILE, using DIR as the directory where the original file resides (may not be the same as dirname(objfile->name) due to symlinks), and DEBUGLINK as the file we are - looking for. Returns the name of the debuginfo, of NULL. */ + looking for. CANON_DIR is the "realpath" form of DIR. + DIR must contain a trailing '/'. + Returns the path of the file with separate debug info, of NULL. */ static char * find_separate_debug_file (const char *dir, @@ -1529,7 +1511,10 @@ find_separate_debug_file (const char *dir, strcat (debugfile, debuglink); if (separate_debug_file_exists (debugfile, crc32, objfile)) - return debugfile; + { + do_cleanups (back_to); + return debugfile; + } /* If the file is in the sysroot, try using its base path in the global debugfile directory. */ @@ -1544,7 +1529,10 @@ find_separate_debug_file (const char *dir, strcat (debugfile, debuglink); if (separate_debug_file_exists (debugfile, crc32, objfile)) - return debugfile; + { + do_cleanups (back_to); + return debugfile; + } } } @@ -1553,7 +1541,7 @@ find_separate_debug_file (const char *dir, return NULL; } -/* Modify PATH to contain only "directory/" part of PATH. +/* Modify PATH to contain only "[/]directory/" part of PATH. If there were no directory separators in PATH, PATH will be empty string on return. */ @@ -1584,7 +1572,7 @@ find_separate_debug_file_by_debuglink (struct objfile *objfile) unsigned long crc32; struct cleanup *cleanups; - debuglink = get_debug_link_info (objfile, &crc32); + debuglink = bfd_get_debug_link_info (objfile->obfd, &crc32); if (debuglink == NULL) { @@ -1594,7 +1582,7 @@ find_separate_debug_file_by_debuglink (struct objfile *objfile) } cleanups = make_cleanup (xfree, debuglink); - dir = xstrdup (objfile->name); + dir = xstrdup (objfile_name (objfile)); make_cleanup (xfree, dir); terminate_after_last_dir_separator (dir); canon_dir = lrealpath (dir); @@ -1611,11 +1599,12 @@ find_separate_debug_file_by_debuglink (struct objfile *objfile) struct stat st_buf; - if (lstat (objfile->name, &st_buf) == 0 && S_ISLNK(st_buf.st_mode)) + if (lstat (objfile_name (objfile), &st_buf) == 0 + && S_ISLNK (st_buf.st_mode)) { char *symlink_dir; - symlink_dir = lrealpath (objfile->name); + symlink_dir = lrealpath (objfile_name (objfile)); if (symlink_dir != NULL) { make_cleanup (xfree, symlink_dir); @@ -1638,7 +1627,6 @@ find_separate_debug_file_by_debuglink (struct objfile *objfile) return debugfile; } - /* This is the symbol-file command. Read the file, analyze its symbols, and add a struct symtab to a symtab list. The syntax of the command is rather bizarre: @@ -1706,17 +1694,15 @@ symbol_file_command (char *args, int from_tty) void set_initial_language (void) { - enum language lang = language_unknown; + enum language lang = main_language (); - if (language_of_main != language_unknown) - lang = language_of_main; - else + if (lang == language_unknown) { - const char *filename; + char *name = main_name (); + struct symbol *sym = lookup_symbol (name, NULL, VAR_DOMAIN, NULL); - filename = find_main_filename (); - if (filename != NULL) - lang = deduce_language_from_filename (filename); + if (sym != NULL) + lang = SYMBOL_LANGUAGE (sym); } if (lang == language_unknown) @@ -1746,40 +1732,40 @@ gdb_bfd_open_maybe_remote (const char *name) return result; } - /* 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 absolute). In case of trouble, error() is called. */ bfd * -symfile_bfd_open (char *name) +symfile_bfd_open (const char *cname) { bfd *sym_bfd; int desc; - char *absolute_name; + char *name, *absolute_name; + struct cleanup *back_to; - if (remote_filename_p (name)) + if (remote_filename_p (cname)) { - sym_bfd = remote_bfd_open (name, gnutarget); + sym_bfd = remote_bfd_open (cname, gnutarget); if (!sym_bfd) - error (_("`%s': can't open to read symbols: %s."), name, + error (_("`%s': can't open to read symbols: %s."), cname, bfd_errmsg (bfd_get_error ())); if (!bfd_check_format (sym_bfd, bfd_object)) { make_cleanup_bfd_unref (sym_bfd); - error (_("`%s': can't read symbols: %s."), name, + error (_("`%s': can't read symbols: %s."), cname, bfd_errmsg (bfd_get_error ())); } return sym_bfd; } - name = tilde_expand (name); /* Returns 1st new malloc'd copy. */ + name = tilde_expand (cname); /* Returns 1st new malloc'd copy. */ /* Look down path for it, allocate 2nd new malloc'd copy. */ - desc = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, name, + desc = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, name, O_RDONLY | O_BINARY, &absolute_name); #if defined(__GO32__) || defined(_WIN32) || defined (__CYGWIN__) if (desc < 0) @@ -1787,8 +1773,8 @@ symfile_bfd_open (char *name) char *exename = alloca (strlen (name) + 5); strcat (strcpy (exename, name), ".exe"); - desc = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, exename, - O_RDONLY | O_BINARY, &absolute_name); + desc = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, + exename, O_RDONLY | O_BINARY, &absolute_name); } #endif if (desc < 0) @@ -1799,15 +1785,12 @@ symfile_bfd_open (char *name) xfree (name); name = absolute_name; - make_cleanup (xfree, name); + back_to = make_cleanup (xfree, name); sym_bfd = gdb_bfd_open (name, gnutarget, desc); if (!sym_bfd) - { - make_cleanup (xfree, name); - error (_("`%s': can't open to read symbols: %s."), name, - bfd_errmsg (bfd_get_error ())); - } + error (_("`%s': can't open to read symbols: %s."), name, + bfd_errmsg (bfd_get_error ())); bfd_set_cacheable (sym_bfd, 1); if (!bfd_check_format (sym_bfd, bfd_object)) @@ -1817,6 +1800,8 @@ symfile_bfd_open (char *name) bfd_errmsg (bfd_get_error ())); } + do_cleanups (back_to); + return sym_bfd; } @@ -1834,14 +1819,18 @@ get_section_index (struct objfile *objfile, char *section_name) return -1; } -/* Link SF into the global symtab_fns list. Called on startup by the - _initialize routine in each object file format reader, to register - information about each format the reader is prepared to handle. */ +/* Link SF into the global symtab_fns list. + FLAVOUR is the file format that SF handles. + Called on startup by the _initialize routine in each object file format + reader, to register information about each format the reader is prepared + to handle. */ void -add_symtab_fns (const struct sym_fns *sf) +add_symtab_fns (enum bfd_flavour flavour, const struct sym_fns *sf) { - VEC_safe_push (sym_fns_ptr, symtab_fns, sf); + registered_sym_fns fns = { flavour, sf }; + + VEC_safe_push (registered_sym_fns, symtab_fns, &fns); } /* Initialize OBJFILE to read symbols from its associated BFD. It @@ -1852,7 +1841,7 @@ add_symtab_fns (const struct sym_fns *sf) static const struct sym_fns * find_sym_fns (bfd *abfd) { - const struct sym_fns *sf; + registered_sym_fns *rsf; enum bfd_flavour our_flavour = bfd_get_flavour (abfd); int i; @@ -1861,9 +1850,9 @@ find_sym_fns (bfd *abfd) || our_flavour == bfd_target_tekhex_flavour) return NULL; /* No symbols. */ - for (i = 0; VEC_iterate (sym_fns_ptr, symtab_fns, i, sf); ++i) - if (our_flavour == sf->sym_flavour) - return sf; + for (i = 0; VEC_iterate (registered_sym_fns, symtab_fns, i, rsf); ++i) + if (our_flavour == rsf->sym_flavour) + return rsf->sym_fns; error (_("I'm sorry, Dave, I can't do that. Symbol format `%s' unknown."), bfd_get_target (abfd)); @@ -1875,6 +1864,8 @@ find_sym_fns (bfd *abfd) static void load_command (char *arg, int from_tty) { + struct cleanup *cleanup = make_cleanup (null_cleanup, NULL); + dont_repeat (); /* The user might be reloading because the binary has changed. Take @@ -1924,6 +1915,8 @@ load_command (char *arg, int from_tty) /* After re-loading the executable, we don't really know which overlays are mapped any more. */ overlay_cache_invalid = 1; + + do_cleanups (cleanup); } /* This version of "load" should be usable for any target. Currently @@ -2278,6 +2271,7 @@ add_symbol_file_command (char *args, int from_tty) int expecting_sec_name = 0; int expecting_sec_addr = 0; char **argv; + struct objfile *objf; struct sect_opt { @@ -2311,63 +2305,54 @@ add_symbol_file_command (char *args, int from_tty) filename = tilde_expand (arg); make_cleanup (xfree, filename); } + else if (argcnt == 1) + { + /* The second argument is always the text address at which + to load the program. */ + sect_opts[section_index].name = ".text"; + sect_opts[section_index].value = arg; + if (++section_index >= num_sect_opts) + { + num_sect_opts *= 2; + sect_opts = ((struct sect_opt *) + xrealloc (sect_opts, + num_sect_opts + * sizeof (struct sect_opt))); + } + } else - if (argcnt == 1) - { - /* The second argument is always the text address at which - to load the program. */ - sect_opts[section_index].name = ".text"; - sect_opts[section_index].value = arg; - if (++section_index >= num_sect_opts) - { - num_sect_opts *= 2; - sect_opts = ((struct sect_opt *) - xrealloc (sect_opts, - num_sect_opts - * sizeof (struct sect_opt))); - } - } - else - { - /* It's an option (starting with '-') or it's an argument - to an option. */ - - if (*arg == '-') - { - if (strcmp (arg, "-readnow") == 0) - flags |= OBJF_READNOW; - else if (strcmp (arg, "-s") == 0) - { - expecting_sec_name = 1; - expecting_sec_addr = 1; - } - } - else - { - if (expecting_sec_name) - { - sect_opts[section_index].name = arg; - expecting_sec_name = 0; - } - else - if (expecting_sec_addr) - { - sect_opts[section_index].value = arg; - expecting_sec_addr = 0; - if (++section_index >= num_sect_opts) - { - num_sect_opts *= 2; - sect_opts = ((struct sect_opt *) - xrealloc (sect_opts, - num_sect_opts - * sizeof (struct sect_opt))); - } - } - else - error (_("USAGE: add-symbol-file " - " [-readnow] [-s ]*")); - } - } + { + /* It's an option (starting with '-') or it's an argument + to an option. */ + if (expecting_sec_name) + { + sect_opts[section_index].name = arg; + expecting_sec_name = 0; + } + else if (expecting_sec_addr) + { + sect_opts[section_index].value = arg; + expecting_sec_addr = 0; + if (++section_index >= num_sect_opts) + { + num_sect_opts *= 2; + sect_opts = ((struct sect_opt *) + xrealloc (sect_opts, + num_sect_opts + * sizeof (struct sect_opt))); + } + } + else if (strcmp (arg, "-readnow") == 0) + flags |= OBJF_READNOW; + else if (strcmp (arg, "-s") == 0) + { + expecting_sec_name = 1; + expecting_sec_addr = 1; + } + else + error (_("USAGE: add-symbol-file " + " [-readnow] [-s ]*")); + } } /* This command takes at least two arguments. The first one is a @@ -2408,12 +2393,15 @@ add_symbol_file_command (char *args, int from_tty) At this point, we don't know what file type this is, so we can't determine what section names are valid. */ } + section_addrs->num_sections = sec_num; if (from_tty && (!query ("%s", ""))) error (_("Not confirmed.")); - symbol_file_add (filename, from_tty ? SYMFILE_VERBOSE : 0, - section_addrs, flags); + objf = symbol_file_add (filename, from_tty ? SYMFILE_VERBOSE : 0, + section_addrs, flags); + + add_target_sections_of_objfile (objf); /* Getting new symbols may change our opinion about what is frameless. */ @@ -2422,11 +2410,88 @@ add_symbol_file_command (char *args, int from_tty) } +/* This function removes a symbol file that was added via add-symbol-file. */ + +static void +remove_symbol_file_command (char *args, int from_tty) +{ + char **argv; + struct objfile *objf = NULL; + struct cleanup *my_cleanups; + struct program_space *pspace = current_program_space; + struct gdbarch *gdbarch = get_current_arch (); + + dont_repeat (); + + if (args == NULL) + error (_("remove-symbol-file: no symbol file provided")); + + my_cleanups = make_cleanup (null_cleanup, NULL); + + argv = gdb_buildargv (args); + + if (strcmp (argv[0], "-a") == 0) + { + /* Interpret the next argument as an address. */ + CORE_ADDR addr; + + if (argv[1] == NULL) + error (_("Missing address argument")); + + if (argv[2] != NULL) + error (_("Junk after %s"), argv[1]); + + addr = parse_and_eval_address (argv[1]); + + ALL_OBJFILES (objf) + { + if (objf != 0 + && objf->flags & OBJF_USERLOADED + && objf->pspace == pspace && is_addr_in_objfile (addr, objf)) + break; + } + } + else if (argv[0] != NULL) + { + /* Interpret the current argument as a file name. */ + char *filename; + + if (argv[1] != NULL) + error (_("Junk after %s"), argv[0]); + + filename = tilde_expand (argv[0]); + make_cleanup (xfree, filename); + + ALL_OBJFILES (objf) + { + if (objf != 0 + && objf->flags & OBJF_USERLOADED + && objf->pspace == pspace + && filename_cmp (filename, objfile_name (objf)) == 0) + break; + } + } + + if (objf == NULL) + error (_("No symbol file found")); + + if (from_tty + && !query (_("Remove symbol table from file \"%s\"? "), + objfile_name (objf))) + error (_("Not confirmed.")); + + free_objfile (objf); + clear_symtab_users (0); + + do_cleanups (my_cleanups); +} + typedef struct objfile *objfilep; DEF_VEC_P (objfilep); /* Re-read symbols if a symbol-file has changed. */ + void reread_symbols (void) { @@ -2447,7 +2512,6 @@ reread_symbols (void) for (objfile = object_files; objfile; objfile = objfile->next) { - /* solib-sunos.c creates one objfile with obfd. */ if (objfile->obfd == NULL) continue; @@ -2462,12 +2526,12 @@ reread_symbols (void) if (objfile->obfd->my_archive) res = stat (objfile->obfd->my_archive->filename, &new_statbuf); else - res = stat (objfile->name, &new_statbuf); + res = stat (objfile_name (objfile), &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); + objfile_name (objfile)); continue; } new_modtime = new_statbuf.st_mtime; @@ -2476,10 +2540,10 @@ reread_symbols (void) struct cleanup *old_cleanups; struct section_offsets *offsets; int num_offsets; - char *obfd_filename; + char *original_name; printf_unfiltered (_("`%s' has changed; re-reading symbols.\n"), - objfile->name); + objfile_name (objfile)); /* There are various functions like symbol_file_add, symfile_bfd_open, syms_from_objfile, etc., which might @@ -2530,6 +2594,7 @@ reread_symbols (void) /* Clean up any state BFD has sitting around. */ { struct bfd *obfd = objfile->obfd; + char *obfd_filename; obfd_filename = bfd_get_filename (objfile->obfd); /* Open the new BFD before freeing the old one, so that @@ -2546,10 +2611,12 @@ reread_symbols (void) gdb_bfd_unref (obfd); } - objfile->name = bfd_get_filename (objfile->obfd); + original_name = xstrdup (objfile->original_name); + make_cleanup (xfree, original_name); + /* 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, + error (_("Can't read symbols from %s: %s."), objfile_name (objfile), bfd_errmsg (bfd_get_error ())); /* Save the offsets, we will nuke them with the rest of the @@ -2574,11 +2641,6 @@ reread_symbols (void) /* Free the obstacks for non-reusable objfiles. */ psymbol_bcache_free (objfile->psymbol_cache); objfile->psymbol_cache = psymbol_bcache_init (); - 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; @@ -2586,19 +2648,27 @@ reread_symbols (void) objfile->psymtabs_addrmap = NULL; objfile->free_psymtabs = NULL; objfile->template_symbols = NULL; - objfile->msymbols = 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)); - - set_objfile_per_bfd (objfile); /* 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); + + /* set_objfile_per_bfd potentially allocates the per-bfd + data on the objfile's obstack (if sharing data across + multiple users is not possible), so it's important to + do it *after* the obstack has been initialized. */ + set_objfile_per_bfd (objfile); + + objfile->original_name = obstack_copy0 (&objfile->objfile_obstack, + original_name, + strlen (original_name)); + + /* Reset the sym_fns pointer. The ELF reader can change it + based on whether .gdb_index is present, and we need it to + start over. PR symtab/15885 */ + objfile_set_sym_fns (objfile, find_sym_fns (objfile->obfd)); + build_objfile_section_table (objfile); terminate_minimal_symbol_table (objfile); @@ -2677,7 +2747,6 @@ reread_symbols (void) } - typedef struct { char *ext; @@ -2872,8 +2941,8 @@ allocate_symtab (const char *filename, struct objfile *objfile) symtab = (struct symtab *) obstack_alloc (&objfile->objfile_obstack, sizeof (struct symtab)); memset (symtab, 0, sizeof (*symtab)); - symtab->filename = (char *) bcache (filename, strlen (filename) + 1, - objfile->per_bfd->filename_cache); + symtab->filename = bcache (filename, strlen (filename) + 1, + objfile->per_bfd->filename_cache); symtab->fullname = NULL; symtab->language = deduce_language_from_filename (filename); symtab->debugformat = "unknown"; @@ -2884,17 +2953,19 @@ allocate_symtab (const char *filename, struct objfile *objfile) symtab->next = objfile->symtabs; objfile->symtabs = symtab; - if (symtab_create_debug) + /* This can be very verbose with lots of headers. + Only print at higher debug levels. */ + if (symtab_create_debug >= 2) { /* Be a bit clever with debugging messages, and don't print objfile every time, only when it changes. */ static char *last_objfile_name = NULL; if (last_objfile_name == NULL - || strcmp (last_objfile_name, objfile->name) != 0) + || strcmp (last_objfile_name, objfile_name (objfile)) != 0) { xfree (last_objfile_name); - last_objfile_name = xstrdup (objfile->name); + last_objfile_name = xstrdup (objfile_name (objfile)); fprintf_unfiltered (gdb_stdlog, "Creating one or more symtabs for objfile %s ...\n", last_objfile_name); @@ -3114,9 +3185,9 @@ pc_in_mapped_range (CORE_ADDR pc, struct obj_section *section) return 0; } - /* Return true if the mapped ranges of sections A and B overlap, false otherwise. */ + static int sections_overlap (struct obj_section *a, struct obj_section *b) { @@ -3166,7 +3237,6 @@ overlay_mapped_address (CORE_ADDR pc, struct obj_section *section) return pc; } - /* Function: symbol_overlayed_address Return one of two addresses (relative to the VMA or to the LMA), depending on whether the section is mapped or not. */ @@ -3417,10 +3487,9 @@ overlay_command (char *args, int from_tty) { printf_unfiltered ("\"overlay\" must be followed by the name of an overlay command.\n"); - help_list (overlaylist, "overlay ", -1, gdb_stdout); + help_list (overlaylist, "overlay ", all_commands, gdb_stdout); } - /* Target Overlays for the "Simplest" overlay manager: This is GDB's default target overlay layer. It works with the @@ -3464,6 +3533,7 @@ enum ovly_index }; /* Throw away the cached copy of _ovly_table. */ + static void simple_free_overlay_table (void) { @@ -3476,6 +3546,7 @@ simple_free_overlay_table (void) /* Read an array of ints of size SIZE from the target into a local buffer. Convert to host order. int LEN is number of ints. */ + static void read_target_long_array (CORE_ADDR memaddr, unsigned int *myaddr, int len, int size, enum bfd_endian byte_order) @@ -3491,17 +3562,19 @@ read_target_long_array (CORE_ADDR memaddr, unsigned int *myaddr, /* Find and grab a copy of the target _ovly_table (and _novlys, which is needed for the table's size). */ + static int simple_read_overlay_table (void) { - struct minimal_symbol *novlys_msym, *ovly_table_msym; + struct bound_minimal_symbol novlys_msym; + struct bound_minimal_symbol ovly_table_msym; struct gdbarch *gdbarch; int word_size; enum bfd_endian byte_order; simple_free_overlay_table (); novlys_msym = lookup_minimal_symbol ("_novlys", NULL, NULL); - if (! novlys_msym) + if (! novlys_msym.minsym) { error (_("Error reading inferior's overlay table: " "couldn't find `_novlys' variable\n" @@ -3509,8 +3582,8 @@ simple_read_overlay_table (void) return 0; } - ovly_table_msym = lookup_minimal_symbol ("_ovly_table", NULL, NULL); - if (! ovly_table_msym) + ovly_table_msym = lookup_bound_minimal_symbol ("_ovly_table"); + if (! ovly_table_msym.minsym) { error (_("Error reading inferior's overlay table: couldn't find " "`_ovly_table' array\n" @@ -3518,15 +3591,15 @@ simple_read_overlay_table (void) return 0; } - gdbarch = get_objfile_arch (msymbol_objfile (ovly_table_msym)); + gdbarch = get_objfile_arch (ovly_table_msym.objfile); word_size = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT; byte_order = gdbarch_byte_order (gdbarch); - cache_novlys = read_memory_integer (SYMBOL_VALUE_ADDRESS (novlys_msym), + cache_novlys = read_memory_integer (BMSYMBOL_VALUE_ADDRESS (novlys_msym), 4, byte_order); cache_ovly_table = (void *) xmalloc (cache_novlys * sizeof (*cache_ovly_table)); - cache_ovly_table_base = SYMBOL_VALUE_ADDRESS (ovly_table_msym); + cache_ovly_table_base = BMSYMBOL_VALUE_ADDRESS (ovly_table_msym); read_target_long_array (cache_ovly_table_base, (unsigned int *) cache_ovly_table, cache_novlys * 4, word_size, byte_order); @@ -3594,15 +3667,15 @@ simple_overlay_update (struct obj_section *osect) { /* Does its cached location match what's currently in the symtab? */ - struct minimal_symbol *minsym + struct bound_minimal_symbol minsym = lookup_minimal_symbol ("_ovly_table", NULL, NULL); - if (minsym == NULL) + if (minsym.minsym == NULL) error (_("Error reading inferior's overlay table: couldn't " "find `_ovly_table' array\n" "in inferior. Use `overlay manual' mode.")); - if (cache_ovly_table_base == SYMBOL_VALUE_ADDRESS (minsym)) + if (cache_ovly_table_base == BMSYMBOL_VALUE_ADDRESS (minsym)) /* Then go ahead and try to look up this single section in the cache. */ if (simple_overlay_update_1 (osect)) @@ -3651,7 +3724,6 @@ symfile_dummy_outputs (bfd *abfd, asection *sectp, void *dummy) /* Default implementation for sym_relocate. */ - bfd_byte * default_symfile_relocate (struct objfile *objfile, asection *sectp, bfd_byte *buf) @@ -3715,7 +3787,6 @@ free_symfile_segment_data (struct symfile_segment_data *data) xfree (data); } - /* Given: - DATA, containing segment addresses from the object file ABFD, and the mapping from ABFD's sections onto the segments that own them, @@ -3730,8 +3801,10 @@ free_symfile_segment_data (struct symfile_segment_data *data) If there are more entries, then ignore the extra. The target may not be able to distinguish between an empty data segment and a missing data segment; a missing text segment is less plausible. */ + int -symfile_map_offsets_to_segments (bfd *abfd, struct symfile_segment_data *data, +symfile_map_offsets_to_segments (bfd *abfd, + const struct symfile_segment_data *data, struct section_offsets *offsets, int num_segment_bases, const CORE_ADDR *segment_bases) @@ -3814,11 +3887,62 @@ symfile_find_segment_sections (struct objfile *objfile) free_symfile_segment_data (data); } +/* Listen for free_objfile events. */ + +static void +symfile_free_objfile (struct objfile *objfile) +{ + /* Remove the target sections owned by this objfile. */ + if (objfile != NULL) + remove_target_sections ((void *) objfile); +} + +/* Wrapper around the quick_symbol_functions expand_symtabs_matching "method". + Expand all symtabs that match the specified criteria. + See quick_symbol_functions.expand_symtabs_matching for details. */ + +void +expand_symtabs_matching (expand_symtabs_file_matcher_ftype *file_matcher, + expand_symtabs_symbol_matcher_ftype *symbol_matcher, + enum search_domain kind, + void *data) +{ + struct objfile *objfile; + + ALL_OBJFILES (objfile) + { + if (objfile->sf) + objfile->sf->qf->expand_symtabs_matching (objfile, file_matcher, + symbol_matcher, kind, + data); + } +} + +/* Wrapper around the quick_symbol_functions map_symbol_filenames "method". + Map function FUN over every file. + See quick_symbol_functions.map_symbol_filenames for details. */ + +void +map_symbol_filenames (symbol_filename_ftype *fun, void *data, + int need_fullname) +{ + struct objfile *objfile; + + ALL_OBJFILES (objfile) + { + if (objfile->sf) + objfile->sf->qf->map_symbol_filenames (objfile, fun, data, + need_fullname); + } +} + void _initialize_symfile (void) { struct cmd_list_element *c; + observer_attach_free_objfile (symfile_free_objfile); + c = add_cmd ("symbol-file", class_files, symbol_file_command, _("\ Load symbol table from executable file FILE.\n\ The `file' command can also load symbol tables, as well as setting the file\n\ @@ -3835,6 +3959,15 @@ with the text. SECT is a section name to be loaded at SECT_ADDR."), &cmdlist); set_cmd_completer (c, filename_completer); + c = add_cmd ("remove-symbol-file", class_files, + remove_symbol_file_command, _("\ +Remove a symbol file added via the add-symbol-file command.\n\ +Usage: remove-symbol-file FILENAME\n\ + remove-symbol-file -a ADDRESS\n\ +The file to remove can be identified by its filename or by an address\n\ +that lies within the boundaries of this symbol file in memory."), + &cmdlist); + c = add_cmd ("load", class_files, load_command, _("\ Dynamically load FILE into the running program, and record its symbols\n\ for access from GDB.\n\ @@ -3891,4 +4024,18 @@ each global debug-file-directory component prepended."), NULL, show_debug_file_directory, &setlist, &showlist); + + add_setshow_enum_cmd ("symbol-loading", no_class, + print_symbol_loading_enums, &print_symbol_loading, + _("\ +Set printing of symbol loading messages."), _("\ +Show printing of symbol loading messages."), _("\ +off == turn all messages off\n\ +brief == print messages for the executable,\n\ + and brief messages for shared libraries\n\ +full == print messages for the executable,\n\ + and messages for each shared library."), + NULL, + NULL, + &setprintlist, &showprintlist); }