/* 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
struct target_section **table_pp = (struct target_section **) table_pp_char;
flagword aflag;
+ gdb_assert (abfd == asect->owner);
+
/* 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
if (!(aflag & SEC_ALLOC))
return;
- (*table_pp)->key = NULL;
- (*table_pp)->bfd = abfd;
+ (*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
+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 *key, bfd *abfd)
+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->bfd != abfd)
+ if (src->owner != owner)
{
/* Keep this section. */
if (dest < src)
for (p = sections; p < sections_end; p++)
{
- if ((bfd_get_section_flags (p->bfd, p->the_bfd_section)
+ if ((bfd_get_section_flags (p->the_bfd_section->owner,
+ p->the_bfd_section)
& SEC_READONLY) == 0)
continue;
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"));
for (p = sections; p < sections_end; p++)
{
- if (section_name && strcmp (section_name, p->the_bfd_section->name) != 0)
+ struct bfd_section *asect = p->the_bfd_section;
+ bfd *abfd = asect->owner;
+
+ if (section_name && strcmp (section_name, asect->name) != 0)
continue; /* not the section we need. */
if (memaddr >= p->addr)
{
{
/* Entire transfer is within this section. */
if (writebuf)
- res = bfd_set_section_contents (p->bfd, p->the_bfd_section,
+ res = bfd_set_section_contents (abfd, asect,
writebuf, memaddr - p->addr,
len);
else
- res = bfd_get_section_contents (p->bfd, p->the_bfd_section,
+ res = bfd_get_section_contents (abfd, asect,
readbuf, memaddr - p->addr,
len);
return (res != 0) ? len : 0;
/* This section overlaps the transfer. Just do half. */
len = p->endaddr - memaddr;
if (writebuf)
- res = bfd_set_section_contents (p->bfd, p->the_bfd_section,
+ res = bfd_set_section_contents (abfd, asect,
writebuf, memaddr - p->addr,
len);
else
- res = bfd_get_section_contents (p->bfd, p->the_bfd_section,
+ res = bfd_get_section_contents (abfd, asect,
readbuf, memaddr - p->addr,
len);
return (res != 0) ? len : 0;
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);
for (p = t->sections; p < t->sections_end; p++)
{
- asection *asect = p->the_bfd_section;
+ struct bfd_section *psect = p->the_bfd_section;
+ bfd *pbfd = psect->owner;
- if ((bfd_get_section_flags (abfd, asect) & (SEC_ALLOC | SEC_LOAD))
+ if ((bfd_get_section_flags (pbfd, psect) & (SEC_ALLOC | SEC_LOAD))
!= (SEC_ALLOC | SEC_LOAD))
continue;
- if (bfd_get_section_vma (abfd, asect) <= abfd->start_address
- && abfd->start_address < (bfd_get_section_vma (abfd, asect)
- + bfd_get_section_size (asect)))
+ if (bfd_get_section_vma (pbfd, psect) <= abfd->start_address
+ && abfd->start_address < (bfd_get_section_vma (pbfd, psect)
+ + bfd_get_section_size (psect)))
{
- displacement = p->addr - bfd_get_section_vma (abfd, asect);
+ displacement = p->addr - bfd_get_section_vma (pbfd, psect);
break;
}
}
}
for (p = t->sections; p < t->sections_end; p++)
{
+ struct bfd_section *psect = p->the_bfd_section;
+ bfd *pbfd = psect->owner;
+
printf_filtered ("\t%s", hex_string_custom (p->addr, wid));
printf_filtered (" - %s", hex_string_custom (p->endaddr, wid));
/* FIXME: i18n: Need to rewrite this sentence. */
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));
- if (p->bfd != abfd)
- printf_filtered (" in %s", bfd_get_filename (p->bfd));
+ hex_string_custom (psect->filepos, 8));
+ printf_filtered (" is %s", bfd_section_name (pbfd, psect));
+ if (pbfd != abfd)
+ printf_filtered (" in %s", bfd_get_filename (pbfd));
printf_filtered ("\n");
}
}
table = current_target_sections;
for (p = table->sections; p < table->sections_end; p++)
{
- if (filename_cmp (filename, p->bfd->filename) == 0
+ if (filename_cmp (filename, p->the_bfd_section->owner->filename) == 0
&& index == p->the_bfd_section->index)
{
p->endaddr += address - p->addr;