* target.h (struct thread_resume): Delete leave_stopped member.
[deliverable/binutils-gdb.git] / gdb / gcore.c
index 6d9ae0664109d68fd72b9faaeba173931c304e61..ec1be44de852f482cb1d24670a40612a51144657 100644 (file)
@@ -1,12 +1,13 @@
 /* Generate a core file for the inferior process.
 
-   Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -15,9 +16,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "elf-bfd.h"
 
 #include "gdb_assert.h"
 
+/* The largest amount of memory to read from the target at once.  We
+   must throttle it to limit the amount of memory used by GDB during
+   generate-core-file for programs with large resident data.  */
+#define MAX_COPY_BYTES (1024 * 1024)
+
 static char *default_gcore_target (void);
 static enum bfd_architecture default_gcore_arch (void);
 static unsigned long default_gcore_mach (void);
@@ -82,14 +86,15 @@ gcore_command (char *args, int from_tty)
   /* Create the note section.  */
   if (note_data != NULL && note_size != 0)
     {
-      note_sec = bfd_make_section_anyway (obfd, "note0");
+      note_sec = bfd_make_section_anyway_with_flags (obfd, "note0",
+                                                    SEC_HAS_CONTENTS
+                                                    | SEC_READONLY
+                                                    | SEC_ALLOC);
       if (note_sec == NULL)
        error (_("Failed to create 'note' section for corefile: %s"),
               bfd_errmsg (bfd_get_error ()));
 
       bfd_set_section_vma (obfd, note_sec, 0);
-      bfd_set_section_flags (obfd, note_sec,
-                            SEC_HAS_CONTENTS | SEC_READONLY | SEC_ALLOC);
       bfd_set_section_alignment (obfd, note_sec, 0);
       bfd_set_section_size (obfd, note_sec, note_size);
     }
@@ -119,12 +124,11 @@ default_gcore_mach (void)
 #if 1  /* See if this even matters...  */
   return 0;
 #else
-#ifdef TARGET_ARCHITECTURE
-  const struct bfd_arch_info *bfdarch = TARGET_ARCHITECTURE;
+
+  const struct bfd_arch_info *bfdarch = gdbarch_bfd_arch_info (current_gdbarch);
 
   if (bfdarch != NULL)
     return bfdarch->mach;
-#endif /* TARGET_ARCHITECTURE */
   if (exec_bfd == NULL)
     error (_("Can't find default bfd machine type (need execfile)."));
 
@@ -135,12 +139,11 @@ default_gcore_mach (void)
 static enum bfd_architecture
 default_gcore_arch (void)
 {
-#ifdef TARGET_ARCHITECTURE
-  const struct bfd_arch_info * bfdarch = TARGET_ARCHITECTURE;
+  const struct bfd_arch_info * bfdarch = gdbarch_bfd_arch_info
+                                        (current_gdbarch);
 
   if (bfdarch != NULL)
     return bfdarch->arch;
-#endif
   if (exec_bfd == NULL)
     error (_("Can't find bfd architecture for corefile (need execfile)."));
 
@@ -181,8 +184,8 @@ derive_stack_segment (bfd_vma *bottom, bfd_vma *top)
   /* Save frame pointer of TOS frame.  */
   *top = get_frame_base (fi);
   /* If current stack pointer is more "inner", use that instead.  */
-  if (INNER_THAN (read_sp (), *top))
-    *top = read_sp ();
+  if (gdbarch_inner_than (get_frame_arch (fi), get_frame_sp (fi), *top))
+    *top = get_frame_sp (fi);
 
   /* Find prev-most frame.  */
   while ((tmp_fi = get_prev_frame (fi)) != NULL)
@@ -212,6 +215,8 @@ derive_stack_segment (bfd_vma *bottom, bfd_vma *top)
 static int
 derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top)
 {
+  struct objfile *sbrk_objf;
+  struct gdbarch *gdbarch;
   bfd_vma top_of_data_memory = 0;
   bfd_vma top_of_heap = 0;
   bfd_size_type sec_size;
@@ -253,20 +258,21 @@ derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top)
   /* Now get the top-of-heap by calling sbrk in the inferior.  */
   if (lookup_minimal_symbol ("sbrk", NULL, NULL) != NULL)
     {
-      sbrk = find_function_in_inferior ("sbrk");
+      sbrk = find_function_in_inferior ("sbrk", &sbrk_objf);
       if (sbrk == NULL)
        return 0;
     }
   else if (lookup_minimal_symbol ("_sbrk", NULL, NULL) != NULL)
     {
-      sbrk = find_function_in_inferior ("_sbrk");
+      sbrk = find_function_in_inferior ("_sbrk", &sbrk_objf);
       if (sbrk == NULL)
        return 0;
     }
   else
     return 0;
 
-  zero = value_from_longest (builtin_type_int, 0);
+  gdbarch = get_objfile_arch (sbrk_objf);
+  zero = value_from_longest (builtin_type (gdbarch)->builtin_int, 0);
   gdb_assert (zero);
   sbrk = call_function_by_hand (sbrk, 1, &zero);
   if (sbrk == NULL)
@@ -322,7 +328,7 @@ gcore_create_callback (CORE_ADDR vaddr, unsigned long size,
       if (info_verbose)
         {
           fprintf_filtered (gdb_stdout, "Ignore segment, %s bytes at 0x%s\n",
-                           paddr_d (size), paddr_nz (vaddr));
+                            plongest (size), paddr_nz (vaddr));
         }
 
       return 0;
