* 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.
This commit is contained in:
Daniel Jacobowitz 2005-06-13 16:15:40 +00:00
parent 37f6032b85
commit c1bd25fd1d
8 changed files with 168 additions and 7 deletions

View File

@ -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

View File

@ -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)

View File

@ -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). */

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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"