/* Work with executable files, for GDB.
- Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
- 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation,
- Inc.
+ Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000, 2001, 2002, 2003, 2007, 2008, 2009
+ Free Software Foundation, Inc.
This file is part of GDB.
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
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
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. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "frame.h"
#include "value.h"
#include "exec.h"
#include "observer.h"
+#include "arch-utils.h"
#include <fcntl.h>
#include "readline/readline.h"
/* The Binary File Descriptor handle for the executable file. */
bfd *exec_bfd = NULL;
+long exec_bfd_mtime = 0;
/* Whether to open exec and core files read-only or read-write. */
name, bfd_errmsg (bfd_get_error ()));
xfree (name);
exec_bfd = NULL;
+ exec_bfd_mtime = 0;
}
if (exec_ops.to_sections)
{
if (from_tty)
printf_unfiltered (_("No executable file now.\n"));
+
+ set_gdbarch_from_file (NULL);
}
else
{
+ struct cleanup *cleanups;
char *scratch_pathname;
int scratch_chan;
scratch_chan);
if (!exec_bfd)
- error (_("\"%s\": could not open as an executable file: %s"),
- scratch_pathname, bfd_errmsg (bfd_get_error ()));
+ {
+ close (scratch_chan);
+ error (_("\"%s\": could not open as an executable file: %s"),
+ scratch_pathname, bfd_errmsg (bfd_get_error ()));
+ }
/* At this point, scratch_pathname and exec_bfd->name both point to the
same malloc'd string. However exec_close() will attempt to free it
via the exec_bfd->name pointer, so we need to make another copy and
leave exec_bfd as the new owner of the original copy. */
scratch_pathname = xstrdup (scratch_pathname);
- make_cleanup (xfree, scratch_pathname);
+ cleanups = make_cleanup (xfree, scratch_pathname);
if (!bfd_check_format (exec_bfd, bfd_object))
{
scratch_pathname, bfd_errmsg (bfd_get_error ()));
}
+ exec_bfd_mtime = bfd_get_mtime (exec_bfd);
+
validate_files ();
set_gdbarch_from_file (exec_bfd);
/* Tell display code (if any) about the changed file name. */
if (deprecated_exec_file_display_hook)
(*deprecated_exec_file_display_hook) (filename);
+
+ do_cleanups (cleanups);
}
bfd_cache_close_all ();
- observer_notify_executable_changed (NULL);
+ observer_notify_executable_changed ();
}
/* Process the first arg in ARGS as the new exec file.
if (args)
{
+ struct cleanup *cleanups;
+
/* Scan through the args and pick up the first non option arg
as the filename. */
- argv = buildargv (args);
- if (argv == NULL)
- nomem (0);
-
- make_cleanup_freeargv (argv);
+ argv = gdb_buildargv (args);
+ cleanups = make_cleanup_freeargv (argv);
for (; (*argv != NULL) && (**argv == '-'); argv++)
{;
filename = tilde_expand (*argv);
make_cleanup (xfree, filename);
exec_file_attach (filename, from_tty);
+
+ do_cleanups (cleanups);
}
else
exec_file_attach (NULL, from_tty);
struct section_table **table_pp = (struct section_table **) table_pp_char;
flagword aflag;
+ /* Check the section flags, but do not discard zero-length sections, since
+ some symbols may still be attached to this section. For instance, we
+ encountered on sparc-solaris 2.10 a shared library with an empty .bss
+ section to which a symbol named "_end" was attached. The address
+ of this symbol still needs to be relocated. */
aflag = bfd_get_section_flags (abfd, asect);
if (!(aflag & SEC_ALLOC))
return;
- if (0 == bfd_section_size (abfd, asect))
- return;
+
(*table_pp)->bfd = abfd;
(*table_pp)->the_bfd_section = asect;
(*table_pp)->addr = bfd_section_vma (abfd, asect);
int res;
struct section_table *p;
CORE_ADDR nextsectaddr, memend;
- asection *section = NULL;
+ struct obj_section *section = NULL;
if (len <= 0)
internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
for (p = target->to_sections; p < target->to_sections_end; p++)
{
- if (overlay_debugging && section && p->the_bfd_section &&
- strcmp (section->name, p->the_bfd_section->name) != 0)
+ if (overlay_debugging && section
+ && strcmp (section->the_bfd_section->name,
+ p->the_bfd_section->name) != 0)
continue; /* not the section we need */
if (memaddr >= p->addr)
{
print_section_info (struct target_ops *t, bfd *abfd)
{
struct section_table *p;
- /* FIXME: 16 is not wide enough when TARGET_ADDR_BIT > 64. */
- int wid = TARGET_ADDR_BIT <= 32 ? 8 : 16;
+ /* FIXME: 16 is not wide enough when gdbarch_addr_bit > 64. */
+ int wid = gdbarch_addr_bit (gdbarch_from_bfd (abfd)) <= 32 ? 8 : 16;
printf_filtered ("\t`%s', ", bfd_get_filename (abfd));
wrap_here (" ");
printf_filtered (_("file type %s.\n"), bfd_get_target (abfd));
if (abfd == exec_bfd)
- {
- printf_filtered (_("\tEntry point: "));
- deprecated_print_address_numeric (bfd_get_start_address (abfd), 1, gdb_stdout);
- printf_filtered ("\n");
- }
+ printf_filtered (_("\tEntry point: %s\n"),
+ paddress (bfd_get_start_address (abfd)));
for (p = t->to_sections; p < t->to_sections_end; p++)
{
printf_filtered ("\t%s", hex_string_custom (p->addr, wid));
}
}
-/* msnyder 5/21/99:
- exec_set_section_offsets sets the offsets of all the sections
- in the exec objfile. */
-
-void
-exec_set_section_offsets (bfd_signed_vma text_off, bfd_signed_vma data_off,
- bfd_signed_vma bss_off)
-{
- struct section_table *sect;
-
- for (sect = exec_ops.to_sections;
- sect < exec_ops.to_sections_end;
- sect++)
- {
- flagword flags;
-
- flags = bfd_get_section_flags (exec_bfd, sect->the_bfd_section);
-
- if (flags & SEC_CODE)
- {
- sect->addr += text_off;
- sect->endaddr += text_off;
- }
- else if (flags & (SEC_DATA | SEC_LOAD))
- {
- sect->addr += data_off;
- sect->endaddr += data_off;
- }
- else if (flags & SEC_ALLOC)
- {
- sect->addr += bss_off;
- sect->endaddr += bss_off;
- }
- }
-}
-
static void
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. */
+/* If we can find a section in FILENAME with BFD index INDEX, adjust
+ it to ADDRESS. */
void
exec_set_section_address (const char *filename, int index, CORE_ADDR address)
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)
+ && index == p->the_bfd_section->index)
{
+ p->endaddr += address - p->addr;
p->addr = address;
- p->endaddr += address;
}
}
}