@@ -341,8 +347,8 @@ gcore_create_callback (CORE_ADDR vaddr, unsigned long size,
          asection *asec = objsec->the_bfd_section;
          bfd_vma align = (bfd_vma) 1 << bfd_get_section_alignment (abfd,
                                                                    asec);
-         bfd_vma start = objsec->addr & -align;
-         bfd_vma end = (objsec->endaddr + align - 1) & -align;
+         bfd_vma start = obj_section_addr (objsec) & -align;
+         bfd_vma end = (obj_section_endaddr (objsec) + align - 1) & -align;
          /* Match if either the entire memory region lies inside the
             section (i.e. a mapping covering some pages of a large
             segment) or the entire section lies inside the memory region
@@ -355,6 +361,7 @@ gcore_create_callback (CORE_ADDR vaddr, unsigned long size,
              && !(bfd_get_file_flags (abfd) & BFD_IN_MEMORY))
            {
              flags &= ~SEC_LOAD;
+             flags |= SEC_NEVER_LOAD;
              goto keep;        /* break out of two nested for loops */
            }
        }
@@ -368,7 +375,7 @@ gcore_create_callback (CORE_ADDR vaddr, unsigned long size,
   else
     flags |= SEC_DATA;
 
-  osec = bfd_make_section_anyway (obfd, "load");
+  osec = bfd_make_section_anyway_with_flags (obfd, "load", flags);
   if (osec == NULL)
     {
       warning (_("Couldn't make gcore segment: %s"),
@@ -379,13 +386,12 @@ gcore_create_callback (CORE_ADDR vaddr, unsigned long size,
   if (info_verbose)
     {
       fprintf_filtered (gdb_stdout, "Save segment, %s bytes at 0x%s\n",
-                       paddr_d (size), paddr_nz (vaddr));
+                       plongest (size), paddr_nz (vaddr));
     }
 
   bfd_set_section_size (obfd, osec, size);
   bfd_set_section_vma (obfd, osec, vaddr);
   bfd_section_lma (obfd, osec) = 0; /* ??? bfd_set_section_lma?  */
-  bfd_set_section_flags (obfd, osec, flags);
   return 0;
 }
 
@@ -412,7 +418,7 @@ objfile_find_memory_regions (int (*func) (CORE_ADDR, unsigned long,
          int size = bfd_section_size (ibfd, isec);
          int ret;
 
-         ret = (*func) (objsec->addr, bfd_section_size (ibfd, isec),
+         ret = (*func) (obj_section_addr (objsec), bfd_section_size (ibfd, isec),
                         1, /* All sections will be readable.  */
                         (flags & SEC_READONLY) == 0, /* Writable.  */
                         (flags & SEC_CODE) != 0, /* Executable.  */
@@ -444,7 +450,8 @@ objfile_find_memory_regions (int (*func) (CORE_ADDR, unsigned long,
 static void
 gcore_copy_callback (bfd *obfd, asection *osec, void *ignored)
 {
-  bfd_size_type size = bfd_section_size (obfd, osec);
+  bfd_size_type size, total_size = bfd_section_size (obfd, osec);
+  file_ptr offset = 0;
   struct cleanup *old_chain = NULL;
   void *memhunk;
 
@@ -456,19 +463,35 @@ gcore_copy_callback (bfd *obfd, asection *osec, void *ignored)
   if (strncmp ("load", bfd_section_name (obfd, osec), 4) != 0)
     return;
 
+  size = min (total_size, MAX_COPY_BYTES);
   memhunk = xmalloc (size);
   /* ??? This is crap since xmalloc should never return NULL.  */
   if (memhunk == NULL)
     error (_("Not enough memory to create corefile."));
   old_chain = make_cleanup (xfree, memhunk);
 
-  if (target_read_memory (bfd_section_vma (obfd, osec),
-                         memhunk, size) != 0)
-    warning (_("Memory read failed for corefile section, %s bytes at 0x%s."),
-            paddr_d (size), paddr (bfd_section_vma (obfd, osec)));
-  if (!bfd_set_section_contents (obfd, osec, memhunk, 0, size))
-    warning (_("Failed to write corefile contents (%s)."),
-            bfd_errmsg (bfd_get_error ()));
+  while (total_size > 0)
+    {
+      if (size > total_size)
+       size = total_size;
+
+      if (target_read_memory (bfd_section_vma (obfd, osec) + offset,
+                             memhunk, size) != 0)
+       {
+         warning (_("Memory read failed for corefile section, %s bytes at 0x%s."),
+                  plongest (size), paddr (bfd_section_vma (obfd, osec)));
+         break;
+       }
+      if (!bfd_set_section_contents (obfd, osec, memhunk, offset, size))
+       {
+         warning (_("Failed to write corefile contents (%s)."),
+                  bfd_errmsg (bfd_get_error ()));
+         break;
+       }
+
+      total_size -= size;
+      offset += size;
+    }
 
   do_cleanups (old_chain);     /* Frees MEMHUNK.  */
 }
@@ -488,6 +511,9 @@ gcore_memory_sections (bfd *obfd)
   return 1;
 }
 
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+extern initialize_file_ftype _initialize_gcore;
+
 void
 _initialize_gcore (void)
 {
This page took 0.02855 seconds and 4 git commands to generate.