aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog16
-rw-r--r--gdb/objfiles.c55
-rw-r--r--gdb/solib-spu.c22
-rw-r--r--gdb/symfile.c35
-rw-r--r--gdb/symfile.h8
5 files changed, 86 insertions, 50 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 1ff5f35..da66b7b 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,19 @@
+2010-01-09 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ Fix displacement of separate debug info files.
+ * objfiles.c (objfile_relocate): Rename to ...
+ (objfile_relocate1): ... here and make it static. Extend the comment.
+ (objfile_relocate): New function.
+ * solib-spu.c (spu_relocate_main_executable): Explicitly check if
+ SYMFILE_OBJFILE is NULL. Remove variables objfile and old_chain.
+ Remove following of SEPARATE_DEBUG_OBJFILE. new_offsets is now
+ allocated using alloca.
+ * symfile.c (copy_section_addr_info): Remove.
+ (build_section_addr_info_from_objfile): Make it global. New variables
+ addr_bit and mask, use them.
+ * symfile.h (build_section_addr_info_from_objfile): New prototype.
+ (copy_section_addr_info): Remove.
+
2010-01-09 Joel Brobecker <brobecker@adacore.com>
Signal unwinder for mips-irix N32.
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
index 9f779a4..d1e441b 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -693,9 +693,10 @@ free_all_objfiles (void)
}
/* Relocate OBJFILE to NEW_OFFSETS. There should be OBJFILE->NUM_SECTIONS
- entries in new_offsets. */
-void
-objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
+ entries in new_offsets. SEPARATE_DEBUG_OBJFILE is not touched here. */
+
+static void
+objfile_relocate1 (struct objfile *objfile, struct section_offsets *new_offsets)
{
struct obj_section *s;
struct section_offsets *delta =
@@ -849,6 +850,54 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
exec_set_section_address (bfd_get_filename (objfile->obfd), idx,
obj_section_addr (s));
}
+}
+
+/* Relocate OBJFILE to NEW_OFFSETS. There should be OBJFILE->NUM_SECTIONS
+ entries in new_offsets. Process also OBJFILE's SEPARATE_DEBUG_OBJFILEs.
+
+ The number and ordering of sections does differ between the two objfiles.
+ Only their names match. Also the file offsets will differ (objfile being
+ possibly prelinked but separate_debug_objfile is probably not prelinked) but
+ the in-memory absolute address as specified by NEW_OFFSETS must match both
+ files. */
+
+void
+objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
+{
+ struct objfile *debug_objfile;
+
+ objfile_relocate1 (objfile, new_offsets);
+
+ for (debug_objfile = objfile->separate_debug_objfile;
+ debug_objfile;
+ debug_objfile = objfile_separate_debug_iterate (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);
+ my_cleanups = make_cleanup (xfree, objfile_addrs);
+
+ /* Here OBJFILE_ADDRS contain the correct absolute addresses, the
+ relative ones must be already created according to debug_objfile. */
+
+ addr_info_make_relative (objfile_addrs, debug_objfile->obfd);
+
+ gdb_assert (debug_objfile->num_sections
+ == bfd_count_sections (debug_objfile->obfd));
+ 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);
+
+ do_cleanups (my_cleanups);
+ }
/* Relocate breakpoints as necessary, after things are relocated. */
breakpoint_re_set ();
diff --git a/gdb/solib-spu.c b/gdb/solib-spu.c
index e752544..94a77fb 100644
--- a/gdb/solib-spu.c
+++ b/gdb/solib-spu.c
@@ -50,25 +50,19 @@
static void
spu_relocate_main_executable (int spufs_fd)
{
- struct objfile *objfile;
- struct cleanup *old_chain;
struct section_offsets *new_offsets;
int i;
- for (objfile = symfile_objfile;
- objfile;
- objfile = objfile->separate_debug_objfile)
- {
- new_offsets = xcalloc (objfile->num_sections,
- sizeof (struct section_offsets));
- old_chain = make_cleanup (xfree, new_offsets);
+ if (symfile_objfile == NULL)
+ return;
- for (i = 0; i < objfile->num_sections; i++)
- new_offsets->offsets[i] = SPUADDR (spufs_fd, 0);
+ new_offsets = alloca (symfile_objfile->num_sections
+ * sizeof (struct section_offsets));
- objfile_relocate (objfile, new_offsets);
- do_cleanups (old_chain);
- }
+ for (i = 0; i < symfile_objfile->num_sections; i++)
+ new_offsets->offsets[i] = SPUADDR (spufs_fd, 0);
+
+ objfile_relocate (symfile_objfile, new_offsets);
}
/* When running a stand-alone SPE executable, we may need to skip one more
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 42aff0d..89cc07c 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -328,32 +328,6 @@ alloc_section_addr_info (size_t num_sections)
return sap;
}
-
-/* Return a freshly allocated copy of ADDRS. The section names, if
- any, are also freshly allocated copies of those in ADDRS. */
-struct section_addr_info *
-copy_section_addr_info (struct section_addr_info *addrs)
-{
- struct section_addr_info *copy
- = alloc_section_addr_info (addrs->num_sections);
- int i;
-
- copy->num_sections = addrs->num_sections;
- for (i = 0; i < addrs->num_sections; i++)
- {
- copy->other[i].addr = addrs->other[i].addr;
- if (addrs->other[i].name)
- copy->other[i].name = xstrdup (addrs->other[i].name);
- else
- copy->other[i].name = NULL;
- copy->other[i].sectindex = addrs->other[i].sectindex;
- }
-
- return copy;
-}
-
-
-
/* Build (allocate and populate) a section_addr_info struct from
an existing section table. */
@@ -386,12 +360,17 @@ build_section_addr_info_from_section_table (const struct target_section *start,
/* Create a section_addr_info from section offsets in OBJFILE. */
-static struct section_addr_info *
+struct section_addr_info *
build_section_addr_info_from_objfile (const struct objfile *objfile)
{
struct section_addr_info *sap;
int i;
struct bfd_section *sec;
+ int addr_bit = gdbarch_addr_bit (objfile->gdbarch);
+ CORE_ADDR mask = CORE_ADDR_MAX;
+
+ if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT))
+ mask = ((CORE_ADDR) 1 << addr_bit) - 1;
sap = alloc_section_addr_info (objfile->num_sections);
for (i = 0, sec = objfile->obfd->sections;
@@ -400,7 +379,7 @@ build_section_addr_info_from_objfile (const struct objfile *objfile)
{
gdb_assert (sec != NULL);
sap->other[i].addr = (bfd_get_section_vma (objfile->obfd, sec)
- + objfile->section_offsets->offsets[i]);
+ + objfile->section_offsets->offsets[i]) & mask;
sap->other[i].name = xstrdup (bfd_get_section_name (objfile->obfd, sec));
sap->other[i].sectindex = sec->index;
}
diff --git a/gdb/symfile.h b/gdb/symfile.h
index 57e6286..7ae819c 100644
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -174,6 +174,9 @@ struct sym_fns
};
+extern struct section_addr_info *
+ build_section_addr_info_from_objfile (const struct objfile *objfile);
+
extern void relative_addr_info_to_section_offsets
(struct section_offsets *section_offsets, int num_sections,
struct section_addr_info *addrs);
@@ -254,11 +257,6 @@ extern char *find_separate_debug_file_by_debuglink (struct objfile *);
extern struct section_addr_info *alloc_section_addr_info (size_t
num_sections);
-/* Return a freshly allocated copy of ADDRS. The section names, if
- any, are also freshly allocated copies of those in ADDRS. */
-extern struct section_addr_info *(copy_section_addr_info
- (struct section_addr_info *addrs));
-
/* Build (allocate and populate) a section_addr_info struct from an
existing section table. */