/* 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
- Free Software Foundation, Inc.
+ Copyright (C) 1988-2003, 2007-2012 Free Software Foundation, Inc.
This file is part of GDB.
#include "target.h"
#include "gdbcmd.h"
#include "language.h"
+#include "filenames.h"
#include "symfile.h"
#include "objfiles.h"
#include "completer.h"
#include "arch-utils.h"
#include "gdbthread.h"
#include "progspace.h"
+#include "gdb_bfd.h"
#include <fcntl.h>
#include "readline/readline.h"
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. */
nxt = vp->nxt;
/* if there is an objfile associated with this bfd,
- free_objfile() will do proper cleanup of objfile *and* bfd. */
+ free_objfile() will do proper cleanup of objfile *and* bfd. */
if (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);
+ gdb_bfd_unref (vp->bfd);
xfree (vp);
}
if (scratch_chan < 0)
{
char *exename = alloca (strlen (filename) + 5);
+
strcat (strcpy (exename, filename), ".exe");
scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, exename,
write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY,
&scratch_pathname);
}
#endif
+
+ cleanups = make_cleanup (xfree, scratch_pathname);
+
if (scratch_chan < 0)
perror_with_name (filename);
- exec_bfd = bfd_fopen (scratch_pathname, gnutarget,
- write_files ? FOPEN_RUB : FOPEN_RB,
- scratch_chan);
+ exec_bfd = gdb_bfd_fopen (scratch_pathname, gnutarget,
+ write_files ? FOPEN_RUB : FOPEN_RB,
+ 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
/* FIXME - This should only be run for RS6000, but the ifdef is a poor
way to accomplish. */
#ifdef DEPRECATED_IBM6000_TARGET
- /* Setup initial vmap. */
+ /* Setup initial vmap. */
map_vmap (exec_bfd, 0);
if (vmap == NULL)
be called from file_command(), which also calls symbol_file_command()
which can take multiple args.
- If ARGS is NULL, we just want to close the exec file. */
+ If ARGS is NULL, we just want to close the exec file. */
static void
exec_file_command (char *args, int from_tty)
exec_file_attach (NULL, from_tty);
}
-/* Set both the exec file and the symbol file, in one command.
+/* Set both the exec file and the symbol file, in one command.
What a novelty. Why did GDB go through four major releases before this
command was added? */
}
\f
-/* Locate all mappable sections of a BFD file.
+/* Locate all mappable sections of a BFD file.
table_pp_char is a char * to get it through bfd_map_over_sections;
we cast it back to its proper type. */
*end = *start;
bfd_map_over_sections (some_bfd, add_to_section_table, (char *) end);
if (*end > *start + count)
- internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
+ internal_error (__FILE__, __LINE__,
+ _("failed internal consistency check"));
/* We could realloc the table, but it probably loses for most files. */
return 0;
}
if (count > 0)
{
int space = resize_section_table (table, count);
+
memcpy (table->sections + space,
sections, count * sizeof (sections[0]));
remove_target_sections (bfd *abfd)
{
struct target_section *src, *dest;
-
struct target_section_table *table = current_target_sections;
dest = table->sections;
vp->dend = vp->dstart + bfd_section_size (abfd, sect);
vp->dvma = bfd_section_vma (abfd, sect);
}
- /* Silently ignore other types of sections. (FIXME?) */
+ /* Silently ignore other types of sections. (FIXME?) */
}
/* Make a vmap for ABFD which might be a member of the archive ARCH.
vmap_bfd.pvmap = vp;
bfd_map_over_sections (abfd, bfdsec_to_vmap, &vmap_bfd);
- /* Find the end of the list and append. */
+ /* Find the end of the list and append. */
for (vpp = &vmap; *vpp; vpp = &(*vpp)->nxt)
;
*vpp = vp;
}
\f
+VEC(mem_range_s) *
+section_table_available_memory (VEC(mem_range_s) *memory,
+ CORE_ADDR memaddr, ULONGEST len,
+ struct target_section *sections,
+ struct target_section *sections_end)
+{
+ struct target_section *p;
+
+ for (p = sections; p < sections_end; p++)
+ {
+ if ((bfd_get_section_flags (p->bfd, p->the_bfd_section)
+ & SEC_READONLY) == 0)
+ continue;
+
+ /* Copy the meta-data, adjusted. */
+ if (mem_ranges_overlap (p->addr, p->endaddr - p->addr, memaddr, len))
+ {
+ ULONGEST lo1, hi1, lo2, hi2;
+ struct mem_range *r;
+
+ lo1 = memaddr;
+ hi1 = memaddr + len;
+
+ lo2 = p->addr;
+ hi2 = p->endaddr;
+
+ r = VEC_safe_push (mem_range_s, memory, NULL);
+
+ r->start = max (lo1, lo2);
+ r->length = min (hi1, hi2) - r->start;
+ }
+ }
+
+ return memory;
+}
+
int
section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
ULONGEST offset, LONGEST len,
ULONGEST memend = memaddr + len;
if (len <= 0)
- internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
+ internal_error (__FILE__, __LINE__,
+ _("failed internal consistency check"));
for (p = sections; p < sections_end; p++)
{
if (section_name && strcmp (section_name, p->the_bfd_section->name) != 0)
- continue; /* not the section we need */
+ continue; /* not the section we need. */
if (memaddr >= p->addr)
{
if (memend <= p->endaddr)
}
}
- return 0; /* We can't help */
+ 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;
printf_filtered (_("file type %s.\n"), bfd_get_target (abfd));
if (abfd == exec_bfd)
{
- /* gcc-3.4 does not like the initialization in <p == t->sections_end>. */
+ /* gcc-3.4 does not like the initialization in
+ <p == t->sections_end>. */
bfd_vma displacement = 0;
+ bfd_vma entry_point;
for (p = t->sections; p < t->sections_end; p++)
{
}
}
if (p == t->sections_end)
- warning (_("Cannot find section for the entry point of %s.\n"),
+ warning (_("Cannot find section for the entry point of %s."),
bfd_get_filename (abfd));
+ entry_point = gdbarch_addr_bits_remove (gdbarch,
+ bfd_get_start_address (abfd)
+ + displacement);
printf_filtered (_("\tEntry point: %s\n"),
- paddress (gdbarch, (bfd_get_start_address (abfd)
- + displacement)));
+ paddress (gdbarch, entry_point));
}
for (p = t->sections; p < t->sections_end; p++)
{
if (info_verbose)
printf_filtered (" @ %s",
hex_string_custom (p->the_bfd_section->filepos, 8));
- printf_filtered (" is %s", bfd_section_name (p->bfd, p->the_bfd_section));
+ printf_filtered (" is %s", bfd_section_name (p->bfd,
+ p->the_bfd_section));
if (p->bfd != abfd)
printf_filtered (" in %s", bfd_get_filename (p->bfd));
printf_filtered ("\n");
static void
exec_files_info (struct target_ops *t)
{
- print_section_info (current_target_sections, exec_bfd);
+ if (exec_bfd)
+ print_section_info (current_target_sections, exec_bfd);
+ else
+ puts_filtered (_("\t<no file loaded>\n"));
if (vmap)
{
if (args == 0)
error (_("Must specify section name and its virtual address"));
- /* Parse out section name */
+ /* Parse out section name. */
for (secname = args; !isspace (*args); args++);
seclen = args - secname;
- /* Parse out new virtual address */
+ /* Parse out new virtual address. */
secaddr = parse_and_eval_address (args);
table = current_target_sections;
for (p = table->sections; p < table->sections_end; p++)
{
- if (!strncmp (secname, bfd_section_name (exec_bfd, p->the_bfd_section), seclen)
- && bfd_section_name (exec_bfd, p->the_bfd_section)[seclen] == '\0')
+ if (!strncmp (secname, bfd_section_name (p->bfd,
+ p->the_bfd_section), seclen)
+ && bfd_section_name (p->bfd, p->the_bfd_section)[seclen] == '\0')
{
offset = secaddr - p->addr;
p->addr += offset;
table = current_target_sections;
for (p = table->sections; p < table->sections_end; p++)
{
- if (strcmp (filename, p->bfd->filename) == 0
+ if (filename_cmp (filename, p->bfd->filename) == 0
&& index == p->the_bfd_section->index)
{
p->endaddr += address - p->addr;
!= current_target_sections->sections_end);
}
-/* Find mapped memory. */
+/* Find mapped memory. */
extern void
-exec_set_find_memory_regions (int (*func) (int (*) (CORE_ADDR,
- unsigned long,
- int, int, int,
- void *),
- void *))
+exec_set_find_memory_regions (int (*func) (find_memory_region_ftype, void *))
{
exec_ops.to_find_memory_regions = func;
}