+
+/* 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;
+ }
+ }
+
+ /* 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;
+}
+
+\f
+/* Return printable description of proc. */
+char *
+proc_string (struct proc *proc)
+{
+ static char tid_str[80];
+ if (proc_is_task (proc))
+ sprintf (tid_str, "process %d", proc->inf->pid);
+ else
+ sprintf (tid_str, "thread %d.%d",
+ proc->inf->pid, pid_to_thread_id (MERGEPID (proc->tid, 0)));
+ return tid_str;
+}
+
+static char *
+gnu_pid_to_str (ptid_t ptid)
+{
+ struct inf *inf = current_inferior;
+ int tid = PIDGET (ptid);
+ struct proc *thread = inf_tid_to_thread (inf, tid);
+
+ if (thread)
+ return proc_string (thread);
+ else
+ {
+ static char tid_str[80];
+ sprintf (tid_str, "bogus thread id %d", tid);
+ return tid_str;
+ }
+}
+