Return early in target_xfer_partial when LEN is zero.
[deliverable/binutils-gdb.git] / gdb / exec.c
index 5b256ef01f1123bcbb5bcc663e4d660337242ab9..3ec6c2f124eb110a9b1eab56d27d0c2a7f595c91 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
@@ -339,7 +350,7 @@ add_to_section_table (bfd *abfd, struct bfd_section *asect,
   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);
@@ -397,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)
 {
@@ -414,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
@@ -427,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
-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)
@@ -509,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)
@@ -519,7 +578,7 @@ 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"));
 
@@ -580,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);
 
@@ -591,7 +650,7 @@ exec_xfer_partial (struct target_ops *ops, enum target_object object,
                                              table->sections_end,
                                              NULL);
   else
-    return -1;
+    return TARGET_XFER_E_IO;
 }
 \f
 
@@ -742,7 +801,8 @@ exec_set_section_address (const char *filename, int index, CORE_ADDR address)
    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;
 }
This page took 0.027902 seconds and 4 git commands to generate.