* infrun.c (follow_fork): Initialize new step_* locals
[deliverable/binutils-gdb.git] / gdb / exec.c
index 94e0a0d3500d936e320d99ff6e75b358a27f5a63..985fbe57129ef86ea401f7ed32cf88f4390e8c25 100644 (file)
@@ -1,7 +1,7 @@
 /* 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
+   1998, 1999, 2000, 2001, 2002, 2003, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -158,7 +158,7 @@ exec_file_clear (int from_tty)
     printf_unfiltered (_("No executable file now.\n"));
 }
 
-/*  Process the first arg in ARGS as the new exec file.
+/* Set FILENAME as the new exec file.
 
    This function is intended to be behave essentially the same
    as exec_file_command, except that the latter will detect when
@@ -173,9 +173,7 @@ exec_file_clear (int from_tty)
    given a pid but not a exec pathname, and the attach command could
    figure out the pathname from the pid.  (In this case, we shouldn't
    ask the user whether the current target should be shut down --
-   we're supplying the exec pathname late for good reason.)
-   
-   ARGS is assumed to be the filename. */
+   we're supplying the exec pathname late for good reason.)  */
 
 void
 exec_file_attach (char *filename, int from_tty)
@@ -194,11 +192,12 @@ exec_file_attach (char *filename, int from_tty)
     }
   else
     {
+      struct cleanup *cleanups;
       char *scratch_pathname;
       int scratch_chan;
 
       scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, filename,
-                  write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, 0,
+                  write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY,
                            &scratch_pathname);
 #if defined(__GO32__) || defined(_WIN32) || defined(__CYGWIN__)
       if (scratch_chan < 0)
@@ -206,7 +205,7 @@ exec_file_attach (char *filename, int from_tty)
          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, 0,
+            write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY,
             &scratch_pathname);
        }
 #endif
@@ -217,15 +216,18 @@ exec_file_attach (char *filename, int from_tty)
                            scratch_chan);
 
       if (!exec_bfd)
-       error (_("\"%s\": could not open as an executable file: %s"),
-              scratch_pathname, bfd_errmsg (bfd_get_error ()));
+       {
+         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);
-      make_cleanup (xfree, scratch_pathname);
+      cleanups = make_cleanup (xfree, scratch_pathname);
 
       if (!bfd_check_format (exec_bfd, bfd_object))
        {
@@ -273,6 +275,8 @@ exec_file_attach (char *filename, int from_tty)
       /* Tell display code (if any) about the changed file name.  */
       if (deprecated_exec_file_display_hook)
        (*deprecated_exec_file_display_hook) (filename);
+
+      do_cleanups (cleanups);
     }
   bfd_cache_close_all ();
   observer_notify_executable_changed ();
