Can you put this into gdb and test it if you get a chance?  I'm CC'ing to
bug-hurd, in hopes that someone else might test this out and follow up
either with fixes or confirmation that it works.  I'm not quite sure if
gdb's "gcore" will be happy doing just the memory part when there is no
make_corefile_notes hook; if not, we could hack in a no-op hook for testing
purposes.  

I would also like your input on what the note segments ought to look like
in Hurd ELF core files.  With the new gcore target stuff in gdb 5.2, we can
work out the format details and the reading and writing code all in gdb first.
Then once we're satisfied with it, we can modify that code to go into the
crash server.



2002-03-06  Roland McGrath  <[EMAIL PROTECTED]>

        * gnu-nat.c (gnu_find_memory_regions): New function.
        (init_gnu_ops): Set `to_find_memory_regions' hook to that.

Index: gnu-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/gnu-nat.c,v
retrieving revision 1.18
diff -p -b -u -r1.18 gnu-nat.c
--- gnu-nat.c   2002/01/06 19:18:28     1.18
+++ gnu-nat.c   2002/03/07 04:12:30
@@ -2467,6 +2467,86 @@ gnu_xfer_memory (CORE_ADDR memaddr, char
     }
 }
 
+/* Call FUNC on each memory region in the task.  */
+static int
+gnu_find_memory_regions (int (*func) (CORE_ADDR,
+                                     unsigned long,
+                                     int, int, int,
+                                     void *),
+                          void *data)
+{
+  error_t err;
+  task_t task;
+  vm_address_t region_address, last_region_address, last_region_end;
+  vm_prot_t last_protection;
+
+  if (current_inferior == 0 || current_inferior->task == 0)
+    return 0;
+  task = current_inferior->task->port;
+  if (task == MACH_PORT_NULL)
+    return 0;
+
+  region_address = last_region_address = last_region_end = VM_MIN_ADDRESS;
+  last_protection = VM_PROT_NONE;
+  while (region_address < VM_MAX_ADDRESS)
+    {
+      vm_prot_t protection;
+      vm_prot_t max_protection;
+      vm_inherit_t inheritance;
+      boolean_t shared;
+      mach_port_t object_name;
+      vm_offset_t offset;
+      vm_size_t region_length = VM_MAX_ADDRESS - region_address;
+      vm_address_t old_address = region_address;
+
+      err = vm_region (task,
+                      &region_address,
+                      &region_length,
+                      &protection,
+                      &max_protection,
+                      &inheritance,
+                      &shared,
+                      &object_name,
+                      &offset);
+      if (err == KERN_NO_SPACE)
+       break;
+      if (err != KERN_SUCCESS)
+       {
+         warning ("vm_region failed: %s", mach_error_string (err));
+         return -1;
+       }
+
+      if (protection == last_protection && region_address == last_region_end)
+       /* This region is contiguous with and indistinguishable from
+          the previous one, so we just extend that one.  */
+       last_region_end = region_address += region_length;
+      else
+       {
+         /* This region is distinct from the last one we saw, so report
+            that previous one.  */
+         if (last_protection != VM_PROT_NONE)
+           (*func) (last_region_address,
+                    last_region_end - last_region_address,
+                    last_protection & VM_PROT_READ,
+                    last_protection & VM_PROT_WRITE,
+                    last_protection & VM_PROT_EXECUTE,
+                    data);
+         last_region_address = region_address;
+         last_region_end = region_address += region_length;
+         last_protection = protection;
+       }
+    }
+
+  /* Report the final region.  */
+  if (last_region_end > last_region_address && last_protection != VM_PROT_NONE)
+    (*func) (last_region_address, last_region_end - last_region_address,
+            last_protection & VM_PROT_READ,
+            last_protection & VM_PROT_WRITE,
+            last_protection & VM_PROT_EXECUTE,
+            data);
+
+  return 0;
+}
 
 /* Return printable description of proc.  */
 char *
@@ -2524,6 +2604,7 @@ init_gnu_ops (void)
   gnu_ops.to_store_registers = gnu_store_registers;    /* to_store_registers */
   gnu_ops.to_prepare_to_store = gnu_prepare_to_store; /* to_prepare_to_store */
   gnu_ops.to_xfer_memory = gnu_xfer_memory; /* to_xfer_memory */
+  gnu_ops.to_find_memory_regions = gnu_find_memory_regions;
   gnu_ops.to_files_info = 0;           /* to_files_info */
   gnu_ops.to_insert_breakpoint = memory_insert_breakpoint;
   gnu_ops.to_remove_breakpoint = memory_remove_breakpoint;

_______________________________________________
Bug-hurd mailing list
[EMAIL PROTECTED]
http://mail.gnu.org/mailman/listinfo/bug-hurd

Reply via email to