diff options
-rw-r--r-- | gdb/ChangeLog | 10 | ||||
-rw-r--r-- | gdb/config/i386/i386gnu.mh | 6 | ||||
-rw-r--r-- | gdb/gnu-nat.c | 74 | ||||
-rw-r--r-- | gdb/i386gnu-nat.c | 22 |
4 files changed, 110 insertions, 2 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e488e31..b46f11f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2002-04-24 Roland McGrath <roland@frob.com> + + * config/i386/i386gnu.mh (NATDEPFILES): Add core-regset.o here. + * i386gnu-nat.c [HAVE_SYS_PROCFS_H] + (supply_gregset, supply_fpregset): New functions. + + * gnu-nat.c (gnu_find_memory_regions): New function. + (init_gnu_ops): Set `to_find_memory_regions' hook to that. + (gnu_xfer_memory): Add a cast. + 2002-04-24 Michael Snyder <msnyder@redhat.com> * arm-tdep.c (arm_scan_prologue): Move "mov ip, sp" into the diff --git a/gdb/config/i386/i386gnu.mh b/gdb/config/i386/i386gnu.mh index 252b2e5..13feba5 100644 --- a/gdb/config/i386/i386gnu.mh +++ b/gdb/config/i386/i386gnu.mh @@ -1,5 +1,9 @@ # Host: Intel 386 running the GNU Hurd -NATDEPFILES= i386gnu-nat.o i387-nat.o gnu-nat.o fork-child.o solib.o solib-svr4.o solib-legacy.o corelow.o notify_S.o process_reply_S.o msg_reply_S.o msg_U.o exc_request_U.o exc_request_S.o +NATDEPFILES= i386gnu-nat.o i387-nat.o gnu-nat.o corelow.o core-regset.o \ + fork-child.o solib.o solib-svr4.o solib-legacy.o \ + notify_S.o process_reply_S.o msg_reply_S.o \ + msg_U.o exc_request_U.o exc_request_S.o + XM_FILE= xm-i386gnu.h NAT_FILE= nm-gnu.h MH_CFLAGS = -D_GNU_SOURCE diff --git a/gdb/gnu-nat.c b/gdb/gnu-nat.c index 95a7899..824ee83 100644 --- a/gdb/gnu-nat.c +++ b/gdb/gnu-nat.c @@ -2458,7 +2458,7 @@ gnu_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, else { inf_debug (current_inferior, "%s %p[%d] %s %p", - write ? "writing" : "reading", memaddr, len, + write ? "writing" : "reading", (void *) memaddr, len, write ? "<--" : "-->", myaddr); if (write) return gnu_write_inferior (task, memaddr, myaddr, len); @@ -2467,6 +2467,77 @@ gnu_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, } } +/* 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, + ®ion_address, + ®ion_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; + } + } +} + /* Return printable description of proc. */ char * @@ -2524,6 +2595,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; diff --git a/gdb/i386gnu-nat.c b/gdb/i386gnu-nat.c index 9188ea4..e82fe0d 100644 --- a/gdb/i386gnu-nat.c +++ b/gdb/i386gnu-nat.c @@ -38,6 +38,10 @@ #include "gnu-nat.h" #include "i387-nat.h" +#ifdef HAVE_SYS_PROCFS_H +# include <sys/procfs.h> +# include "gregset.h" +#endif /* Offset to the thread_state_t location where REG is stored. */ #define REG_OFFSET(reg) offsetof (struct i386_thread_state, reg) @@ -88,6 +92,24 @@ fetch_fpregs (struct proc *thread) i387_supply_fsave (state.hw_state); } +#ifdef HAVE_SYS_PROCFS_H +/* These two calls are used by the core-regset.c code for + reading ELF core files. */ +void +supply_gregset (gdb_gregset_t *gregs) +{ + int i; + for (i = 0; i < NUM_GREGS; i++) + supply_register (i, REG_ADDR (gregs, i)); +} + +void +supply_fpregset (gdb_fpregset_t *fpregs) +{ + i387_supply_fsave ((char *) fpregs); +} +#endif + /* Fetch register REGNO, or all regs if REGNO is -1. */ void gnu_fetch_registers (int regno) |