@@ -299,14 +303,13 @@ exec_file_command (char *args, int from_tty)
 
   if (args)
     {
+      struct cleanup *cleanups;
+
       /* Scan through the args and pick up the first non option arg
          as the filename.  */
 
-      argv = buildargv (args);
-      if (argv == NULL)
-        nomem (0);
-
-      make_cleanup_freeargv (argv);
+      argv = gdb_buildargv (args);
+      cleanups = make_cleanup_freeargv (argv);
 
       for (; (*argv != NULL) && (**argv == '-'); argv++)
         {;
@@ -317,6 +320,8 @@ exec_file_command (char *args, int from_tty)
       filename = tilde_expand (*argv);
       make_cleanup (xfree, filename);
       exec_file_attach (filename, from_tty);
+
+      do_cleanups (cleanups);
     }
   else
     exec_file_attach (NULL, from_tty);
@@ -346,7 +351,7 @@ static void
 add_to_section_table (bfd *abfd, struct bfd_section *asect,
                      void *table_pp_char)
 {
-  struct section_table **table_pp = (struct section_table **) table_pp_char;
+  struct target_section **table_pp = (struct target_section **) table_pp_char;
   flagword aflag;
 
   /* Check the section flags, but do not discard zero-length sections, since
@@ -369,15 +374,15 @@ add_to_section_table (bfd *abfd, struct bfd_section *asect,
    Returns 0 if OK, 1 on error.  */
 
 int
-build_section_table (struct bfd *some_bfd, struct section_table **start,
-                    struct section_table **end)
+build_section_table (struct bfd *some_bfd, struct target_section **start,
+                    struct target_section **end)
 {
   unsigned count;
 
   count = bfd_count_sections (some_bfd);
   if (*start)
     xfree (* start);
-  *start = (struct section_table *) xmalloc (count * sizeof (**start));
+  *start = (struct target_section *) xmalloc (count * sizeof (**start));
   *end = *start;
   bfd_map_over_sections (some_bfd, add_to_section_table, (char *) end);
   if (*end > *start + count)
@@ -441,10 +446,16 @@ map_vmap (bfd *abfd, bfd *arch)
   return vp;
 }
 \f
-/* Read or write the exec file.
+/* Read or write from BFD executable files.
 
-   Args are address within a BFD file, address within gdb address-space,
-   length, and a flag indicating whether to read or write.
+   MEMADDR is an address within the target address space, MYADDR is an
+   address within GDB address-space where data is written to, LEN is
+   length of buffer, and WRITE indicates whether to read or write.
+   SECTIONS and SECTIONS_END defines a section table holding sections
+   from possibly multiple BFDs.
+
+   If SECTION_NAME is not NULL, only access sections with that same
+   name.
 
    Result is a length:
 
@@ -454,38 +465,28 @@ map_vmap (bfd *abfd, bfd *arch)
    to handle more bytes beyond this length, but no
    promises.
    < 0:  We cannot handle this address, but if somebody
-   else handles (-N) bytes, we can start from there.
-
-   The same routine is used to handle both core and exec files;
-   we just tail-call it with more arguments to select between them.  */
+   else handles (-N) bytes, we can start from there.  */
 
-int
-xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int write,
-            struct mem_attrib *attrib, struct target_ops *target)
+static int
+section_table_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr,
+                          int len, int write,
+                          struct target_section *sections,
+                          struct target_section *sections_end,
+                          const char *section_name)
 {
   int res;
-  struct section_table *p;
+  struct target_section *p;
   CORE_ADDR nextsectaddr, memend;
-  struct obj_section *section = NULL;
 
   if (len <= 0)
     internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
 
-  if (overlay_debugging)
-    {
-      section = find_pc_overlay (memaddr);
-      if (pc_in_unmapped_range (memaddr, section))
-       memaddr = overlay_mapped_address (memaddr, section);
-    }
-
   memend = memaddr + len;
   nextsectaddr = memend;
 
-  for (p = target->to_sections; p < target->to_sections_end; p++)
+  for (p = sections; p < sections_end; p++)
     {
-      if (overlay_debugging && section
-         && strcmp (section->the_bfd_section->name,
-                    p->the_bfd_section->name) != 0)
+      if (section_name && strcmp (section_name, p->the_bfd_section->name) != 0)
        continue;               /* not the section we need */
       if (memaddr >= p->addr)
         {
@@ -531,12 +532,72 @@ xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int write,
   else
     return -(nextsectaddr - memaddr);  /* Next boundary where we can help */
 }
+
+int
+section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
+                                  ULONGEST offset, LONGEST len,
+                                  struct target_section *sections,
+                                  struct target_section *sections_end)
+{
+  if (readbuf != NULL)
+    return section_table_xfer_memory (offset, readbuf, len, 0,
+                                     sections, sections_end, NULL);
+  else
+    return section_table_xfer_memory (offset, (gdb_byte *) writebuf, len, 1,
+                                     sections, sections_end, NULL);
+}
+
+/* Read or write the exec file.
+
+   Args are address within a BFD file, address within gdb address-space,
+   length, and a flag indicating whether to read or write.
+
+   Result is a length:
+
+   0:    We cannot handle this address and length.
+   > 0:  We have handled N bytes starting at this address.
+   (If N == length, we did it all.)  We might be able
+   to handle more bytes beyond this length, but no
+   promises.
+   < 0:  We cannot handle this address, but if somebody
+   else handles (-N) bytes, we can start from there.
+
+   The same routine is used to handle both core and exec files;
+   we just tail-call it with more arguments to select between them.  */
+
+int
+xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int write,
+            struct mem_attrib *attrib, struct target_ops *target)
+{
+  int res;
+  const char *section_name = NULL;
+
+  if (len <= 0)
+    internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
+
+  if (overlay_debugging)
+    {
+      struct obj_section *section = find_pc_overlay (memaddr);
+
+      if (section != NULL)
+       {
+         if (pc_in_unmapped_range (memaddr, section))
+           memaddr = overlay_mapped_address (memaddr, section);
+         section_name = section->the_bfd_section->name;
+       }
+    }
+
+  return section_table_xfer_memory (memaddr, myaddr, len, write,
+                                   target->to_sections,
+                                   target->to_sections_end,
+                                   section_name);
+}
 \f
 
 void
 print_section_info (struct target_ops *t, bfd *abfd)
 {
-  struct section_table *p;
+  struct target_section *p;
   /* FIXME: 16 is not wide enough when gdbarch_addr_bit > 64.  */
   int wid = gdbarch_addr_bit (gdbarch_from_bfd (abfd)) <= 32 ? 8 : 16;
 
@@ -600,7 +661,7 @@ exec_files_info (struct target_ops *t)
 static void
 set_section_command (char *args, int from_tty)
 {
-  struct section_table *p;
+  struct target_section *p;
   char *secname;
   unsigned seclen;
   unsigned long secaddr;
@@ -643,7 +704,7 @@ set_section_command (char *args, int from_tty)
 void
 exec_set_section_address (const char *filename, int index, CORE_ADDR address)
 {
-  struct section_table *p;
+  struct target_section *p;
 
   for (p = exec_ops.to_sections; p < exec_ops.to_sections_end; p++)
     {
This page took 0.027216 seconds and 4 git commands to generate.