/* Work with executable files, for GDB.
- Copyright (C) 1988-2013 Free Software Foundation, Inc.
+ Copyright (C) 1988-2014 Free Software Foundation, Inc.
This file is part of GDB.
#include <fcntl.h>
#include "readline/readline.h"
-#include "gdb_string.h"
+#include <string.h>
#include "gdbcore.h"
#include <ctype.h>
-#include "gdb_stat.h"
+#include <sys/stat.h>
void (*deprecated_file_changed_hook) (char *);
exec_bfd = NULL;
exec_bfd_mtime = 0;
- remove_target_sections (&exec_bfd, abfd);
+ remove_target_sections (&exec_bfd);
+
+ xfree (exec_filename);
+ exec_filename = NULL;
}
}
else
{
struct cleanup *cleanups;
- char *scratch_pathname;
+ char *scratch_pathname, *canonical_pathname;
int scratch_chan;
struct target_section *sections = NULL, *sections_end = NULL;
char **matching;
cleanups = make_cleanup (xfree, scratch_pathname);
+ /* gdb_bfd_open (and its variants) prefers canonicalized pathname for
+ better BFD caching. */
+ canonical_pathname = gdb_realpath (scratch_pathname);
+ make_cleanup (xfree, canonical_pathname);
+
if (write_files)
- exec_bfd = gdb_bfd_fopen (scratch_pathname, gnutarget,
+ exec_bfd = gdb_bfd_fopen (canonical_pathname, gnutarget,
FOPEN_RUB, scratch_chan);
else
- exec_bfd = gdb_bfd_open (scratch_pathname, gnutarget, scratch_chan);
+ exec_bfd = gdb_bfd_open (canonical_pathname, gnutarget, scratch_chan);
if (!exec_bfd)
{
scratch_pathname, bfd_errmsg (bfd_get_error ()));
}
+ gdb_assert (exec_filename == NULL);
+ exec_filename = gdb_realpath_keepfile (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
if (!(aflag & SEC_ALLOC))
return;
- (*table_pp)->key = NULL;
+ (*table_pp)->owner = NULL;
(*table_pp)->the_bfd_section = asect;
(*table_pp)->addr = bfd_section_vma (abfd, asect);
(*table_pp)->endaddr = (*table_pp)->addr + bfd_section_size (abfd, asect);
current set of target sections. */
void
-add_target_sections (void *key,
+add_target_sections (void *owner,
struct target_section *sections,
struct target_section *sections_end)
{
for (i = 0; i < count; ++i)
{
table->sections[space + i] = sections[i];
- table->sections[space + i].key = key;
+ table->sections[space + i].owner = owner;
}
/* If these are the first file sections we can provide memory
}
}
-/* Remove all target sections taken from ABFD. */
+/* Add the sections of OBJFILE to the current set of target sections. */
void
-remove_target_sections (void *key, bfd *abfd)
+add_target_sections_of_objfile (struct objfile *objfile)
+{
+ struct target_section_table *table = current_target_sections;
+ struct obj_section *osect;
+ int space;
+ unsigned count = 0;
+ struct target_section *ts;
+
+ if (objfile == NULL)
+ return;
+
+ /* Compute the number of sections to add. */
+ ALL_OBJFILE_OSECTIONS (objfile, osect)
+ {
+ if (bfd_get_section_size (osect->the_bfd_section) == 0)
+ continue;
+ count++;
+ }
+
+ if (count == 0)
+ return;
+
+ space = resize_section_table (table, count);
+
+ ts = table->sections + space;
+
+ ALL_OBJFILE_OSECTIONS (objfile, osect)
+ {
+ if (bfd_get_section_size (osect->the_bfd_section) == 0)
+ continue;
+
+ gdb_assert (ts < table->sections + space + count);
+
+ ts->addr = obj_section_addr (osect);
+ ts->endaddr = obj_section_endaddr (osect);
+ ts->the_bfd_section = osect->the_bfd_section;
+ ts->owner = (void *) objfile;
+
+ ts++;
+ }
+}
+
+/* Remove all target sections owned by OWNER.
+ OWNER must be the same value passed to add_target_sections. */
+
+void
+remove_target_sections (void *owner)
{
struct target_section *src, *dest;
struct target_section_table *table = current_target_sections;
+ gdb_assert (owner != NULL);
+
dest = table->sections;
for (src = table->sections; src < table->sections_end; src++)
- if (src->key != key || src->the_bfd_section->owner != abfd)
+ if (src->owner != owner)
{
/* Keep this section. */
if (dest < src)
int
section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
- ULONGEST offset, LONGEST len,
+ ULONGEST offset, ULONGEST len,
struct target_section *sections,
struct target_section *sections_end,
const char *section_name)
ULONGEST memaddr = offset;
ULONGEST memend = memaddr + len;
- if (len <= 0)
+ if (len == 0)
internal_error (__FILE__, __LINE__,
_("failed internal consistency check"));
exec_xfer_partial (struct target_ops *ops, enum target_object object,
const char *annex, gdb_byte *readbuf,
const gdb_byte *writebuf,
- ULONGEST offset, LONGEST len)
+ ULONGEST offset, ULONGEST len)
{
struct target_section_table *table = target_get_section_table (ops);
table->sections_end,
NULL);
else
- return -1;
+ return TARGET_XFER_E_IO;
}
\f
breakpoint_init_inferior). */
static int
-ignore (struct gdbarch *gdbarch, struct bp_target_info *bp_tgt)
+ignore (struct target_ops *ops, struct gdbarch *gdbarch,
+ struct bp_target_info *bp_tgt)
{
return 0;
}