summaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorDaniel Jacobowitz <dan@debian.org>2005-06-13 16:15:40 +0000
committerDaniel Jacobowitz <dan@debian.org>2005-06-13 16:15:40 +0000
commit2c7d0587d9b790f2c61ad23918385965df9fd964 (patch)
tree5121d2b0cbcd8f2da6f0535586f6e08c03c88d73 /gdb
parentb240d68d1c18adfc6cbf04a432a5e89bcad3e927 (diff)
downloadgdb-2c7d0587d9b790f2c61ad23918385965df9fd964.tar.gz
gdb/
* Makefile.in (symfile.o): Add $(exec_h). * exec.h (exec_set_section_address): Add prototype. * exec.c (exec_set_section_address): New function. * symfile.c: Include "exec.h". (struct place_section_arg, place_section): New. (default_symfile_offsets): Call place_section for each section of a relocatable file. gdb/testsuite/ * gdb.base/relocate.c: Add a copyright notice. (dummy): Remove. * gdb.base/relocate.exp: Test printing the values of variables from a relocatable file.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog10
-rw-r--r--gdb/Makefile.in2
-rw-r--r--gdb/exec.c21
-rw-r--r--gdb/exec.h3
-rw-r--r--gdb/symfile.c92
-rw-r--r--gdb/testsuite/ChangeLog7
-rw-r--r--gdb/testsuite/gdb.base/relocate.c24
-rw-r--r--gdb/testsuite/gdb.base/relocate.exp16
8 files changed, 168 insertions, 7 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 6a5c47b90b1..50b3b9e7d01 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,13 @@
+2005-06-13 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * Makefile.in (symfile.o): Add $(exec_h).
+ * exec.h (exec_set_section_address): Add prototype.
+ * exec.c (exec_set_section_address): New function.
+ * symfile.c: Include "exec.h".
+ (struct place_section_arg, place_section): New.
+ (default_symfile_offsets): Call place_section for each
+ section of a relocatable file.
+
2005-06-13 Joel Brobecker <brobecker@adacore.com>
* hppa-tdep.c (hppa_pc_requires_run_before_use): Really test all
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 7a27d0bb196..2cdb1b70e4a 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -2642,7 +2642,7 @@ symfile.o: symfile.c $(defs_h) $(bfdlink_h) $(symtab_h) $(gdbtypes_h) \
$(complaints_h) $(demangle_h) $(inferior_h) $(filenames_h) \
$(gdb_stabs_h) $(gdb_obstack_h) $(completer_h) $(bcache_h) \
$(hashtab_h) $(readline_h) $(gdb_assert_h) $(block_h) \
- $(gdb_string_h) $(gdb_stat_h) $(observer_h)
+ $(gdb_string_h) $(gdb_stat_h) $(observer_h) $(exec_h)
symfile-mem.o: symfile-mem.c $(defs_h) $(symtab_h) $(gdbcore_h) \
$(objfiles_h) $(exceptions_h) $(gdbcmd_h) $(target_h) $(value_h) \
$(symfile_h) $(observer_h) $(auxv_h) $(elf_common_h)
diff --git a/gdb/exec.c b/gdb/exec.c
index 938b106adef..60e3b36ae3c 100644
--- a/gdb/exec.c
+++ b/gdb/exec.c
@@ -670,6 +670,27 @@ set_section_command (char *args, int from_tty)
error (_("Section %s not found"), secprint);
}
+/* If we can find a section in FILENAME with BFD index INDEX, and the
+ user has not assigned an address to it yet (via "set section"), adjust it
+ to ADDRESS. */
+
+void
+exec_set_section_address (const char *filename, int index, CORE_ADDR address)
+{
+ struct section_table *p;
+
+ for (p = exec_ops.to_sections; p < exec_ops.to_sections_end; p++)
+ {
+ if (strcmp (filename, p->bfd->filename) == 0
+ && index == p->the_bfd_section->index
+ && p->addr == 0)
+ {
+ p->addr = address;
+ p->endaddr += address;
+ }
+ }
+}
+
/* If mourn is being called in all the right places, this could be say
`gdb internal error' (since generic_mourn calls
breakpoint_init_inferior). */
diff --git a/gdb/exec.h b/gdb/exec.h
index d0862516c97..c6bef72847d 100644
--- a/gdb/exec.h
+++ b/gdb/exec.h
@@ -36,4 +36,7 @@ extern struct target_ops exec_ops;
extern int build_section_table (struct bfd *, struct section_table **,
struct section_table **);
+/* Set the loaded address of a section. */
+extern void exec_set_section_address (const char *, int, CORE_ADDR);
+
#endif
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 87709437c8e..7bd3853bf73 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -49,6 +49,7 @@
#include "gdb_assert.h"
#include "block.h"
#include "observer.h"
+#include "exec.h"
#include <sys/types.h>
#include <fcntl.h>
@@ -456,6 +457,84 @@ init_objfile_sect_indices (struct objfile *objfile)
}
}
+/* The arguments to place_section. */
+
+struct place_section_arg
+{
+ struct section_offsets *offsets;
+ CORE_ADDR lowest;
+};
+
+/* Find a unique offset to use for loadable section SECT if
+ the user did not provide an offset. */
+
+void
+place_section (bfd *abfd, asection *sect, void *obj)
+{
+ struct place_section_arg *arg = obj;
+ CORE_ADDR *offsets = arg->offsets->offsets, start_addr;
+ int done;
+
+ /* We are only interested in loadable sections. */
+ if ((bfd_get_section_flags (abfd, sect) & SEC_LOAD) == 0)
+ return;
+
+ /* If the user specified an offset, honor it. */
+ if (offsets[sect->index] != 0)
+ return;
+
+ /* Otherwise, let's try to find a place for the section. */
+ do {
+ asection *cur_sec;
+ ULONGEST align = 1 << bfd_get_section_alignment (abfd, sect);
+
+ start_addr = (arg->lowest + align - 1) & -align;
+ done = 1;
+
+ 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)
+ continue;
+
+ /* We can only conflict with loadable sections. */
+ if ((bfd_get_section_flags (abfd, cur_sec) & SEC_LOAD) == 0)
+ continue;
+
+ /* We do not expect this to happen; just ignore sections in a
+ relocatable file with an assigned VMA. */
+ if (bfd_section_vma (abfd, cur_sec) != 0)
+ continue;
+
+ /* If the section offset is 0, either the section has not been placed
+ yet, or it was the lowest section placed (in which case LOWEST
+ will be past its end). */
+ if (offsets[indx] == 0)
+ 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))
+ {
+ start_addr = offsets[indx] + bfd_get_section_size (cur_sec);
+ start_addr = (start_addr + align - 1) & -align;
+ done = 0;
+ continue;
+ }
+
+ /* Otherwise, we appear to be OK. So far. */
+ }
+ }
+ while (!done);
+
+ offsets[sect->index] = start_addr;
+ arg->lowest = start_addr + bfd_get_section_size (sect);
+
+ exec_set_section_address (bfd_get_filename (abfd), sect->index, start_addr);
+}
/* Parse the user's idea of an offset for dynamic linking, into our idea
of how to represent it for fast symbol reading. This is the default
@@ -492,6 +571,19 @@ default_symfile_offsets (struct objfile *objfile,
(objfile->section_offsets)->offsets[osp->sectindex] = osp->addr;
}
+ /* For relocatable files, all loadable sections will start at zero.
+ The zero is meaningless, so try to pick arbitrary addresses such
+ that no loadable sections overlap. This algorithm is quadratic,
+ but the number of sections in a single object file is generally
+ small. */
+ if ((bfd_get_file_flags (objfile->obfd) & (EXEC_P | DYNAMIC)) == 0)
+ {
+ struct place_section_arg arg;
+ arg.offsets = objfile->section_offsets;
+ arg.lowest = 0;
+ bfd_map_over_sections (objfile->obfd, place_section, &arg);
+ }
+
/* Remember the bfd indexes for the .text, .data, .bss and
.rodata sections. */
init_objfile_sect_indices (objfile);
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 48bf65cda90..e8580dbf0f0 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2005-06-13 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * gdb.base/relocate.c: Add a copyright notice.
+ (dummy): Remove.
+ * gdb.base/relocate.exp: Test printing the values of variables
+ from a relocatable file.
+
2005-06-12 Daniel Jacobowitz <dan@codesourcery.com>
* gdb.mi/mi-syn-frame.exp, gdb.mi/mi2-syn-frame.exp: Don't expect
diff --git a/gdb/testsuite/gdb.base/relocate.c b/gdb/testsuite/gdb.base/relocate.c
index 90e70ffe8b6..7e85efb6cbf 100644
--- a/gdb/testsuite/gdb.base/relocate.c
+++ b/gdb/testsuite/gdb.base/relocate.c
@@ -1,10 +1,26 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2002, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
static int static_foo = 1;
static int static_bar = 2;
-/* This padding is just for the benefit of the test harness. It
- causes the globals to have different addresses than the functions. */
-int dummy[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
-
int global_foo = 3;
int global_bar = 4;
diff --git a/gdb/testsuite/gdb.base/relocate.exp b/gdb/testsuite/gdb.base/relocate.exp
index 916ce1ce41c..13ea62aa824 100644
--- a/gdb/testsuite/gdb.base/relocate.exp
+++ b/gdb/testsuite/gdb.base/relocate.exp
@@ -1,4 +1,4 @@
-# Copyright 2002, 2003 Free Software Foundation, Inc.
+# Copyright 2002, 2003, 2005 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -131,4 +131,16 @@ if { "${function_foo_addr}" == "${new_function_foo_addr}" } {
pass "function foo has a different address"
}
-return 0
+# Now try loading the object as an exec-file; we should be able to print
+# the values of variables after we do this.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Check the values of the variables.
+gdb_test "print static_foo" "\\\$$decimal = 1"
+gdb_test "print static_bar" "\\\$$decimal = 2"
+gdb_test "print global_foo" "\\\$$decimal = 3"
+gdb_test "print global_bar" "\\\$$decimal = 4"