gdbarch: add instruction predicate methods
[deliverable/binutils-gdb.git] / gdb / exec.c
index e8605b961c83a8b06615d964dfd3f9dd32d20195..809a0b2f8fe10b728dda4f81364a8ba8148785e9 100644 (file)
@@ -1,6 +1,6 @@
 /* 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 *);
 
@@ -101,7 +101,10 @@ exec_close (void)
       exec_bfd = NULL;
       exec_bfd_mtime = 0;
 
-      remove_target_sections (&exec_bfd, abfd);
+      remove_target_sections (&exec_bfd);
+
+      xfree (exec_filename);
+      exec_filename = NULL;
     }
 }
 
@@ -179,7 +182,7 @@ exec_file_attach (char *filename, int from_tty)
   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;
@@ -203,11 +206,16 @@ exec_file_attach (char *filename, int from_tty)
 
       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)
        {
@@ -215,6 +223,9 @@ exec_file_attach (char *filename, int from_tty)
                 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
@@ -328,6 +339,8 @@ add_to_section_table (bfd *abfd, struct bfd_section *asect,
   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
@@ -337,8 +350,7 @@ add_to_section_table (bfd *abfd, struct bfd_section *asect,
   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);
@@ -396,7 +408,7 @@ build_section_table (struct bfd *some_bfd, struct target_section **start,
    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)
 {
@@ -413,7 +425,7 @@ add_target_sections (void *key,
       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
@@ -426,17 +438,65 @@ add_target_sections (void *key,
     }
 }
 
-/* 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)
@@ -479,7 +539,8 @@ section_table_available_memory (VEC(mem_range_s) *memory,
 
   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;
 
@@ -507,7 +568,7 @@ section_table_available_memory (VEC(mem_range_s) *memory,
 
 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)
@@ -517,13 +578,16 @@ section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
   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)
         {
@@ -531,11 +595,11 @@ section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
            {
              /* 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;
@@ -550,11 +614,11 @@ section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
              /* 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;
@@ -575,7 +639,7 @@ static LONGEST
 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);
 
@@ -610,17 +674,18 @@ print_section_info (struct target_section_table *t, bfd *abfd)
 
       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;
            }
        }
@@ -636,6 +701,9 @@ print_section_info (struct target_section_table *t, bfd *abfd)
     }
   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));
 
@@ -647,11 +715,10 @@ print_section_info (struct target_section_table *t, bfd *abfd)
       /* 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");
     }
 }
@@ -720,7 +787,7 @@ exec_set_section_address (const char *filename, int index, CORE_ADDR address)
   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;
This page took 0.030608 seconds and 4 git commands to generate.