X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fsymfile.c;h=0d67bfd834594cd68ad1da3aec9e2811dc32bfd8;hb=173981bc49c9e8fce9271cb47714952dbe2ec627;hp=ecf4e328358051b327a05a8ea4e940664558ba8f;hpb=8fb8eb5ca4ca4c7a1410659a289e1a91c380832d;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/symfile.c b/gdb/symfile.c index ecf4e32835..0d67bfd834 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-2016 Free Software Foundation, Inc. Contributed by Cygnus Support, using pieces from other GDB modules. @@ -45,7 +45,6 @@ #include "bcache.h" #include "hashtab.h" #include "readline/readline.h" -#include "gdb_assert.h" #include "block.h" #include "observer.h" #include "exec.h" @@ -60,11 +59,10 @@ #include #include -#include "gdb_string.h" -#include "gdb_stat.h" +#include #include #include -#include +#include "gdb_sys_time.h" #include "psymtab.h" @@ -143,6 +141,20 @@ DEF_VEC_O (registered_sym_fns); 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 attaching to the inferior. This is almost always what users will @@ -156,6 +168,31 @@ static VEC (registered_sym_fns) *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; @@ -387,7 +424,7 @@ struct place_section_arg static void place_section (bfd *abfd, asection *sect, void *obj) { - struct place_section_arg *arg = obj; + struct place_section_arg *arg = (struct place_section_arg *) obj; CORE_ADDR *offsets = arg->offsets->offsets, start_addr; int done; ULONGEST align = ((ULONGEST) 1) << bfd_get_section_alignment (abfd, sect); @@ -518,7 +555,7 @@ addrs_section_sort (struct section_addr_info *addrs) int i; /* `+ 1' for the NULL terminator. */ - array = xmalloc (sizeof (*array) * (addrs->num_sections + 1)); + array = XNEWVEC (struct other_sections *, addrs->num_sections + 1); for (i = 0; i < addrs->num_sections; i++) array[i] = &addrs->other[i]; array[i] = NULL; @@ -577,8 +614,7 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd) /* Now create ADDRS_TO_ABFD_ADDRS from ADDRS_SORTED and ABFD_ADDRS_SORTED. */ - addrs_to_abfd_addrs = xzalloc (sizeof (*addrs_to_abfd_addrs) - * addrs->num_sections); + addrs_to_abfd_addrs = XCNEWVEC (struct other_sections *, addrs->num_sections); make_cleanup (xfree, addrs_to_abfd_addrs); while (*addrs_sorted) @@ -799,13 +835,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) { @@ -836,6 +872,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. */ @@ -867,6 +904,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. */ @@ -874,8 +917,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) @@ -883,18 +926,20 @@ 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. */ @@ -905,8 +950,27 @@ init_entry_point_info (struct objfile *objfile) /* Remove any ISA markers, so that this matches entries in the symbol table. */ - objfile->ei.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); } } @@ -951,7 +1015,8 @@ syms_from_objfile_1 (struct objfile *objfile, objfile->num_sections = num_sections; objfile->section_offsets - = obstack_alloc (&objfile->objfile_obstack, size); + = (struct section_offsets *) obstack_alloc (&objfile->objfile_obstack, + size); memset (objfile->section_offsets, 0, size); return; } @@ -1034,8 +1099,8 @@ syms_from_objfile (struct objfile *objfile, symbols for a new objfile, or mapping in the symbols from a reusable objfile. ADD_FLAGS is a bitmask of enum symfile_add_flags. */ -void -new_symfile_objfile (struct objfile *objfile, int add_flags) +static void +finish_new_objfile (struct objfile *objfile, int add_flags) { /* If this is the main symbol file we have to clean up all users of the old main symbol file. Otherwise it is sufficient to fixup all the @@ -1084,7 +1149,7 @@ symbol_file_add_with_addrs (bfd *abfd, const char *name, int add_flags, struct objfile *objfile; 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)); @@ -1169,7 +1234,7 @@ symbol_file_add_with_addrs (bfd *abfd, const char *name, int add_flags, return objfile; /* No symbols. */ } - new_symfile_objfile (objfile, add_flags); + finish_new_objfile (objfile, add_flags); observer_notify_new_objfile (objfile); @@ -1303,7 +1368,7 @@ separate_debug_file_exists (const char *name, unsigned long crc, if (filename_cmp (name, objfile_name (parent_objfile)) == 0) return 0; - abfd = gdb_bfd_open_maybe_remote (name); + abfd = gdb_bfd_open (name, gnutarget, -1); if (!abfd) return 0; @@ -1312,11 +1377,12 @@ separate_debug_file_exists (const char *name, unsigned long crc, 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. */ + meaningful st_dev.) Files accessed from gdbservers that do not + support the vFile:fstat packet will also have st_ino set to zero. + Do not indicate a duplicate library in either 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 && abfd_stat.st_ino != 0 @@ -1344,9 +1410,9 @@ separate_debug_file_exists (const char *name, unsigned long 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 the files could not be verified as different with + bfd_stat then we need to calculate the parent's CRC + to verify whether the files are different or not. */ if (!verified_as_different) { @@ -1405,12 +1471,13 @@ find_separate_debug_file (const char *dir, if (canon_dir != NULL && strlen (canon_dir) > i) i = strlen (canon_dir); - debugfile = xmalloc (strlen (debug_file_directory) + 1 - + i - + strlen (DEBUG_SUBDIRECTORY) - + strlen ("/") - + strlen (debuglink) - + 1); + debugfile + = (char *) xmalloc (strlen (debug_file_directory) + 1 + + i + + strlen (DEBUG_SUBDIRECTORY) + + strlen ("/") + + strlen (debuglink) + + 1); /* First try in the same directory as the original file. */ strcpy (debugfile, dir); @@ -1526,7 +1593,6 @@ find_separate_debug_file_by_debuglink (struct objfile *objfile) if (debugfile == NULL) { -#ifdef HAVE_LSTAT /* For PR gdb/9538, try again with realpath (if different from the original). */ @@ -1553,7 +1619,6 @@ find_separate_debug_file_by_debuglink (struct objfile *objfile) } } } -#endif /* HAVE_LSTAT */ } do_cleanups (cleanups); @@ -1627,14 +1692,12 @@ 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) { char *name = main_name (); - struct symbol *sym = lookup_symbol (name, NULL, VAR_DOMAIN, NULL); + struct symbol *sym = lookup_symbol (name, NULL, VAR_DOMAIN, NULL).symbol; if (sym != NULL) lang = SYMBOL_LANGUAGE (sym); @@ -1650,83 +1713,57 @@ set_initial_language (void) expected_language = current_language; /* Don't warn the user. */ } -/* If NAME is a remote name open the file using remote protocol, otherwise - open it normally. Returns a new reference to the BFD. On error, - returns NULL with the BFD error set. */ - -bfd * -gdb_bfd_open_maybe_remote (const char *name) -{ - bfd *result; - - if (remote_filename_p (name)) - result = remote_bfd_open (name, gnutarget); - else - result = gdb_bfd_open (name, gnutarget, -1); - - 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 (const char *cname) +symfile_bfd_open (const char *name) { bfd *sym_bfd; - int desc; - char *name, *absolute_name; - struct cleanup *back_to; + int desc = -1; + struct cleanup *back_to = make_cleanup (null_cleanup, 0); - if (remote_filename_p (cname)) + if (!is_target_filename (name)) { - sym_bfd = remote_bfd_open (cname, gnutarget); - if (!sym_bfd) - 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."), cname, - bfd_errmsg (bfd_get_error ())); - } - - return sym_bfd; - } + char *expanded_name, *absolute_name; - name = tilde_expand (cname); /* Returns 1st new malloc'd copy. */ + expanded_name = tilde_expand (name); /* 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 | OPF_RETURN_REALPATH, name, - O_RDONLY | O_BINARY, &absolute_name); + /* Look down path for it, allocate 2nd new malloc'd copy. */ + desc = openp (getenv ("PATH"), + OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, + expanded_name, O_RDONLY | O_BINARY, &absolute_name); #if defined(__GO32__) || defined(_WIN32) || defined (__CYGWIN__) - if (desc < 0) - { - char *exename = alloca (strlen (name) + 5); + if (desc < 0) + { + char *exename = (char *) alloca (strlen (expanded_name) + 5); - strcat (strcpy (exename, name), ".exe"); - desc = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, - exename, O_RDONLY | O_BINARY, &absolute_name); - } + strcat (strcpy (exename, expanded_name), ".exe"); + desc = openp (getenv ("PATH"), + OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, + exename, O_RDONLY | O_BINARY, &absolute_name); + } #endif - if (desc < 0) - { - make_cleanup (xfree, name); - perror_with_name (name); - } + if (desc < 0) + { + make_cleanup (xfree, expanded_name); + perror_with_name (expanded_name); + } - xfree (name); - name = absolute_name; - back_to = make_cleanup (xfree, name); + xfree (expanded_name); + make_cleanup (xfree, absolute_name); + name = absolute_name; + } sym_bfd = gdb_bfd_open (name, gnutarget, desc); if (!sym_bfd) error (_("`%s': can't open to read symbols: %s."), name, bfd_errmsg (bfd_get_error ())); - bfd_set_cacheable (sym_bfd, 1); + + if (!gdb_bfd_has_target_filename (sym_bfd)) + bfd_set_cacheable (sym_bfd, 1); if (!bfd_check_format (sym_bfd, bfd_object)) { @@ -1825,7 +1862,7 @@ load_command (char *arg, int from_tty) if (count) { /* We need to quote this string so buildargv can pull it apart. */ - char *temp = xmalloc (strlen (arg) + count + 1 ); + char *temp = (char *) xmalloc (strlen (arg) + count + 1 ); char *ptemp = temp; char *prev; @@ -1870,7 +1907,7 @@ static int validate_download = 0; static void add_section_size_callback (bfd *abfd, asection *asec, void *data) { - bfd_size_type *sum = data; + bfd_size_type *sum = (bfd_size_type *) data; *sum += bfd_get_section_size (asec); } @@ -1907,7 +1944,8 @@ struct load_progress_section_data { static void load_progress (ULONGEST bytes, void *untyped_arg) { - struct load_progress_section_data *args = untyped_arg; + struct load_progress_section_data *args + = (struct load_progress_section_data *) untyped_arg; struct load_progress_data *totals; if (args == NULL) @@ -1936,7 +1974,7 @@ load_progress (ULONGEST bytes, void *untyped_arg) might add a verify_memory() method to the target vector and then use that. remote.c could implement that method using the ``qCRC'' packet. */ - gdb_byte *check = xmalloc (bytes); + gdb_byte *check = (gdb_byte *) xmalloc (bytes); struct cleanup *verify_cleanups = make_cleanup (xfree, check); if (target_read_memory (args->lma, check, bytes) != 0) @@ -1972,7 +2010,7 @@ static void load_section_callback (bfd *abfd, asection *asec, void *data) { struct memory_write_request *new_request; - struct load_section_data *args = data; + struct load_section_data *args = (struct load_section_data *) data; struct load_progress_section_data *section_data; bfd_size_type size = bfd_get_section_size (asec); gdb_byte *buffer; @@ -1987,11 +2025,11 @@ load_section_callback (bfd *abfd, asection *asec, void *data) new_request = VEC_safe_push (memory_write_request_s, args->requests, NULL); memset (new_request, 0, sizeof (struct memory_write_request)); - section_data = xcalloc (1, sizeof (struct load_progress_section_data)); + section_data = XCNEW (struct load_progress_section_data); new_request->begin = bfd_section_lma (abfd, asec) + args->load_offset; new_request->end = new_request->begin + size; /* FIXME Should size be in instead? */ - new_request->data = xmalloc (size); + new_request->data = (gdb_byte *) xmalloc (size); new_request->baton = section_data; buffer = new_request->data; @@ -2011,7 +2049,7 @@ load_section_callback (bfd *abfd, asection *asec, void *data) static void clear_memory_write_data (void *arg) { - VEC(memory_write_request_s) **vec_p = arg; + VEC(memory_write_request_s) **vec_p = (VEC(memory_write_request_s) **) arg; VEC(memory_write_request_s) *vec = *vec_p; int i; struct memory_write_request *mr; @@ -2025,7 +2063,7 @@ clear_memory_write_data (void *arg) } void -generic_load (char *args, int from_tty) +generic_load (const char *args, int from_tty) { bfd *loadfile_bfd; struct timeval start_time, end_time; @@ -2104,8 +2142,6 @@ generic_load (char *args, int from_tty) ui_out_text (uiout, ", load size "); ui_out_field_fmt (uiout, "load-size", "%lu", total_progress.data_count); ui_out_text (uiout, "\n"); - /* We were doing this in remote-mips.c, I suspect it is right - for other targets too. */ regcache_write_pc (get_current_regcache (), entry); /* Reset breakpoints, now that we have changed the load image. For @@ -2118,12 +2154,6 @@ generic_load (char *args, int from_tty) breakpoint_re_set (); - /* FIXME: are we supposed to call symbol_file_add or not? According - to a comment from remote-mips.c (where a call to symbol_file_add - was commented out), making the call confuses GDB if more than one - file is loaded in. Some targets do (e.g., remote-vx.c) but - others don't (or didn't - perhaps they have all been deleted). */ - print_transfer_performance (gdb_stdout, total_progress.data_count, total_progress.write_count, &start_time, &end_time); @@ -2197,7 +2227,7 @@ add_symbol_file_command (char *args, int from_tty) { struct gdbarch *gdbarch = get_current_arch (); char *filename = NULL; - int flags = OBJF_USERLOADED; + int flags = OBJF_USERLOADED | OBJF_SHARED; char *arg; int section_index = 0; int argcnt = 0; @@ -2206,6 +2236,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 { @@ -2219,8 +2250,7 @@ add_symbol_file_command (char *args, int from_tty) struct cleanup *my_cleanups = make_cleanup (null_cleanup, NULL); num_sect_opts = 16; - sect_opts = (struct sect_opt *) xmalloc (num_sect_opts - * sizeof (struct sect_opt)); + sect_opts = XNEWVEC (struct sect_opt, num_sect_opts); dont_repeat (); @@ -2332,8 +2362,10 @@ add_symbol_file_command (char *args, int from_tty) 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. */ @@ -2342,6 +2374,82 @@ 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->flags & OBJF_USERLOADED) != 0 + && (objf->flags & OBJF_SHARED) != 0 + && 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->flags & OBJF_USERLOADED) != 0 + && (objf->flags & OBJF_SHARED) != 0 + && 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); @@ -2455,7 +2563,7 @@ reread_symbols (void) obfd_filename = bfd_get_filename (objfile->obfd); /* Open the new BFD before freeing the old one, so that the filename remains live. */ - objfile->obfd = gdb_bfd_open_maybe_remote (obfd_filename); + objfile->obfd = gdb_bfd_open (obfd_filename, gnutarget, -1); if (objfile->obfd == NULL) { /* We have to make a cleanup and error here, rather @@ -2497,35 +2605,28 @@ 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; + objfile->compunit_symtabs = NULL; objfile->psymtabs = NULL; 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); - objfile->original_name = obstack_copy0 (&objfile->objfile_obstack, - original_name, - strlen (original_name)); + /* 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 + = (char *) 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 @@ -2626,9 +2727,9 @@ add_filename_language (char *ext, enum language lang) if (fl_table_next >= fl_table_size) { fl_table_size += 10; - filename_language_table = - xrealloc (filename_language_table, - fl_table_size * sizeof (*filename_language_table)); + filename_language_table = XRESIZEVEC (filename_language, + filename_language_table, + fl_table_size); } filename_language_table[fl_table_next].ext = xstrdup (ext); @@ -2725,8 +2826,8 @@ init_filename_language_table (void) { fl_table_size = 20; fl_table_next = 0; - filename_language_table = - xmalloc (fl_table_size * sizeof (*filename_language_table)); + filename_language_table = XNEWVEC (filename_language, fl_table_size); + add_filename_language (".c", language_c); add_filename_language (".d", language_d); add_filename_language (".C", language_cplus); @@ -2772,7 +2873,7 @@ enum language deduce_language_from_filename (const char *filename) { int i; - char *cp; + const char *cp; if (filename != NULL) if ((cp = strrchr (filename, '.')) != NULL) @@ -2783,40 +2884,25 @@ deduce_language_from_filename (const char *filename) return language_unknown; } -/* allocate_symtab: - - Allocate and partly initialize a new symbol table. Return a pointer - to it. error() if no space. - - Caller must set these fields: - LINETABLE(symtab) - symtab->blockvector - symtab->dirname - symtab->free_code - symtab->free_ptr - */ +/* Allocate and initialize a new symbol table. + CUST is from the result of allocate_compunit_symtab. */ struct symtab * -allocate_symtab (const char *filename, struct objfile *objfile) +allocate_symtab (struct compunit_symtab *cust, const char *filename) { - struct symtab *symtab; + struct objfile *objfile = cust->objfile; + struct symtab *symtab + = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symtab); - 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 + = (const char *) bcache (filename, strlen (filename) + 1, + objfile->per_bfd->filename_cache); symtab->fullname = NULL; symtab->language = deduce_language_from_filename (filename); - symtab->debugformat = "unknown"; - - /* Hook it to the objfile it comes from. */ - - symtab->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. */ @@ -2836,7 +2922,65 @@ allocate_symtab (const char *filename, struct objfile *objfile) host_address_to_string (symtab), filename); } - return (symtab); + /* Add it to CUST's list of symtabs. */ + if (cust->filetabs == NULL) + { + cust->filetabs = symtab; + cust->last_filetab = symtab; + } + else + { + cust->last_filetab->next = symtab; + cust->last_filetab = symtab; + } + + /* Backlink to the containing compunit symtab. */ + symtab->compunit_symtab = cust; + + return symtab; +} + +/* Allocate and initialize a new compunit. + NAME is the name of the main source file, if there is one, or some + descriptive text if there are no source files. */ + +struct compunit_symtab * +allocate_compunit_symtab (struct objfile *objfile, const char *name) +{ + struct compunit_symtab *cu = OBSTACK_ZALLOC (&objfile->objfile_obstack, + struct compunit_symtab); + const char *saved_name; + + cu->objfile = objfile; + + /* The name we record here is only for display/debugging purposes. + Just save the basename to avoid path issues (too long for display, + relative vs absolute, etc.). */ + saved_name = lbasename (name); + cu->name + = (const char *) obstack_copy0 (&objfile->objfile_obstack, saved_name, + strlen (saved_name)); + + COMPUNIT_DEBUGFORMAT (cu) = "unknown"; + + if (symtab_create_debug) + { + fprintf_unfiltered (gdb_stdlog, + "Created compunit symtab %s for %s.\n", + host_address_to_string (cu), + cu->name); + } + + return cu; +} + +/* Hook CU to the objfile it comes from. */ + +void +add_compunit_symtab_to_objfile (struct compunit_symtab *cu) +{ + cu->next = cu->objfile->compunit_symtabs; + cu->objfile->compunit_symtabs = cu; } @@ -2854,8 +2998,6 @@ clear_symtab_users (int add_flags) clear_current_source_symtab_and_line (); clear_displays (); - if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0) - breakpoint_re_set (); clear_last_displayed_sal (); clear_pc_function_cache (); observer_notify_new_objfile (NULL); @@ -2869,6 +3011,10 @@ clear_symtab_users (int add_flags) /* Varobj may refer to old symbols, perform a cleanup. */ varobj_invalidate (); + /* Now that the various caches have been cleared, we can re_set + our breakpoints without risking it using stale data. */ + if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0) + breakpoint_re_set (); } static void @@ -3265,7 +3411,7 @@ static void unmap_overlay_command (char *args, int from_tty) { struct objfile *objfile; - struct obj_section *sec; + struct obj_section *sec = NULL; if (!overlay_debugging) error (_("Overlay debugging not enabled. " @@ -3348,7 +3494,7 @@ 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: @@ -3367,12 +3513,12 @@ overlay_command (char *args, int from_tty) In this simple implementation, the target data structures are as follows: unsigned _novlys; /# number of overlay sections #/ unsigned _ovly_table[_novlys][4] = { - {VMA, SIZE, LMA, MAPPED}, /# one entry per overlay section #/ + {VMA, OSIZE, LMA, MAPPED}, /# one entry per overlay section #/ {..., ..., ..., ...}, } unsigned _novly_regions; /# number of overlay regions #/ unsigned _ovly_region_table[_novly_regions][3] = { - {VMA, SIZE, MAPPED_TO_LMA}, /# one entry per overlay region #/ + {VMA, OSIZE, MAPPED_TO_LMA}, /# one entry per overlay region #/ {..., ..., ...}, } These functions will attempt to update GDB's mappedness state in the @@ -3390,7 +3536,7 @@ static unsigned cache_novlys = 0; static CORE_ADDR cache_ovly_table_base = 0; enum ovly_index { - VMA, SIZE, LMA, MAPPED + VMA, OSIZE, LMA, MAPPED }; /* Throw away the cached copy of _ovly_table. */ @@ -3413,7 +3559,7 @@ read_target_long_array (CORE_ADDR memaddr, unsigned int *myaddr, int len, int size, enum bfd_endian byte_order) { /* FIXME (alloca): Not safe if array is very large. */ - gdb_byte *buf = alloca (len * size); + gdb_byte *buf = (gdb_byte *) alloca (len * size); int i; read_memory (memaddr, buf, len * size); @@ -3427,7 +3573,7 @@ read_target_long_array (CORE_ADDR memaddr, unsigned int *myaddr, static int simple_read_overlay_table (void) { - struct minimal_symbol *novlys_msym; + struct bound_minimal_symbol novlys_msym; struct bound_minimal_symbol ovly_table_msym; struct gdbarch *gdbarch; int word_size; @@ -3435,7 +3581,7 @@ simple_read_overlay_table (void) 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" @@ -3456,11 +3602,11 @@ simple_read_overlay_table (void) 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.minsym); + = (unsigned int (*)[4]) xmalloc (cache_novlys * sizeof (*cache_ovly_table)); + 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); @@ -3490,14 +3636,14 @@ simple_overlay_update_1 (struct obj_section *osect) for (i = 0; i < cache_novlys; i++) if (cache_ovly_table[i][VMA] == bfd_section_vma (obfd, bsect) && cache_ovly_table[i][LMA] == bfd_section_lma (obfd, bsect) - /* && cache_ovly_table[i][SIZE] == size */ ) + /* && cache_ovly_table[i][OSIZE] == size */ ) { read_target_long_array (cache_ovly_table_base + i * word_size, (unsigned int *) cache_ovly_table[i], 4, word_size, byte_order); if (cache_ovly_table[i][VMA] == bfd_section_vma (obfd, bsect) && cache_ovly_table[i][LMA] == bfd_section_lma (obfd, bsect) - /* && cache_ovly_table[i][SIZE] == size */ ) + /* && cache_ovly_table[i][OSIZE] == size */ ) { osect->ovly_mapped = cache_ovly_table[i][MAPPED]; return 1; @@ -3528,15 +3674,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)) @@ -3563,7 +3709,7 @@ simple_overlay_update (struct obj_section *osect) for (i = 0; i < cache_novlys; i++) if (cache_ovly_table[i][VMA] == bfd_section_vma (obfd, bsect) && cache_ovly_table[i][LMA] == bfd_section_lma (obfd, bsect) - /* && cache_ovly_table[i][SIZE] == size */ ) + /* && cache_ovly_table[i][OSIZE] == size */ ) { /* obj_section matches i'th entry in ovly_table. */ osect->ovly_mapped = cache_ovly_table[i][MAPPED]; break; /* finished with inner for loop: break out. */ @@ -3748,11 +3894,64 @@ 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, + expand_symtabs_exp_notify_ftype *expansion_notify, + 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, + expansion_notify, 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\ @@ -3769,6 +3968,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\ @@ -3825,4 +4033,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); }