(core_file_thread_alive): Rename to...
(core_thread_alive): ... this.
(core_pid_to_str): Try gdbarch_core_pid_to_str first.
(init_core_ops): Adjust.
(coreops_suppress_target): Delete.
(_initialize_corelow): Unconditionally add core_ops.
* procfs.c: Include "inf-child.h".
(procfs_ops): Delete.
(init_procfs_ops): Delete. Reimplement as...
(procfs_target): ... this, inheriting from inf-child.
(procfs_attach, procfs_detach, procfs_fetch_registers): Adjust.
(procfs_prepare_to_store): Delete.
(procfs_store_registers, procfs_resume): Adjust.
(procfs_open): Delete.
(procfs_suppress_run): Delete.
(procfs_can_run): Delete.
(procfs_mourn_inferior): Adjust.
(procfs_init_inferior): Add target_ops parameter. Adjust.
(procfs_create_inferior): Don't pass procfs_init_inferior to
fork_inferior. Instead call it after fork_inferior returns.
(procfs_find_new_threads): Adjust.
(_initialize_procfs): Adjust to use procfs_target instead of
init_procfs_ops.
* sol-thread.c (orig_core_ops, sol_core_ops): Delete.
(lwp_to_thread): Use target_thread_alive.
(sol_thread_open): Delete.
(sol_thread_attach): Delete.
(sol_thread_detach, sol_thread_resume, sol_thread_wait)
(sol_thread_fetch_registers, sol_thread_store_registers): Adjust
to use find_target_beneath.
(sol_thread_prepare_to_store, sol_thread_xfer_memory): Delete.
(sol_thread_xfer_partial): Adjust to use find_target_beneath.
(sol_thread_files_info, sol_thread_kill_inferior): Delete.
(check_for_thread_db): New.
(sol_thread_notice_signals, sol_thread_create_inferior): Delete.
(sol_thread_new_objfile): Call check_for_thread_db.
(sol_thread_mourn_inferior): Adjust to use find_target_beneath.
(sol_thread_can_run): Delete.
(sol_thread_alive): Adjust to use find_target_beneath.
(sol_thread_stop): Delete.
(rw_common): Use target_write_memory or target_read_memory.
(ps_lgetregs, ps_lgetfpregs): Use target_fetch_registers.
(ps_lsetregs, ps_lsetfpregs): Use target_store_registers.
(solaris_pid_to_str): Remove check for libthread_db initialization
failing.
(sol_find_new_threads): Remove check for libthread_db
initialization failing, or for an invalid inferior_ptid. Adjust
to use find_target_beneath.
(sol_core_open, sol_core_close, sol_core_detach,
sol_core_files_info, sol_find_memory_regions,
sol_make_note_section, ignore): Delete.
(init_sol_thread_ops): Make it a thread_stratum target. Remove
unneeded callback settings.
(init_sol_core_ops): Delete.
(_initialize_sol_thread): No longer call init_sol_core_ops, set
procfs_suppress_run, or hack with core_ops.
* target.h (struct target_ops): Add a target_ops * parameter to
to_resume, to_fetch_registers, to_store_registers, to_thread_alive
and to_find_new_threads.
(target_fetch_registers, target_store_registers)
(target_thread_alive, target_find_new_threads): Redeclare as
function.
* target.c (update_current_target): Do not inherit or de_fault
to_resume, to_fetch_registers, to_store_registers,
to_thread_alive, to_find_new_threads.
(target_resume): Adjust.
(target_thread_alive, target_find_new_threads): New.
(debug_to_resume, debug_to_fetch_registers): Delete.
(target_fetch_registers): New.
(debug_to_store_registers): Delete.
(target_store_registers): New.
(debug_to_thread_alive, debug_to_find_new_threads): Delete.
(setup_target_debug): Adjust.
* gdbcore.h (core_ops): Delete declaration.
* inf-ptrace.c, linux-nat.c, remote.c, amd64-linux-nat.c,
inf-child.c, linux-thread-db.c, bsd-uthread.c, inf-ttrace.c,
i386-sol2-tdep.c, darwin-nat.c, gnu-nat.c, go32-nat.c,
hpux-thread.c, i386-linux-nat.c, i386fbsd-nat.c, monitor.c,
nto-procfs.c, remote-m32r-sdi.c, remote-mips.c, windows-nat.c,
alphabsd-nat.c, amd64bsd-nat.c, arm-linux-nat.c, armnbsd-nat.c,
bsd-kvm.c, hppa-hpux-nat.c, hppa-linux-nat.c, hppabsd-nat.c,
hppanbsd-nat.c, i386-darwin-nat.c, i386bsd-nat.c,
ia64-linux-nat.c, m32r-linux-nat.c, m68kbsd-nat.c,
m68klinux-nat.c, m88kbsd-nat.c, mips-linux-nat.c,
mips64obsd-nat.c, mipsnbsd-nat.c, ppc-linux-nat.c, ppcnbsd-nat.c,
ppcobsd-nat.c, remote-sim.c, rs6000-nat.c, s390-nat.c,
shnbsd-nat.c, sparc-nat.c, sparc-nat.h, spu-linux-nat.c,
vaxbsd-nat.c, xtensa-linux-nat.c: Adjust to target_ops changes.
* gdbarch.sh (core_pid_to_str): New gdbarch callback.
* gdbarch.h, gdbarch.c: Regenerate.
* sol2-tdep.c: Include "inferior.h".
(sol2_core_pid_to_str): New.
* sol2-tdep.h (sol2_core_pid_to_str): Declare.
* amd64-sol2-tdep.c (amd64_sol2_init_abi): Set it.
* sparc-sol2-tdep.c (sparc32_sol2_init_abi): Set it.
* sparc64-sol2-tdep.c (sparc64_sol2_init_abi): Set it.
* i386-sol2-tdep.c (i386_sol2_init_abi): Set it.
+2009-02-23 Pedro Alves <pedro@codesourcery.com>
+
+ * corelow.c (get_core_registers): Adjust.
+ (core_file_thread_alive): Rename to...
+ (core_thread_alive): ... this.
+ (core_pid_to_str): Try gdbarch_core_pid_to_str first.
+ (init_core_ops): Adjust.
+ (coreops_suppress_target): Delete.
+ (_initialize_corelow): Unconditionally add core_ops.
+ * procfs.c: Include "inf-child.h".
+ (procfs_ops): Delete.
+ (init_procfs_ops): Delete. Reimplement as...
+ (procfs_target): ... this, inheriting from inf-child.
+ (procfs_attach, procfs_detach, procfs_fetch_registers): Adjust.
+ (procfs_prepare_to_store): Delete.
+ (procfs_store_registers, procfs_resume): Adjust.
+ (procfs_open): Delete.
+ (procfs_suppress_run): Delete.
+ (procfs_can_run): Delete.
+ (procfs_mourn_inferior): Adjust.
+ (procfs_init_inferior): Add target_ops parameter. Adjust.
+ (procfs_create_inferior): Don't pass procfs_init_inferior to
+ fork_inferior. Instead call it after fork_inferior returns.
+ (procfs_find_new_threads): Adjust.
+ (_initialize_procfs): Adjust to use procfs_target instead of
+ init_procfs_ops.
+ * sol-thread.c (orig_core_ops, sol_core_ops): Delete.
+ (lwp_to_thread): Use target_thread_alive.
+ (sol_thread_open): Delete.
+ (sol_thread_attach): Delete.
+ (sol_thread_detach, sol_thread_resume, sol_thread_wait)
+ (sol_thread_fetch_registers, sol_thread_store_registers): Adjust
+ to use find_target_beneath.
+ (sol_thread_prepare_to_store, sol_thread_xfer_memory): Delete.
+ (sol_thread_xfer_partial): Adjust to use find_target_beneath.
+ (sol_thread_files_info, sol_thread_kill_inferior): Delete.
+ (check_for_thread_db): New.
+ (sol_thread_notice_signals, sol_thread_create_inferior): Delete.
+ (sol_thread_new_objfile): Call check_for_thread_db.
+ (sol_thread_mourn_inferior): Adjust to use find_target_beneath.
+ (sol_thread_can_run): Delete.
+ (sol_thread_alive): Adjust to use find_target_beneath.
+ (sol_thread_stop): Delete.
+ (rw_common): Use target_write_memory or target_read_memory.
+ (ps_lgetregs, ps_lgetfpregs): Use target_fetch_registers.
+ (ps_lsetregs, ps_lsetfpregs): Use target_store_registers.
+ (solaris_pid_to_str): Remove check for libthread_db initialization
+ failing.
+ (sol_find_new_threads): Remove check for libthread_db
+ initialization failing, or for an invalid inferior_ptid. Adjust
+ to use find_target_beneath.
+ (sol_core_open, sol_core_close, sol_core_detach,
+ sol_core_files_info, sol_find_memory_regions,
+ sol_make_note_section, ignore): Delete.
+ (init_sol_thread_ops): Make it a thread_stratum target. Remove
+ unneeded callback settings.
+ (init_sol_core_ops): Delete.
+ (_initialize_sol_thread): No longer call init_sol_core_ops, set
+ procfs_suppress_run, or hack with core_ops.
+
+ * target.h (struct target_ops): Add a target_ops * parameter to
+ to_resume, to_fetch_registers, to_store_registers, to_thread_alive
+ and to_find_new_threads.
+ (target_fetch_registers, target_store_registers)
+ (target_thread_alive, target_find_new_threads): Redeclare as
+ function.
+
+ * target.c (update_current_target): Do not inherit or de_fault
+ to_resume, to_fetch_registers, to_store_registers,
+ to_thread_alive, to_find_new_threads.
+ (target_resume): Adjust.
+ (target_thread_alive, target_find_new_threads): New.
+ (debug_to_resume, debug_to_fetch_registers): Delete.
+ (target_fetch_registers): New.
+ (debug_to_store_registers): Delete.
+ (target_store_registers): New.
+ (debug_to_thread_alive, debug_to_find_new_threads): Delete.
+ (setup_target_debug): Adjust.
+
+ * gdbcore.h (core_ops): Delete declaration.
+
+ * inf-ptrace.c, linux-nat.c, remote.c, amd64-linux-nat.c,
+ inf-child.c, linux-thread-db.c, bsd-uthread.c, inf-ttrace.c,
+ i386-sol2-tdep.c, darwin-nat.c, gnu-nat.c, go32-nat.c,
+ hpux-thread.c, i386-linux-nat.c, i386fbsd-nat.c, monitor.c,
+ nto-procfs.c, remote-m32r-sdi.c, remote-mips.c, windows-nat.c,
+ alphabsd-nat.c, amd64bsd-nat.c, arm-linux-nat.c, armnbsd-nat.c,
+ bsd-kvm.c, hppa-hpux-nat.c, hppa-linux-nat.c, hppabsd-nat.c,
+ hppanbsd-nat.c, i386-darwin-nat.c, i386bsd-nat.c,
+ ia64-linux-nat.c, m32r-linux-nat.c, m68kbsd-nat.c,
+ m68klinux-nat.c, m88kbsd-nat.c, mips-linux-nat.c,
+ mips64obsd-nat.c, mipsnbsd-nat.c, ppc-linux-nat.c, ppcnbsd-nat.c,
+ ppcobsd-nat.c, remote-sim.c, rs6000-nat.c, s390-nat.c,
+ shnbsd-nat.c, sparc-nat.c, sparc-nat.h, spu-linux-nat.c,
+ vaxbsd-nat.c, xtensa-linux-nat.c: Adjust to target_ops changes.
+
+ * gdbarch.sh (core_pid_to_str): New gdbarch callback.
+ * gdbarch.h, gdbarch.c: Regenerate.
+
+ * sol2-tdep.c: Include "inferior.h".
+ (sol2_core_pid_to_str): New.
+ * sol2-tdep.h (sol2_core_pid_to_str): Declare.
+
+ * amd64-sol2-tdep.c (amd64_sol2_init_abi): Set it.
+ * sparc-sol2-tdep.c (sparc32_sol2_init_abi): Set it.
+ * sparc64-sol2-tdep.c (sparc64_sol2_init_abi): Set it.
+ * i386-sol2-tdep.c (i386_sol2_init_abi): Set it.
+
2009-02-22 Doug Evans <dje@google.com>
* exec.c (exec_file_attach): Fix comment.
for all registers (including the floating point registers). */
static void
-alphabsd_fetch_inferior_registers (struct regcache *regcache, int regno)
+alphabsd_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
if (regno == -1 || getregs_supplies (regno))
{
this for all registers (including the floating point registers). */
static void
-alphabsd_store_inferior_registers (struct regcache *regcache, int regno)
+alphabsd_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
if (regno == -1 || getregs_supplies (regno))
{
registers). */
static void
-amd64_linux_fetch_inferior_registers (struct regcache *regcache, int regnum)
+amd64_linux_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
int tid;
registers). */
static void
-amd64_linux_store_inferior_registers (struct regcache *regcache, int regnum)
+amd64_linux_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
int tid;
/* Solaris encodes the pid of the inferior in regset section
names. */
set_gdbarch_core_reg_section_encodes_pid (gdbarch, 1);
+
+ /* How to print LWP PTIDs from core files. */
+ set_gdbarch_core_pid_to_str (gdbarch, sol2_core_pid_to_str);
}
\f
for all registers (including the floating-point registers). */
static void
-amd64bsd_fetch_inferior_registers (struct regcache *regcache, int regnum)
+amd64bsd_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
this for all registers (including the floating-point registers). */
static void
-amd64bsd_store_inferior_registers (struct regcache *regcache, int regnum)
+amd64bsd_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
point registers depending upon the value of regno. */
static void
-arm_linux_fetch_inferior_registers (struct regcache *regcache, int regno)
+arm_linux_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
if (-1 == regno)
{
point registers depending upon the value of regno. */
static void
-arm_linux_store_inferior_registers (struct regcache *regcache, int regno)
+arm_linux_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
if (-1 == regno)
{
}
static void
-armnbsd_fetch_registers (struct regcache *regcache, int regno)
+armnbsd_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
if (regno >= 0)
{
}
static void
-armnbsd_store_registers (struct regcache *regcache, int regno)
+armnbsd_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
if (regno >= 0)
{
}
static void
-bsd_kvm_fetch_registers (struct regcache *regcache, int regnum)
+bsd_kvm_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
struct nlist nl[2];
}
static int
-bsd_kvm_thread_alive (ptid_t ptid)
+bsd_kvm_thread_alive (struct target_ops *ops,
+ ptid_t ptid)
{
return 1;
}
static void
bsd_uthread_mourn_inferior (struct target_ops *ops)
{
- struct target_ops *beneath = find_target_beneath (bsd_uthread_ops_hack);
+ struct target_ops *beneath = find_target_beneath (ops);
beneath->to_mourn_inferior (beneath);
bsd_uthread_deactivate ();
}
static void
-bsd_uthread_fetch_registers (struct regcache *regcache, int regnum)
+bsd_uthread_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct bsd_uthread_ops *ops = gdbarch_data (gdbarch, bsd_uthread_data);
+ struct bsd_uthread_ops *uthread_ops = gdbarch_data (gdbarch, bsd_uthread_data);
CORE_ADDR addr = ptid_get_tid (inferior_ptid);
+ struct target_ops *beneath = find_target_beneath (ops);
CORE_ADDR active_addr;
/* Always fetch the appropriate registers from the layer beneath. */
- find_target_beneath (bsd_uthread_ops_hack)->to_fetch_registers (regcache, regnum);
+ beneath->to_fetch_registers (beneath, regcache, regnum);
/* FIXME: That might have gotten us more than we asked for. Make
sure we overwrite all relevant registers with values from the
if (addr != 0 && addr != active_addr)
{
bsd_uthread_check_magic (addr);
- ops->supply_uthread (regcache, regnum,
- addr + bsd_uthread_thread_ctx_offset);
+ uthread_ops->supply_uthread (regcache, regnum,
+ addr + bsd_uthread_thread_ctx_offset);
}
}
static void
-bsd_uthread_store_registers (struct regcache *regcache, int regnum)
+bsd_uthread_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct bsd_uthread_ops *ops = gdbarch_data (gdbarch, bsd_uthread_data);
+ struct bsd_uthread_ops *uthread_ops = gdbarch_data (gdbarch, bsd_uthread_data);
+ struct target_ops *beneath = find_target_beneath (ops);
CORE_ADDR addr = ptid_get_tid (inferior_ptid);
CORE_ADDR active_addr;
if (addr != 0 && addr != active_addr)
{
bsd_uthread_check_magic (addr);
- ops->collect_uthread (regcache, regnum,
- addr + bsd_uthread_thread_ctx_offset);
+ uthread_ops->collect_uthread (regcache, regnum,
+ addr + bsd_uthread_thread_ctx_offset);
}
else
{
/* Updating the thread that is currently running; pass the
request to the layer beneath. */
- find_target_beneath (bsd_uthread_ops_hack)->to_store_registers (regcache, regnum);
+ beneath->to_store_registers (beneath, regcache, regnum);
}
}
ptid_t ptid, struct target_waitstatus *status)
{
CORE_ADDR addr;
- struct target_ops *beneath = find_target_beneath (bsd_uthread_ops_hack);
+ struct target_ops *beneath = find_target_beneath (ops);
/* Pass the request to the layer beneath. */
ptid = beneath->to_wait (beneath, ptid, status);
}
static void
-bsd_uthread_resume (ptid_t ptid, int step, enum target_signal sig)
+bsd_uthread_resume (struct target_ops *ops,
+ ptid_t ptid, int step, enum target_signal sig)
{
/* Pass the request to the layer beneath. */
- find_target_beneath (bsd_uthread_ops_hack)->to_resume (ptid, step, sig);
+ struct target_ops *beneath = find_target_beneath (ops);
+ beneath->to_resume (beneath, ptid, step, sig);
}
static int
-bsd_uthread_thread_alive (ptid_t ptid)
+bsd_uthread_thread_alive (struct target_ops *ops, ptid_t ptid)
{
+ struct target_ops *beneath = find_target_beneath (ops);
CORE_ADDR addr = ptid_get_tid (inferior_ptid);
if (addr != 0)
return 0;
}
- return find_target_beneath (bsd_uthread_ops_hack)->to_thread_alive (ptid);
+ return beneath->to_thread_alive (beneath, ptid);
}
static void
-bsd_uthread_find_new_threads (void)
+bsd_uthread_find_new_threads (struct target_ops *ops)
{
pid_t pid = ptid_get_pid (inferior_ptid);
int offset = bsd_uthread_thread_next_offset;
static void core_close_cleanup (void *ignore);
-static void get_core_registers (struct regcache *, int);
-
static void add_to_thread_list (bfd *, asection *, void *);
-static int core_file_thread_alive (ptid_t tid);
-
static void init_core_ops (void);
void _initialize_corelow (void);
/* We just get all the registers, so we don't use regno. */
static void
-get_core_registers (struct regcache *regcache, int regno)
+get_core_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
int i;
behaviour.
*/
static int
-core_file_thread_alive (ptid_t tid)
+core_thread_alive (struct target_ops *ops, ptid_t ptid)
{
return 1;
}
{
static char buf[64];
+ if (core_gdbarch
+ && gdbarch_core_pid_to_str_p (core_gdbarch))
+ {
+ char *ret = gdbarch_core_pid_to_str (core_gdbarch, ptid);
+ if (ret != NULL)
+ return ret;
+ }
+
if (ptid_get_lwp (ptid) == 0)
xsnprintf (buf, sizeof buf, "<main task>");
else
core_ops.to_insert_breakpoint = ignore;
core_ops.to_remove_breakpoint = ignore;
core_ops.to_create_inferior = find_default_create_inferior;
- core_ops.to_thread_alive = core_file_thread_alive;
+ core_ops.to_thread_alive = core_thread_alive;
core_ops.to_read_description = core_read_description;
core_ops.to_pid_to_str = core_pid_to_str;
core_ops.to_stratum = core_stratum;
core_ops.to_magic = OPS_MAGIC;
}
-/* non-zero if we should not do the add_target call in
- _initialize_corelow; not initialized (i.e., bss) so that
- the target can initialize it (i.e., data) if appropriate.
- This needs to be set at compile time because we don't know
- for sure whether the target's initialize routine is called
- before us or after us. */
-int coreops_suppress_target;
-
void
_initialize_corelow (void)
{
init_core_ops ();
- if (!coreops_suppress_target)
- add_target (&core_ops);
+ add_target (&core_ops);
}
static void darwin_stop (ptid_t);
-static void darwin_resume (ptid_t ptid, int step,
- enum target_signal signal);
-
static void darwin_mourn_inferior (struct target_ops *ops);
static int darwin_lookup_task (char *args, task_t * ptask, int *ppid);
static void darwin_files_info (struct target_ops *ops);
-static int darwin_thread_alive (ptid_t tpid);
-
/* Current inferior. */
darwin_inferior *darwin_inf = NULL;
}
static void
-darwin_resume (ptid_t ptid, int step, enum target_signal signal)
+darwin_resume (struct target_ops *ops,
+ ptid_t ptid, int step, enum target_signal signal)
{
struct target_waitstatus status;
int pid;
MACH_CHECK_ERROR (kret);
if (msg_state == GOT_MESSAGE)
- darwin_resume (inferior_ptid, 0, 0);
+ darwin_resume (darwin_ops, inferior_ptid, 0, 0);
res = kill (inf->pid, SIGSTOP);
if (res != 0)
}
static void
-darwin_kill_inferior (void)
+darwin_kill_inferior (struct target_ops *ops)
{
struct target_waitstatus wstatus;
ptid_t ptid;
if (msg_state == GOT_MESSAGE)
{
exc_msg.ex_type = 0;
- darwin_resume (inferior_ptid, 0, 0);
+ darwin_resume (ops, inferior_ptid, 0, 0);
}
kret = task_resume (darwin_inf->task);
if (msg_state == GOT_MESSAGE)
{
exc_msg.ex_type = 0;
- darwin_resume (inferior_ptid, 0, 0);
+ darwin_resume (ops, inferior_ptid, 0, 0);
}
kret = task_resume (darwin_inf->task);
}
static int
-darwin_thread_alive (ptid_t ptid)
+darwin_thread_alive (struct target_ops *ops, ptid_t ptid)
{
return 1;
}
int core_reg_section_encodes_pid;
struct core_regset_section * core_regset_sections;
gdbarch_core_xfer_shared_libraries_ftype *core_xfer_shared_libraries;
+ gdbarch_core_pid_to_str_ftype *core_pid_to_str;
int vtable_function_descriptors;
int vbit_in_delta;
gdbarch_skip_permanent_breakpoint_ftype *skip_permanent_breakpoint;
0, /* core_reg_section_encodes_pid */
0, /* core_regset_sections */
0, /* core_xfer_shared_libraries */
+ 0, /* core_pid_to_str */
0, /* vtable_function_descriptors */
0, /* vbit_in_delta */
0, /* skip_permanent_breakpoint */
/* Skip verify of regset_from_core_section, has predicate */
/* Skip verify of core_reg_section_encodes_pid, invalid_p == 0 */
/* Skip verify of core_xfer_shared_libraries, has predicate */
+ /* Skip verify of core_pid_to_str, has predicate */
/* Skip verify of vtable_function_descriptors, invalid_p == 0 */
/* Skip verify of vbit_in_delta, invalid_p == 0 */
/* Skip verify of skip_permanent_breakpoint, has predicate */
fprintf_unfiltered (file,
"gdbarch_dump: convert_register_p = <%s>\n",
host_address_to_string (gdbarch->convert_register_p));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: gdbarch_core_pid_to_str_p() = %d\n",
+ gdbarch_core_pid_to_str_p (gdbarch));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: core_pid_to_str = <%s>\n",
+ host_address_to_string (gdbarch->core_pid_to_str));
fprintf_unfiltered (file,
"gdbarch_dump: gdbarch_core_read_description_p() = %d\n",
gdbarch_core_read_description_p (gdbarch));
gdbarch->core_xfer_shared_libraries = core_xfer_shared_libraries;
}
+int
+gdbarch_core_pid_to_str_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->core_pid_to_str != NULL;
+}
+
+char *
+gdbarch_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid)
+{
+ gdb_assert (gdbarch != NULL);
+ gdb_assert (gdbarch->core_pid_to_str != NULL);
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_core_pid_to_str called\n");
+ return gdbarch->core_pid_to_str (gdbarch, ptid);
+}
+
+void
+set_gdbarch_core_pid_to_str (struct gdbarch *gdbarch,
+ gdbarch_core_pid_to_str_ftype core_pid_to_str)
+{
+ gdbarch->core_pid_to_str = core_pid_to_str;
+}
+
int
gdbarch_vtable_function_descriptors (struct gdbarch *gdbarch)
{
extern LONGEST gdbarch_core_xfer_shared_libraries (struct gdbarch *gdbarch, gdb_byte *readbuf, ULONGEST offset, LONGEST len);
extern void set_gdbarch_core_xfer_shared_libraries (struct gdbarch *gdbarch, gdbarch_core_xfer_shared_libraries_ftype *core_xfer_shared_libraries);
+/* How the core_stratum layer converts a PTID from a core file to a
+ string. */
+
+extern int gdbarch_core_pid_to_str_p (struct gdbarch *gdbarch);
+
+typedef char * (gdbarch_core_pid_to_str_ftype) (struct gdbarch *gdbarch, ptid_t ptid);
+extern char * gdbarch_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid);
+extern void set_gdbarch_core_pid_to_str (struct gdbarch *gdbarch, gdbarch_core_pid_to_str_ftype *core_pid_to_str);
+
/* If the elements of C++ vtables are in-place function descriptors rather
than normal function pointers (which may point to code or a descriptor),
set this to one. */
# core file into buffer READBUF with length LEN.
M:LONGEST:core_xfer_shared_libraries:gdb_byte *readbuf, ULONGEST offset, LONGEST len:readbuf, offset, len
+# How the core_stratum layer converts a PTID from a core file to a
+# string.
+M:char *:core_pid_to_str:ptid_t ptid:ptid
+
# If the elements of C++ vtables are in-place function descriptors rather
# than normal function pointers (which may point to code or a descriptor),
# set this to one.
extern void validate_files (void);
-/* The target vector for core files. */
-
-extern struct target_ops core_ops;
-
/* The current default bfd target. */
extern char *gnutarget;
in multiple events returned by wait).
*/
static void
-gnu_resume (ptid_t ptid, int step, enum target_signal sig)
+gnu_resume (struct target_ops *ops,
+ ptid_t ptid, int step, enum target_signal sig)
{
struct proc *step_thread = 0;
int resume_all;
}
static int
-gnu_thread_alive (ptid_t ptid)
+gnu_thread_alive (struct target_ops *ops, ptid_t ptid)
{
inf_update_procs (gnu_current_inf);
return !!inf_tid_to_thread (gnu_current_inf,
}
\f
-extern void gnu_store_registers (struct regcache *regcache, int regno);
-extern void gnu_fetch_registers (struct regcache *regcache, int regno);
+extern void gnu_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno);
+extern void gnu_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno);
struct target_ops gnu_ops;
static void go32_close (int quitting);
static void go32_attach (char *args, int from_tty);
static void go32_detach (char *args, int from_tty);
-static void go32_resume (ptid_t ptid, int step,
- enum target_signal siggnal);
-static void go32_fetch_registers (struct regcache *, int regno);
+static void go32_resume (struct target_ops *ops,
+ ptid_t ptid, int step,
+ enum target_signal siggnal);
+static void go32_fetch_registers (struct target_ops *ops,
+ struct regcache *, int regno);
static void store_register (const struct regcache *, int regno);
-static void go32_store_registers (struct regcache *, int regno);
+static void go32_store_registers (struct target_ops *ops,
+ struct regcache *, int regno);
static void go32_prepare_to_store (struct regcache *);
static int go32_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len,
int write,
static int resume_signal = -1;
static void
-go32_resume (ptid_t ptid, int step, enum target_signal siggnal)
+go32_resume (struct target_ops *ops,
+ ptid_t ptid, int step, enum target_signal siggnal)
{
int i;
}
static void
-go32_fetch_registers (struct regcache *regcache, int regno)
+go32_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
if (regno >= 0)
fetch_register (regcache, regno);
}
static void
-go32_store_registers (struct regcache *regcache, int regno)
+go32_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
unsigned r;
}
static int
-go32_thread_alive (ptid_t ptid)
+go32_thread_alive (struct target_ops *ops, ptid_t ptid)
{
return 1;
}
}
static void
-hppa_hpux_fetch_inferior_registers (struct regcache *regcache, int regnum)
+hppa_hpux_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
if (regnum == -1)
for (regnum = 0;
this for all registers (including the floating point registers). */
static void
-hppa_hpux_store_inferior_registers (struct regcache *regcache, int regnum)
+hppa_hpux_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
if (regnum == -1)
for (regnum = 0;
point registers depending upon the value of regno. */
static void
-hppa_linux_fetch_inferior_registers (struct regcache *regcache, int regno)
+hppa_linux_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
if (-1 == regno)
{
point registers depending upon the value of regno. */
static void
-hppa_linux_store_inferior_registers (struct regcache *regcache, int regno)
+hppa_linux_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
if (-1 == regno)
{
for all registers (including the floating-point registers). */
static void
-hppabsd_fetch_registers (struct regcache *regcache, int regnum)
+hppabsd_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
if (regnum == -1 || hppabsd_gregset_supplies_p (regnum))
{
this for all registers (including the floating-point registers). */
static void
-hppabsd_store_registers (struct regcache *regcache, int regnum)
+hppabsd_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
if (regnum == -1 || hppabsd_gregset_supplies_p (regnum))
{
for all registers (including the floating-point registers). */
static void
-hppanbsd_fetch_registers (struct regcache *regcache, int regnum)
+hppanbsd_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
this for all registers (including the floating-point registers). */
static void
-hppanbsd_store_registers (struct regcache *regcache, int regnum)
+hppanbsd_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
{
static CORE_ADDR P_cma__g_known_threads;
static CORE_ADDR P_cma__g_current_thread;
-static void hpux_thread_resume (ptid_t ptid, int step,
- enum target_signal signo);
-
static void init_hpux_thread_ops (void);
static struct target_ops hpux_thread_ops;
for procfs. */
static void
-hpux_thread_resume (ptid_t ptid, int step, enum target_signal signo)
+hpux_thread_resume (struct target_ops *ops,
+ ptid_t ptid, int step, enum target_signal signo)
{
struct cleanup *old_chain;
ptid = main_ptid;
inferior_ptid = main_ptid;
- deprecated_child_ops.to_resume (ptid, step, signo);
+ deprecated_child_ops.to_resume (&deprecated_child_ops, ptid, step, signo);
cached_thread = 0;
};
static void
-hpux_thread_fetch_registers (struct regcache *regcache, int regno)
+hpux_thread_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
cma__t_int_tcb tcb, *tcb_ptr;
if (tcb_ptr->state == cma__c_state_running)
{
- deprecated_child_ops.to_fetch_registers (regcache, regno);
+ deprecated_child_ops.to_fetch_registers (&deprecated_child_ops,
+ regcache, regno);
do_cleanups (old_chain);
for (regno = first_regno; regno <= last_regno; regno++)
{
if (regmap[regno] == -1)
- deprecated_child_ops.to_fetch_registers (regcache, regno);
+ deprecated_child_ops.to_fetch_registers (&deprecated_child_ops,
+ regcache, regno);
else
{
unsigned char buf[MAX_REGISTER_SIZE];
}
static void
-hpux_thread_store_registers (struct regcache *regcache, int regno)
+hpux_thread_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
cma__t_int_tcb tcb, *tcb_ptr;
if (tcb_ptr->state == cma__c_state_running)
{
- deprecated_child_ops.to_store_registers (regcache, regno);
+ deprecated_child_ops.to_store_registers (&deprecated_child_ops,
+ regcache, regno);
do_cleanups (old_chain);
sp = (CORE_ADDR) tcb_ptr->static_ctx.sp - 160;
if (regno == HPPA_FLAGS_REGNUM)
- deprecated_child_ops.to_store_registers (regcache, regno); /* Let lower layer handle this... */
+ {
+ /* Let lower layer handle this... */
+ deprecated_child_ops.to_store_registers
+ (&deprecated_child_ops, regcache, regno);
+ }
else if (regno == HPPA_SP_REGNUM)
{
regcache_raw_collect (regcache, regno, buf);
}
static int
-hpux_thread_alive (ptid_t ptid)
+hpux_thread_alive (struct target_ops *ops, ptid_t ptid)
{
return 1;
}
If REGNO is -1, do this for all registers.
Otherwise, REGNO specifies which register (so we can save time). */
static void
-i386_darwin_fetch_inferior_registers (struct regcache *regcache, int regno)
+i386_darwin_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
thread_t current_thread = ptid_get_tid (inferior_ptid);
int fetched = 0;
Otherwise, REGNO specifies which register (so we can save time). */
static void
-i386_darwin_store_inferior_registers (struct regcache *regcache, int regno)
+i386_darwin_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
thread_t current_thread = ptid_get_tid (inferior_ptid);
struct gdbarch *gdbarch = get_regcache_arch (regcache);
registers). */
static void
-i386_linux_fetch_inferior_registers (struct regcache *regcache, int regno)
+i386_linux_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
int tid;
do this for all registers (including the floating point and SSE
registers). */
static void
-i386_linux_store_inferior_registers (struct regcache *regcache, int regno)
+i386_linux_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
int tid;
If SIGNAL is nonzero, give it that signal. */
static void
-i386_linux_resume (ptid_t ptid, int step, enum target_signal signal)
+i386_linux_resume (struct target_ops *ops,
+ ptid_t ptid, int step, enum target_signal signal)
{
int pid = PIDGET (ptid);
/* Solaris encodes the pid of the inferior in regset section
names. */
set_gdbarch_core_reg_section_encodes_pid (gdbarch, 1);
+
+ /* How to print LWP PTIDs from core files. */
+ set_gdbarch_core_pid_to_str (gdbarch, sol2_core_pid_to_str);
}
\f
for all registers (including the floating point registers). */
static void
-i386bsd_fetch_inferior_registers (struct regcache *regcache, int regnum)
+i386bsd_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
if (regnum == -1 || GETREGS_SUPPLIES (regnum))
{
this for all registers (including the floating point registers). */
static void
-i386bsd_store_inferior_registers (struct regcache *regcache, int regnum)
+i386bsd_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
if (regnum == -1 || GETREGS_SUPPLIES (regnum))
{
single-step it. If SIGNAL is nonzero, give it that signal. */
static void
-i386fbsd_resume (ptid_t ptid, int step, enum target_signal signal)
+i386fbsd_resume (struct target_ops *ops,
+ ptid_t ptid, int step, enum target_signal signal)
{
pid_t pid = ptid_get_pid (ptid);
int request = PT_STEP;
for all registers. */
static void
-ia64_linux_fetch_registers (struct regcache *regcache, int regnum)
+ia64_linux_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
if (regnum == -1)
for (regnum = 0;
this for all registers. */
static void
-ia64_linux_store_registers (struct regcache *regcache, int regnum)
+ia64_linux_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
if (regnum == -1)
for (regnum = 0;
for all registers. */
static void
-inf_child_fetch_inferior_registers (struct regcache *regcache, int regnum)
+inf_child_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
if (regnum == -1)
{
this for all registers (including the floating point registers). */
static void
-inf_child_store_inferior_registers (struct regcache *regcache, int regnum)
+inf_child_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
}
that signal. */
static void
-inf_ptrace_resume (ptid_t ptid, int step, enum target_signal signal)
+inf_ptrace_resume (struct target_ops *ops,
+ ptid_t ptid, int step, enum target_signal signal)
{
pid_t pid = ptid_get_pid (ptid);
int request = PT_CONTINUE;
/* Return non-zero if the thread specified by PTID is alive. */
static int
-inf_ptrace_thread_alive (ptid_t ptid)
+inf_ptrace_thread_alive (struct target_ops *ops, ptid_t ptid)
{
/* ??? Is kill the right way to do this? */
return (kill (ptid_get_pid (ptid), 0) != -1);
for all registers. */
static void
-inf_ptrace_fetch_registers (struct regcache *regcache, int regnum)
+inf_ptrace_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
if (regnum == -1)
for (regnum = 0;
this for all registers. */
static void
-inf_ptrace_store_registers (struct regcache *regcache, int regnum)
+inf_ptrace_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
if (regnum == -1)
for (regnum = 0;
#include "inf-child.h"
#include "inf-ttrace.h"
-/* HACK: Save the ttrace ops returned by inf_ttrace_target. */
-static struct target_ops *ttrace_ops_hack;
\f
/* HP-UX uses a threading model where each user-space thread
/* Start tracing PID. */
static void
-inf_ttrace_him (int pid)
+inf_ttrace_him (struct target_ops *ops, int pid)
{
struct cleanup *old_chain = make_cleanup (do_cleanup_pfds, 0);
ttevent_t tte;
do_cleanups (old_chain);
- push_target (ttrace_ops_hack);
+ push_target (ops);
/* On some targets, there must be some explicit synchronization
between the parent and child processes after the debugger forks,
inf_ttrace_create_inferior (struct target_ops *ops, char *exec_file,
char *allargs, char **env, int from_tty)
{
+ int pid;
+
gdb_assert (inf_ttrace_num_lwps == 0);
gdb_assert (inf_ttrace_num_lwps_in_syscall == 0);
gdb_assert (inf_ttrace_page_dict.count == 0);
gdb_assert (inf_ttrace_reenable_page_protections == 0);
gdb_assert (inf_ttrace_vfork_ppid == -1);
- fork_inferior (exec_file, allargs, env, inf_ttrace_me, inf_ttrace_him,
- inf_ttrace_prepare, NULL);
+ pid = fork_inferior (exec_file, allargs, env, inf_ttrace_me, NULL,
+ inf_ttrace_prepare, NULL);
+
+ inf_ttrace_him (ops, pid);
}
static void
}
inf_ttrace_page_dict.count = 0;
- unpush_target (ttrace_ops_hack);
+ unpush_target (ops);
generic_mourn_inferior ();
}
(uintptr_t)&tte, sizeof tte, 0) == -1)
perror_with_name (("ttrace"));
- push_target (ttrace_ops_hack);
+ push_target (ops);
/* We'll bump inf_ttrace_num_lwps up and add the private data to the
thread as soon as we get to inf_ttrace_wait. At this point, we
inferior_ptid = null_ptid;
detach_inferior (pid);
- unpush_target (ttrace_ops_hack);
+ unpush_target (ops);
}
static void
}
static void
-inf_ttrace_resume (ptid_t ptid, int step, enum target_signal signal)
+inf_ttrace_resume (struct target_ops *ops,
+ ptid_t ptid, int step, enum target_signal signal)
{
int resume_all;
ttreq_t request = step ? TT_LWP_SINGLE : TT_LWP_CONTINUE;
}
static int
-inf_ttrace_thread_alive (ptid_t ptid)
+inf_ttrace_thread_alive (struct target_ops *ops, ptid_t ptid)
{
return 1;
}
t->to_pid_to_str = inf_ttrace_pid_to_str;
t->to_xfer_partial = inf_ttrace_xfer_partial;
- ttrace_ops_hack = t;
return t;
}
#endif
/* Prototypes for local functions. */
static int stop_wait_callback (struct lwp_info *lp, void *data);
-static int linux_nat_thread_alive (ptid_t ptid);
+static int linux_thread_alive (ptid_t ptid);
static char *linux_child_pid_to_exec_file (int pid);
static int cancel_breakpoint (struct lwp_info *lp);
{
if (lp->stopped && lp->status == 0)
{
- linux_ops->to_resume (pid_to_ptid (GET_LWP (lp->ptid)),
+ linux_ops->to_resume (linux_ops,
+ pid_to_ptid (GET_LWP (lp->ptid)),
0, TARGET_SIGNAL_0);
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
}
static void
-linux_nat_resume (ptid_t ptid, int step, enum target_signal signo)
+linux_nat_resume (struct target_ops *ops,
+ ptid_t ptid, int step, enum target_signal signo)
{
struct lwp_info *lp;
int resume_all;
if (resume_all)
iterate_over_lwps (resume_callback, NULL);
- linux_ops->to_resume (ptid, step, signo);
+ linux_ops->to_resume (linux_ops, ptid, step, signo);
memset (&lp->siginfo, 0, sizeof (lp->siginfo));
if (debug_linux_nat)
thread model, LWPs other than the main thread do not issue
signals when they exit so we must check whenever the thread has
stopped. A similar check is made in stop_wait_callback(). */
- if (num_lwps > 1 && !linux_nat_thread_alive (lp->ptid))
+ if (num_lwps > 1 && !linux_thread_alive (lp->ptid))
{
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
registers_changed ();
- linux_ops->to_resume (pid_to_ptid (GET_LWP (lp->ptid)),
+ linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
lp->step, TARGET_SIGNAL_0);
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
lp->ignore_sigint = 0;
registers_changed ();
- linux_ops->to_resume (pid_to_ptid (GET_LWP (lp->ptid)),
+ linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
lp->step, TARGET_SIGNAL_0);
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
/* Resume the thread. It should halt immediately returning the
pending SIGSTOP. */
registers_changed ();
- linux_ops->to_resume (pid_to_ptid (GET_LWP (lp->ptid)),
+ linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
lp->step, TARGET_SIGNAL_0);
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
newly attached threads may cause an unwanted delay in
getting them running. */
registers_changed ();
- linux_ops->to_resume (pid_to_ptid (GET_LWP (lp->ptid)),
+ linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
lp->step, signo);
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
}
static int
-linux_nat_thread_alive (ptid_t ptid)
+linux_thread_alive (ptid_t ptid)
{
int err;
return 1;
}
+static int
+linux_nat_thread_alive (struct target_ops *ops, ptid_t ptid)
+{
+ return linux_thread_alive (ptid);
+}
+
static char *
linux_nat_pid_to_str (struct target_ops *ops, ptid_t ptid)
{
static CORE_ADDR td_death_bp_addr;
/* Prototypes for local functions. */
-static void thread_db_find_new_threads (void);
+static void thread_db_find_new_threads_1 (void);
static void attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
const td_thrinfo_t *ti_p);
static void detach_thread (ptid_t ptid);
{
/* New thread. Attach to it now (why wait?). */
if (!have_threads ())
- thread_db_find_new_threads ();
+ thread_db_find_new_threads_1 ();
else
attach_thread (thread_ptid, thp, &ti);
thread_info = find_thread_pid (thread_ptid);
initialized, we may not know its thread ID yet. Make sure we do
before we add another thread to the list. */
if (!have_threads ())
- thread_db_find_new_threads ();
+ thread_db_find_new_threads_1 ();
err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th);
if (err != TD_OK)
using_thread_db = 1;
enable_thread_event_reporting ();
- thread_db_find_new_threads ();
+ thread_db_find_new_threads_1 ();
break;
default:
initialized, we may not know its thread ID yet. Make sure we do
before we add another thread to the list. */
if (!have_threads ())
- thread_db_find_new_threads ();
+ thread_db_find_new_threads_1 ();
/* If we are at a create breakpoint, we do not know what new lwp
was created and cannot specifically locate the event message for it.
/* If we do not know about the main thread yet, this would be a good time to
find it. */
if (ourstatus->kind == TARGET_WAITKIND_STOPPED && !have_threads ())
- thread_db_find_new_threads ();
+ thread_db_find_new_threads_1 ();
if (ourstatus->kind == TARGET_WAITKIND_STOPPED
&& ourstatus->value.sig == TARGET_SIGNAL_TRAP)
PTID. */
static void
-thread_db_find_new_threads (void)
+thread_db_find_new_threads_1 (void)
{
td_err_e err;
struct lwp_info *lp;
error (_("Cannot find new threads: %s"), thread_db_err_str (err));
}
+static void
+thread_db_find_new_threads (struct target_ops *ops)
+{
+ thread_db_find_new_threads_1 ();
+}
+
static char *
thread_db_pid_to_str (struct target_ops *ops, ptid_t ptid)
{
/* If we have not discovered any threads yet, check now. */
if (!have_threads ())
- thread_db_find_new_threads ();
+ thread_db_find_new_threads_1 ();
/* Find the matching thread. */
thread_info = find_thread_pid (ptid);
{
struct thread_info *thread_info;
- thread_db_find_new_threads ();
+ thread_db_find_new_threads_1 ();
thread_info = iterate_over_threads (thread_db_find_thread_from_tid, &thread);
gdb_assert (thread_info != NULL);
registers). */
static void
-m32r_linux_fetch_inferior_registers (struct regcache *regcache, int regno)
+m32r_linux_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
int tid;
do this for all registers (including the floating point and SSE
registers). */
static void
-m32r_linux_store_inferior_registers (struct regcache *regcache, int regno)
+m32r_linux_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
int tid;
for all registers (including the floating-point registers). */
static void
-m68kbsd_fetch_inferior_registers (struct regcache *regcache, int regnum)
+m68kbsd_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
{
this for all registers (including the floating-point registers). */
static void
-m68kbsd_store_inferior_registers (struct regcache *regcache, int regnum)
+m68kbsd_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
{
registers). */
static void
-m68k_linux_fetch_inferior_registers (struct regcache *regcache, int regno)
+m68k_linux_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
int tid;
do this for all registers (including the floating point and SSE
registers). */
static void
-m68k_linux_store_inferior_registers (struct regcache *regcache, int regno)
+m68k_linux_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
int tid;
for all registers. */
static void
-m88kbsd_fetch_inferior_registers (struct regcache *regcache, int regnum)
+m88kbsd_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
struct reg regs;
this for all registers. */
static void
-m88kbsd_store_inferior_registers (struct regcache *regcache, int regnum)
+m88kbsd_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
struct reg regs;
/* Saved function pointers to fetch and store a single register using
PTRACE_PEEKUSER and PTRACE_POKEUSER. */
-void (*super_fetch_registers) (struct regcache *, int);
-void (*super_store_registers) (struct regcache *, int);
+void (*super_fetch_registers) (struct target_ops *, struct regcache *, int);
+void (*super_store_registers) (struct target_ops *, struct regcache *, int);
/* Map gdb internal register number to ptrace ``address''.
These ``addresses'' are normally defined in <asm/ptrace.h>.
using any working method. */
static void
-mips64_linux_fetch_registers (struct regcache *regcache, int regnum)
+mips64_linux_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
/* Unless we already know that PTRACE_GETREGS does not work, try it. */
if (have_ptrace_regsets)
using any working method. */
static void
-mips64_linux_store_registers (struct regcache *regcache, int regnum)
+mips64_linux_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
/* Unless we already know that PTRACE_GETREGS does not work, try it. */
if (have_ptrace_regsets)
for all registers. */
static void
-mips64obsd_fetch_inferior_registers (struct regcache *regcache, int regnum)
+mips64obsd_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
struct reg regs;
this for all registers. */
static void
-mips64obsd_store_inferior_registers (struct regcache *regcache, int regnum)
+mips64obsd_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
struct reg regs;
}
static void
-mipsnbsd_fetch_inferior_registers (struct regcache *regcache, int regno)
+mipsnbsd_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
if (regno == -1 || getregs_supplies (gdbarch, regno))
}
static void
-mipsnbsd_store_inferior_registers (struct regcache *regcache, int regno)
+mipsnbsd_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
if (regno == -1 || getregs_supplies (gdbarch, regno))
/* Tell the remote machine to resume. */
static void
-monitor_resume (ptid_t ptid, int step, enum target_signal sig)
+monitor_resume (struct target_ops *ops,
+ ptid_t ptid, int step, enum target_signal sig)
{
/* Some monitors require a different command when starting a program */
monitor_debug ("MON resume\n");
}
static void
-monitor_fetch_registers (struct regcache *regcache, int regno)
+monitor_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
monitor_debug ("MON fetchregs\n");
if (current_monitor->getreg.cmd)
/* Store the remote registers. */
static void
-monitor_store_registers (struct regcache *regcache, int regno)
+monitor_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
if (regno >= 0)
{
/* Check to see if a thread is still alive. */
static int
-monitor_thread_alive (ptid_t ptid)
+monitor_thread_alive (struct target_ops *ops, ptid_t ptid)
{
if (ptid_equal (ptid, monitor_ptid))
/* The monitor's task is always alive. */
struct mem_attrib *attrib,
struct target_ops *);
-static void procfs_fetch_registers (struct regcache *, int);
-
static void notice_signals (void);
static void init_procfs_ops (void);
/* Return nonzero if the thread TH is still alive. */
static int
-procfs_thread_alive (ptid_t ptid)
+procfs_thread_alive (struct target_ops *ops, ptid_t ptid)
{
pid_t tid;
}
void
-procfs_find_new_threads (void)
+procfs_find_new_threads (struct target_ops *ops)
{
procfs_status status;
pid_t pid;
inf = add_inferior (pid);
inf->attach_flag = 1;
- push_target (&procfs_ops);
+ push_target (ops);
- procfs_find_new_threads ();
+ procfs_find_new_threads (ops);
}
static void
general register set and floating point registers (if supported)
and update gdb's idea of their current values. */
static void
-procfs_fetch_registers (struct regcache *regcache, int regno)
+procfs_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
union
{
}
static void
-procfs_resume (ptid_t ptid, int step, enum target_signal signo)
+procfs_resume (struct target_ops *ops,
+ ptid_t ptid, int step, enum target_signal signo)
{
int signal_to_pass;
procfs_status status;
close (fds[2]);
inferior_ptid = do_attach (pid_to_ptid (pid));
- procfs_find_new_threads ();
+ procfs_find_new_threads (ops);
inf = add_inferior (pid);
inf->attach_flag = 0;
/* warning( "Failed to set Kill-on-Last-Close flag: errno = %d(%s)\n",
errn, strerror(errn) ); */
}
- push_target (&procfs_ops);
+ push_target (ops);
target_terminal_init ();
if (exec_bfd != NULL
}
void
-procfs_store_registers (struct regcache *regcache, int regno)
+procfs_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
union
{
regno == -1, otherwise fetch all general registers or all floating
point registers depending upon the value of regno. */
static void
-ppc_linux_fetch_inferior_registers (struct regcache *regcache, int regno)
+ppc_linux_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
/* Overload thread id onto process id */
int tid = TIDGET (inferior_ptid);
}
static void
-ppc_linux_store_inferior_registers (struct regcache *regcache, int regno)
+ppc_linux_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
/* Overload thread id onto process id */
int tid = TIDGET (inferior_ptid);
}
static void
-ppcnbsd_fetch_inferior_registers (struct regcache *regcache, int regnum)
+ppcnbsd_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
}
static void
-ppcnbsd_store_inferior_registers (struct regcache *regcache, int regnum)
+ppcnbsd_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
for all registers. */
static void
-ppcobsd_fetch_registers (struct regcache *regcache, int regnum)
+ppcobsd_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
struct reg regs;
this for all registers. */
static void
-ppcobsd_store_registers (struct regcache *regcache, int regnum)
+ppcobsd_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
struct reg regs;
#include "gdbcmd.h"
#include "gdbthread.h"
#include "regcache.h"
+#include "inf-child.h"
#if defined (NEW_PROC_API)
#define _STRUCTURED_PROC 1 /* Should be done by configure script. */
* This module defines the GDB target vector and its methods.
*/
-static void procfs_open (char *, int);
static void procfs_attach (struct target_ops *, char *, int);
static void procfs_detach (struct target_ops *, char *, int);
-static void procfs_resume (ptid_t, int, enum target_signal);
-static int procfs_can_run (void);
+static void procfs_resume (struct target_ops *,
+ ptid_t, int, enum target_signal);
static void procfs_stop (ptid_t);
static void procfs_files_info (struct target_ops *);
-static void procfs_fetch_registers (struct regcache *, int);
-static void procfs_store_registers (struct regcache *, int);
+static void procfs_fetch_registers (struct target_ops *,
+ struct regcache *, int);
+static void procfs_store_registers (struct target_ops *,
+ struct regcache *, int);
static void procfs_notice_signals (ptid_t);
-static void procfs_prepare_to_store (struct regcache *);
static void procfs_kill_inferior (void);
static void procfs_mourn_inferior (struct target_ops *ops);
static void procfs_create_inferior (struct target_ops *, char *,
gdb_byte *readbuf, const gdb_byte *writebuf,
ULONGEST offset, LONGEST len);
-static int procfs_thread_alive (ptid_t);
+static int procfs_thread_alive (struct target_ops *ops, ptid_t);
-void procfs_find_new_threads (void);
+void procfs_find_new_threads (struct target_ops *ops);
char *procfs_pid_to_str (struct target_ops *, ptid_t);
static int proc_find_memory_regions (int (*) (CORE_ADDR,
static int procfs_can_use_hw_breakpoint (int, int, int);
-struct target_ops procfs_ops; /* the target vector */
-
#if defined (PR_MODEL_NATIVE) && (PR_MODEL_NATIVE == PR_MODEL_LP64)
/* When GDB is built as 64-bit application on Solaris, the auxv data is
presented in 64-bit format. We need to provide a custom parser to handle
}
#endif
-static void
-init_procfs_ops (void)
+static struct target_ops *
+procfs_target (void)
{
- procfs_ops.to_shortname = "procfs";
- procfs_ops.to_longname = "Unix /proc child process";
- procfs_ops.to_doc =
+ struct target_ops *t = inf_child_target ();
+
+ t->to_shortname = "procfs";
+ t->to_longname = "Unix /proc child process";
+ t->to_doc =
"Unix /proc child process (started by the \"run\" command).";
- procfs_ops.to_open = procfs_open;
- procfs_ops.to_can_run = procfs_can_run;
- procfs_ops.to_create_inferior = procfs_create_inferior;
- procfs_ops.to_kill = procfs_kill_inferior;
- procfs_ops.to_mourn_inferior = procfs_mourn_inferior;
- procfs_ops.to_attach = procfs_attach;
- procfs_ops.to_detach = procfs_detach;
- procfs_ops.to_wait = procfs_wait;
- procfs_ops.to_resume = procfs_resume;
- procfs_ops.to_prepare_to_store = procfs_prepare_to_store;
- procfs_ops.to_fetch_registers = procfs_fetch_registers;
- procfs_ops.to_store_registers = procfs_store_registers;
- procfs_ops.to_xfer_partial = procfs_xfer_partial;
- procfs_ops.deprecated_xfer_memory = procfs_xfer_memory;
- procfs_ops.to_insert_breakpoint = memory_insert_breakpoint;
- procfs_ops.to_remove_breakpoint = memory_remove_breakpoint;
- procfs_ops.to_notice_signals = procfs_notice_signals;
- procfs_ops.to_files_info = procfs_files_info;
- procfs_ops.to_stop = procfs_stop;
-
- procfs_ops.to_terminal_init = terminal_init_inferior;
- procfs_ops.to_terminal_inferior = terminal_inferior;
- procfs_ops.to_terminal_ours_for_output = terminal_ours_for_output;
- procfs_ops.to_terminal_ours = terminal_ours;
- procfs_ops.to_terminal_save_ours = terminal_save_ours;
- procfs_ops.to_terminal_info = child_terminal_info;
-
- procfs_ops.to_find_new_threads = procfs_find_new_threads;
- procfs_ops.to_thread_alive = procfs_thread_alive;
- procfs_ops.to_pid_to_str = procfs_pid_to_str;
-
- procfs_ops.to_has_all_memory = 1;
- procfs_ops.to_has_memory = 1;
- procfs_ops.to_has_execution = 1;
- procfs_ops.to_has_stack = 1;
- procfs_ops.to_has_registers = 1;
- procfs_ops.to_stratum = process_stratum;
- procfs_ops.to_has_thread_control = tc_schedlock;
- procfs_ops.to_find_memory_regions = proc_find_memory_regions;
- procfs_ops.to_make_corefile_notes = procfs_make_note_section;
- procfs_ops.to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint;
+ t->to_create_inferior = procfs_create_inferior;
+ t->to_kill = procfs_kill_inferior;
+ t->to_mourn_inferior = procfs_mourn_inferior;
+ t->to_attach = procfs_attach;
+ t->to_detach = procfs_detach;
+ t->to_wait = procfs_wait;
+ t->to_resume = procfs_resume;
+ t->to_fetch_registers = procfs_fetch_registers;
+ t->to_store_registers = procfs_store_registers;
+ t->to_xfer_partial = procfs_xfer_partial;
+ t->deprecated_xfer_memory = procfs_xfer_memory;
+ t->to_notice_signals = procfs_notice_signals;
+ t->to_files_info = procfs_files_info;
+ t->to_stop = procfs_stop;
+
+ t->to_find_new_threads = procfs_find_new_threads;
+ t->to_thread_alive = procfs_thread_alive;
+ t->to_pid_to_str = procfs_pid_to_str;
+
+ t->to_has_thread_control = tc_schedlock;
+ t->to_find_memory_regions = proc_find_memory_regions;
+ t->to_make_corefile_notes = procfs_make_note_section;
+ t->to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint;
#if defined(PR_MODEL_NATIVE) && (PR_MODEL_NATIVE == PR_MODEL_LP64)
- procfs_ops.to_auxv_parse = procfs_auxv_parse;
+ t->to_auxv_parse = procfs_auxv_parse;
#endif
- procfs_ops.to_magic = OPS_MAGIC;
+ t->to_magic = OPS_MAGIC;
+
+ return t;
}
/* =================== END, TARGET_OPS "MODULE" =================== */
fflush (stdout);
}
inferior_ptid = do_attach (pid_to_ptid (pid));
- push_target (&procfs_ops);
+ push_target (ops);
}
static void
inferior_ptid = null_ptid;
detach_inferior (pid);
- unpush_target (&procfs_ops);
+ unpush_target (ops);
}
static ptid_t
when the process is resumed. */
static void
-procfs_fetch_registers (struct regcache *regcache, int regnum)
+procfs_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
gdb_gregset_t *gregs;
procinfo *pi;
}
}
-/* Get ready to modify the registers array. On machines which store
- individual registers, this doesn't need to do anything. On
- machines which store all the registers in one fell swoop, such as
- /proc, this makes sure that registers contains all the registers
- from the program being debugged. */
-
-static void
-procfs_prepare_to_store (struct regcache *regcache)
-{
-}
-
/* Store register REGNUM back into the inferior. If REGNUM is -1, do
this for all registers.
writing one register might affect the value of others, etc. */
static void
-procfs_store_registers (struct regcache *regcache, int regnum)
+procfs_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
gdb_gregset_t *gregs;
procinfo *pi;
*/
static void
-procfs_resume (ptid_t ptid, int step, enum target_signal signo)
+procfs_resume (struct target_ops *ops,
+ ptid_t ptid, int step, enum target_signal signo)
{
procinfo *pi, *thread;
int native_signo;
target_pid_to_str (inferior_ptid));
}
-/*
- * Function: target_open
- *
- * A dummy: you don't open procfs.
- */
-
-static void
-procfs_open (char *args, int from_tty)
-{
- error (_("Use the \"run\" command to start a Unix child process."));
-}
-
-/*
- * Function: target_can_run
- *
- * This tells GDB that this target vector can be invoked
- * for "run" or "attach".
- */
-
-int procfs_suppress_run = 0; /* Non-zero if procfs should pretend not to
- be a runnable target. Used by targets
- that can sit atop procfs, such as solaris
- thread support. */
-
-
-static int
-procfs_can_run (void)
-{
- /* This variable is controlled by modules that sit atop procfs that
- may layer their own process structure atop that provided here.
- sol-thread.c does this because of the Solaris two-level thread
- model. */
-
- /* NOTE: possibly obsolete -- use the thread_stratum approach instead. */
-
- return !procfs_suppress_run;
-}
-
/*
* Function: target_stop
*
if (pi)
destroy_procinfo (pi);
}
- unpush_target (&procfs_ops);
+ unpush_target (ops);
if (dbx_link_bpt != NULL)
{
*/
static void
-procfs_init_inferior (int pid)
+procfs_init_inferior (struct target_ops *ops, int pid)
{
procinfo *pi;
gdb_sigset_t signals;
/* This routine called on the parent side (GDB side)
after GDB forks the inferior. */
-
- push_target (&procfs_ops);
+ push_target (ops);
if ((pi = create_procinfo (pid, 0)) == NULL)
perror ("procfs: out of memory in 'init_inferior'");
{
char *shell_file = getenv ("SHELL");
char *tryname;
+ int pid;
+
if (shell_file != NULL && strchr (shell_file, '/') == NULL)
{
shell_file = tryname;
}
- fork_inferior (exec_file, allargs, env, procfs_set_exec_trap,
- procfs_init_inferior, NULL, shell_file);
+ pid = fork_inferior (exec_file, allargs, env, procfs_set_exec_trap,
+ NULL, NULL, shell_file);
+
+ procfs_init_inferior (ops, pid);
#ifdef SYS_syssgi
/* Make sure to cancel the syssgi() syscall-exit notifications.
*/
void
-procfs_find_new_threads (void)
+procfs_find_new_threads (struct target_ops *ops)
{
procinfo *pi;
*/
static int
-procfs_thread_alive (ptid_t ptid)
+procfs_thread_alive (struct target_ops *ops, ptid_t ptid)
{
int proc, thread;
procinfo *pi;
void
_initialize_procfs (void)
{
- init_procfs_ops ();
- add_target (&procfs_ops);
+ struct target_ops * t;
+
+ t = procfs_target ();
+
+ add_target (t);
+
add_info ("proc", info_proc_cmd, _("\
Show /proc process information about any running process.\n\
Specify process id, or use the program being debugged by default.\n\
/* Tell the remote machine to resume. */
static void
-m32r_resume (ptid_t ptid, int step, enum target_signal sig)
+m32r_resume (struct target_ops *ops,
+ ptid_t ptid, int step, enum target_signal sig)
{
unsigned long pc_addr, bp_addr, ab_addr;
int ib_breakpoints;
if (remote_debug)
fprintf_unfiltered (gdb_stdlog, "m32r_detach(%d)\n", from_tty);
- m32r_resume (inferior_ptid, 0, 0);
+ m32r_resume (ops, inferior_ptid, 0, 0);
/* calls m32r_close to do the real work */
pop_target ();
return regno;
}
-/* Read the remote registers into the block REGS. */
-
-static void m32r_fetch_register (struct regcache *, int);
-
-static void
-m32r_fetch_registers (struct regcache *regcache)
-{
- int regno;
-
- for (regno = 0;
- regno < gdbarch_num_regs (get_regcache_arch (regcache));
- regno++)
- m32r_fetch_register (regcache, regno);
-}
-
/* Fetch register REGNO, or all registers if REGNO is -1.
Returns errno value. */
static void
-m32r_fetch_register (struct regcache *regcache, int regno)
+m32r_fetch_register (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
unsigned long val, val2, regid;
if (regno == -1)
- m32r_fetch_registers (regcache);
+ {
+ for (regno = 0;
+ regno < gdbarch_num_regs (get_regcache_arch (regcache));
+ regno++)
+ m32r_fetch_register (ops, regcache, regno);
+ }
else
{
char buffer[MAX_REGISTER_SIZE];
return;
}
-/* Store the remote registers from the contents of the block REGS. */
-
-static void m32r_store_register (struct regcache *, int);
-
-static void
-m32r_store_registers (struct regcache *regcache)
-{
- int regno;
-
- for (regno = 0;
- regno < gdbarch_num_regs (get_regcache_arch (regcache));
- regno++)
- m32r_store_register (regcache, regno);
-
- registers_changed ();
-}
-
/* Store register REGNO, or all if REGNO == 0.
Return errno value. */
static void
-m32r_store_register (struct regcache *regcache, int regno)
+m32r_store_register (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
int regid;
ULONGEST regval, tmp;
if (regno == -1)
- m32r_store_registers (regcache);
+ {
+ for (regno = 0;
+ regno < gdbarch_num_regs (get_regcache_arch (regcache));
+ regno++)
+ m32r_store_register (ops, regcache, regno);
+ }
else
{
regcache_cooked_read_unsigned (regcache, regno, ®val);
/* Check to see if a thread is still alive. */
static int
-m32r_thread_alive (ptid_t ptid)
+m32r_thread_alive (struct target_ops *ops, ptid_t ptid)
{
if (ptid_equal (ptid, remote_m32r_ptid))
/* The main task is always alive. */
static void mips_detach (struct target_ops *ops, char *args, int from_tty);
-static void mips_resume (ptid_t ptid, int step,
- enum target_signal siggnal);
-
static int mips_map_regno (struct gdbarch *, int);
-static void mips_fetch_registers (struct regcache *regcache, int regno);
-
static void mips_prepare_to_store (struct regcache *regcache);
-static void mips_store_registers (struct regcache *regcache, int regno);
-
static unsigned int mips_fetch_word (CORE_ADDR addr);
static int mips_store_word (CORE_ADDR addr, unsigned int value,
where PMON does return a reply. */
static void
-mips_resume (ptid_t ptid, int step, enum target_signal siggnal)
+mips_resume (struct target_ops *ops,
+ ptid_t ptid, int step, enum target_signal siggnal)
{
int err;
/* Fetch the remote registers. */
static void
-mips_fetch_registers (struct regcache *regcache, int regno)
+mips_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
unsigned LONGEST val;
if (regno == -1)
{
for (regno = 0; regno < gdbarch_num_regs (gdbarch); regno++)
- mips_fetch_registers (regcache, regno);
+ mips_fetch_registers (ops, regcache, regno);
return;
}
/* Store remote register(s). */
static void
-mips_store_registers (struct regcache *regcache, int regno)
+mips_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
ULONGEST val;
if (regno == -1)
{
for (regno = 0; regno < gdbarch_num_regs (gdbarch); regno++)
- mips_store_registers (regcache, regno);
+ mips_store_registers (ops, regcache, regno);
return;
}
static void gdb_os_error (host_callback *, const char *, ...) ATTR_NORETURN;
-static void gdbsim_fetch_register (struct regcache *regcache, int regno);
-
-static void gdbsim_store_register (struct regcache *regcache, int regno);
-
static void gdbsim_kill (void);
static void gdbsim_load (char *prog, int fromtty);
}
static void
-gdbsim_fetch_register (struct regcache *regcache, int regno)
+gdbsim_fetch_register (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
if (regno == -1)
{
for (regno = 0; regno < gdbarch_num_regs (gdbarch); regno++)
- gdbsim_fetch_register (regcache, regno);
+ gdbsim_fetch_register (ops, regcache, regno);
return;
}
static void
-gdbsim_store_register (struct regcache *regcache, int regno)
+gdbsim_store_register (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
if (regno == -1)
{
for (regno = 0; regno < gdbarch_num_regs (gdbarch); regno++)
- gdbsim_store_register (regcache, regno);
+ gdbsim_store_register (ops, regcache, regno);
return;
}
else if (gdbarch_register_sim_regno (gdbarch, regno) >= 0)
/* Check to see if a thread is still alive. */
static int
-gdbsim_thread_alive (ptid_t ptid)
+gdbsim_thread_alive (struct target_ops *ops, ptid_t ptid)
{
if (ptid_equal (ptid, remote_sim_ptid))
/* The simulators' task is always alive. */
static void remote_prepare_to_store (struct regcache *regcache);
-static void remote_fetch_registers (struct regcache *regcache, int regno);
-
-static void remote_resume (ptid_t ptid, int step,
- enum target_signal siggnal);
static void remote_open (char *name, int from_tty);
static void extended_remote_open (char *name, int from_tty);
static void remote_close (int quitting);
-static void remote_store_registers (struct regcache *regcache, int regno);
-
static void remote_mourn (struct target_ops *ops);
static void extended_remote_restart (void);
static void set_general_thread (struct ptid ptid);
static void set_continue_thread (struct ptid ptid);
-static int remote_thread_alive (ptid_t);
-
static void get_offsets (void);
static void skip_frame (void);
system. */
static int
-remote_thread_alive (ptid_t ptid)
+remote_thread_alive (struct target_ops *ops, ptid_t ptid)
{
struct remote_state *rs = get_remote_state ();
int tid = ptid_get_tid (ptid);
*/
static void
-remote_threads_info (void)
+remote_threads_info (struct target_ops *ops)
{
struct remote_state *rs = get_remote_state ();
char *bufp;
controlling. We default to adding them in the running state.
The '?' query below will then tell us about which threads are
stopped. */
- remote_threads_info ();
+ remote_threads_info (args->target);
}
else if (rs->non_stop_aware)
{
if (non_stop)
/* Get list of threads. */
- remote_threads_info ();
+ remote_threads_info (target);
else
/* Add the main thread to the thread list. */
add_thread_silent (inferior_ptid);
static int last_sent_step;
static void
-remote_resume (ptid_t ptid, int step, enum target_signal siggnal)
+remote_resume (struct target_ops *ops,
+ ptid_t ptid, int step, enum target_signal siggnal)
{
struct remote_state *rs = get_remote_state ();
char *buf;
}
static void
-remote_fetch_registers (struct regcache *regcache, int regnum)
+remote_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
struct remote_state *rs = get_remote_state ();
struct remote_arch_state *rsa = get_remote_arch_state ();
of the register cache buffer. FIXME: ignores errors. */
static void
-remote_store_registers (struct regcache *regcache, int regnum)
+remote_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
struct remote_state *rs = get_remote_state ();
struct remote_arch_state *rsa = get_remote_arch_state ();
REGNO otherwise. */
static void
-rs6000_fetch_inferior_registers (struct regcache *regcache, int regno)
+rs6000_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
if (regno != -1)
Otherwise, REGNO specifies which register (so we can save time). */
static void
-rs6000_store_inferior_registers (struct regcache *regcache, int regno)
+rs6000_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
if (regno != -1)
/* Fetch register REGNUM from the child process. If REGNUM is -1, do
this for all registers. */
static void
-s390_linux_fetch_inferior_registers (struct regcache *regcache, int regnum)
+s390_linux_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
int tid = s390_inferior_tid ();
/* Store register REGNUM back into the child process. If REGNUM is
-1, do this for all registers. */
static void
-s390_linux_store_inferior_registers (struct regcache *regcache, int regnum)
+s390_linux_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
int tid = s390_inferior_tid ();
|| (regno) == SR_REGNUM)
static void
-shnbsd_fetch_inferior_registers (struct regcache *regcache, int regno)
+shnbsd_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
if (regno == -1 || GETREGS_SUPPLIES (get_regcache_arch (regcache), regno))
{
}
static void
-shnbsd_store_inferior_registers (struct regcache *regcache, int regno)
+shnbsd_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
if (regno == -1 || GETREGS_SUPPLIES (get_regcache_arch (regcache), regno))
{
#include "gdb_string.h"
-extern struct target_ops sol_thread_ops; /* Forward declaration */
-extern struct target_ops sol_core_ops; /* Forward declaration */
-
-/* place to store core_ops before we overwrite it */
-static struct target_ops orig_core_ops;
-
struct target_ops sol_thread_ops;
-struct target_ops sol_core_ops;
-extern int procfs_suppress_run;
-extern struct target_ops procfs_ops; /* target vector for procfs.c */
-extern struct target_ops core_ops; /* target vector for corelow.c */
extern char *procfs_pid_to_str (struct target_ops *ops, ptid_t ptid);
/* Prototypes for supply_gregset etc. */
static td_thragent_t *main_ta;
static int sol_thread_active = 0;
-static void sol_thread_resume (ptid_t ptid, int step, enum target_signal signo);
-static int sol_thread_alive (ptid_t ptid);
-static void sol_core_close (int quitting);
-
static void init_sol_thread_ops (void);
-static void init_sol_core_ops (void);
/* Default definitions: These must be defined in tm.h if they are to
be shared with a process module such as procfs. */
/* It's an LWP. Convert it to a thread ID. */
- if (!sol_thread_alive (lwp))
+ if (!target_thread_alive (lwp))
return pid_to_ptid (-1); /* Must be a defunct LPW. */
val = p_td_ta_map_lwp2thr (main_ta, GET_LWP (lwp), &th);
\f
/* Most target vector functions from here on actually just pass
- through to procfs.c, as they don't need to do anything specific for
- threads. */
-
-static void
-sol_thread_open (char *arg, int from_tty)
-{
- procfs_ops.to_open (arg, from_tty);
-}
-
-/* Attach to process PID, then initialize for debugging it and wait
- for the trace-trap that results from attaching. */
-
-static void
-sol_thread_attach (struct target_ops *ops, char *args, int from_tty)
-{
- sol_thread_active = 0;
- procfs_ops.to_attach (&procfs_ops, args, from_tty);
-
- /* Must get symbols from shared libraries before libthread_db can run! */
- solib_add (NULL, from_tty, (struct target_ops *) 0, auto_solib_add);
-
- if (sol_thread_active)
- {
- ptid_t ptid;
- printf_filtered ("sol-thread active.\n");
- main_ph.ptid = inferior_ptid; /* Save for xfer_memory. */
- push_target (&sol_thread_ops);
- ptid = lwp_to_thread (inferior_ptid);
- if (PIDGET (ptid) != -1)
- thread_change_ptid (inferior_ptid, ptid);
- }
-
- /* FIXME: Might want to iterate over all the threads and register
- them. */
-}
+ through to the layer beneath, as they don't need to do anything
+ specific for threads. */
/* Take a program previously attached to and detaches it. The program
resumes execution and will no longer stop on signals, etc. We'd
static void
sol_thread_detach (struct target_ops *ops, char *args, int from_tty)
{
+ struct target_ops *beneath = find_target_beneath (ops);
+
sol_thread_active = 0;
inferior_ptid = pid_to_ptid (PIDGET (main_ph.ptid));
- unpush_target (&sol_thread_ops);
- procfs_ops.to_detach (&procfs_ops, args, from_tty);
+ unpush_target (ops);
+ beneath->to_detach (beneath, args, from_tty);
}
/* Resume execution of process PTID. If STEP is nozero, then just
ID for procfs. */
static void
-sol_thread_resume (ptid_t ptid, int step, enum target_signal signo)
+sol_thread_resume (struct target_ops *ops,
+ ptid_t ptid, int step, enum target_signal signo)
{
struct cleanup *old_chain;
+ struct target_ops *beneath = find_target_beneath (ops);
old_chain = save_inferior_ptid ();
GET_THREAD (save_ptid));
}
- procfs_ops.to_resume (ptid, step, signo);
+ beneath->to_resume (beneath, ptid, step, signo);
do_cleanups (old_chain);
}
{
ptid_t rtnval;
ptid_t save_ptid;
+ struct target_ops *beneath = find_target_beneath (ops);
struct cleanup *old_chain;
save_ptid = inferior_ptid;
GET_THREAD (save_ptid));
}
- rtnval = procfs_ops.to_wait (&procfs_ops, ptid, ourstatus);
+ rtnval = beneath->to_wait (beneath, ptid, ourstatus);
if (ourstatus->kind != TARGET_WAITKIND_EXITED)
{
}
static void
-sol_thread_fetch_registers (struct regcache *regcache, int regnum)
+sol_thread_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
thread_t thread;
td_thrhandle_t thandle;
prfpregset_t fpregset;
gdb_gregset_t *gregset_p = &gregset;
gdb_fpregset_t *fpregset_p = &fpregset;
+ struct target_ops *beneath = find_target_beneath (ops);
#if 0
int xregsize;
if (!is_thread (inferior_ptid))
{
- /* It's an LWP; pass the request on to procfs. */
- if (target_has_execution)
- procfs_ops.to_fetch_registers (regcache, regnum);
- else
- orig_core_ops.to_fetch_registers (regcache, regnum);
+ /* It's an LWP; pass the request on to the layer beneath. */
+ beneath->to_fetch_registers (beneath, regcache, regnum);
return;
}
}
static void
-sol_thread_store_registers (struct regcache *regcache, int regnum)
+sol_thread_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
thread_t thread;
td_thrhandle_t thandle;
if (!is_thread (inferior_ptid))
{
- /* It's an LWP; pass the request on to procfs.c. */
- procfs_ops.to_store_registers (regcache, regnum);
+ struct target_ops *beneath = find_target_beneath (ops);
+
+ /* It's an LWP; pass the request on to the layer beneath. */
+ beneath->to_store_registers (beneath, regcache, regnum);
return;
}
#endif
}
-/* Get ready to modify the registers array. On machines which store
- individual registers, this doesn't need to do anything. On
- machines which store all the registers in one fell swoop, this
- makes sure that registers contains all the registers from the
- program being debugged. */
-
-static void
-sol_thread_prepare_to_store (struct regcache *regcache)
-{
- procfs_ops.to_prepare_to_store (regcache);
-}
-
-/* Transfer LEN bytes between GDB address MYADDR and target address
- MEMADDR. If DOWRITE is non-zero, transfer them to the target,
- otherwise transfer them from the target. TARGET is unused.
-
- Returns the number of bytes transferred. */
-
-static int
-sol_thread_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len,
- int dowrite, struct mem_attrib *attrib,
- struct target_ops *target)
-{
- int retval;
- struct cleanup *old_chain;
-
- old_chain = save_inferior_ptid ();
-
- if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
- {
- /* It's either a thread or an LWP that isn't alive. Any live
- LWP will do so use the first available.
-
- NOTE: We don't need to call switch_to_thread; we're just
- reading memory. */
- inferior_ptid = procfs_first_available ();
- }
-
- if (target_has_execution)
- retval = procfs_ops.deprecated_xfer_memory (memaddr, myaddr, len,
- dowrite, attrib, target);
- else
- retval = orig_core_ops.deprecated_xfer_memory (memaddr, myaddr, len,
- dowrite, attrib, target);
-
- do_cleanups (old_chain);
-
- return retval;
-}
-
/* Perform partial transfers on OBJECT. See target_read_partial and
target_write_partial for details of each variant. One, and only
one, of readbuf or writebuf must be non-NULL. */
{
int retval;
struct cleanup *old_chain;
+ struct target_ops *beneath = find_target_beneath (ops);
old_chain = save_inferior_ptid ();
inferior_ptid = procfs_first_available ();
}
- if (target_has_execution)
- retval = procfs_ops.to_xfer_partial (ops, object, annex,
- readbuf, writebuf, offset, len);
- else
- retval = orig_core_ops.to_xfer_partial (ops, object, annex,
- readbuf, writebuf, offset, len);
+ retval = beneath->to_xfer_partial (beneath, object, annex,
+ readbuf, writebuf, offset, len);
do_cleanups (old_chain);
return retval;
}
-/* Print status information about what we're accessing. */
-
static void
-sol_thread_files_info (struct target_ops *ignore)
+check_for_thread_db (void)
{
- procfs_ops.to_files_info (ignore);
-}
+ td_err_e err;
+ ptid_t ptid;
-static void
-sol_thread_kill_inferior (void)
-{
- procfs_ops.to_kill ();
-}
+ /* Do nothing if we couldn't load libthread_db.so.1. */
+ if (p_td_ta_new == NULL)
+ return;
-static void
-sol_thread_notice_signals (ptid_t ptid)
-{
- procfs_ops.to_notice_signals (pid_to_ptid (PIDGET (ptid)));
-}
+ if (sol_thread_active)
+ /* Nothing to do. The thread library was already detected and the
+ target vector was already activated. */
+ return;
-/* Fork an inferior process, and start debugging it with /proc. */
+ /* Now, initialize libthread_db. This needs to be done after the
+ shared libraries are located because it needs information from
+ the user's thread library. */
-static void
-sol_thread_create_inferior (struct target_ops *ops, char *exec_file,
- char *allargs, char **env, int from_tty)
-{
- sol_thread_active = 0;
- procfs_ops.to_create_inferior (&procfs_ops, exec_file, allargs, env, from_tty);
+ err = p_td_init ();
+ if (err != TD_OK)
+ {
+ warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (err));
+ return;
+ }
- if (sol_thread_active && !ptid_equal (inferior_ptid, null_ptid))
+ /* Now attempt to open a connection to the thread library. */
+ err = p_td_ta_new (&main_ph, &main_ta);
+ switch (err)
{
- ptid_t ptid;
+ case TD_NOLIBTHREAD:
+ /* No thread library was detected. */
+ break;
- /* Save for xfer_memory. */
- main_ph.ptid = inferior_ptid;
+ case TD_OK:
+ printf_unfiltered (_("[Thread debugging using libthread_db enabled]\n"));
+ /* The thread library was detected. Activate the sol_thread target. */
push_target (&sol_thread_ops);
+ sol_thread_active = 1;
+ main_ph.ptid = inferior_ptid; /* Save for xfer_memory. */
ptid = lwp_to_thread (inferior_ptid);
if (PIDGET (ptid) != -1)
- thread_change_ptid (inferior_ptid, ptid);
+ inferior_ptid = ptid;
+
+ target_find_new_threads ();
+ break;
+
+ default:
+ warning (_("Cannot initialize thread debugging library: %s"),
+ td_err_string (err));
+ break;
}
}
static void
sol_thread_new_objfile (struct objfile *objfile)
{
- td_err_e val;
-
- if (!objfile)
- {
- sol_thread_active = 0;
- return;
- }
-
- /* Don't do anything if init failed to resolve the libthread_db
- library. */
- if (!procfs_suppress_run)
- return;
-
- /* Now, initialize libthread_db. This needs to be done after the
- shared libraries are located because it needs information from
- the user's thread library. */
-
- val = p_td_init ();
- if (val != TD_OK)
- {
- warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (val));
- return;
- }
-
- val = p_td_ta_new (&main_ph, &main_ta);
- if (val == TD_NOLIBTHREAD)
- return;
- else if (val != TD_OK)
- {
- warning (_("sol_thread_new_objfile: td_ta_new: %s"), td_err_string (val));
- return;
- }
-
- sol_thread_active = 1;
+ if (objfile != NULL)
+ check_for_thread_db ();
}
/* Clean up after the inferior dies. */
static void
sol_thread_mourn_inferior (struct target_ops *ops)
{
+ struct target_ops *beneath = find_target_beneath (ops);
+
sol_thread_active = 0;
- unpush_target (&sol_thread_ops);
- procfs_ops.to_mourn_inferior (&procfs_ops);
-}
-/* Mark our target-struct as eligible for stray "run" and "attach"
- commands. */
+ unpush_target (ops);
-static int
-sol_thread_can_run (void)
-{
- return procfs_suppress_run;
+ beneath->to_mourn_inferior (beneath);
}
-/*
-
- LOCAL FUNCTION
-
- sol_thread_alive - test thread for "aliveness"
-
- SYNOPSIS
-
- static bool sol_thread_alive (ptid_t ptid);
-
- DESCRIPTION
-
- returns true if thread still active in inferior.
-
- */
-
/* Return true if PTID is still active in the inferior. */
static int
-sol_thread_alive (ptid_t ptid)
+sol_thread_alive (struct target_ops *ops, ptid_t ptid)
{
if (is_thread (ptid))
{
}
else
{
- /* It's an LPW; pass the request on to procfs. */
- if (target_has_execution)
- return procfs_ops.to_thread_alive (ptid);
- else
- return orig_core_ops.to_thread_alive (ptid);
+ struct target_ops *beneath = find_target_beneath (ops);
+
+ /* It's an LPW; pass the request on to the layer below. */
+ return beneath->to_thread_alive (beneath, ptid);
}
}
-static void
-sol_thread_stop (ptid_t ptid)
-{
- procfs_ops.to_stop (ptid);
-}
\f
/* These routines implement the lower half of the thread_db interface,
i.e. the ps_* routines. */
rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
char *buf, int size)
{
+ int ret;
struct cleanup *old_chain;
old_chain = save_inferior_ptid ();
addr &= 0xffffffff;
#endif
- while (size > 0)
- {
- int cc;
-
- /* FIXME: passing 0 as attrib argument. */
- if (target_has_execution)
- cc = procfs_ops.deprecated_xfer_memory (addr, buf, size,
- dowrite, 0, &procfs_ops);
- else
- cc = orig_core_ops.deprecated_xfer_memory (addr, buf, size,
- dowrite, 0, &core_ops);
-
- if (cc < 0)
- {
- if (dowrite == 0)
- print_sys_errmsg ("rw_common (): read", errno);
- else
- print_sys_errmsg ("rw_common (): write", errno);
-
- do_cleanups (old_chain);
-
- return PS_ERR;
- }
- else if (cc == 0)
- {
- if (dowrite == 0)
- warning (_("rw_common (): unable to read at addr 0x%lx"),
- (long) addr);
- else
- warning (_("rw_common (): unable to write at addr 0x%lx"),
- (long) addr);
-
- do_cleanups (old_chain);
-
- return PS_ERR;
- }
-
- size -= cc;
- buf += cc;
- }
+ if (dowrite)
+ ret = target_write_memory (addr, buf, size);
+ else
+ ret = target_read_memory (addr, buf, size);
do_cleanups (old_chain);
- return PS_OK;
+ return (ret == 0 ? PS_OK : PS_ERR);
}
/* Copies SIZE bytes from target process .data segment to debugger memory. */
inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
regcache = get_thread_regcache (inferior_ptid);
- if (target_has_execution)
- procfs_ops.to_fetch_registers (regcache, -1);
- else
- orig_core_ops.to_fetch_registers (regcache, -1);
+ target_fetch_registers (regcache, -1);
fill_gregset (regcache, (gdb_gregset_t *) gregset, -1);
do_cleanups (old_chain);
regcache = get_thread_regcache (inferior_ptid);
supply_gregset (regcache, (const gdb_gregset_t *) gregset);
- if (target_has_execution)
- procfs_ops.to_store_registers (regcache, -1);
- else
- orig_core_ops.to_store_registers (regcache, -1);
+ target_store_registers (regcache, -1);
do_cleanups (old_chain);
inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
regcache = get_thread_regcache (inferior_ptid);
- if (target_has_execution)
- procfs_ops.to_fetch_registers (regcache, -1);
- else
- orig_core_ops.to_fetch_registers (regcache, -1);
+ target_fetch_registers (regcache, -1);
fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1);
do_cleanups (old_chain);
regcache = get_thread_regcache (inferior_ptid);
supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset);
- if (target_has_execution)
- procfs_ops.to_store_registers (regcache, -1);
- else
- orig_core_ops.to_store_registers (regcache, -1);
+ target_store_registers (regcache, -1);
do_cleanups (old_chain);
{
static char buf[100];
- /* In case init failed to resolve the libthread_db library. */
- if (!procfs_suppress_run)
- return procfs_pid_to_str (&procfs_ops, ptid);
-
if (is_thread (ptid))
{
ptid_t lwp;
}
static void
-sol_find_new_threads (void)
+sol_find_new_threads (struct target_ops *ops)
{
- /* Don't do anything if init failed to resolve the libthread_db
- library. */
- if (!procfs_suppress_run)
- return;
-
- if (PIDGET (inferior_ptid) == -1)
- {
- printf_filtered ("No process.\n");
- return;
- }
+ struct target_ops *beneath = find_target_beneath (ops);
/* First Find any new LWP's. */
- procfs_ops.to_find_new_threads ();
+ if (beneath->to_find_new_threads != NULL)
+ beneath->to_find_new_threads (beneath);
/* Then find any new user-level threads. */
p_td_ta_thr_iter (main_ta, sol_find_new_threads_callback, (void *) 0,
TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
}
-static void
-sol_core_open (char *filename, int from_tty)
-{
- orig_core_ops.to_open (filename, from_tty);
-}
-
-static void
-sol_core_close (int quitting)
-{
- orig_core_ops.to_close (quitting);
-}
-
-static void
-sol_core_detach (struct target_ops *ops, char *args, int from_tty)
-{
- unpush_target (&core_ops);
- orig_core_ops.to_detach (&orig_core_ops, args, from_tty);
-}
-
-static void
-sol_core_files_info (struct target_ops *t)
-{
- orig_core_ops.to_files_info (t);
-}
-
/* Worker bee for the "info sol-thread" command. This is a callback
function that gets called once for each Solaris user-level thread
(i.e. not for LWPs) in the inferior. Print anything interesting
TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
}
-static int
-sol_find_memory_regions (int (*func) (CORE_ADDR, unsigned long,
- int, int, int, void *),
- void *data)
-{
- return procfs_ops.to_find_memory_regions (func, data);
-}
-
-static char *
-sol_make_note_section (bfd *obfd, int *note_size)
-{
- return procfs_ops.to_make_corefile_notes (obfd, note_size);
-}
-
-static int
-ignore (struct bp_target_info *bp_tgt)
-{
- return 0;
-}
-
static void
init_sol_thread_ops (void)
{
sol_thread_ops.to_shortname = "solaris-threads";
sol_thread_ops.to_longname = "Solaris threads and pthread.";
sol_thread_ops.to_doc = "Solaris threads and pthread support.";
- sol_thread_ops.to_open = sol_thread_open;
- sol_thread_ops.to_attach = sol_thread_attach;
sol_thread_ops.to_detach = sol_thread_detach;
sol_thread_ops.to_resume = sol_thread_resume;
sol_thread_ops.to_wait = sol_thread_wait;
sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
sol_thread_ops.to_store_registers = sol_thread_store_registers;
- sol_thread_ops.to_prepare_to_store = sol_thread_prepare_to_store;
- sol_thread_ops.deprecated_xfer_memory = sol_thread_xfer_memory;
sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial;
- sol_thread_ops.to_files_info = sol_thread_files_info;
- sol_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
- sol_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
- sol_thread_ops.to_terminal_init = terminal_init_inferior;
- sol_thread_ops.to_terminal_inferior = terminal_inferior;
- sol_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
- sol_thread_ops.to_terminal_ours = terminal_ours;
- sol_thread_ops.to_terminal_save_ours = terminal_save_ours;
- sol_thread_ops.to_terminal_info = child_terminal_info;
- sol_thread_ops.to_kill = sol_thread_kill_inferior;
- sol_thread_ops.to_create_inferior = sol_thread_create_inferior;
sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
- sol_thread_ops.to_can_run = sol_thread_can_run;
- sol_thread_ops.to_notice_signals = sol_thread_notice_signals;
sol_thread_ops.to_thread_alive = sol_thread_alive;
sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
sol_thread_ops.to_find_new_threads = sol_find_new_threads;
- sol_thread_ops.to_stop = sol_thread_stop;
- sol_thread_ops.to_stratum = process_stratum;
- sol_thread_ops.to_has_all_memory = 1;
- sol_thread_ops.to_has_memory = 1;
- sol_thread_ops.to_has_stack = 1;
- sol_thread_ops.to_has_registers = 1;
- sol_thread_ops.to_has_execution = 1;
- sol_thread_ops.to_has_thread_control = tc_none;
- sol_thread_ops.to_find_memory_regions = sol_find_memory_regions;
- sol_thread_ops.to_make_corefile_notes = sol_make_note_section;
+ sol_thread_ops.to_stratum = thread_stratum;
sol_thread_ops.to_magic = OPS_MAGIC;
}
-static void
-init_sol_core_ops (void)
-{
- sol_core_ops.to_shortname = "solaris-core";
- sol_core_ops.to_longname = "Solaris core threads and pthread.";
- sol_core_ops.to_doc = "Solaris threads and pthread support for core files.";
- sol_core_ops.to_open = sol_core_open;
- sol_core_ops.to_close = sol_core_close;
- sol_core_ops.to_attach = sol_thread_attach;
- sol_core_ops.to_detach = sol_core_detach;
- sol_core_ops.to_fetch_registers = sol_thread_fetch_registers;
- sol_core_ops.deprecated_xfer_memory = sol_thread_xfer_memory;
- sol_core_ops.to_xfer_partial = sol_thread_xfer_partial;
- sol_core_ops.to_files_info = sol_core_files_info;
- sol_core_ops.to_insert_breakpoint = ignore;
- sol_core_ops.to_remove_breakpoint = ignore;
- sol_core_ops.to_create_inferior = sol_thread_create_inferior;
- sol_core_ops.to_stratum = core_stratum;
- sol_core_ops.to_has_memory = 1;
- sol_core_ops.to_has_stack = 1;
- sol_core_ops.to_has_registers = 1;
- sol_core_ops.to_has_thread_control = tc_none;
- sol_core_ops.to_thread_alive = sol_thread_alive;
- sol_core_ops.to_pid_to_str = solaris_pid_to_str;
- /* On Solaris/x86, when debugging a threaded core file from process
- <n>, the following causes "info threads" to produce "procfs:
- couldn't find pid <n> in procinfo list" where <n> is the pid of
- the process that produced the core file. Disable it for now. */
-#if 0
- sol_core_ops.to_find_new_threads = sol_find_new_threads;
-#endif
- sol_core_ops.to_magic = OPS_MAGIC;
-}
-
-/* We suppress the call to add_target of core_ops in corelow because
- if there are two targets in the stratum core_stratum,
- find_core_target won't know which one to return. See corelow.c for
- an additonal comment on coreops_suppress_target. */
-int coreops_suppress_target = 1;
-
void
_initialize_sol_thread (void)
{
void *dlhandle;
init_sol_thread_ops ();
- init_sol_core_ops ();
dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
if (!dlhandle)
add_target (&sol_thread_ops);
- procfs_suppress_run = 1;
-
add_cmd ("sol-threads", class_maintenance, info_solthreads,
_("Show info on Solaris user threads."), &maintenanceinfolist);
- /* FIXME: This code takes errant advantage of the order in which
- initialization routines are run. _initialize_corelow must run before
- this one otherwise orig_core_ops will still contain zeros and the work
- of init_sol_core_ops will be undone. */
- memcpy (&orig_core_ops, &core_ops, sizeof (struct target_ops));
- memcpy (&core_ops, &sol_core_ops, sizeof (struct target_ops));
- add_target (&core_ops);
-
/* Hook into new_objfile notification. */
observer_attach_new_objfile (sol_thread_new_objfile);
return;
if (dlhandle)
dlclose (dlhandle);
- /* Allow the user to debug non-threaded core files. */
- add_target (&core_ops);
-
return;
}
#include "defs.h"
#include "frame.h"
#include "symtab.h"
+#include "inferior.h"
#include "sol2-tdep.h"
return 0;
}
+
+/* This is how we want PTIDs from Solaris core files to be
+ printed. */
+
+char *
+sol2_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid)
+{
+ static char buf[80];
+
+ xsnprintf (buf, sizeof buf, "LWP %ld", ptid_get_lwp (ptid));
+ return buf;
+}
CORE_ADDR sol2_skip_solib_resolver (struct gdbarch *, CORE_ADDR);
+char *sol2_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid);
+
#endif /* sol2-tdep.h */
for all registers (including the floating-point registers). */
void
-sparc_fetch_inferior_registers (struct regcache *regcache, int regnum)
+sparc_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
int pid;
}
void
-sparc_store_inferior_registers (struct regcache *regcache, int regnum)
+sparc_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
int pid;
extern struct target_ops *sparc_target (void);
-extern void sparc_fetch_inferior_registers (struct regcache *, int);
-extern void sparc_store_inferior_registers (struct regcache *, int);
+extern void sparc_fetch_inferior_registers (struct target_ops *,
+ struct regcache *, int);
+extern void sparc_store_inferior_registers (struct target_ops *,
+ struct regcache *, int);
#endif /* sparc-nat.h */
/* Solaris encodes the pid of the inferior in regset section
names. */
set_gdbarch_core_reg_section_encodes_pid (gdbarch, 1);
+
+ /* How to print LWP PTIDs from core files. */
+ set_gdbarch_core_pid_to_str (gdbarch, sol2_core_pid_to_str);
}
\f
/* Solaris encodes the pid of the inferior in regset section
names. */
set_gdbarch_core_reg_section_encodes_pid (gdbarch, 1);
+
+ /* How to print LWP PTIDs from core files. */
+ set_gdbarch_core_pid_to_str (gdbarch, sol2_core_pid_to_str);
}
\f
/* Override the fetch_inferior_register routine. */
static void
-spu_fetch_inferior_registers (struct regcache *regcache, int regno)
+spu_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
int fd;
ULONGEST addr;
/* Override the store_inferior_register routine. */
static void
-spu_store_inferior_registers (struct regcache *regcache, int regno)
+spu_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
int fd;
ULONGEST addr;
static void debug_to_open (char *, int);
-static void debug_to_resume (ptid_t, int, enum target_signal);
-
-static void debug_to_fetch_registers (struct regcache *, int);
-
-static void debug_to_store_registers (struct regcache *, int);
-
static void debug_to_prepare_to_store (struct regcache *);
static void debug_to_files_info (struct target_ops *);
static void debug_to_notice_signals (ptid_t);
-static int debug_to_thread_alive (ptid_t);
-
static void debug_to_stop (ptid_t);
/* NOTE: cagney/2004-09-29: Many targets reference this variable in
INHERIT (to_attach_no_wait, t);
/* Do not inherit to_detach. */
/* Do not inherit to_disconnect. */
- INHERIT (to_resume, t);
+ /* Do not inherit to_resume. */
/* Do not inherit to_wait. */
- INHERIT (to_fetch_registers, t);
- INHERIT (to_store_registers, t);
+ /* Do not inherit to_fetch_registers. */
+ /* Do not inherit to_store_registers. */
INHERIT (to_prepare_to_store, t);
INHERIT (deprecated_xfer_memory, t);
INHERIT (to_files_info, t);
/* Do not inherit to_mourn_inferiour. */
INHERIT (to_can_run, t);
INHERIT (to_notice_signals, t);
- INHERIT (to_thread_alive, t);
- INHERIT (to_find_new_threads, t);
+ /* Do not inherit to_thread_alive. */
+ /* Do not inherit to_find_new_threads. */
/* Do not inherit to_pid_to_str. */
INHERIT (to_extra_thread_info, t);
INHERIT (to_stop, t);
de_fault (to_post_attach,
(void (*) (int))
target_ignore);
- de_fault (to_resume,
- (void (*) (ptid_t, int, enum target_signal))
- noprocess);
- de_fault (to_fetch_registers,
- (void (*) (struct regcache *, int))
- target_ignore);
- de_fault (to_store_registers,
- (void (*) (struct regcache *, int))
- noprocess);
de_fault (to_prepare_to_store,
(void (*) (struct regcache *))
noprocess);
de_fault (to_notice_signals,
(void (*) (ptid_t))
target_ignore);
- de_fault (to_thread_alive,
- (int (*) (ptid_t))
- return_zero);
- de_fault (to_find_new_threads,
- (void (*) (void))
- target_ignore);
de_fault (to_extra_thread_info,
(char *(*) (struct thread_info *))
return_zero);
void
target_resume (ptid_t ptid, int step, enum target_signal signal)
{
+ struct target_ops *t;
+
dcache_invalidate (target_dcache);
- (*current_target.to_resume) (ptid, step, signal);
- set_executing (ptid, 1);
- set_running (ptid, 1);
+
+ for (t = current_target.beneath; t != NULL; t = t->beneath)
+ {
+ if (t->to_resume != NULL)
+ {
+ t->to_resume (t, ptid, step, signal);
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog, "target_resume (%d, %s, %s)\n",
+ PIDGET (ptid),
+ step ? "step" : "continue",
+ target_signal_to_name (signal));
+
+ set_executing (ptid, 1);
+ set_running (ptid, 1);
+ return;
+ }
+ }
+
+ noprocess ();
}
/* Look through the list of possible targets for a target that can
follow forks. */
"could not find a target to attach");
}
-static void
-debug_to_post_attach (int pid)
+int
+target_thread_alive (ptid_t ptid)
{
- debug_target.to_post_attach (pid);
+ struct target_ops *t;
+ for (t = current_target.beneath; t != NULL; t = t->beneath)
+ {
+ if (t->to_thread_alive != NULL)
+ {
+ int retval;
- fprintf_unfiltered (gdb_stdlog, "target_post_attach (%d)\n", pid);
+ retval = t->to_thread_alive (t, ptid);
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog, "target_thread_alive (%d) = %d\n",
+ PIDGET (ptid), retval);
+
+ return retval;
+ }
+ }
+
+ return 0;
+}
+
+void
+target_find_new_threads (void)
+{
+ struct target_ops *t;
+ for (t = current_target.beneath; t != NULL; t = t->beneath)
+ {
+ if (t->to_find_new_threads != NULL)
+ {
+ t->to_find_new_threads (t);
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog, "target_find_new_threads ()\n");
+
+ return;
+ }
+ }
}
static void
-debug_to_resume (ptid_t ptid, int step, enum target_signal siggnal)
+debug_to_post_attach (int pid)
{
- debug_target.to_resume (ptid, step, siggnal);
+ debug_target.to_post_attach (pid);
- fprintf_unfiltered (gdb_stdlog, "target_resume (%d, %s, %s)\n", PIDGET (ptid),
- step ? "step" : "continue",
- target_signal_to_name (siggnal));
+ fprintf_unfiltered (gdb_stdlog, "target_post_attach (%d)\n", pid);
}
/* Return a pretty printed form of target_waitstatus.
fprintf_unfiltered (gdb_stdlog, "\n");
}
-static void
-debug_to_fetch_registers (struct regcache *regcache, int regno)
+void
+target_fetch_registers (struct regcache *regcache, int regno)
{
- debug_target.to_fetch_registers (regcache, regno);
- debug_print_register ("target_fetch_registers", regcache, regno);
+ struct target_ops *t;
+ for (t = current_target.beneath; t != NULL; t = t->beneath)
+ {
+ if (t->to_fetch_registers != NULL)
+ {
+ t->to_fetch_registers (t, regcache, regno);
+ if (targetdebug)
+ debug_print_register ("target_fetch_registers", regcache, regno);
+ return;
+ }
+ }
}
-static void
-debug_to_store_registers (struct regcache *regcache, int regno)
+void
+target_store_registers (struct regcache *regcache, int regno)
{
- debug_target.to_store_registers (regcache, regno);
- debug_print_register ("target_store_registers", regcache, regno);
- fprintf_unfiltered (gdb_stdlog, "\n");
+
+ struct target_ops *t;
+ for (t = current_target.beneath; t != NULL; t = t->beneath)
+ {
+ if (t->to_store_registers != NULL)
+ {
+ t->to_store_registers (t, regcache, regno);
+ if (targetdebug)
+ {
+ debug_print_register ("target_store_registers", regcache, regno);
+ }
+ return;
+ }
+ }
+
+ noprocess ();
}
static void
PIDGET (ptid));
}
-static int
-debug_to_thread_alive (ptid_t ptid)
-{
- int retval;
-
- retval = debug_target.to_thread_alive (ptid);
-
- fprintf_unfiltered (gdb_stdlog, "target_thread_alive (%d) = %d\n",
- PIDGET (ptid), retval);
-
- return retval;
-}
-
-static void
-debug_to_find_new_threads (void)
-{
- debug_target.to_find_new_threads ();
-
- fputs_unfiltered ("target_find_new_threads ()\n", gdb_stdlog);
-}
-
static void
debug_to_stop (ptid_t ptid)
{
current_target.to_open = debug_to_open;
current_target.to_post_attach = debug_to_post_attach;
- current_target.to_resume = debug_to_resume;
- current_target.to_fetch_registers = debug_to_fetch_registers;
- current_target.to_store_registers = debug_to_store_registers;
current_target.to_prepare_to_store = debug_to_prepare_to_store;
current_target.deprecated_xfer_memory = deprecated_debug_xfer_memory;
current_target.to_files_info = debug_to_files_info;
current_target.to_has_exited = debug_to_has_exited;
current_target.to_can_run = debug_to_can_run;
current_target.to_notice_signals = debug_to_notice_signals;
- current_target.to_thread_alive = debug_to_thread_alive;
- current_target.to_find_new_threads = debug_to_find_new_threads;
current_target.to_stop = debug_to_stop;
current_target.to_rcmd = debug_to_rcmd;
current_target.to_pid_to_exec_file = debug_to_pid_to_exec_file;
void (*to_post_attach) (int);
void (*to_detach) (struct target_ops *ops, char *, int);
void (*to_disconnect) (struct target_ops *, char *, int);
- void (*to_resume) (ptid_t, int, enum target_signal);
+ void (*to_resume) (struct target_ops *, ptid_t, int, enum target_signal);
ptid_t (*to_wait) (struct target_ops *,
ptid_t, struct target_waitstatus *);
- void (*to_fetch_registers) (struct regcache *, int);
- void (*to_store_registers) (struct regcache *, int);
+ void (*to_fetch_registers) (struct target_ops *, struct regcache *, int);
+ void (*to_store_registers) (struct target_ops *, struct regcache *, int);
void (*to_prepare_to_store) (struct regcache *);
/* Transfer LEN bytes of memory between GDB address MYADDR and
void (*to_mourn_inferior) (struct target_ops *);
int (*to_can_run) (void);
void (*to_notice_signals) (ptid_t ptid);
- int (*to_thread_alive) (ptid_t ptid);
- void (*to_find_new_threads) (void);
+ int (*to_thread_alive) (struct target_ops *, ptid_t ptid);
+ void (*to_find_new_threads) (struct target_ops *);
char *(*to_pid_to_str) (struct target_ops *, ptid_t);
char *(*to_extra_thread_info) (struct thread_info *);
void (*to_stop) (ptid_t);
/* Fetch at least register REGNO, or all regs if regno == -1. No result. */
-#define target_fetch_registers(regcache, regno) \
- (*current_target.to_fetch_registers) (regcache, regno)
+extern void target_fetch_registers (struct regcache *regcache, int regno);
/* Store at least register REGNO, or all regs if REGNO == -1.
It can store as many registers as it wants to, so target_prepare_to_store
must have been previously called. Calls error() if there are problems. */
-#define target_store_registers(regcache, regs) \
- (*current_target.to_store_registers) (regcache, regs)
+extern void target_store_registers (struct regcache *regcache, int regs);
/* Get ready to modify the registers array. On machines which store
individual registers, this doesn't need to do anything. On machines
/* Check to see if a thread is still alive. */
-#define target_thread_alive(ptid) \
- (*current_target.to_thread_alive) (ptid)
+extern int target_thread_alive (ptid_t ptid);
/* Query for new threads and add them to the thread list. */
-#define target_find_new_threads() \
- (*current_target.to_find_new_threads) ()
+extern void target_find_new_threads (void);
/* Make target stop in a continuable fashion. (For instance, under
Unix, this should act like SIGSTOP). This function is normally
for all registers. */
static void
-vaxbsd_fetch_inferior_registers (struct regcache *regcache, int regnum)
+vaxbsd_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
struct reg regs;
this for all registers. */
static void
-vaxbsd_store_inferior_registers (struct regcache *regcache, int regnum)
+vaxbsd_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
struct reg regs;
}
static void
-windows_fetch_inferior_registers (struct regcache *regcache, int r)
+windows_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int r)
{
current_thread = thread_rec (ptid_get_tid (inferior_ptid), TRUE);
/* Check if current_thread exists. Windows sometimes uses a non-existent
/* Store a new register value into the current thread context */
static void
-windows_store_inferior_registers (struct regcache *regcache, int r)
+windows_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int r)
{
current_thread = thread_rec (ptid_get_tid (inferior_ptid), TRUE);
/* Check if current_thread exists. Windows sometimes uses a non-existent
}
static void
-windows_resume (ptid_t ptid, int step, enum target_signal sig)
+windows_resume (struct target_ops *ops,
+ ptid_t ptid, int step, enum target_signal sig)
{
thread_info *th;
DWORD continue_status = DBG_CONTINUE;
if (step)
{
/* Single step by setting t bit */
- windows_fetch_inferior_registers (get_current_regcache (),
- gdbarch_ps_regnum (current_gdbarch));
+ windows_fetch_inferior_registers (ops,
+ get_current_regcache (),
+ gdbarch_ps_regnum (current_gdbarch));
th->context.EFlags |= FLAG_TRACE_BIT;
}
handling by WFI (or whatever).
*/
static int
-get_windows_debug_event (int pid, struct target_waitstatus *ourstatus)
+get_windows_debug_event (struct target_ops *ops,
+ int pid, struct target_waitstatus *ourstatus)
{
BOOL debug_event;
DWORD continue_status, event_code;
to find a better solution to that problem. But in the meantime,
the current approach already greatly mitigate this issue. */
SetConsoleCtrlHandler (NULL, TRUE);
- retval = get_windows_debug_event (pid, ourstatus);
+ retval = get_windows_debug_event (ops, pid, ourstatus);
SetConsoleCtrlHandler (NULL, FALSE);
if (retval)
if (has_detach_ability ())
{
ptid_t ptid = {-1};
- windows_resume (ptid, 0, TARGET_SIGNAL_0);
+ windows_resume (ops, ptid, 0, TARGET_SIGNAL_0);
if (!kernel32_DebugActiveProcessStop (current_event.dwProcessId))
{
by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
it means that the thread has died. Otherwise it is assumed to be alive. */
static int
-windows_thread_alive (ptid_t ptid)
+windows_thread_alive (struct target_ops *ops, ptid_t ptid)
{
int tid;
}
void
-xtensa_linux_fetch_inferior_registers (struct regcache *regcache, int regnum)
+xtensa_linux_fetch_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
if (regnum == -1)
{
}
void
-xtensa_linux_store_inferior_registers (struct regcache *regcache, int regnum)
+xtensa_linux_store_inferior_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
if (regnum == -1)
{