int get_section_index (struct objfile *, char *);
-static struct sym_fns *find_sym_fns (bfd *);
+static const struct sym_fns *find_sym_fns (bfd *);
static void decrement_reading_symtab (void *);
calls add_symtab_fns() to register information on each format it is
prepared to read. */
-static struct sym_fns *symtab_fns = NULL;
+typedef const struct sym_fns *sym_fns_ptr;
+DEF_VEC_P (sym_fns_ptr);
+
+static VEC (sym_fns_ptr) *symtab_fns = NULL;
/* Flag for whether user will be reloading symbols multiple times.
Defaults to ON for VxWorks, otherwise OFF. */
const char *p1 = ptr;
char *p2 = p;
const char *end = ptr + size;
+
while (p1 != end)
*p2++ = *p1++;
}
return p;
}
-/* Concatenate strings S1, S2 and S3; return the new string. Space is found
- in the obstack pointed to by OBSTACKP. */
+/* Concatenate NULL terminated variable argument list of `const char *' strings;
+ return the new string. Space is found in the OBSTACKP. Argument list must
+ be terminated by a sentinel expression `(char *) NULL'. */
char *
-obconcat (struct obstack *obstackp, const char *s1, const char *s2,
- const char *s3)
+obconcat (struct obstack *obstackp, ...)
{
- int len = strlen (s1) + strlen (s2) + strlen (s3) + 1;
- char *val = (char *) obstack_alloc (obstackp, len);
- strcpy (val, s1);
- strcat (val, s2);
- strcat (val, s3);
- return val;
+ va_list ap;
+
+ va_start (ap, obstackp);
+ for (;;)
+ {
+ const char *s = va_arg (ap, const char *);
+
+ if (s == NULL)
+ break;
+
+ obstack_grow_str (obstackp, s);
+ }
+ va_end (ap);
+ obstack_1grow (obstackp, 0);
+
+ return obstack_finish (obstackp);
}
/* True if we are reading a symbol table. */
return sap;
}
-/* Create a section_addr_info from section offsets in OBJFILE. */
+/* Create a section_addr_info from section offsets in ABFD. */
-struct section_addr_info *
-build_section_addr_info_from_objfile (const struct objfile *objfile)
+static struct 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 (objfile->num_sections);
- for (i = 0, sec = objfile->obfd->sections; sec != NULL; sec = sec->next)
- if (bfd_get_section_flags (objfile->obfd, sec) & (SEC_ALLOC | SEC_LOAD))
+ 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 (objfile->obfd, sec)
- + objfile->section_offsets->offsets[i]);
- sap->other[i].name = xstrdup (bfd_get_section_name (objfile->obfd,
- sec));
+ sap->other[i].addr = bfd_get_section_vma (abfd, sec);
+ sap->other[i].name = xstrdup (bfd_get_section_name (abfd, sec));
sap->other[i].sectindex = sec->index;
i++;
}
return sap;
}
+/* Create a section_addr_info from section offsets in OBJFILE. */
+
+struct section_addr_info *
+build_section_addr_info_from_objfile (const struct objfile *objfile)
+{
+ struct section_addr_info *sap;
+ int i;
+
+ /* 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 && sap->other[i].name; i++)
+ {
+ int sectindex = sap->other[i].sectindex;
+
+ sap->other[i].addr += objfile->section_offsets->offsets[sectindex];
+ }
+ return sap;
+}
/* Free all memory allocated by build_section_addr_info_from_section_table. */
for (cur_sec = abfd->sections; cur_sec != NULL; cur_sec = cur_sec->next)
{
int indx = cur_sec->index;
- CORE_ADDR cur_offset;
/* We don't need to compare against ourself. */
if (cur_sec == sect)
}
}
+/* Transform section name S for a name comparison. prelink can split section
+ `.bss' into two sections `.dynbss' and `.bss' (in this order). Similarly
+ prelink can split `.sbss' into `.sdynbss' and `.sbss'. Use virtual address
+ of the new `.dynbss' (`.sdynbss') section as the adjacent new `.bss'
+ (`.sbss') section has invalid (increased) virtual address. */
+
+static const char *
+addr_section_name (const char *s)
+{
+ if (strcmp (s, ".dynbss") == 0)
+ return ".bss";
+ if (strcmp (s, ".sdynbss") == 0)
+ return ".sbss";
+
+ 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. */
+
+static int
+addrs_section_compar (const void *ap, const void *bp)
+{
+ const struct other_sections *a = *((struct other_sections **) ap);
+ const struct other_sections *b = *((struct other_sections **) bp);
+ int retval, a_idx, b_idx;
+
+ retval = strcmp (addr_section_name (a->name), addr_section_name (b->name));
+ if (retval)
+ return retval;
+
+ /* SECTINDEX is undefined iff ADDR is zero. */
+ a_idx = a->addr == 0 ? 0 : a->sectindex;
+ b_idx = b->addr == 0 ? 0 : b->sectindex;
+ return a_idx - b_idx;
+}
+
+/* Provide sorted array of pointers to sections of ADDRS. The array is
+ terminated by NULL. Caller is responsible to call xfree for it. */
+
+static struct other_sections **
+addrs_section_sort (struct section_addr_info *addrs)
+{
+ struct other_sections **array;
+ int i;
+
+ /* `+ 1' for the NULL terminator. */
+ array = xmalloc (sizeof (*array) * (addrs->num_sections + 1));
+ for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++)
+ array[i] = &addrs->other[i];
+ array[i] = NULL;
+
+ qsort (array, i, sizeof (*array), addrs_section_compar);
+
+ return array;
+}
+
/* Relativize absolute addresses in ADDRS into offsets based on ABFD. Fill-in
also SECTINDEXes specific to ABFD there. This function can be used to
rebase ADDRS to start referencing different BFD than before. */
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. */
else
lower_offset = bfd_section_vma (bfd_get_filename (abfd), 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
+ the same name. Also the sections of the same name do not have to be
+ adjacent to each other. Some sections may be present only in one of the
+ files. Even sections present in both files do not have to be in the same
+ order.
+
+ 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);
+
+ 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);
+
+ /* 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);
+ make_cleanup (xfree, addrs_to_abfd_addrs);
+
+ while (*addrs_sorted)
+ {
+ const char *sect_name = addr_section_name ((*addrs_sorted)->name);
+
+ while (*abfd_addrs_sorted
+ && strcmp (addr_section_name ((*abfd_addrs_sorted)->name),
+ sect_name) < 0)
+ abfd_addrs_sorted++;
+
+ if (*abfd_addrs_sorted
+ && strcmp (addr_section_name ((*abfd_addrs_sorted)->name),
+ sect_name) == 0)
+ {
+ int index_in_addrs;
+
+ /* Make the found item directly addressable from ADDRS. */
+ index_in_addrs = *addrs_sorted - addrs->other;
+ gdb_assert (addrs_to_abfd_addrs[index_in_addrs] == NULL);
+ addrs_to_abfd_addrs[index_in_addrs] = *abfd_addrs_sorted;
+
+ /* Never use the same ABFD entry twice. */
+ abfd_addrs_sorted++;
+ }
+
+ addrs_sorted++;
+ }
+
/* Calculate offsets for the loadable sections.
FIXME! Sections must be in order of increasing loadable section
so that contiguous sections can use the lower-offset!!!
for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++)
{
- const char *sect_name = addrs->other[i].name;
- asection *sect = bfd_get_section_by_name (abfd, sect_name);
+ struct other_sections *sect = addrs_to_abfd_addrs[i];
if (sect)
{
/* This is the index used by BFD. */
- addrs->other[i].sectindex = sect->index;
+ addrs->other[i].sectindex = sect->sectindex;
if (addrs->other[i].addr != 0)
{
- addrs->other[i].addr -= bfd_section_vma (abfd, sect);
+ addrs->other[i].addr -= sect->addr;
lower_offset = addrs->other[i].addr;
}
else
}
else
{
+ /* addr_section_name transformation is not used for SECT_NAME. */
+ const char *sect_name = addrs->other[i].name;
+
/* This section does not exist in ABFD, which is normally
unexpected and we want to issue a warning.
a warning. Shared libraries contain just the section
".gnu.liblist" but it is not marked as loadable there. There is
no other way to identify them than by their name as the sections
- created by prelink have no special flags. */
+ created by prelink have no special flags.
+
+ 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, ".dynbss") == 0
- || strcmp (sect_name, ".sdynbss") == 0))
+ || (strcmp (sect_name, ".bss") == 0
+ && i > 0
+ && strcmp (addrs->other[i - 1].name, ".dynbss") == 0
+ && addrs_to_abfd_addrs[i - 1] != NULL)
+ || (strcmp (sect_name, ".sbss") == 0
+ && i > 0
+ && strcmp (addrs->other[i - 1].name, ".sdynbss") == 0
+ && addrs_to_abfd_addrs[i - 1] != NULL)))
warning (_("section %s not found in %s"), sect_name,
bfd_get_filename (abfd));
/* SECTINDEX is invalid if ADDR is zero. */
}
}
+
+ do_cleanups (my_cleanup);
}
/* Parse the user's idea of an offset for dynamic linking, into our idea
struct place_section_arg arg;
bfd *abfd = objfile->obfd;
asection *cur_sec;
- CORE_ADDR lowest = 0;
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
void
new_symfile_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
breakpoints that may have been redefined by this symbol file. */
const char *name = bfd_get_filename (abfd);
const int from_tty = add_flags & SYMFILE_VERBOSE;
+ if (readnow_symbol_files)
+ flags |= OBJF_READNOW;
+
my_cleanups = make_cleanup_bfd_close (abfd);
/* Give user a chance to burp if we'd be
the gdb startup command line or on a per symbol file basis. Expand
all partial symbol tables for this objfile if so. */
- if ((flags & OBJF_READNOW) || readnow_symbol_files)
+ if ((flags & OBJF_READNOW))
{
if (from_tty || info_verbose)
{
: !query (_("Discard symbol table? "))))
error (_("Not confirmed."));
- free_all_objfiles ();
-
- /* solib descriptors may have handles to objfiles. Since their
- storage has just been released, we'd better wipe the solib
- descriptors as well. */
+ /* solib descriptors may have handles to objfiles. Wipe them before their
+ objfiles get stale by free_all_objfiles. */
no_shared_libraries (NULL, from_tty);
+ free_all_objfiles ();
+
gdb_assert (symfile_objfile == NULL);
if (from_tty)
printf_unfiltered (_("No symbol file now.\n"));
unsigned long crc32;
char *contents;
int crc_offset;
- unsigned char *p;
sect = bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink");
char *
find_separate_debug_file_by_debuglink (struct objfile *objfile)
{
- asection *sect;
- char *basename, *name_copy, *debugdir;
+ char *basename, *debugdir;
char *dir = NULL;
char *debugfile = NULL;
char *canon_name = NULL;
- bfd_size_type debuglink_size;
unsigned long crc32;
int i;
dir = xstrdup (objfile->name);
/* Strip off the final filename part, leaving the directory name,
- followed by a slash. Objfile names should always be absolute and
- tilde-expanded, so there should always be a slash in there
- somewhere. */
+ followed by a slash. The directory can be relative or absolute. */
for (i = strlen(dir) - 1; i >= 0; i--)
{
if (IS_DIR_SEPARATOR (dir[i]))
break;
}
- gdb_assert (i >= 0 && IS_DIR_SEPARATOR (dir[i]));
+ /* If I is -1 then no directory is present there and DIR will be "". */
dir[i+1] = '\0';
/* Set I to max (strlen (canon_name), strlen (dir)). */
void
set_initial_language (void)
{
- char *filename;
+ const char *filename;
enum language lang = language_unknown;
filename = find_main_filename ();
if (desc < 0)
{
char *exename = alloca (strlen (name) + 5);
+
strcat (strcpy (exename, name), ".exe");
desc = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, exename,
O_RDONLY | O_BINARY, &absolute_name);
handle. */
void
-add_symtab_fns (struct sym_fns *sf)
+add_symtab_fns (const struct sym_fns *sf)
{
- sf->next = symtab_fns;
- symtab_fns = sf;
+ VEC_safe_push (sym_fns_ptr, symtab_fns, sf);
}
/* Initialize OBJFILE to read symbols from its associated BFD. It
struct sym_fns in the objfile structure, that contains cached
information about the symbol file. */
-static struct sym_fns *
+static const struct sym_fns *
find_sym_fns (bfd *abfd)
{
- struct sym_fns *sf;
+ const struct sym_fns *sf;
enum bfd_flavour our_flavour = bfd_get_flavour (abfd);
+ int i;
if (our_flavour == bfd_target_srec_flavour
|| our_flavour == bfd_target_ihex_flavour
|| our_flavour == bfd_target_tekhex_flavour)
return NULL; /* No symbols. */
- for (sf = symtab_fns; sf != NULL; sf = sf->next)
+ for (i = 0; VEC_iterate (sym_fns_ptr, symtab_fns, i, sf); ++i)
if (our_flavour == sf->sym_flavour)
return sf;
for other targets too. */
regcache_write_pc (get_current_regcache (), entry);
+ /* Reset breakpoints, now that we have changed the load image. For
+ instance, breakpoints may have been set (or reset, by
+ post_create_inferior) while connected to the target but before we
+ loaded the program. In that case, the prologue analyzer could
+ have read instructions from the target to find the right
+ breakpoint locations. Loading has changed the contents of that
+ memory. */
+
+ 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
char *filename = NULL;
int flags = OBJF_USERLOADED;
char *arg;
- int expecting_option = 0;
int section_index = 0;
int argcnt = 0;
int sec_num = 0;
if (objfile->separate_debug_objfile_backlink)
continue;
-#ifdef DEPRECATED_IBM6000_TARGET
- /* If this object is from a shared library, then you should
- stat on the library name, not member name. */
-
+ /* If this object is from an archive (what you usually create with
+ `ar', often called a `static library' on most systems, though
+ 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);
else
-#endif
res = stat (objfile->name, &new_statbuf);
if (res != 0)
{
sizeof (objfile->static_psymbols));
/* Free the obstacks for non-reusable objfiles */
- bcache_xfree (objfile->psymbol_cache);
- objfile->psymbol_cache = bcache_xmalloc ();
+ psymbol_bcache_free (objfile->psymbol_cache);
+ objfile->psymbol_cache = psymbol_bcache_init ();
bcache_xfree (objfile->macro_cache);
- objfile->macro_cache = bcache_xmalloc ();
+ objfile->macro_cache = bcache_xmalloc (NULL, NULL);
bcache_xfree (objfile->filename_cache);
- objfile->filename_cache = bcache_xmalloc ();
+ objfile->filename_cache = bcache_xmalloc (NULL,NULL);
if (objfile->demangled_names_hash != NULL)
{
htab_delete (objfile->demangled_names_hash);
objfile->psymtabs_addrmap = NULL;
objfile->free_psymtabs = NULL;
objfile->cp_namespace_symtab = NULL;
+ objfile->template_symbols = NULL;
objfile->msymbols = NULL;
objfile->deprecated_sym_private = NULL;
objfile->minimal_symbol_count = 0;
memset (&objfile->msymbol_demangled_hash, 0,
sizeof (objfile->msymbol_demangled_hash));
- objfile->psymbol_cache = bcache_xmalloc ();
- objfile->macro_cache = bcache_xmalloc ();
- objfile->filename_cache = bcache_xmalloc ();
+ objfile->psymbol_cache = psymbol_bcache_init ();
+ objfile->macro_cache = bcache_xmalloc (NULL, NULL);
+ objfile->filename_cache = bcache_xmalloc (NULL, NULL);
/* obstack_init also initializes the obstack so it is
empty. We could use obstack_specify_allocation but
gdb_obstack.h specifies the alloc/dealloc
filename_language_table =
xmalloc (fl_table_size * sizeof (*filename_language_table));
add_filename_language (".c", language_c);
+ add_filename_language (".d", language_d);
add_filename_language (".C", language_cplus);
add_filename_language (".cc", language_cplus);
add_filename_language (".cp", language_cplus);
add_filename_language (".m", language_objc);
add_filename_language (".f", language_fortran);
add_filename_language (".F", language_fortran);
+ add_filename_language (".for", language_fortran);
+ add_filename_language (".FOR", language_fortran);
+ add_filename_language (".ftn", language_fortran);
+ add_filename_language (".FTN", language_fortran);
+ add_filename_language (".fpp", language_fortran);
+ add_filename_language (".FPP", language_fortran);
+ add_filename_language (".f90", language_fortran);
+ add_filename_language (".F90", language_fortran);
+ add_filename_language (".f95", language_fortran);
+ add_filename_language (".F95", language_fortran);
+ add_filename_language (".f03", language_fortran);
+ add_filename_language (".F03", language_fortran);
+ add_filename_language (".f08", language_fortran);
+ add_filename_language (".F08", language_fortran);
add_filename_language (".s", language_asm);
add_filename_language (".sx", language_asm);
add_filename_language (".S", language_asm);
add_filename_language (".ads", language_ada);
add_filename_language (".a", language_ada);
add_filename_language (".ada", language_ada);
+ add_filename_language (".dg", language_ada);
}
}
enum language
-deduce_language_from_filename (char *filename)
+deduce_language_from_filename (const char *filename)
{
int i;
char *cp;
*/
struct symtab *
-allocate_symtab (char *filename, struct objfile *objfile)
+allocate_symtab (const char *filename, struct objfile *objfile)
{
struct symtab *symtab;
struct symfile_segment_data *
get_symfile_segment_data (bfd *abfd)
{
- struct sym_fns *sf = find_sym_fns (abfd);
+ const struct sym_fns *sf = find_sym_fns (abfd);
if (sf == NULL)
return NULL;
for (i = 0, sect = abfd->sections; sect != NULL; i++, sect = sect->next)
{
- CORE_ADDR vma;
int which = data->segment_info[i];
if (which == 1)