X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fsymfile.c;h=b29f864b3735989392dae7684754e7958413a08d;hb=2d0a923cc653b76a531651c9f4b026a0ae366858;hp=f714845a6ea99f68513df1f5797351e85d0f383d;hpb=b577b6af8e7f4cc53e73ee01188d1700fb8d3b82;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/symfile.c b/gdb/symfile.c index f714845a6e..b29f864b37 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-2018 Free Software Foundation, Inc. + Copyright (C) 1990-2020 Free Software Foundation, Inc. Contributed by Cygnus Support, using pieces from other GDB modules. @@ -44,9 +44,9 @@ #include "completer.h" #include "bcache.h" #include "hashtab.h" -#include "readline/readline.h" +#include "readline/tilde.h" #include "block.h" -#include "observer.h" +#include "observable.h" #include "exec.h" #include "parser-defs.h" #include "varobj.h" @@ -56,14 +56,18 @@ #include "stack.h" #include "gdb_bfd.h" #include "cli/cli-utils.h" -#include "common/byte-vector.h" -#include "selftest.h" +#include "gdbsupport/byte-vector.h" +#include "gdbsupport/pathstuff.h" +#include "gdbsupport/selftest.h" +#include "cli/cli-style.h" +#include "gdbsupport/forward-scope-exit.h" #include #include #include #include #include +#include #include "psymtab.h" @@ -77,7 +81,8 @@ void (*deprecated_show_load_progress) (const char *section, void (*deprecated_pre_add_symbol_hook) (const char *); void (*deprecated_post_add_symbol_hook) (void); -static void clear_symtab_users_cleanup (void *ignore); +using clear_symtab_users_cleanup + = FORWARD_SCOPE_EXIT (clear_symtab_users); /* Global variables owned by this file. */ int readnow_symbol_files; /* Read full symbols immediately. */ @@ -86,7 +91,7 @@ int readnever_symbol_files; /* Never read full symbols. */ /* Functions this file defines. */ static void symbol_file_add_main_1 (const char *args, symfile_add_flags add_flags, - objfile_flags flags); + objfile_flags flags, CORE_ADDR reloff); static const struct sym_fns *find_sym_fns (bfd *); @@ -136,17 +141,9 @@ static const char *print_symbol_loading_enums[] = }; 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 - want to have happen; but for very large programs, the startup time - will be excessive, and so if this is a problem, the user can clear - this flag and then add the shared library symbols as needed. Note - that there is a potential for confusion, since if the shared - library symbols are not loaded, commands like "info fun" will *not* - report all the functions that are actually present. */ - -int auto_solib_add = 1; +/* See symfile.h. */ + +bool auto_solib_add = true; /* Return non-zero if symbol-loading messages should be printed. @@ -203,126 +200,80 @@ find_lowest_section (bfd *abfd, asection *sect, void *obj) { asection **lowest = (asection **) obj; - if (0 == (bfd_get_section_flags (abfd, sect) & (SEC_ALLOC | SEC_LOAD))) + if (0 == (bfd_section_flags (sect) & (SEC_ALLOC | SEC_LOAD))) return; if (!*lowest) *lowest = sect; /* First loadable section */ - else if (bfd_section_vma (abfd, *lowest) > bfd_section_vma (abfd, sect)) + else if (bfd_section_vma (*lowest) > bfd_section_vma (sect)) *lowest = sect; /* A lower loadable section */ - else if (bfd_section_vma (abfd, *lowest) == bfd_section_vma (abfd, sect) - && (bfd_section_size (abfd, (*lowest)) - <= bfd_section_size (abfd, sect))) + else if (bfd_section_vma (*lowest) == bfd_section_vma (sect) + && (bfd_section_size (*lowest) <= bfd_section_size (sect))) *lowest = sect; } -/* 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) -{ - struct section_addr_info *sap; - size_t size; - - size = (sizeof (struct section_addr_info) - + sizeof (struct other_sections) * (num_sections - 1)); - sap = (struct section_addr_info *) xmalloc (size); - memset (sap, 0, size); - - return sap; -} - /* Build (allocate and populate) a section_addr_info struct from an existing section table. */ -extern struct section_addr_info * +section_addr_info build_section_addr_info_from_section_table (const struct target_section *start, const struct target_section *end) { - struct section_addr_info *sap; const struct target_section *stp; - int oidx; - sap = alloc_section_addr_info (end - start); + section_addr_info sap; - for (stp = start, oidx = 0; stp != end; stp++) + for (stp = start; stp != end; stp++) { 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 (abfd, asect)); - sap->other[oidx].sectindex = gdb_bfd_section_index (abfd, asect); - oidx++; - } + if (bfd_section_flags (asect) & (SEC_ALLOC | SEC_LOAD) + && sap.size () < end - start) + sap.emplace_back (stp->addr, + bfd_section_name (asect), + gdb_bfd_section_index (abfd, asect)); } - sap->num_sections = oidx; - return sap; } /* Create a section_addr_info from section offsets in ABFD. */ -static struct section_addr_info * +static section_addr_info build_section_addr_info_from_bfd (bfd *abfd) { - struct section_addr_info *sap; - int i; struct bfd_section *sec; - sap = alloc_section_addr_info (bfd_count_sections (abfd)); - for (i = 0, sec = abfd->sections; sec != NULL; sec = sec->next) - if (bfd_get_section_flags (abfd, sec) & (SEC_ALLOC | SEC_LOAD)) - { - 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 = gdb_bfd_section_index (abfd, sec); - i++; - } - - sap->num_sections = i; + section_addr_info sap; + for (sec = abfd->sections; sec != NULL; sec = sec->next) + if (bfd_section_flags (sec) & (SEC_ALLOC | SEC_LOAD)) + sap.emplace_back (bfd_section_vma (sec), + bfd_section_name (sec), + gdb_bfd_section_index (abfd, sec)); return sap; } /* Create a section_addr_info from section offsets in OBJFILE. */ -struct section_addr_info * +section_addr_info build_section_addr_info_from_objfile (const struct objfile *objfile) { - struct section_addr_info *sap; int i; /* Before reread_symbols gets rewritten it is not safe to call: 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; i++) + section_addr_info sap = build_section_addr_info_from_bfd (objfile->obfd); + for (i = 0; i < sap.size (); i++) { - int sectindex = sap->other[i].sectindex; + int sectindex = sap[i].sectindex; - sap->other[i].addr += objfile->section_offsets->offsets[sectindex]; + sap[i].addr += objfile->section_offsets[sectindex]; } return sap; } -/* Free all memory allocated by build_section_addr_info_from_section_table. */ - -extern void -free_section_addr_info (struct section_addr_info *sap) -{ - int idx; - - for (idx = 0; idx < sap->num_sections; idx++) - xfree (sap->other[idx].name); - xfree (sap); -} - /* Initialize OBJFILE's sect_index_* members. */ static void @@ -364,14 +315,14 @@ init_objfile_sect_indices (struct objfile *objfile) later, e.g. by the remote qOffsets packet, and then this will be wrong! That's why we try segments first. */ - for (i = 0; i < objfile->num_sections; i++) + for (i = 0; i < objfile->section_offsets.size (); i++) { - if (ANOFFSET (objfile->section_offsets, i) != 0) + if (objfile->section_offsets[i] != 0) { break; } } - if (i == objfile->num_sections) + if (i == objfile->section_offsets.size ()) { if (objfile->sect_index_text == -1) objfile->sect_index_text = 0; @@ -388,7 +339,7 @@ init_objfile_sect_indices (struct objfile *objfile) struct place_section_arg { - struct section_offsets *offsets; + section_offsets *offsets; CORE_ADDR lowest; }; @@ -399,12 +350,13 @@ static void place_section (bfd *abfd, asection *sect, void *obj) { struct place_section_arg *arg = (struct place_section_arg *) obj; - CORE_ADDR *offsets = arg->offsets->offsets, start_addr; + section_offsets &offsets = *arg->offsets; + CORE_ADDR start_addr; int done; - ULONGEST align = ((ULONGEST) 1) << bfd_get_section_alignment (abfd, sect); + ULONGEST align = ((ULONGEST) 1) << bfd_section_alignment (sect); /* We are only interested in allocated sections. */ - if ((bfd_get_section_flags (abfd, sect) & SEC_ALLOC) == 0) + if ((bfd_section_flags (sect) & SEC_ALLOC) == 0) return; /* If the user specified an offset, honor it. */ @@ -428,7 +380,7 @@ place_section (bfd *abfd, asection *sect, void *obj) continue; /* We can only conflict with allocated sections. */ - if ((bfd_get_section_flags (abfd, cur_sec) & SEC_ALLOC) == 0) + if ((bfd_section_flags (cur_sec) & SEC_ALLOC) == 0) continue; /* If the section offset is 0, either the section has not been placed @@ -438,10 +390,10 @@ place_section (bfd *abfd, asection *sect, void *obj) continue; /* If this section would overlap us, then we must move up. */ - if (start_addr + bfd_get_section_size (sect) > offsets[indx] - && start_addr < offsets[indx] + bfd_get_section_size (cur_sec)) + if (start_addr + bfd_section_size (sect) > offsets[indx] + && start_addr < offsets[indx] + bfd_section_size (cur_sec)) { - start_addr = offsets[indx] + bfd_get_section_size (cur_sec); + start_addr = offsets[indx] + bfd_section_size (cur_sec); start_addr = (start_addr + align - 1) & -align; done = 0; break; @@ -453,35 +405,33 @@ place_section (bfd *abfd, asection *sect, void *obj) while (!done); offsets[gdb_bfd_section_index (abfd, sect)] = start_addr; - arg->lowest = start_addr + bfd_get_section_size (sect); + arg->lowest = start_addr + bfd_section_size (sect); } -/* 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. */ +/* Store section_addr_info as prepared (made relative and with SECTINDEX + filled-in) by addr_info_make_relative into SECTION_OFFSETS. */ void -relative_addr_info_to_section_offsets (struct section_offsets *section_offsets, - int num_sections, - const struct section_addr_info *addrs) +relative_addr_info_to_section_offsets (section_offsets §ion_offsets, + const section_addr_info &addrs) { int i; - memset (section_offsets, 0, SIZEOF_N_SECTION_OFFSETS (num_sections)); + section_offsets.assign (section_offsets.size (), 0); /* Now calculate offsets for section that were specified by the caller. */ - for (i = 0; i < addrs->num_sections; i++) + for (i = 0; i < addrs.size (); i++) { const struct other_sections *osp; - osp = &addrs->other[i]; + osp = &addrs[i]; if (osp->sectindex == -1) continue; /* Record all sections in offsets. */ /* The section_offsets in the objfile are here filled in using the BFD index. */ - section_offsets->offsets[osp->sectindex] = osp->addr; + section_offsets[osp->sectindex] = osp->addr; } } @@ -502,39 +452,36 @@ addr_section_name (const char *s) return s; } -/* qsort comparator for addrs_section_sort. Sort entries in ascending order by - their (name, sectindex) pair. sectindex makes the sort by name stable. */ +/* std::sort comparator for addrs_section_sort. Sort entries in + ascending order by their (name, sectindex) pair. sectindex makes + the sort by name stable. */ -static int -addrs_section_compar (const void *ap, const void *bp) +static bool +addrs_section_compar (const struct other_sections *a, + const struct other_sections *b) { - const struct other_sections *a = *((struct other_sections **) ap); - const struct other_sections *b = *((struct other_sections **) bp); int retval; - retval = strcmp (addr_section_name (a->name), addr_section_name (b->name)); - if (retval) - return retval; + retval = strcmp (addr_section_name (a->name.c_str ()), + addr_section_name (b->name.c_str ())); + if (retval != 0) + return retval < 0; - return a->sectindex - b->sectindex; + return a->sectindex < b->sectindex; } -/* Provide sorted array of pointers to sections of ADDRS. The array is - terminated by NULL. Caller is responsible to call xfree for it. */ +/* Provide sorted array of pointers to sections of ADDRS. */ -static struct other_sections ** -addrs_section_sort (struct section_addr_info *addrs) +static std::vector +addrs_section_sort (const section_addr_info &addrs) { - struct other_sections **array; int i; - /* `+ 1' for the NULL terminator. */ - 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; + std::vector array (addrs.size ()); + for (i = 0; i < addrs.size (); i++) + array[i] = &addrs[i]; - qsort (array, i, sizeof (*array), addrs_section_compar); + std::sort (array.begin (), array.end (), addrs_section_compar); return array; } @@ -544,18 +491,14 @@ addrs_section_sort (struct section_addr_info *addrs) rebase ADDRS to start referencing different BFD than before. */ void -addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd) +addr_info_make_relative (section_addr_info *addrs, bfd *abfd) { asection *lower_sect; CORE_ADDR lower_offset; int i; - struct cleanup *my_cleanup; - struct section_addr_info *abfd_addrs; - struct other_sections **addrs_sorted, **abfd_addrs_sorted; - struct other_sections **addrs_to_abfd_addrs; /* Find lowest loadable section to be used as starting point for - continguous sections. */ + contiguous sections. */ lower_sect = NULL; bfd_map_over_sections (abfd, find_lowest_section, &lower_sect); if (lower_sect == NULL) @@ -565,7 +508,7 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd) lower_offset = 0; } else - lower_offset = bfd_section_vma (bfd_get_filename (abfd), lower_sect); + lower_offset = bfd_section_vma (lower_sect); /* Create ADDRS_TO_ABFD_ADDRS array to map the sections in ADDRS to sections in ABFD. Section names are not unique - there can be multiple sections of @@ -577,45 +520,44 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd) Use stable sort by name for the sections in both files. Then linearly scan both lists matching as most of the entries as possible. */ - addrs_sorted = addrs_section_sort (addrs); - my_cleanup = make_cleanup (xfree, addrs_sorted); + std::vector addrs_sorted + = addrs_section_sort (*addrs); - abfd_addrs = build_section_addr_info_from_bfd (abfd); - make_cleanup_free_section_addr_info (abfd_addrs); - abfd_addrs_sorted = addrs_section_sort (abfd_addrs); - make_cleanup (xfree, abfd_addrs_sorted); + section_addr_info abfd_addrs = build_section_addr_info_from_bfd (abfd); + std::vector abfd_addrs_sorted + = addrs_section_sort (abfd_addrs); /* Now create ADDRS_TO_ABFD_ADDRS from ADDRS_SORTED and ABFD_ADDRS_SORTED. */ - addrs_to_abfd_addrs = XCNEWVEC (struct other_sections *, addrs->num_sections); - make_cleanup (xfree, addrs_to_abfd_addrs); + std::vector + addrs_to_abfd_addrs (addrs->size (), nullptr); - while (*addrs_sorted) + std::vector::iterator abfd_sorted_iter + = abfd_addrs_sorted.begin (); + for (const other_sections *sect : addrs_sorted) { - const char *sect_name = addr_section_name ((*addrs_sorted)->name); + const char *sect_name = addr_section_name (sect->name.c_str ()); - while (*abfd_addrs_sorted - && strcmp (addr_section_name ((*abfd_addrs_sorted)->name), + while (abfd_sorted_iter != abfd_addrs_sorted.end () + && strcmp (addr_section_name ((*abfd_sorted_iter)->name.c_str ()), sect_name) < 0) - abfd_addrs_sorted++; + abfd_sorted_iter++; - if (*abfd_addrs_sorted - && strcmp (addr_section_name ((*abfd_addrs_sorted)->name), + if (abfd_sorted_iter != abfd_addrs_sorted.end () + && strcmp (addr_section_name ((*abfd_sorted_iter)->name.c_str ()), sect_name) == 0) { int index_in_addrs; /* Make the found item directly addressable from ADDRS. */ - index_in_addrs = *addrs_sorted - addrs->other; + index_in_addrs = sect - addrs->data (); gdb_assert (addrs_to_abfd_addrs[index_in_addrs] == NULL); - addrs_to_abfd_addrs[index_in_addrs] = *abfd_addrs_sorted; + addrs_to_abfd_addrs[index_in_addrs] = *abfd_sorted_iter; /* Never use the same ABFD entry twice. */ - abfd_addrs_sorted++; + abfd_sorted_iter++; } - - addrs_sorted++; } /* Calculate offsets for the loadable sections. @@ -628,27 +570,27 @@ 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; i++) + for (i = 0; i < addrs->size (); i++) { - struct other_sections *sect = addrs_to_abfd_addrs[i]; + const struct other_sections *sect = addrs_to_abfd_addrs[i]; if (sect) { /* This is the index used by BFD. */ - addrs->other[i].sectindex = sect->sectindex; + (*addrs)[i].sectindex = sect->sectindex; - if (addrs->other[i].addr != 0) + if ((*addrs)[i].addr != 0) { - addrs->other[i].addr -= sect->addr; - lower_offset = addrs->other[i].addr; + (*addrs)[i].addr -= sect->addr; + lower_offset = (*addrs)[i].addr; } else - addrs->other[i].addr = lower_offset; + (*addrs)[i].addr = lower_offset; } else { /* addr_section_name transformation is not used for SECT_NAME. */ - const char *sect_name = addrs->other[i].name; + const std::string §_name = (*addrs)[i].name; /* This section does not exist in ABFD, which is normally unexpected and we want to issue a warning. @@ -664,25 +606,23 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd) For the sections `.bss' and `.sbss' see addr_section_name. */ - if (!(strcmp (sect_name, ".gnu.liblist") == 0 - || strcmp (sect_name, ".gnu.conflict") == 0 - || (strcmp (sect_name, ".bss") == 0 + if (!(sect_name == ".gnu.liblist" + || sect_name == ".gnu.conflict" + || (sect_name == ".bss" && i > 0 - && strcmp (addrs->other[i - 1].name, ".dynbss") == 0 + && (*addrs)[i - 1].name == ".dynbss" && addrs_to_abfd_addrs[i - 1] != NULL) - || (strcmp (sect_name, ".sbss") == 0 + || (sect_name == ".sbss" && i > 0 - && strcmp (addrs->other[i - 1].name, ".sdynbss") == 0 + && (*addrs)[i - 1].name == ".sdynbss" && addrs_to_abfd_addrs[i - 1] != NULL))) - warning (_("section %s not found in %s"), sect_name, + warning (_("section %s not found in %s"), sect_name.c_str (), bfd_get_filename (abfd)); - addrs->other[i].addr = 0; - addrs->other[i].sectindex = -1; + (*addrs)[i].addr = 0; + (*addrs)[i].sectindex = -1; } } - - do_cleanups (my_cleanup); } /* Parse the user's idea of an offset for dynamic linking, into our idea @@ -693,14 +633,10 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd) void default_symfile_offsets (struct objfile *objfile, - const struct section_addr_info *addrs) + const section_addr_info &addrs) { - 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)); - relative_addr_info_to_section_offsets (objfile->section_offsets, - objfile->num_sections, addrs); + objfile->section_offsets.resize (gdb_bfd_count_sections (objfile->obfd)); + relative_addr_info_to_section_offsets (objfile->section_offsets, addrs); /* For relocatable files, all loadable sections will start at zero. The zero is meaningless, so try to pick arbitrary addresses such @@ -716,16 +652,16 @@ default_symfile_offsets (struct objfile *objfile, for (cur_sec = abfd->sections; cur_sec != NULL; cur_sec = cur_sec->next) /* We do not expect this to happen; just skip this step if the relocatable file has a section with an assigned VMA. */ - if (bfd_section_vma (abfd, cur_sec) != 0) + if (bfd_section_vma (cur_sec) != 0) break; if (cur_sec == NULL) { - CORE_ADDR *offsets = objfile->section_offsets->offsets; + section_offsets &offsets = objfile->section_offsets; /* Pick non-overlapping offsets for sections the user did not place explicitly. */ - arg.offsets = objfile->section_offsets; + arg.offsets = &objfile->section_offsets; arg.lowest = 0; bfd_map_over_sections (objfile->obfd, place_section, &arg); @@ -758,10 +694,10 @@ default_symfile_offsets (struct objfile *objfile, for (cur_sec = abfd->sections; cur_sec != NULL; cur_sec = cur_sec->next) { - if ((bfd_get_section_flags (abfd, cur_sec) & SEC_ALLOC) == 0) + if ((bfd_section_flags (cur_sec) & SEC_ALLOC) == 0) continue; - bfd_set_section_vma (abfd, cur_sec, offsets[cur_sec->index]); + bfd_set_section_vma (cur_sec, offsets[cur_sec->index]); exec_set_section_address (bfd_get_filename (abfd), cur_sec->index, offsets[cur_sec->index]); @@ -781,12 +717,11 @@ default_symfile_offsets (struct objfile *objfile, It assumes that object files do not have segments, and fully linked files have a single segment. */ -struct symfile_segment_data * +symfile_segment_data_up default_symfile_segments (bfd *abfd) { int num_sections, i; asection *sect; - struct symfile_segment_data *data; CORE_ADDR low, high; /* Relocatable files contain enough information to position each @@ -798,7 +733,7 @@ default_symfile_segments (bfd *abfd) /* Make sure there is at least one loadable section in the file. */ for (sect = abfd->sections; sect != NULL; sect = sect->next) { - if ((bfd_get_section_flags (abfd, sect) & SEC_ALLOC) == 0) + if ((bfd_section_flags (sect) & SEC_ALLOC) == 0) continue; break; @@ -806,35 +741,33 @@ default_symfile_segments (bfd *abfd) if (sect == NULL) return NULL; - low = bfd_get_section_vma (abfd, sect); - high = low + bfd_get_section_size (sect); + low = bfd_section_vma (sect); + high = low + bfd_section_size (sect); - data = XCNEW (struct symfile_segment_data); - data->num_segments = 1; - data->segment_bases = XCNEW (CORE_ADDR); - data->segment_sizes = XCNEW (CORE_ADDR); + symfile_segment_data_up data (new symfile_segment_data); num_sections = bfd_count_sections (abfd); - data->segment_info = XCNEWVEC (int, num_sections); + + /* All elements are initialized to 0 (map to no segment). */ + data->segment_info.resize (num_sections); for (i = 0, sect = abfd->sections; sect != NULL; i++, sect = sect->next) { CORE_ADDR vma; - if ((bfd_get_section_flags (abfd, sect) & SEC_ALLOC) == 0) + if ((bfd_section_flags (sect) & SEC_ALLOC) == 0) continue; - vma = bfd_get_section_vma (abfd, sect); + vma = bfd_section_vma (sect); if (vma < low) low = vma; - if (vma + bfd_get_section_size (sect) > high) - high = vma + bfd_get_section_size (sect); + if (vma + bfd_section_size (sect) > high) + high = vma + bfd_section_size (sect); data->segment_info[i] = 1; } - data->segment_bases[0] = low; - data->segment_sizes[0] = high - low; + data->segments.emplace_back (low, high - low); return data; } @@ -862,12 +795,13 @@ read_symbols (struct objfile *objfile, symfile_add_flags add_flags) 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.get (), objfile->original_name, - add_flags, objfile); + symbol_file_add_separate (abfd.get (), + bfd_get_filename (abfd.get ()), + add_flags | SYMFILE_NOT_FILENAME, objfile); } } if ((add_flags & SYMFILE_NO_READ) == 0) - require_partial_symbols (objfile, 0); + require_partial_symbols (objfile, false); } /* Initialize entry point information for this objfile. */ @@ -915,23 +849,23 @@ init_entry_point_info (struct objfile *objfile) /* Make certain that the address points at real code, and not a function descriptor. */ entry_point - = gdbarch_convert_from_func_ptr_addr (get_objfile_arch (objfile), + = gdbarch_convert_from_func_ptr_addr (objfile->arch (), entry_point, - ¤t_target); + current_top_target ()); /* Remove any ISA markers, so that this matches entries in the symbol table. */ ei->entry_point - = gdbarch_addr_bits_remove (get_objfile_arch (objfile), entry_point); + = gdbarch_addr_bits_remove (objfile->arch (), 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))) + if (entry_point >= bfd_section_vma (sect) + && entry_point < (bfd_section_vma (sect) + + bfd_section_size (sect))) { ei->the_bfd_section_index = gdb_bfd_section_index (objfile->obfd, sect); @@ -960,19 +894,21 @@ init_entry_point_info (struct objfile *objfile) (as gleaned by GDB's shared library code). We convert each address 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'. + into a format-specific offset table --- a `section_offsets'. + The sectindex field is used to control the ordering of sections + with the same name. Upon return, it is updated to contain the + corresponding BFD section index, or -1 if the section was not found. ADD_FLAGS encodes verbosity level, whether this is main symbol or - an extra symbol file such as dynamically loaded code, and wether + an extra symbol file such as dynamically loaded code, and whether breakpoint reset should be deferred. */ static void syms_from_objfile_1 (struct objfile *objfile, - struct section_addr_info *addrs, + section_addr_info *addrs, symfile_add_flags add_flags) { - struct section_addr_info *local_addr = NULL; - struct cleanup *old_chain; + section_addr_info local_addr; const int mainline = add_flags & SYMFILE_MAINLINE; objfile_set_sym_fns (objfile, find_sym_fns (objfile->obfd)); @@ -982,42 +918,34 @@ syms_from_objfile_1 (struct objfile *objfile, /* No symbols to load, but we still need to make sure that the section_offsets table is allocated. */ 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 - = (struct section_offsets *) obstack_alloc (&objfile->objfile_obstack, - size); - memset (objfile->section_offsets, 0, size); + objfile->section_offsets.assign (num_sections, 0); return; } /* Make sure that partially constructed symbol tables will be cleaned up if an error occurs during symbol reading. */ - old_chain = make_cleanup (null_cleanup, NULL); - std::unique_ptr objfile_holder (objfile); + gdb::optional defer_clear_users; + + objfile_up objfile_holder (objfile); /* 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) - { - local_addr = alloc_section_addr_info (1); - make_cleanup (xfree, local_addr); - addrs = local_addr; - } + addrs = &local_addr; if (mainline) { /* We will modify the main symbol table, make sure that all its users will be cleaned up if an error occurs during symbol reading. */ - make_cleanup (clear_symtab_users_cleanup, 0 /*ignore*/); + defer_clear_users.emplace ((symfile_add_flag) 0); /* Since no error yet, throw away the old symbol table. */ if (symfile_objfile != NULL) { - delete symfile_objfile; + symfile_objfile->unlink (); gdb_assert (symfile_objfile == NULL); } @@ -1035,7 +963,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->num_sections > 0) + if (addrs->size () > 0) addr_info_make_relative (addrs, objfile->obfd); /* Initialize symbol reading routines for this objfile, allow complaints to @@ -1043,17 +971,17 @@ syms_from_objfile_1 (struct objfile *objfile, initial symbol reading for this file. */ (*objfile->sf->sym_init) (objfile); - clear_complaints (&symfile_complaints, 1, add_flags & SYMFILE_VERBOSE); + clear_complaints (); - (*objfile->sf->sym_offsets) (objfile, addrs); + (*objfile->sf->sym_offsets) (objfile, *addrs); read_symbols (objfile, add_flags); /* Discard cleanups as symbol reading was successful. */ objfile_holder.release (); - discard_cleanups (old_chain); - xfree (local_addr); + if (defer_clear_users) + defer_clear_users->release (); } /* Same as syms_from_objfile_1, but also initializes the objfile @@ -1061,7 +989,7 @@ syms_from_objfile_1 (struct objfile *objfile, static void syms_from_objfile (struct objfile *objfile, - struct section_addr_info *addrs, + section_addr_info *addrs, symfile_add_flags add_flags) { syms_from_objfile_1 (objfile, addrs, add_flags); @@ -1091,7 +1019,7 @@ finish_new_objfile (struct objfile *objfile, symfile_add_flags add_flags) } /* We're done reading the symbol file; finish off complaints. */ - clear_complaints (&symfile_complaints, 0, add_flags & SYMFILE_VERBOSE); + clear_complaints (); } /* Process a symbol file, as either the main file or as a dynamically @@ -1103,7 +1031,7 @@ finish_new_objfile (struct objfile *objfile, symfile_add_flags add_flags) For NAME description see the objfile constructor. ADD_FLAGS encodes verbosity, whether this is main symbol file or - extra, such as dynamically loaded code, and what to do with breakpoins. + extra, such as dynamically loaded code, and what to do with breakpoints. ADDRS is as described for syms_from_objfile_1, above. ADDRS is ignored when SYMFILE_MAINLINE bit is set in ADD_FLAGS. @@ -1117,7 +1045,7 @@ finish_new_objfile (struct objfile *objfile, symfile_add_flags add_flags) static struct objfile * symbol_file_add_with_addrs (bfd *abfd, const char *name, symfile_add_flags add_flags, - struct section_addr_info *addrs, + section_addr_info *addrs, objfile_flags flags, struct objfile *parent) { struct objfile *objfile; @@ -1138,6 +1066,8 @@ symbol_file_add_with_addrs (bfd *abfd, const char *name, flags |= OBJF_READNEVER; add_flags |= SYMFILE_NO_READ; } + if ((add_flags & SYMFILE_NOT_FILENAME) != 0) + flags |= OBJF_NOT_FILENAME; /* Give user a chance to burp if we'd be interactively wiping out any existing symbols. */ @@ -1150,10 +1080,7 @@ symbol_file_add_with_addrs (bfd *abfd, const char *name, if (mainline) flags |= OBJF_MAINLINE; - objfile = new struct objfile (abfd, name, flags); - - if (parent) - add_separate_debug_objfile (objfile, parent); + objfile = objfile::make (abfd, name, flags, parent); /* We either created a new mapped symbol table, mapped an existing symbol table file which has not had initial symbol reading @@ -1163,11 +1090,8 @@ symbol_file_add_with_addrs (bfd *abfd, const char *name, if (deprecated_pre_add_symbol_hook) deprecated_pre_add_symbol_hook (name); else - { - printf_unfiltered (_("Reading symbols from %s..."), name); - wrap_here (""); - gdb_flush (gdb_stdout); - } + printf_filtered (_("Reading symbols from %ps...\n"), + styled_string (file_name_style.style (), name)); } syms_from_objfile (objfile, addrs, add_flags); @@ -1179,29 +1103,26 @@ symbol_file_add_with_addrs (bfd *abfd, const char *name, if ((flags & OBJF_READNOW)) { if (should_print) - { - printf_unfiltered (_("expanding to full symbols...")); - wrap_here (""); - gdb_flush (gdb_stdout); - } + printf_filtered (_("Expanding full symbols from %ps...\n"), + styled_string (file_name_style.style (), name)); if (objfile->sf) objfile->sf->qf->expand_all_symtabs (objfile); } - if (should_print && !objfile_has_symbols (objfile)) - { - wrap_here (""); - printf_unfiltered (_("(no debugging symbols found)...")); - wrap_here (""); - } + /* Note that we only print a message if we have no symbols and have + no separate debug file. If there is a separate debug file which + does not have symbols, we'll have emitted this message for that + file, and so printing it twice is just redundant. */ + if (should_print && !objfile_has_symbols (objfile) + && objfile->separate_debug_objfile == nullptr) + printf_filtered (_("(No debugging symbols found in %ps)\n"), + styled_string (file_name_style.style (), name)); if (should_print) { if (deprecated_post_add_symbol_hook) deprecated_post_add_symbol_hook (); - else - printf_unfiltered (_("done.\n")); } /* We print some messages regardless of whether 'from_tty || @@ -1211,13 +1132,13 @@ symbol_file_add_with_addrs (bfd *abfd, const char *name, if (objfile->sf == NULL) { - observer_notify_new_objfile (objfile); + gdb::observers::new_objfile.notify (objfile); return objfile; /* No symbols. */ } finish_new_objfile (objfile, add_flags); - observer_notify_new_objfile (objfile); + gdb::observers::new_objfile.notify (objfile); bfd_cache_close_all (); return (objfile); @@ -1231,22 +1152,16 @@ symbol_file_add_separate (bfd *bfd, const char *name, symfile_add_flags symfile_flags, struct objfile *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); + section_addr_info sap = build_section_addr_info_from_objfile (objfile); symbol_file_add_with_addrs - (bfd, name, symfile_flags, sap, + (bfd, name, symfile_flags, &sap, objfile->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW - | OBJF_USERLOADED), + | OBJF_USERLOADED | OBJF_MAINLINE), objfile); - - do_cleanups (my_cleanup); } /* Process the symbol file ABFD, as either the main file or as a @@ -1256,7 +1171,7 @@ symbol_file_add_separate (bfd *bfd, const char *name, struct objfile * symbol_file_add_from_bfd (bfd *abfd, const char *name, symfile_add_flags add_flags, - struct section_addr_info *addrs, + section_addr_info *addrs, objfile_flags flags, struct objfile *parent) { return symbol_file_add_with_addrs (abfd, name, add_flags, addrs, flags, @@ -1268,7 +1183,7 @@ symbol_file_add_from_bfd (bfd *abfd, const char *name, struct objfile * symbol_file_add (const char *name, symfile_add_flags add_flags, - struct section_addr_info *addrs, objfile_flags flags) + section_addr_info *addrs, objfile_flags flags) { gdb_bfd_ref_ptr bfd (symfile_bfd_open (name)); @@ -1287,16 +1202,18 @@ symbol_file_add (const char *name, symfile_add_flags add_flags, void symbol_file_add_main (const char *args, symfile_add_flags add_flags) { - symbol_file_add_main_1 (args, add_flags, 0); + symbol_file_add_main_1 (args, add_flags, 0, 0); } static void symbol_file_add_main_1 (const char *args, symfile_add_flags add_flags, - objfile_flags flags) + objfile_flags flags, CORE_ADDR reloff) { add_flags |= current_inferior ()->symfile_flags | SYMFILE_MAINLINE; - symbol_file_add (args, add_flags, NULL, flags); + struct objfile *objfile = symbol_file_add (args, add_flags, NULL, flags); + if (reloff != 0) + objfile_rebase (objfile, reloff); /* Getting new symbols may change our opinion about what is frameless. */ @@ -1321,16 +1238,18 @@ symbol_file_clear (int from_tty) objfiles get stale by free_all_objfiles. */ no_shared_libraries (NULL, from_tty); - free_all_objfiles (); + current_program_space->free_all_objfiles (); + + clear_symtab_users (0); gdb_assert (symfile_objfile == NULL); if (from_tty) - printf_unfiltered (_("No symbol file now.\n")); + printf_filtered (_("No symbol file now.\n")); } /* See symfile.h. */ -int separate_debug_file_debug = 0; +bool separate_debug_file_debug = false; static int separate_debug_file_exists (const std::string &name, unsigned long crc, @@ -1351,12 +1270,20 @@ separate_debug_file_exists (const std::string &name, unsigned long crc, return 0; if (separate_debug_file_debug) - printf_unfiltered (_(" Trying %s\n"), name.c_str ()); + { + printf_filtered (_(" Trying %s..."), name.c_str ()); + gdb_flush (gdb_stdout); + } - gdb_bfd_ref_ptr abfd (gdb_bfd_open (name.c_str (), gnutarget, -1)); + gdb_bfd_ref_ptr abfd (gdb_bfd_open (name.c_str (), gnutarget)); if (abfd == NULL) - return 0; + { + if (separate_debug_file_debug) + printf_filtered (_(" no, unable to open.\n")); + + return 0; + } /* Verify symlinks were not the cause of filename_cmp name difference above. @@ -1375,7 +1302,12 @@ separate_debug_file_exists (const std::string &name, unsigned long crc, { if (abfd_stat.st_dev == parent_stat.st_dev && abfd_stat.st_ino == parent_stat.st_ino) - return 0; + { + if (separate_debug_file_debug) + printf_filtered (_(" no, same file as the objfile.\n")); + + return 0; + } verified_as_different = 1; } else @@ -1384,7 +1316,12 @@ separate_debug_file_exists (const std::string &name, unsigned long crc, file_crc_p = gdb_bfd_crc (abfd.get (), &file_crc); if (!file_crc_p) - return 0; + { + if (separate_debug_file_debug) + printf_filtered (_(" no, error computing CRC.\n")); + + return 0; + } if (crc != file_crc) { @@ -1397,7 +1334,12 @@ separate_debug_file_exists (const std::string &name, unsigned long crc, if (!verified_as_different) { if (!gdb_bfd_crc (parent_objfile->obfd, &parent_crc)) - return 0; + { + if (separate_debug_file_debug) + printf_filtered (_(" no, error computing CRC.\n")); + + return 0; + } } if (verified_as_different || parent_crc != file_crc) @@ -1405,9 +1347,15 @@ separate_debug_file_exists (const std::string &name, unsigned long crc, " does not match \"%s\" (CRC mismatch).\n"), name.c_str (), objfile_name (parent_objfile)); + if (separate_debug_file_debug) + printf_filtered (_(" no, CRC doesn't match.\n")); + return 0; } + if (separate_debug_file_debug) + printf_filtered (_(" yes!\n")); + return 1; } @@ -1441,8 +1389,8 @@ find_separate_debug_file (const char *dir, unsigned long crc32, struct objfile *objfile) { if (separate_debug_file_debug) - printf_unfiltered (_("\nLooking for separate debug info (debug link) for " - "%s\n"), objfile_name (objfile)); + printf_filtered (_("\nLooking for separate debug info (debug link) for " + "%s\n"), objfile_name (objfile)); /* First try in the same directory as the original file. */ std::string debugfile = dir; @@ -1465,34 +1413,81 @@ find_separate_debug_file (const char *dir, Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will cause "/..." lookups. */ + bool target_prefix = startswith (dir, "target:"); + const char *dir_notarget = target_prefix ? dir + strlen ("target:") : dir; std::vector> debugdir_vec = dirnames_to_char_ptr_vec (debug_file_directory); + gdb::unique_xmalloc_ptr canon_sysroot = gdb_realpath (gdb_sysroot); + + /* MS-Windows/MS-DOS don't allow colons in file names; we must + convert the drive letter into a one-letter directory, so that the + file name resulting from splicing below will be valid. + + FIXME: The below only works when GDB runs on MS-Windows/MS-DOS. + There are various remote-debugging scenarios where such a + transformation of the drive letter might be required when GDB runs + on a Posix host, see + + https://sourceware.org/ml/gdb-patches/2019-04/msg00605.html + + If some of those scenarios need to be supported, we will need to + use a different condition for HAS_DRIVE_SPEC and a different macro + instead of STRIP_DRIVE_SPEC, which work on Posix systems as well. */ + std::string drive; + if (HAS_DRIVE_SPEC (dir_notarget)) + { + drive = dir_notarget[0]; + dir_notarget = STRIP_DRIVE_SPEC (dir_notarget); + } for (const gdb::unique_xmalloc_ptr &debugdir : debugdir_vec) { - debugfile = debugdir.get (); + debugfile = target_prefix ? "target:" : ""; + debugfile += debugdir.get (); debugfile += "/"; - debugfile += dir; + debugfile += drive; + debugfile += dir_notarget; debugfile += debuglink; if (separate_debug_file_exists (debugfile, crc32, objfile)) return debugfile; - /* If the file is in the sysroot, try using its base path in the - global debugfile directory. */ - if (canon_dir != NULL - && filename_ncmp (canon_dir, gdb_sysroot, - strlen (gdb_sysroot)) == 0 - && IS_DIR_SEPARATOR (canon_dir[strlen (gdb_sysroot)])) + const char *base_path = NULL; + if (canon_dir != NULL) + { + if (canon_sysroot.get () != NULL) + base_path = child_path (canon_sysroot.get (), canon_dir); + else + base_path = child_path (gdb_sysroot, canon_dir); + } + if (base_path != NULL) { - debugfile = debugdir.get (); - debugfile += (canon_dir + strlen (gdb_sysroot)); + /* If the file is in the sysroot, try using its base path in + the global debugfile directory. */ + debugfile = target_prefix ? "target:" : ""; + debugfile += debugdir.get (); + debugfile += "/"; + debugfile += base_path; + debugfile += "/"; + debugfile += debuglink; + + if (separate_debug_file_exists (debugfile, crc32, objfile)) + return debugfile; + + /* If the file is in the sysroot, try using its base path in + the sysroot's global debugfile directory. */ + debugfile = target_prefix ? "target:" : ""; + debugfile += gdb_sysroot; + debugfile += debugdir.get (); + debugfile += "/"; + debugfile += base_path; debugfile += "/"; debugfile += debuglink; if (separate_debug_file_exists (debugfile, crc32, objfile)) return debugfile; } + } return std::string (); @@ -1613,6 +1608,7 @@ symbol_file_command (const char *args, int from_tty) symfile_add_flags add_flags = 0; char *name = NULL; bool stop_processing_options = false; + CORE_ADDR offset = 0; int idx; char *arg; @@ -1633,6 +1629,14 @@ symbol_file_command (const char *args, int from_tty) flags |= OBJF_READNOW; else if (strcmp (arg, "-readnever") == 0) flags |= OBJF_READNEVER; + else if (strcmp (arg, "-o") == 0) + { + arg = built_argv[++idx]; + if (arg == NULL) + error (_("Missing argument to -o")); + + offset = parse_and_eval_address (arg); + } else if (strcmp (arg, "--") == 0) stop_processing_options = true; else @@ -1644,39 +1648,47 @@ symbol_file_command (const char *args, int from_tty) validate_readnow_readnever (flags); - symbol_file_add_main_1 (name, add_flags, flags); + /* Set SYMFILE_DEFER_BP_RESET because the proper displacement for a PIE + (Position Independent Executable) main symbol file will only be + computed by the solib_create_inferior_hook below. Without it, + breakpoint_re_set would fail to insert the breakpoints with the zero + displacement. */ + add_flags |= SYMFILE_DEFER_BP_RESET; + + symbol_file_add_main_1 (name, add_flags, flags, offset); + + solib_create_inferior_hook (from_tty); + + /* Now it's safe to re-add the breakpoints. */ + breakpoint_re_set (); } } -/* Set the initial language. - - FIXME: A better solution would be to record the language in the - psymtab when reading partial symbols, and then use it (if known) to - set the language. This would be a win for formats that encode the - language in an easily discoverable place, such as DWARF. For - stabs, we can jump through hoops looking for specially named - symbols or try to intuit the language from the specific type of - stabs we find, but we can't do that until later when we read in - full symbols. */ +/* Set the initial language. */ void set_initial_language (void) { + if (language_mode == language_mode_manual) + return; enum language lang = main_language (); + /* Make C the default language. */ + enum language default_lang = language_c; if (lang == language_unknown) { - char *name = main_name (); - struct symbol *sym = lookup_symbol (name, NULL, VAR_DOMAIN, NULL).symbol; + const char *name = main_name (); + struct symbol *sym + = lookup_symbol_in_language (name, NULL, VAR_DOMAIN, default_lang, + NULL).symbol; if (sym != NULL) - lang = SYMBOL_LANGUAGE (sym); + lang = sym->language (); } if (lang == language_unknown) { - /* Make C the default language */ - lang = language_c; + lang = default_lang; } set_language (lang); @@ -1846,7 +1858,7 @@ add_section_size_callback (bfd *abfd, asection *asec, void *data) { bfd_size_type *sum = (bfd_size_type *) data; - *sum += bfd_get_section_size (asec); + *sum += bfd_section_size (asec); } /* Opaque data for load_progress. */ @@ -1969,16 +1981,16 @@ static void load_section_callback (bfd *abfd, asection *asec, void *data) { struct load_section_data *args = (struct load_section_data *) data; - bfd_size_type size = bfd_get_section_size (asec); - const char *sect_name = bfd_get_section_name (abfd, asec); + bfd_size_type size = bfd_section_size (asec); + const char *sect_name = bfd_section_name (asec); - if ((bfd_get_section_flags (abfd, asec) & SEC_LOAD) == 0) + if ((bfd_section_flags (asec) & SEC_LOAD) == 0) return; if (size == 0) return; - ULONGEST begin = bfd_section_lma (abfd, asec) + args->load_offset; + ULONGEST begin = bfd_section_lma (asec) + args->load_offset; ULONGEST end = begin + size; gdb_byte *buffer = (gdb_byte *) xmalloc (size); bfd_get_section_contents (abfd, asec, buffer, 0, size); @@ -1995,6 +2007,8 @@ static void print_transfer_performance (struct ui_file *stream, unsigned long write_count, std::chrono::steady_clock::duration d); +/* See symfile.h. */ + void generic_load (const char *args, int from_tty) { @@ -2025,7 +2039,7 @@ generic_load (const char *args, int from_tty) } /* Open the file for loading. */ - gdb_bfd_ref_ptr loadfile_bfd (gdb_bfd_open (filename.get (), gnutarget, -1)); + gdb_bfd_ref_ptr loadfile_bfd (gdb_bfd_open (filename.get (), gnutarget)); if (loadfile_bfd == NULL) perror_with_name (filename.get ()); @@ -2053,9 +2067,9 @@ generic_load (const char *args, int from_tty) CORE_ADDR entry = bfd_get_start_address (loadfile_bfd.get ()); entry = gdbarch_addr_bits_remove (target_gdbarch (), entry); uiout->text ("Start address "); - uiout->field_fmt ("address", "%s", paddress (target_gdbarch (), entry)); + uiout->field_core_addr ("address", target_gdbarch (), entry); uiout->text (", load size "); - uiout->field_fmt ("load-size", "%lu", total_progress.data_count); + uiout->field_unsigned ("load-size", total_progress.data_count); uiout->text ("\n"); regcache_write_pc (get_current_regcache (), entry); @@ -2098,42 +2112,90 @@ print_transfer_performance (struct ui_file *stream, if (uiout->is_mi_like_p ()) { - uiout->field_fmt ("transfer-rate", "%lu", rate * 8); + uiout->field_unsigned ("transfer-rate", rate * 8); uiout->text (" bits/sec"); } else if (rate < 1024) { - uiout->field_fmt ("transfer-rate", "%lu", rate); + uiout->field_unsigned ("transfer-rate", rate); uiout->text (" bytes/sec"); } else { - uiout->field_fmt ("transfer-rate", "%lu", rate / 1024); + uiout->field_unsigned ("transfer-rate", rate / 1024); uiout->text (" KB/sec"); } } else { - uiout->field_fmt ("transferred-bits", "%lu", (data_count * 8)); + uiout->field_unsigned ("transferred-bits", (data_count * 8)); uiout->text (" bits in <1 sec"); } if (write_count > 0) { uiout->text (", "); - uiout->field_fmt ("write-rate", "%lu", data_count / write_count); + uiout->field_unsigned ("write-rate", data_count / write_count); uiout->text (" bytes/write"); } uiout->text (".\n"); } +/* Add an OFFSET to the start address of each section in OBJF, except + sections that were specified in ADDRS. */ + +static void +set_objfile_default_section_offset (struct objfile *objf, + const section_addr_info &addrs, + CORE_ADDR offset) +{ + /* Add OFFSET to all sections by default. */ + section_offsets offsets (objf->section_offsets.size (), offset); + + /* Create sorted lists of all sections in ADDRS as well as all + sections in OBJF. */ + + std::vector addrs_sorted + = addrs_section_sort (addrs); + + section_addr_info objf_addrs + = build_section_addr_info_from_objfile (objf); + std::vector objf_addrs_sorted + = addrs_section_sort (objf_addrs); + + /* Walk the BFD section list, and if a matching section is found in + ADDRS_SORTED_LIST, set its offset to zero to keep its address + unchanged. + + Note that both lists may contain multiple sections with the same + name, and then the sections from ADDRS are matched in BFD order + (thanks to sectindex). */ + + std::vector::iterator addrs_sorted_iter + = addrs_sorted.begin (); + for (const other_sections *objf_sect : objf_addrs_sorted) + { + const char *objf_name = addr_section_name (objf_sect->name.c_str ()); + int cmp = -1; + + while (cmp < 0 && addrs_sorted_iter != addrs_sorted.end ()) + { + const struct other_sections *sect = *addrs_sorted_iter; + const char *sect_name = addr_section_name (sect->name.c_str ()); + cmp = strcmp (sect_name, objf_name); + if (cmp <= 0) + ++addrs_sorted_iter; + } + + if (cmp == 0) + offsets[objf_sect->sectindex] = 0; + } + + /* Apply the new section offsets. */ + objfile_relocate (objf, offsets); +} + /* This function allows the addition of incrementally linked object files. It does not modify any state in the target, only in the debugger. */ -/* Note: ezannoni 2000-04-13 This function/command used to have a - special case syntax for the rombug target (Rombug is the boot - monitor for Microware's OS-9 / OS-9000, see remote-os9k.c). In the - rombug case, the user doesn't need to supply a text address, - instead a call to target_link() (in target.c) would supply the - value to use. We are now discontinuing this type of ad hoc syntax. */ static void add_symbol_file_command (const char *args, int from_tty) @@ -2142,7 +2204,6 @@ add_symbol_file_command (const char *args, int from_tty) gdb::unique_xmalloc_ptr filename; char *arg; int argcnt = 0; - int sec_num = 0; struct objfile *objf; objfile_flags flags = OBJF_USERLOADED | OBJF_SHARED; symfile_add_flags add_flags = 0; @@ -2156,10 +2217,9 @@ add_symbol_file_command (const char *args, int from_tty) const char *value; }; - struct section_addr_info *section_addrs; std::vector sect_opts = { { ".text", NULL } }; bool stop_processing_options = false; - struct cleanup *my_cleanups = make_cleanup (null_cleanup, NULL); + CORE_ADDR offset = 0; dont_repeat (); @@ -2167,6 +2227,7 @@ add_symbol_file_command (const char *args, int from_tty) error (_("add-symbol-file takes a file name and an address")); bool seen_addr = false; + bool seen_offset = false; gdb_argv argv (args); for (arg = argv[0], argcnt = 0; arg != NULL; arg = argv[++argcnt]) @@ -2204,6 +2265,15 @@ add_symbol_file_command (const char *args, int from_tty) sect_opts.push_back (sect); argcnt += 2; } + else if (strcmp (arg, "-o") == 0) + { + arg = argv[++argcnt]; + if (arg == NULL) + error (_("Missing argument to -o")); + + offset = parse_and_eval_address (arg); + seen_offset = true; + } else if (strcmp (arg, "--") == 0) stop_processing_options = true; else @@ -2215,39 +2285,37 @@ add_symbol_file_command (const char *args, int from_tty) validate_readnow_readnever (flags); - /* This command takes at least two arguments. The first one is a - filename, and the second is the address where this file has been - loaded. Abort now if this address hasn't been provided by the - user. */ - if (!seen_addr) - error (_("The address where %s has been loaded is missing"), - filename.get ()); - /* Print the prompt for the query below. And save the arguments into a sect_addr_info structure to be passed around to other functions. We have to split this up into separate print statements because hex_string returns a local static string. */ - printf_unfiltered (_("add symbol table from file \"%s\" at\n"), + printf_unfiltered (_("add symbol table from file \"%s\""), filename.get ()); - section_addrs = alloc_section_addr_info (sect_opts.size ()); - make_cleanup (xfree, section_addrs); - for (sect_opt § : sect_opts) + section_addr_info section_addrs; + std::vector::const_iterator it = sect_opts.begin (); + if (!seen_addr) + ++it; + for (; it != sect_opts.end (); ++it) { CORE_ADDR addr; - const char *val = sect.value; - const char *sec = sect.name; + const char *val = it->value; + const char *sec = it->name; + if (section_addrs.empty ()) + printf_unfiltered (_(" at\n")); addr = parse_and_eval_address (val); /* Here we store the section offsets in the order they were - entered on the command line. */ - section_addrs->other[sec_num].name = (char *) sec; - section_addrs->other[sec_num].addr = addr; - printf_unfiltered ("\t%s_addr = %s\n", sec, - paddress (gdbarch, addr)); - sec_num++; + entered on the command line. Every array element is + assigned an ascending section index to preserve the above + order over an unstable sorting algorithm. This dummy + index is not used for any other purpose. + */ + section_addrs.emplace_back (addr, sec, section_addrs.size ()); + printf_filtered ("\t%s_addr = %s\n", sec, + paddress (gdbarch, addr)); /* The object's sections are initialized when a call is made to build_objfile_section_table (objfile). @@ -2255,19 +2323,32 @@ add_symbol_file_command (const 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 (seen_offset) + printf_unfiltered (_("%s offset by %s\n"), + (section_addrs.empty () + ? _(" with all sections") + : _("with other sections")), + paddress (gdbarch, offset)); + else if (section_addrs.empty ()) + printf_unfiltered ("\n"); if (from_tty && (!query ("%s", ""))) error (_("Not confirmed.")); - objf = symbol_file_add (filename.get (), add_flags, section_addrs, flags); + objf = symbol_file_add (filename.get (), add_flags, §ion_addrs, + flags); + if (!objfile_has_symbols (objf) && objf->per_bfd->minimal_symbol_count <= 0) + warning (_("newly-added symbol file \"%s\" does not provide any symbols"), + filename.get ()); + + if (seen_offset) + set_objfile_default_section_offset (objf, section_addrs, offset); add_target_sections_of_objfile (objf); /* Getting new symbols may change our opinion about what is frameless. */ reinit_frame_cache (); - do_cleanups (my_cleanups); } @@ -2299,12 +2380,16 @@ remove_symbol_file_command (const char *args, int from_tty) addr = parse_and_eval_address (argv[1]); - ALL_OBJFILES (objf) + for (objfile *objfile : current_program_space->objfiles ()) { - if ((objf->flags & OBJF_USERLOADED) != 0 - && (objf->flags & OBJF_SHARED) != 0 - && objf->pspace == pspace && is_addr_in_objfile (addr, objf)) - break; + if ((objfile->flags & OBJF_USERLOADED) != 0 + && (objfile->flags & OBJF_SHARED) != 0 + && objfile->pspace == pspace + && is_addr_in_objfile (addr, objfile)) + { + objf = objfile; + break; + } } } else if (argv[0] != NULL) @@ -2316,13 +2401,16 @@ remove_symbol_file_command (const char *args, int from_tty) gdb::unique_xmalloc_ptr filename (tilde_expand (argv[0])); - ALL_OBJFILES (objf) + for (objfile *objfile : current_program_space->objfiles ()) { - if ((objf->flags & OBJF_USERLOADED) != 0 - && (objf->flags & OBJF_SHARED) != 0 - && objf->pspace == pspace - && filename_cmp (filename.get (), objfile_name (objf)) == 0) - break; + if ((objfile->flags & OBJF_USERLOADED) != 0 + && (objfile->flags & OBJF_SHARED) != 0 + && objfile->pspace == pspace + && filename_cmp (filename.get (), objfile_name (objfile)) == 0) + { + objf = objfile; + break; + } } } @@ -2334,7 +2422,7 @@ remove_symbol_file_command (const char *args, int from_tty) objfile_name (objf))) error (_("Not confirmed.")); - delete objf; + objf->unlink (); clear_symtab_users (0); } @@ -2343,19 +2431,12 @@ remove_symbol_file_command (const char *args, int from_tty) void reread_symbols (void) { - struct objfile *objfile; long new_modtime; struct stat new_statbuf; int res; std::vector new_objfiles; - /* With the addition of shared libraries, this should be modified, - the load time should be saved in the partial symbol tables, since - different tables may come from different source files. FIXME. - This routine should then walk down each partial symbol table - and see if the symbol table that it originates from has been changed. */ - - for (objfile = object_files; objfile; objfile = objfile->next) + for (objfile *objfile : current_program_space->objfiles ()) { if (objfile->obfd == NULL) continue; @@ -2369,26 +2450,21 @@ reread_symbols (void) a `shared library' on AIX is also an archive), then you should stat on the archive name, not member name. */ if (objfile->obfd->my_archive) - res = stat (objfile->obfd->my_archive->filename, &new_statbuf); + res = stat (bfd_get_filename (objfile->obfd->my_archive), &new_statbuf); else 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)); + printf_filtered (_("`%s' has disappeared; keeping its symbols.\n"), + objfile_name (objfile)); continue; } new_modtime = new_statbuf.st_mtime; if (new_modtime != objfile->mtime) { - struct cleanup *old_cleanups; - struct section_offsets *offsets; - int num_offsets; - char *original_name; - - printf_unfiltered (_("`%s' has changed; re-reading symbols.\n"), - objfile_name (objfile)); + printf_filtered (_("`%s' has changed; re-reading symbols.\n"), + objfile_name (objfile)); /* There are various functions like symbol_file_add, symfile_bfd_open, syms_from_objfile, etc., which might @@ -2400,10 +2476,10 @@ reread_symbols (void) /* If we get an error, blow away this objfile (not sure if that is the correct response for things like shared libraries). */ - std::unique_ptr objfile_holder (objfile); + objfile_up objfile_holder (objfile); /* We need to do this whenever any symbols go away. */ - old_cleanups = make_cleanup (clear_symtab_users_cleanup, 0 /*ignore*/); + clear_symtab_users_cleanup defer_clear_users (0); if (exec_bfd != NULL && filename_cmp (bfd_get_filename (objfile->obfd), @@ -2420,6 +2496,9 @@ reread_symbols (void) automatically recreated by sym_read. */ free_objfile_separate_debug (objfile); + /* Clear the stale source cache. */ + forget_cached_source_info (); + /* Remove any references to this objfile in the global value lists. */ preserve_values (objfile); @@ -2440,51 +2519,38 @@ reread_symbols (void) /* Clean up any state BFD has sitting around. */ { gdb_bfd_ref_ptr obfd (objfile->obfd); - char *obfd_filename; + const char *obfd_filename; obfd_filename = bfd_get_filename (objfile->obfd); /* Open the new BFD before freeing the old one, so that the filename remains live. */ - gdb_bfd_ref_ptr temp (gdb_bfd_open (obfd_filename, gnutarget, -1)); + gdb_bfd_ref_ptr temp (gdb_bfd_open (obfd_filename, gnutarget)); objfile->obfd = temp.release (); if (objfile->obfd == NULL) error (_("Can't open %s to read symbols."), obfd_filename); } - original_name = xstrdup (objfile->original_name); - make_cleanup (xfree, original_name); + std::string original_name = objfile->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 (objfile), 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)); - - /* FIXME: Do we have to free a whole linked list, or is this - enough? */ - objfile->global_psymbols.clear (); - objfile->static_psymbols.clear (); - - /* Free the obstacks for non-reusable objfiles. */ - psymbol_bcache_free (objfile->psymbol_cache); - objfile->psymbol_cache = psymbol_bcache_init (); + objfile->reset_psymtabs (); /* NB: after this call to obstack_free, objfiles_changed will need to be called (see discussion below). */ obstack_free (&objfile->objfile_obstack, 0); objfile->sections = NULL; + objfile->section_offsets.clear (); + objfile->sect_index_bss = -1; + objfile->sect_index_data = -1; + objfile->sect_index_rodata = -1; + objfile->sect_index_text = -1; objfile->compunit_symtabs = NULL; - objfile->psymtabs = NULL; - objfile->psymtabs_addrmap = NULL; - objfile->free_psymtabs = NULL; objfile->template_symbols = NULL; + objfile->static_links.reset (nullptr); /* obstack_init also initializes the obstack so it is empty. We could use obstack_specify_allocation but @@ -2498,8 +2564,7 @@ reread_symbols (void) set_objfile_per_bfd (objfile); objfile->original_name - = (char *) obstack_copy0 (&objfile->objfile_obstack, original_name, - strlen (original_name)); + = obstack_strdup (&objfile->objfile_obstack, 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 @@ -2507,16 +2572,6 @@ reread_symbols (void) objfile_set_sym_fns (objfile, find_sym_fns (objfile->obfd)); build_objfile_section_table (objfile); - 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 @@ -2527,7 +2582,7 @@ reread_symbols (void) } (*objfile->sf->sym_init) (objfile); - clear_complaints (&symfile_complaints, 1, 1); + clear_complaints (); objfile->flags &= ~OBJF_PSYMTABS_READ; @@ -2547,17 +2602,20 @@ reread_symbols (void) objfiles_changed (); + /* Recompute section offsets and section indices. */ + objfile->sf->sym_offsets (objfile, {}); + read_symbols (objfile, 0); if (!objfile_has_symbols (objfile)) { wrap_here (""); - printf_unfiltered (_("(no debugging symbols found)\n")); + printf_filtered (_("(no debugging symbols found)\n")); wrap_here (""); } /* We're done reading the symbol file; finish off complaints. */ - clear_complaints (&symfile_complaints, 0, 1); + clear_complaints (); /* Getting new symbols may change our opinion about what is frameless. */ @@ -2566,7 +2624,7 @@ reread_symbols (void) /* Discard cleanups as symbol reading was successful. */ objfile_holder.release (); - discard_cleanups (old_cleanups); + defer_clear_users.release (); /* 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 @@ -2583,14 +2641,14 @@ reread_symbols (void) clear_symtab_users (0); /* clear_objfile_data for each objfile was called before freeing it and - observer_notify_new_objfile (NULL) has been called by + gdb::observers::new_objfile.notify (NULL) has been called by clear_symtab_users above. Notify the new files now. */ for (auto iter : new_objfiles) - observer_notify_new_objfile (iter); + gdb::observers::new_objfile.notify (iter); /* At least one objfile has changed, so we can consider that the executable we're debugging has changed too. */ - observer_notify_executable_changed (); + gdb::observers::executable_changed.notify (); } } @@ -2721,9 +2779,7 @@ allocate_symtab (struct compunit_symtab *cust, const char *filename) struct symtab *symtab = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symtab); - symtab->filename - = (const char *) bcache (filename, strlen (filename) + 1, - objfile->per_bfd->filename_cache); + symtab->filename = objfile->intern (filename); symtab->fullname = NULL; symtab->language = deduce_language_from_filename (filename); @@ -2740,13 +2796,13 @@ allocate_symtab (struct compunit_symtab *cust, const char *filename) { xfree (last_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); + fprintf_filtered (gdb_stdlog, + "Creating one or more symtabs for objfile %s ...\n", + last_objfile_name); } - fprintf_unfiltered (gdb_stdlog, - "Created symtab %s for module %s.\n", - host_address_to_string (symtab), filename); + fprintf_filtered (gdb_stdlog, + "Created symtab %s for module %s.\n", + host_address_to_string (symtab), filename); } /* Add it to CUST's list of symtabs. */ @@ -2784,18 +2840,16 @@ allocate_compunit_symtab (struct objfile *objfile, const char *name) 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)); + cu->name = obstack_strdup (&objfile->objfile_obstack, 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); + fprintf_filtered (gdb_stdlog, + "Created compunit symtab %s for %s.\n", + host_address_to_string (cu), + cu->name); } return cu; @@ -2827,13 +2881,7 @@ clear_symtab_users (symfile_add_flags add_flags) clear_displays (); clear_last_displayed_sal (); clear_pc_function_cache (); - observer_notify_new_objfile (NULL); - - /* Clear globals which might have pointed into a removed objfile. - FIXME: It's not clear which of these are supposed to persist - between expressions and which ought to be reset each time. */ - expression_context_block = NULL; - innermost_block.reset (); + gdb::observers::new_objfile.notify (NULL); /* Varobj may refer to old symbols, perform a cleanup. */ varobj_invalidate (); @@ -2843,12 +2891,6 @@ clear_symtab_users (symfile_add_flags add_flags) if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0) breakpoint_re_set (); } - -static void -clear_symtab_users_cleanup (void *ignore) -{ - clear_symtab_users (0); -} /* OVERLAYS: The following code implements an abstraction for debugging overlay sections. @@ -2914,9 +2956,8 @@ section_is_overlay (struct obj_section *section) { asection *bfd_section = section->the_bfd_section; - if (bfd_section_lma (abfd, bfd_section) != 0 - && bfd_section_lma (abfd, bfd_section) - != bfd_section_vma (abfd, bfd_section)) + if (bfd_section_lma (bfd_section) != 0 + && bfd_section_lma (bfd_section) != bfd_section_vma (bfd_section)) return 1; } @@ -2929,12 +2970,12 @@ section_is_overlay (struct obj_section *section) static void overlay_invalidate_all (void) { - struct objfile *objfile; struct obj_section *sect; - ALL_OBJSECTIONS (objfile, sect) - if (section_is_overlay (sect)) - sect->ovly_mapped = -1; + for (objfile *objfile : current_program_space->objfiles ()) + ALL_OBJFILE_OSECTIONS (objfile, sect) + if (section_is_overlay (sect)) + sect->ovly_mapped = -1; } /* Function: section_is_mapped (SECTION) @@ -2962,7 +3003,7 @@ section_is_mapped (struct obj_section *osect) case ovly_auto: /* overlay debugging automatic */ /* Unles there is a gdbarch_overlay_update function, there's really nothing useful to do here (can't really go auto). */ - gdbarch = get_objfile_arch (osect->objfile); + gdbarch = osect->objfile->arch (); if (gdbarch_overlay_update_p (gdbarch)) { if (overlay_cache_invalid) @@ -2973,7 +3014,7 @@ section_is_mapped (struct obj_section *osect) if (osect->ovly_mapped == -1) gdbarch_overlay_update (gdbarch, osect); } - /* fall thru to manual case */ + /* fall thru */ case ovly_on: /* overlay debugging manual */ return osect->ovly_mapped == 1; } @@ -2987,15 +3028,14 @@ pc_in_unmapped_range (CORE_ADDR pc, struct obj_section *section) { if (section_is_overlay (section)) { - bfd *abfd = section->objfile->obfd; asection *bfd_section = section->the_bfd_section; /* We assume the LMA is relocated by the same offset as the VMA. */ - bfd_vma size = bfd_get_section_size (bfd_section); + bfd_vma size = bfd_section_size (bfd_section); CORE_ADDR offset = obj_section_offset (section); - if (bfd_get_section_lma (abfd, bfd_section) + offset <= pc - && pc < bfd_get_section_lma (abfd, bfd_section) + offset + size) + if (bfd_section_lma (bfd_section) + offset <= pc + && pc < bfd_section_lma (bfd_section) + offset + size) return 1; } @@ -3043,8 +3083,8 @@ overlay_unmapped_address (CORE_ADDR pc, struct obj_section *section) { asection *bfd_section = section->the_bfd_section; - return pc + bfd_section_lma (abfd, bfd_section) - - bfd_section_vma (abfd, bfd_section); + return (pc + bfd_section_lma (bfd_section) + - bfd_section_vma (bfd_section)); } return pc; @@ -3061,8 +3101,8 @@ overlay_mapped_address (CORE_ADDR pc, struct obj_section *section) { asection *bfd_section = section->the_bfd_section; - return pc + bfd_section_vma (abfd, bfd_section) - - bfd_section_lma (abfd, bfd_section); + return (pc + bfd_section_vma (bfd_section) + - bfd_section_lma (bfd_section)); } return pc; @@ -3105,24 +3145,24 @@ symbol_overlayed_address (CORE_ADDR address, struct obj_section *section) struct obj_section * find_pc_overlay (CORE_ADDR pc) { - struct objfile *objfile; struct obj_section *osect, *best_match = NULL; if (overlay_debugging) { - ALL_OBJSECTIONS (objfile, osect) - if (section_is_overlay (osect)) - { - if (pc_in_mapped_range (pc, osect)) - { - if (section_is_mapped (osect)) - return osect; - else - best_match = osect; - } - else if (pc_in_unmapped_range (pc, osect)) - best_match = osect; - } + for (objfile *objfile : current_program_space->objfiles ()) + ALL_OBJFILE_OSECTIONS (objfile, osect) + if (section_is_overlay (osect)) + { + if (pc_in_mapped_range (pc, osect)) + { + if (section_is_mapped (osect)) + return osect; + else + best_match = osect; + } + else if (pc_in_unmapped_range (pc, osect)) + best_match = osect; + } } return best_match; } @@ -3134,14 +3174,14 @@ find_pc_overlay (CORE_ADDR pc) struct obj_section * find_pc_mapped_section (CORE_ADDR pc) { - struct objfile *objfile; struct obj_section *osect; if (overlay_debugging) { - ALL_OBJSECTIONS (objfile, osect) - if (pc_in_mapped_range (pc, osect) && section_is_mapped (osect)) - return osect; + for (objfile *objfile : current_program_space->objfiles ()) + ALL_OBJFILE_OSECTIONS (objfile, osect) + if (pc_in_mapped_range (pc, osect) && section_is_mapped (osect)) + return osect; } return NULL; @@ -3154,36 +3194,36 @@ static void list_overlays_command (const char *args, int from_tty) { int nmapped = 0; - struct objfile *objfile; struct obj_section *osect; if (overlay_debugging) { - ALL_OBJSECTIONS (objfile, osect) - if (section_is_mapped (osect)) - { - struct gdbarch *gdbarch = get_objfile_arch (objfile); - const char *name; - bfd_vma lma, vma; - int size; - - vma = bfd_section_vma (objfile->obfd, osect->the_bfd_section); - lma = bfd_section_lma (objfile->obfd, osect->the_bfd_section); - size = bfd_get_section_size (osect->the_bfd_section); - name = bfd_section_name (objfile->obfd, osect->the_bfd_section); - - printf_filtered ("Section %s, loaded at ", name); - fputs_filtered (paddress (gdbarch, lma), gdb_stdout); - puts_filtered (" - "); - fputs_filtered (paddress (gdbarch, lma + size), gdb_stdout); - printf_filtered (", mapped at "); - fputs_filtered (paddress (gdbarch, vma), gdb_stdout); - puts_filtered (" - "); - fputs_filtered (paddress (gdbarch, vma + size), gdb_stdout); - puts_filtered ("\n"); - - nmapped++; - } + for (objfile *objfile : current_program_space->objfiles ()) + ALL_OBJFILE_OSECTIONS (objfile, osect) + if (section_is_mapped (osect)) + { + struct gdbarch *gdbarch = objfile->arch (); + const char *name; + bfd_vma lma, vma; + int size; + + vma = bfd_section_vma (osect->the_bfd_section); + lma = bfd_section_lma (osect->the_bfd_section); + size = bfd_section_size (osect->the_bfd_section); + name = bfd_section_name (osect->the_bfd_section); + + printf_filtered ("Section %s, loaded at ", name); + fputs_filtered (paddress (gdbarch, lma), gdb_stdout); + puts_filtered (" - "); + fputs_filtered (paddress (gdbarch, lma + size), gdb_stdout); + printf_filtered (", mapped at "); + fputs_filtered (paddress (gdbarch, vma), gdb_stdout); + puts_filtered (" - "); + fputs_filtered (paddress (gdbarch, vma + size), gdb_stdout); + puts_filtered ("\n"); + + nmapped++; + } } if (nmapped == 0) printf_filtered (_("No sections are mapped.\n")); @@ -3195,7 +3235,6 @@ list_overlays_command (const char *args, int from_tty) static void map_overlay_command (const char *args, int from_tty) { - struct objfile *objfile, *objfile2; struct obj_section *sec, *sec2; if (!overlay_debugging) @@ -3207,29 +3246,31 @@ map_overlay_command (const char *args, int from_tty) error (_("Argument required: name of an overlay section")); /* First, find a section matching the user supplied argument. */ - ALL_OBJSECTIONS (objfile, sec) - if (!strcmp (bfd_section_name (objfile->obfd, sec->the_bfd_section), args)) - { - /* Now, check to see if the section is an overlay. */ - if (!section_is_overlay (sec)) - continue; /* not an overlay section */ - - /* Mark the overlay as "mapped". */ - sec->ovly_mapped = 1; - - /* Next, make a pass and unmap any sections that are - overlapped by this new section: */ - ALL_OBJSECTIONS (objfile2, sec2) - if (sec2->ovly_mapped && sec != sec2 && sections_overlap (sec, sec2)) + for (objfile *obj_file : current_program_space->objfiles ()) + ALL_OBJFILE_OSECTIONS (obj_file, sec) + if (!strcmp (bfd_section_name (sec->the_bfd_section), args)) { - if (info_verbose) - printf_unfiltered (_("Note: section %s unmapped by overlap\n"), - bfd_section_name (objfile->obfd, - sec2->the_bfd_section)); - sec2->ovly_mapped = 0; /* sec2 overlaps sec: unmap sec2. */ + /* Now, check to see if the section is an overlay. */ + if (!section_is_overlay (sec)) + continue; /* not an overlay section */ + + /* Mark the overlay as "mapped". */ + sec->ovly_mapped = 1; + + /* Next, make a pass and unmap any sections that are + overlapped by this new section: */ + for (objfile *objfile2 : current_program_space->objfiles ()) + ALL_OBJFILE_OSECTIONS (objfile2, sec2) + if (sec2->ovly_mapped && sec != sec2 && sections_overlap (sec, + sec2)) + { + if (info_verbose) + printf_unfiltered (_("Note: section %s unmapped by overlap\n"), + bfd_section_name (sec2->the_bfd_section)); + sec2->ovly_mapped = 0; /* sec2 overlaps sec: unmap sec2. */ + } + return; } - return; - } error (_("No overlay section called %s"), args); } @@ -3240,7 +3281,6 @@ map_overlay_command (const char *args, int from_tty) static void unmap_overlay_command (const char *args, int from_tty) { - struct objfile *objfile; struct obj_section *sec = NULL; if (!overlay_debugging) @@ -3252,14 +3292,15 @@ unmap_overlay_command (const char *args, int from_tty) error (_("Argument required: name of an overlay section")); /* First, find a section matching the user supplied argument. */ - ALL_OBJSECTIONS (objfile, sec) - if (!strcmp (bfd_section_name (objfile->obfd, sec->the_bfd_section), args)) - { - if (!sec->ovly_mapped) - error (_("Section %s is not mapped"), args); - sec->ovly_mapped = 0; - return; - } + for (objfile *objfile : current_program_space->objfiles ()) + ALL_OBJFILE_OSECTIONS (objfile, sec) + if (!strcmp (bfd_section_name (sec->the_bfd_section), args)) + { + if (!sec->ovly_mapped) + error (_("Section %s is not mapped"), args); + sec->ovly_mapped = 0; + return; + } error (_("No overlay section called %s"), args); } @@ -3313,20 +3354,9 @@ overlay_load_command (const char *args, int from_tty) error (_("This target does not know how to read its overlay state.")); } -/* Function: overlay_command - A place-holder for a mis-typed command. */ - /* Command list chain containing all defined "overlay" subcommands. */ static struct cmd_list_element *overlaylist; -static void -overlay_command (const char *args, int from_tty) -{ - printf_unfiltered - ("\"overlay\" must be followed by the name of an overlay command.\n"); - 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 @@ -3374,8 +3404,7 @@ enum ovly_index static void simple_free_overlay_table (void) { - if (cache_ovly_table) - xfree (cache_ovly_table); + xfree (cache_ovly_table); cache_novlys = 0; cache_ovly_table = NULL; cache_ovly_table_base = 0; @@ -3428,7 +3457,7 @@ simple_read_overlay_table (void) return 0; } - gdbarch = get_objfile_arch (ovly_table_msym.objfile); + gdbarch = ovly_table_msym.objfile->arch (); word_size = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT; byte_order = gdbarch_byte_order (gdbarch); @@ -3457,19 +3486,19 @@ simple_overlay_update_1 (struct obj_section *osect) { int i; asection *bsect = osect->the_bfd_section; - struct gdbarch *gdbarch = get_objfile_arch (osect->objfile); + struct gdbarch *gdbarch = osect->objfile->arch (); int word_size = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT; enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 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)) + if (cache_ovly_table[i][VMA] == bfd_section_vma (bsect) + && cache_ovly_table[i][LMA] == bfd_section_lma (bsect)) { 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)) + if (cache_ovly_table[i][VMA] == bfd_section_vma (bsect) + && cache_ovly_table[i][LMA] == bfd_section_lma (bsect)) { osect->ovly_mapped = cache_ovly_table[i][MAPPED]; return 1; @@ -3491,8 +3520,6 @@ simple_overlay_update_1 (struct obj_section *osect) void simple_overlay_update (struct obj_section *osect) { - struct objfile *objfile; - /* Were we given an osect to look up? NULL means do all of them. */ if (osect) /* Have we got a cached copy of the target's overlay table? */ @@ -3524,20 +3551,21 @@ simple_overlay_update (struct obj_section *osect) return; /* Now may as well update all sections, even if only one was requested. */ - ALL_OBJSECTIONS (objfile, osect) - if (section_is_overlay (osect)) - { - int i; - asection *bsect = osect->the_bfd_section; - - 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)) - { /* 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. */ - } - } + for (objfile *objfile : current_program_space->objfiles ()) + ALL_OBJFILE_OSECTIONS (objfile, osect) + if (section_is_overlay (osect)) + { + int i; + asection *bsect = osect->the_bfd_section; + + for (i = 0; i < cache_novlys; i++) + if (cache_ovly_table[i][VMA] == bfd_section_vma (bsect) + && cache_ovly_table[i][LMA] == bfd_section_lma (bsect)) + { /* 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. */ + } + } } /* Set the output sections and output offsets for section SECTP in @@ -3597,7 +3625,7 @@ symfile_relocate_debug_section (struct objfile *objfile, return (*objfile->sf->sym_relocate) (objfile, sectp, buf); } -struct symfile_segment_data * +symfile_segment_data_up get_symfile_segment_data (bfd *abfd) { const struct sym_fns *sf = find_sym_fns (abfd); @@ -3608,15 +3636,6 @@ get_symfile_segment_data (bfd *abfd) return sf->sym_segments (abfd); } -void -free_symfile_segment_data (struct symfile_segment_data *data) -{ - xfree (data->segment_bases); - xfree (data->segment_sizes); - xfree (data->segment_info); - 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, @@ -3635,7 +3654,7 @@ free_symfile_segment_data (struct symfile_segment_data *data) int symfile_map_offsets_to_segments (bfd *abfd, const struct symfile_segment_data *data, - struct section_offsets *offsets, + section_offsets &offsets, int num_segment_bases, const CORE_ADDR *segment_bases) { @@ -3649,13 +3668,13 @@ symfile_map_offsets_to_segments (bfd *abfd, /* If we do not have segment mappings for the object file, we can not relocate it by segments. */ gdb_assert (data != NULL); - gdb_assert (data->num_segments > 0); + gdb_assert (data->segments.size () > 0); for (i = 0, sect = abfd->sections; sect != NULL; i++, sect = sect->next) { int which = data->segment_info[i]; - gdb_assert (0 <= which && which <= data->num_segments); + gdb_assert (0 <= which && which <= data->segments.size ()); /* Don't bother computing offsets for sections that aren't loaded as part of any segment. */ @@ -3667,8 +3686,7 @@ symfile_map_offsets_to_segments (bfd *abfd, if (which > num_segment_bases) which = num_segment_bases; - offsets->offsets[i] = (segment_bases[which - 1] - - data->segment_bases[which - 1]); + offsets[i] = segment_bases[which - 1] - data->segments[which - 1].base; } return 1; @@ -3680,17 +3698,14 @@ symfile_find_segment_sections (struct objfile *objfile) bfd *abfd = objfile->obfd; int i; asection *sect; - struct symfile_segment_data *data; - data = get_symfile_segment_data (objfile->obfd); + symfile_segment_data_up data + = get_symfile_segment_data (objfile->obfd); if (data == NULL) return; - if (data->num_segments != 1 && data->num_segments != 2) - { - free_symfile_segment_data (data); - return; - } + if (data->segments.size () != 1 && data->segments.size () != 2) + return; for (i = 0, sect = abfd->sections; sect != NULL; i++, sect = sect->next) { @@ -3713,8 +3728,6 @@ symfile_find_segment_sections (struct objfile *objfile) objfile->sect_index_bss = sect->index; } } - - free_symfile_segment_data (data); } /* Listen for free_objfile events. */ @@ -3739,16 +3752,14 @@ expand_symtabs_matching gdb::function_view expansion_notify, enum search_domain kind) { - struct objfile *objfile; - - ALL_OBJFILES (objfile) - { - if (objfile->sf) - objfile->sf->qf->expand_symtabs_matching (objfile, file_matcher, - lookup_name, - symbol_matcher, - expansion_notify, kind); - } + for (objfile *objfile : current_program_space->objfiles ()) + { + if (objfile->sf) + objfile->sf->qf->expand_symtabs_matching (objfile, file_matcher, + &lookup_name, + symbol_matcher, + expansion_notify, kind); + } } /* Wrapper around the quick_symbol_functions map_symbol_filenames "method". @@ -3759,14 +3770,12 @@ 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); - } + for (objfile *objfile : current_program_space->objfiles ()) + { + if (objfile->sf) + objfile->sf->qf->map_symbol_filenames (objfile, fun, data, + need_fullname); + } } #if GDB_SELF_TEST @@ -3804,7 +3813,7 @@ test_set_ext_lang_command () SELF_CHECK (lang == language_unknown); /* Test adding a new extension using the CLI command. */ - gdb::unique_xmalloc_ptr args_holder (xstrdup (".hello rust")); + auto args_holder = make_unique_xstrdup (".hello rust"); ext_args = args_holder.get (); set_ext_lang_command (NULL, 1, NULL); @@ -3828,12 +3837,13 @@ test_set_ext_lang_command () #endif /* GDB_SELF_TEST */ +void _initialize_symfile (); void -_initialize_symfile (void) +_initialize_symfile () { struct cmd_list_element *c; - observer_attach_free_objfile (symfile_free_objfile); + gdb::observers::free_objfile.attach (symfile_free_objfile); #define READNOW_READNEVER_HELP \ "The '-readnow' option will cause GDB to read the entire symbol file\n\ @@ -3844,19 +3854,22 @@ symbolic debug information." c = add_cmd ("symbol-file", class_files, symbol_file_command, _("\ Load symbol table from executable file FILE.\n\ -Usage: symbol-file [-readnow | -readnever] FILE\n\ +Usage: symbol-file [-readnow | -readnever] [-o OFF] FILE\n\ +OFF is an optional offset which is added to each section address.\n\ The `file' command can also load symbol tables, as well as setting the file\n\ to execute.\n" READNOW_READNEVER_HELP), &cmdlist); set_cmd_completer (c, filename_completer); c = add_cmd ("add-symbol-file", class_files, add_symbol_file_command, _("\ Load symbols from FILE, assuming FILE has been dynamically loaded.\n\ -Usage: add-symbol-file FILE ADDR [-readnow | -readnever | \ --s SECT-NAME SECT-ADDR]...\n\ +Usage: add-symbol-file FILE [-readnow | -readnever] [-o OFF] [ADDR] \ +[-s SECT-NAME SECT-ADDR]...\n\ ADDR is the starting address of the file's text.\n\ Each '-s' argument provides a section name and address, and\n\ should be specified if the data and bss segments are not contiguous\n\ -with the text. SECT-NAME is a section name to be loaded at SECT-ADDR.\n" +with the text. SECT-NAME is a section name to be loaded at SECT-ADDR.\n\ +OFF is an optional offset which is added to the default load addresses\n\ +of all sections for which no other address was specified.\n" READNOW_READNEVER_HELP), &cmdlist); set_cmd_completer (c, filename_completer); @@ -3871,20 +3884,20 @@ 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\ +Dynamically load FILE into the running program.\n\ +FILE symbols are recorded for access from GDB.\n\ Usage: load [FILE] [OFFSET]\n\ An optional load OFFSET may also be given as a literal address.\n\ When OFFSET is provided, FILE must also be provided. FILE can be provided\n\ on its own."), &cmdlist); set_cmd_completer (c, filename_completer); - add_prefix_cmd ("overlay", class_support, overlay_command, - _("Commands for debugging overlays."), &overlaylist, - "overlay ", 0, &cmdlist); + add_basic_prefix_cmd ("overlay", class_support, + _("Commands for debugging overlays."), &overlaylist, + "overlay ", 0, &cmdlist); - add_com_alias ("ovly", "overlay", class_alias, 1); - add_com_alias ("ov", "overlay", class_alias, 1); + add_com_alias ("ovly", "overlay", class_support, 1); + add_com_alias ("ov", "overlay", class_support, 1); add_cmd ("map-overlay", class_support, map_overlay_command, _("Assert that an overlay section is mapped."), &overlaylist);