/* Work with executable files, for GDB.
- Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002, 2003, 2007, 2008, 2009, 2010, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GDB.
#include "arch-utils.h"
#include "gdbthread.h"
#include "progspace.h"
+#include "gdb_bfd.h"
#include <fcntl.h>
#include "readline/readline.h"
#include <ctype.h>
#include "gdb_stat.h"
-#include "xcoffsolib.h"
-
-struct vmap *map_vmap (bfd *, bfd *);
-
void (*deprecated_file_changed_hook) (char *);
/* Prototypes for local functions */
}
-struct vmap *vmap;
-
static void
exec_open (char *args, int from_tty)
{
if (exec_bfd)
{
bfd *abfd = exec_bfd;
- char *name = bfd_get_filename (abfd);
- gdb_bfd_close_or_warn (abfd);
- xfree (name);
+ gdb_bfd_unref (abfd);
/* Removing target sections may close the exec_ops target.
Clear exec_bfd before doing so to prevent recursion. */
exec_bfd = NULL;
exec_bfd_mtime = 0;
- remove_target_sections (abfd);
+ remove_target_sections (&exec_bfd, abfd);
}
}
sections and closes all executable bfds from all program spaces. */
static void
-exec_close_1 (int quitting)
+exec_close_1 (void)
{
- int need_symtab_cleanup = 0;
- struct vmap *vp, *nxt;
-
using_exec_ops = 0;
- for (nxt = vmap; nxt != NULL;)
- {
- vp = nxt;
- nxt = vp->nxt;
-
- /* if there is an objfile associated with this bfd,
- free_objfile() will do proper cleanup of objfile *and* bfd. */
-
- if (vp->objfile)
- {
- free_objfile (vp->objfile);
- need_symtab_cleanup = 1;
- }
- else if (vp->bfd != exec_bfd)
- /* FIXME-leak: We should be freeing vp->name too, I think. */
- gdb_bfd_close_or_warn (vp->bfd);
-
- xfree (vp);
- }
-
- vmap = NULL;
-
{
struct program_space *ss;
struct cleanup *old_chain;
#endif
if (scratch_chan < 0)
perror_with_name (filename);
- exec_bfd = bfd_fopen (scratch_pathname, gnutarget,
- write_files ? FOPEN_RUB : FOPEN_RB,
- scratch_chan);
+
+ cleanups = make_cleanup (xfree, scratch_pathname);
+
+ if (write_files)
+ exec_bfd = gdb_bfd_fopen (scratch_pathname, gnutarget,
+ FOPEN_RUB, scratch_chan);
+ else
+ exec_bfd = gdb_bfd_open (scratch_pathname, gnutarget, scratch_chan);
if (!exec_bfd)
{
- 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);
- cleanups = make_cleanup (xfree, scratch_pathname);
-
if (!bfd_check_format_matches (exec_bfd, bfd_object, &matching))
{
/* Make sure to close exec_bfd, or else "run" might try to use
gdb_bfd_errmsg (bfd_get_error (), matching));
}
- /* FIXME - This should only be run for RS6000, but the ifdef is a poor
- way to accomplish. */
-#ifdef DEPRECATED_IBM6000_TARGET
- /* Setup initial vmap. */
-
- map_vmap (exec_bfd, 0);
- if (vmap == NULL)
- {
- /* Make sure to close exec_bfd, or else "run" might try to use
- it. */
- exec_close ();
- error (_("\"%s\": can't find the file sections: %s"),
- scratch_pathname, bfd_errmsg (bfd_get_error ()));
- }
-#endif /* DEPRECATED_IBM6000_TARGET */
-
if (build_section_table (exec_bfd, §ions, §ions_end))
{
/* Make sure to close exec_bfd, or else "run" might try to use
/* Add the executable's sections to the current address spaces'
list of sections. This possibly pushes the exec_ops
target. */
- add_target_sections (sections, sections_end);
+ add_target_sections (&exec_bfd, sections, sections_end);
xfree (sections);
/* Tell display code (if any) about the changed file name. */
if (!(aflag & SEC_ALLOC))
return;
+ (*table_pp)->key = NULL;
(*table_pp)->bfd = abfd;
(*table_pp)->the_bfd_section = asect;
(*table_pp)->addr = bfd_section_vma (abfd, asect);
int
resize_section_table (struct target_section_table *table, int num_added)
{
- struct target_section *old_value;
int old_count;
int new_count;
- old_value = table->sections;
old_count = table->sections_end - table->sections;
new_count = num_added + old_count;
current set of target sections. */
void
-add_target_sections (struct target_section *sections,
+add_target_sections (void *key,
+ struct target_section *sections,
struct target_section *sections_end)
{
int count;
if (count > 0)
{
int space = resize_section_table (table, count);
+ int i;
- memcpy (table->sections + space,
- sections, count * sizeof (sections[0]));
+ for (i = 0; i < count; ++i)
+ {
+ table->sections[space + i] = sections[i];
+ table->sections[space + i].key = key;
+ }
/* If these are the first file sections we can provide memory
from, push the file_stratum target. */
/* Remove all target sections taken from ABFD. */
void
-remove_target_sections (bfd *abfd)
+remove_target_sections (void *key, bfd *abfd)
{
struct target_section *src, *dest;
struct target_section_table *table = current_target_sections;
dest = table->sections;
for (src = table->sections; src < table->sections_end; src++)
- if (src->bfd != abfd)
+ if (src->key != key || src->bfd != abfd)
{
/* Keep this section. */
if (dest < src)
}
}
-\f
-static void
-bfdsec_to_vmap (struct bfd *abfd, struct bfd_section *sect, void *arg3)
-{
- struct vmap_and_bfd *vmap_bfd = (struct vmap_and_bfd *) arg3;
- struct vmap *vp;
-
- vp = vmap_bfd->pvmap;
-
- if ((bfd_get_section_flags (abfd, sect) & SEC_LOAD) == 0)
- return;
-
- if (strcmp (bfd_section_name (abfd, sect), ".text") == 0)
- {
- vp->tstart = bfd_section_vma (abfd, sect);
- vp->tend = vp->tstart + bfd_section_size (abfd, sect);
- vp->tvma = bfd_section_vma (abfd, sect);
- vp->toffs = sect->filepos;
- }
- else if (strcmp (bfd_section_name (abfd, sect), ".data") == 0)
- {
- vp->dstart = bfd_section_vma (abfd, sect);
- vp->dend = vp->dstart + bfd_section_size (abfd, sect);
- vp->dvma = bfd_section_vma (abfd, sect);
- }
- /* Silently ignore other types of sections. (FIXME?) */
-}
-
-/* Make a vmap for ABFD which might be a member of the archive ARCH.
- Return the new vmap. */
-
-struct vmap *
-map_vmap (bfd *abfd, bfd *arch)
-{
- struct vmap_and_bfd vmap_bfd;
- struct vmap *vp, **vpp;
-
- vp = (struct vmap *) xmalloc (sizeof (*vp));
- memset ((char *) vp, '\0', sizeof (*vp));
- vp->nxt = 0;
- vp->bfd = abfd;
- vp->name = bfd_get_filename (arch ? arch : abfd);
- vp->member = arch ? bfd_get_filename (abfd) : "";
-
- vmap_bfd.pbfd = arch;
- vmap_bfd.pvmap = vp;
- bfd_map_over_sections (abfd, bfdsec_to_vmap, &vmap_bfd);
-
- /* Find the end of the list and append. */
- for (vpp = &vmap; *vpp; vpp = &(*vpp)->nxt)
- ;
- *vpp = vp;
-
- return vp;
-}
\f
VEC(mem_range_s) *
return 0; /* We can't help. */
}
-struct target_section_table *
+static struct target_section_table *
exec_get_section_table (struct target_ops *ops)
{
return current_target_sections;
static void
exec_files_info (struct target_ops *t)
{
- print_section_info (current_target_sections, exec_bfd);
-
- if (vmap)
- {
- int addr_size = gdbarch_addr_bit (target_gdbarch) / 8;
- struct vmap *vp;
-
- printf_unfiltered (_("\tMapping info for file `%s'.\n"), vmap->name);
- printf_unfiltered ("\t %*s %*s %*s %*s %8.8s %s\n",
- addr_size * 2, "tstart",
- addr_size * 2, "tend",
- addr_size * 2, "dstart",
- addr_size * 2, "dend",
- "section",
- "file(member)");
-
- for (vp = vmap; vp; vp = vp->nxt)
- printf_unfiltered ("\t0x%s 0x%s 0x%s 0x%s %s%s%s%s\n",
- phex (vp->tstart, addr_size),
- phex (vp->tend, addr_size),
- phex (vp->dstart, addr_size),
- phex (vp->dend, addr_size),
- vp->name,
- *vp->member ? "(" : "", vp->member,
- *vp->member ? ")" : "");
- }
+ if (exec_bfd)
+ print_section_info (current_target_sections, exec_bfd);
+ else
+ puts_filtered (_("\t<no file loaded>\n"));
}
static void
table = current_target_sections;
for (p = table->sections; p < table->sections_end; p++)
{
- if (!strncmp (secname, bfd_section_name (exec_bfd,
+ if (!strncmp (secname, bfd_section_name (p->bfd,
p->the_bfd_section), seclen)
- && bfd_section_name (exec_bfd, p->the_bfd_section)[seclen] == '\0')
+ && bfd_section_name (p->bfd, p->the_bfd_section)[seclen] == '\0')
{
offset = secaddr - p->addr;
p->addr += offset;
show_write_files,
&setlist, &showlist);
- add_target (&exec_ops);
+ add_target_with_completer (&exec_ops, filename_completer);
}
static char *