#include "exec.h"
#include "observer.h"
#include "complaints.h"
+#include "psymtab.h"
+#include "solist.h"
/* Prototypes for local functions */
{
struct objfile *res;
+ /* If any, return the first child. */
res = objfile->separate_debug_objfile;
if (res)
return res;
- res = objfile->separate_debug_objfile_link;
- if (res)
- return res;
-
/* Common case where there is no separate debug objfile. */
if (objfile == parent)
return NULL;
+ /* Return the brother if any. Note that we don't iterate on brothers of
+ the parents. */
+ res = objfile->separate_debug_objfile_link;
+ if (res)
+ return res;
+
for (res = objfile->separate_debug_objfile_backlink;
res != parent;
res = res->separate_debug_objfile_backlink)
free_all_objfiles (void)
{
struct objfile *objfile, *temp;
+ struct so_list *so;
+
+ /* Any objfile referencewould become stale. */
+ for (so = master_so_list (); so; so = so->next)
+ gdb_assert (so->objfile == NULL);
ALL_OBJFILES_SAFE (objfile, temp)
{
}
\f
/* Relocate OBJFILE to NEW_OFFSETS. There should be OBJFILE->NUM_SECTIONS
- entries in new_offsets. SEPARATE_DEBUG_OBJFILE is not touched here. */
+ entries in new_offsets. SEPARATE_DEBUG_OBJFILE is not touched here.
+ Return non-zero iff any change happened. */
-static void
-objfile_relocate1 (struct objfile *objfile, struct section_offsets *new_offsets)
+static int
+objfile_relocate1 (struct objfile *objfile,
+ struct section_offsets *new_offsets)
{
struct obj_section *s;
struct section_offsets *delta =
((struct section_offsets *)
alloca (SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)));
- {
- int i;
- int something_changed = 0;
- for (i = 0; i < objfile->num_sections; ++i)
- {
- delta->offsets[i] =
- ANOFFSET (new_offsets, i) - ANOFFSET (objfile->section_offsets, i);
- if (ANOFFSET (delta, i) != 0)
- something_changed = 1;
- }
- if (!something_changed)
- return;
- }
+ int i;
+ int something_changed = 0;
+
+ for (i = 0; i < objfile->num_sections; ++i)
+ {
+ delta->offsets[i] =
+ ANOFFSET (new_offsets, i) - ANOFFSET (objfile->section_offsets, i);
+ if (ANOFFSET (delta, i) != 0)
+ something_changed = 1;
+ }
+ if (!something_changed)
+ return 0;
/* OK, get all the symtabs. */
{
addrmap_relocate (objfile->psymtabs_addrmap,
ANOFFSET (delta, SECT_OFF_TEXT (objfile)));
- {
- struct partial_symtab *p;
-
- ALL_OBJFILE_PSYMTABS (objfile, p)
- {
- p->textlow += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
- p->texthigh += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
- }
- }
-
- {
- struct partial_symbol **psym;
-
- for (psym = objfile->global_psymbols.list;
- psym < objfile->global_psymbols.next;
- psym++)
- {
- fixup_psymbol_section (*psym, objfile);
- if (SYMBOL_SECTION (*psym) >= 0)
- SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta,
- SYMBOL_SECTION (*psym));
- }
- for (psym = objfile->static_psymbols.list;
- psym < objfile->static_psymbols.next;
- psym++)
- {
- fixup_psymbol_section (*psym, objfile);
- if (SYMBOL_SECTION (*psym) >= 0)
- SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta,
- SYMBOL_SECTION (*psym));
- }
- }
+ if (objfile->sf)
+ objfile->sf->qf->relocate (objfile, new_offsets, delta);
{
struct minimal_symbol *msym;
+
ALL_OBJFILE_MSYMBOLS (objfile, msym)
if (SYMBOL_SECTION (msym) >= 0)
SYMBOL_VALUE_ADDRESS (msym) += ANOFFSET (delta, SYMBOL_SECTION (msym));
{
int i;
+
for (i = 0; i < objfile->num_sections; ++i)
(objfile->section_offsets)->offsets[i] = ANOFFSET (new_offsets, i);
}
exec_set_section_address (bfd_get_filename (objfile->obfd), idx,
obj_section_addr (s));
}
+
+ /* Data changed. */
+ return 1;
}
/* Relocate OBJFILE to NEW_OFFSETS. There should be OBJFILE->NUM_SECTIONS
objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
{
struct objfile *debug_objfile;
+ int changed = 0;
- objfile_relocate1 (objfile, new_offsets);
+ changed |= objfile_relocate1 (objfile, new_offsets);
for (debug_objfile = objfile->separate_debug_objfile;
debug_objfile;
{
struct section_addr_info *objfile_addrs;
struct section_offsets *new_debug_offsets;
- int new_debug_num_sections;
struct cleanup *my_cleanups;
objfile_addrs = build_section_addr_info_from_objfile (objfile);
gdb_assert (debug_objfile->num_sections
== bfd_count_sections (debug_objfile->obfd));
- new_debug_offsets = xmalloc (SIZEOF_N_SECTION_OFFSETS
- (debug_objfile->num_sections));
+ new_debug_offsets =
+ xmalloc (SIZEOF_N_SECTION_OFFSETS (debug_objfile->num_sections));
make_cleanup (xfree, new_debug_offsets);
relative_addr_info_to_section_offsets (new_debug_offsets,
debug_objfile->num_sections,
objfile_addrs);
- objfile_relocate1 (debug_objfile, new_debug_offsets);
+ changed |= objfile_relocate1 (debug_objfile, new_debug_offsets);
do_cleanups (my_cleanups);
}
/* Relocate breakpoints as necessary, after things are relocated. */
- breakpoint_re_set ();
+ if (changed)
+ breakpoint_re_set ();
}
\f
/* Return non-zero if OBJFILE has partial symbols. */
int
objfile_has_partial_symbols (struct objfile *objfile)
{
- return objfile->psymtabs != NULL;
+ return objfile->sf ? objfile->sf->qf->has_symbols (objfile) : 0;
}
/* Return non-zero if OBJFILE has full symbols. */
else if (sect1_addr > sect2_addr)
return 1;
else
- {
- /* Sections are at the same address. This could happen if
- A) we have an objfile and a separate debuginfo.
- B) we are confused, and have added sections without proper relocation,
- or something like that. */
-
- const struct objfile *const objfile1 = sect1->objfile;
- const struct objfile *const objfile2 = sect2->objfile;
-
- if (objfile1->separate_debug_objfile == objfile2
- || objfile2->separate_debug_objfile == objfile1)
- {
- /* Case A. The ordering doesn't matter: separate debuginfo files
- will be filtered out later. */
-
- return 0;
- }
-
- /* Case B. Maintain stable sort order, so bugs in GDB are easier to
- triage. This section could be slow (since we iterate over all
- objfiles in each call to qsort_cmp), but this shouldn't happen
- very often (GDB is already in a confused state; one hopes this
- doesn't happen at all). If you discover that significant time is
- spent in the loops below, do 'set complaints 100' and examine the
- resulting complaints. */
-
- if (objfile1 == objfile2)
- {
- /* Both sections came from the same objfile. We are really confused.
- Sort on sequence order of sections within the objfile. */
-
- const struct obj_section *osect;
-
- ALL_OBJFILE_OSECTIONS (objfile1, osect)
- if (osect == sect1)
- return -1;
- else if (osect == sect2)
- return 1;
-
- /* We should have found one of the sections before getting here. */
- gdb_assert (0);
- }
- else
- {
- /* Sort on sequence number of the objfile in the chain. */
-
- const struct objfile *objfile;
-
- ALL_OBJFILES (objfile)
- if (objfile == objfile1)
- return -1;
- else if (objfile == objfile2)
- return 1;
-
- /* We should have found one of the objfiles before getting here. */
- gdb_assert (0);
- }
-
- }
+ {
+ /* Sections are at the same address. This could happen if
+ A) we have an objfile and a separate debuginfo.
+ B) we are confused, and have added sections without proper relocation,
+ or something like that. */
+
+ const struct objfile *const objfile1 = sect1->objfile;
+ const struct objfile *const objfile2 = sect2->objfile;
+
+ if (objfile1->separate_debug_objfile == objfile2
+ || objfile2->separate_debug_objfile == objfile1)
+ {
+ /* Case A. The ordering doesn't matter: separate debuginfo files
+ will be filtered out later. */
+
+ return 0;
+ }
+
+ /* Case B. Maintain stable sort order, so bugs in GDB are easier to
+ triage. This section could be slow (since we iterate over all
+ objfiles in each call to qsort_cmp), but this shouldn't happen
+ very often (GDB is already in a confused state; one hopes this
+ doesn't happen at all). If you discover that significant time is
+ spent in the loops below, do 'set complaints 100' and examine the
+ resulting complaints. */
+
+ if (objfile1 == objfile2)
+ {
+ /* Both sections came from the same objfile. We are really confused.
+ Sort on sequence order of sections within the objfile. */
+
+ const struct obj_section *osect;
+
+ ALL_OBJFILE_OSECTIONS (objfile1, osect)
+ if (osect == sect1)
+ return -1;
+ else if (osect == sect2)
+ return 1;
+
+ /* We should have found one of the sections before getting here. */
+ gdb_assert (0);
+ }
+ else
+ {
+ /* Sort on sequence number of the objfile in the chain. */
+
+ const struct objfile *objfile;
+
+ ALL_OBJFILES (objfile)
+ if (objfile == objfile1)
+ return -1;
+ else if (objfile == objfile2)
+ return 1;
+
+ /* We should have found one of the objfiles before getting here. */
+ gdb_assert (0);
+ }
+ }
/* Unreachable. */
gdb_assert (0);
get_objfile_pspace_data (current_program_space)->objfiles_changed_p = 1;
}
+/* Close ABFD, and warn if that fails. */
+
+int
+gdb_bfd_close_or_warn (struct bfd *abfd)
+{
+ int ret;
+ char *name = bfd_get_filename (abfd);
+
+ ret = bfd_close (abfd);
+
+ if (!ret)
+ warning (_("cannot close \"%s\": %s"),
+ name, bfd_errmsg (bfd_get_error ()));
+
+ return ret;
+}
+
/* Add reference to ABFD. Returns ABFD. */
struct bfd *
gdb_bfd_ref (struct bfd *abfd)
{
- int *p_refcount = bfd_usrdata (abfd);
+ int *p_refcount;
+
+ if (abfd == NULL)
+ return NULL;
+
+ p_refcount = bfd_usrdata (abfd);
if (p_refcount != NULL)
{
bfd_usrdata (abfd) = NULL; /* Paranoia. */
name = bfd_get_filename (abfd);
- if (!bfd_close (abfd))
- warning (_("cannot close \"%s\": %s"),
- name, bfd_errmsg (bfd_get_error ()));
+ gdb_bfd_close_or_warn (abfd);
xfree (name);
}