2014-01-01 03:54:24 +00:00
|
|
|
/* Copyright (C) 2008-2014 Free Software Foundation, Inc.
|
2008-10-20 15:48:17 +00:00
|
|
|
|
|
|
|
This file is part of GDB.
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
|
|
|
|
#include "defs.h"
|
|
|
|
#include "command.h"
|
|
|
|
#include "gdbcmd.h"
|
|
|
|
#include "target.h"
|
|
|
|
#include "observer.h"
|
|
|
|
#include <sys/procfs.h>
|
|
|
|
#include "gregset.h"
|
|
|
|
#include "regcache.h"
|
|
|
|
#include "inferior.h"
|
|
|
|
#include "gdbthread.h"
|
|
|
|
|
|
|
|
#include <pthread_debug.h>
|
|
|
|
|
|
|
|
/* Print debugging traces if set to non-zero. */
|
|
|
|
static int debug_dec_thread = 0;
|
|
|
|
|
|
|
|
/* Non-zero if the dec-thread layer is active. */
|
|
|
|
static int dec_thread_active = 0;
|
|
|
|
|
|
|
|
/* The pthread_debug context. */
|
|
|
|
pthreadDebugContext_t debug_context;
|
|
|
|
|
|
|
|
/* The dec-thread target_ops structure. */
|
|
|
|
static struct target_ops dec_thread_ops;
|
|
|
|
|
|
|
|
/* Print a debug trace if DEBUG_DEC_THREAD is set (its value is adjusted
|
|
|
|
by the user using "set debug dec-thread ..."). */
|
|
|
|
|
|
|
|
static void
|
|
|
|
debug (char *format, ...)
|
|
|
|
{
|
|
|
|
if (debug_dec_thread)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
va_start (args, format);
|
|
|
|
printf_unfiltered ("DEC Threads: ");
|
|
|
|
vprintf_unfiltered (format, args);
|
|
|
|
printf_unfiltered ("\n");
|
|
|
|
va_end (args);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* pthread debug callbacks. */
|
|
|
|
|
|
|
|
static int
|
|
|
|
suspend_clbk (void *caller_context)
|
|
|
|
{
|
|
|
|
return ESUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
resume_clbk (void *caller_context)
|
|
|
|
{
|
|
|
|
return ESUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
hold_clbk (void *caller_context, pthreadDebugKId_t kernel_tid)
|
|
|
|
{
|
|
|
|
return ESUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
unhold_clbk (void *caller_context, pthreadDebugKId_t kernel_tid)
|
|
|
|
{
|
|
|
|
return ESUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
read_clbk (void *caller_context, void *address, void *buffer,
|
|
|
|
unsigned long size)
|
|
|
|
{
|
|
|
|
int status = target_read_memory ((CORE_ADDR) address, buffer, size);
|
|
|
|
|
|
|
|
if (status != 0)
|
|
|
|
return EINVAL;
|
|
|
|
|
|
|
|
return ESUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
write_clbk (void *caller_context, void *address, void *buffer,
|
|
|
|
unsigned long size)
|
|
|
|
{
|
|
|
|
int status = target_write_memory ((CORE_ADDR) address, buffer, size);
|
|
|
|
|
|
|
|
if (status != 0)
|
|
|
|
return EINVAL;
|
|
|
|
|
|
|
|
return ESUCCESS;
|
|
|
|
}
|
|
|
|
|
2011-01-07 19:36:19 +00:00
|
|
|
/* Get integer regs. */
|
2008-10-20 15:48:17 +00:00
|
|
|
|
|
|
|
static int
|
|
|
|
get_reg_clbk(void *caller_context, pthreadDebugGetRegRtn_t regs,
|
|
|
|
pthreadDebugKId_t kernel_tid)
|
|
|
|
{
|
|
|
|
debug ("get_reg_clbk");
|
|
|
|
|
|
|
|
/* Not sure that we actually need to do anything in this callback. */
|
|
|
|
return ESUCCESS;
|
|
|
|
}
|
|
|
|
|
2011-01-07 19:36:19 +00:00
|
|
|
/* Set integer regs. */
|
2008-10-20 15:48:17 +00:00
|
|
|
|
|
|
|
static int
|
|
|
|
set_reg_clbk(void *caller_context, const pthreadDebugRegs_t *regs,
|
|
|
|
pthreadDebugKId_t kernel_tid)
|
|
|
|
{
|
|
|
|
debug ("set_reg_clbk");
|
|
|
|
|
|
|
|
/* Not sure that we actually need to do anything in this callback. */
|
|
|
|
return ESUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
output_clbk (void *caller_context, char *line)
|
|
|
|
{
|
|
|
|
printf_filtered ("%s\n", line);
|
|
|
|
return ESUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
error_clbk (void *caller_context, char *line)
|
|
|
|
{
|
|
|
|
fprintf_filtered (gdb_stderr, "%s\n", line);
|
|
|
|
return ESUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get floating-point regs. */
|
|
|
|
|
|
|
|
static int
|
|
|
|
get_fpreg_clbk (void *caller_context, pthreadDebugFregs_p fregs,
|
|
|
|
pthreadDebugKId_t kernel_tid)
|
|
|
|
{
|
|
|
|
debug ("get_fpreg_clbk");
|
|
|
|
|
|
|
|
/* Not sure that we actually need to do anything in this callback. */
|
|
|
|
return ESUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set floating-point regs. */
|
|
|
|
|
|
|
|
static int
|
|
|
|
set_fpreg_clbk (void *caller_context, const pthreadDebugFregs_t *fregs,
|
|
|
|
pthreadDebugKId_t kernel_tid)
|
|
|
|
{
|
|
|
|
debug ("set_fpreg_clbk");
|
|
|
|
|
|
|
|
/* Not sure that we actually need to do anything in this callback. */
|
|
|
|
return ESUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
malloc_clbk (void *caller_context, size_t size)
|
|
|
|
{
|
|
|
|
return xmalloc (size);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
free_clbk (void *caller_context, void *address)
|
|
|
|
{
|
|
|
|
xfree (address);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
kthdinfo_clbk (pthreadDebugClient_t caller_context,
|
|
|
|
pthreadDebugKId_t kernel_tid,
|
|
|
|
pthreadDebugKThreadInfo_p thread_info)
|
|
|
|
{
|
|
|
|
return ENOTSUP;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
speckthd_clbk (pthreadDebugClient_t caller_context,
|
|
|
|
pthreadDebugSpecialType_t type,
|
|
|
|
pthreadDebugKId_t *kernel_tid)
|
|
|
|
{
|
|
|
|
return ENOTSUP;
|
|
|
|
}
|
|
|
|
|
|
|
|
static pthreadDebugCallbacks_t debug_callbacks =
|
|
|
|
{
|
|
|
|
PTHREAD_DEBUG_VERSION,
|
|
|
|
(pthreadDebugGetMemRtn_t) read_clbk,
|
|
|
|
(pthreadDebugSetMemRtn_t) write_clbk,
|
|
|
|
suspend_clbk,
|
|
|
|
resume_clbk,
|
|
|
|
kthdinfo_clbk,
|
|
|
|
hold_clbk,
|
|
|
|
unhold_clbk,
|
|
|
|
(pthreadDebugGetFregRtn_t) get_fpreg_clbk,
|
|
|
|
(pthreadDebugSetFregRtn_t) set_fpreg_clbk,
|
|
|
|
(pthreadDebugGetRegRtn_t) get_reg_clbk,
|
|
|
|
(pthreadDebugSetRegRtn_t) set_reg_clbk,
|
|
|
|
(pthreadDebugOutputRtn_t) output_clbk,
|
|
|
|
(pthreadDebugOutputRtn_t) error_clbk,
|
|
|
|
malloc_clbk,
|
|
|
|
free_clbk,
|
|
|
|
speckthd_clbk
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Activate thread support if appropriate. Do nothing if thread
|
|
|
|
support is already active. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
enable_dec_thread (void)
|
|
|
|
{
|
use bound_minsym as result for lookup_minimal_symbol et al
This patch changes a few minimal symbol lookup functions to return a
bound_minimal_symbol rather than a pointer to the minsym. This change
helps prepare gdb for computing a minimal symbol's address at the
point of use.
Note that this changes even those functions that ostensibly search a
single objfile. That was necessary because, in fact, those functions
can search an objfile and its separate debug objfiles; and it is
important for the caller to know in which objfile the minimal symbol
was actually found.
The bulk of this patch is mechanical.
2014-02-26 Tom Tromey <tromey@redhat.com>
* ada-lang.c (ada_update_initial_language): Update.
(ada_main_name, ada_has_this_exception_support): Update.
* ada-tasks.c (ada_tasks_inferior_data_sniffer): Update.
* aix-thread.c (pdc_symbol_addrs, pd_enable): Update.
* arm-tdep.c (arm_skip_stub): Update.
* auxv.c (ld_so_xfer_auxv): Update.
* avr-tdep.c (avr_scan_prologue): Update.
* ax-gdb.c (gen_var_ref): Update.
* breakpoint.c (struct breakpoint_objfile_data)
<overlay_msym, longjmp_msym, terminate_msym, exception_msym>: Change
type to bound_minimal_symbol.
(create_overlay_event_breakpoint)
(create_longjmp_master_breakpoint)
(create_std_terminate_master_breakpoint)
(create_exception_master_breakpoint): Update.
* bsd-uthread.c (bsd_uthread_lookup_address): Update.
* c-exp.y (classify_name): Update.
* coffread.c (coff_symfile_read): Update.
* common/agent.c (agent_look_up_symbols): Update.
* d-lang.c (d_main_name): Update.
* dbxread.c (find_stab_function_addr, end_psymtab): Update.
* dec-thread.c (enable_dec_thread): Update.
* dwarf2loc.c (call_site_to_target_addr): Update.
* elfread.c (elf_gnu_ifunc_resolve_by_got): Update.
* eval.c (evaluate_subexp_standard): Update.
* findvar.c (struct minsym_lookup_data) <result>: Change type
to bound_minimal_symbol.
<objfile>: Remove.
(minsym_lookup_iterator_cb, default_read_var_value): Update.
* frame.c (inside_main_func): Update.
* frv-tdep.c (frv_frame_this_id): Update.
* gcore.c (call_target_sbrk): Update.
* glibc-tdep.c (glibc_skip_solib_resolver): Update.
* gnu-v3-abi.c (gnuv3_get_typeid, gnuv3_skip_trampoline):
Update.
* go-lang.c (go_main_name): Update.
* hppa-hpux-tdep.c (hppa_hpux_skip_trampoline_code)
(hppa_hpux_find_import_stub_for_addr): Update.
* hppa-tdep.c (hppa_extract_17, hppa_lookup_stub_minimal_symbol):
Update. Change return type.
* hppa-tdep.h (hppa_lookup_stub_minimal_symbol): Change return
type.
* jit.c (jit_breakpoint_re_set_internal): Update.
* linux-fork.c (inferior_call_waitpid, checkpoint_command):
Update.
* linux-nat.c (get_signo): Update.
* linux-thread-db.c (inferior_has_bug): Update
* m32c-tdep.c (m32c_return_value)
(m32c_m16c_address_to_pointer): Update.
* m32r-tdep.c (m32r_frame_this_id): Update.
* m68hc11-tdep.c (m68hc11_get_register_info): Update.
* machoread.c (macho_resolve_oso_sym_with_minsym): Update.
* minsyms.c (lookup_minimal_symbol_internal): Rename to
lookup_minimal_symbol. Change return type.
(lookup_minimal_symbol): Remove.
(lookup_bound_minimal_symbol): Update.
(lookup_minimal_symbol_text): Change return type.
(lookup_minimal_symbol_solib_trampoline): Change return type.
* minsyms.h (lookup_minimal_symbol, lookup_minimal_symbol_text)
(lookup_minimal_symbol_solib_trampoline): Change return type.
* mips-linux-tdep.c (mips_linux_skip_resolver): Update.
* objc-lang.c (lookup_objc_class, lookup_child_selector)
(value_nsstring, find_imps): Update.
* obsd-tdep.c (obsd_skip_solib_resolver): Update.
* p-lang.c (pascal_main_name): Update.
* ppc-linux-tdep.c (ppc_linux_spe_context_lookup): Update.
* ppc-sysv-tdep.c (convert_code_addr_to_desc_addr): Update.
* proc-service.c (ps_pglobal_lookup): Update.
* ravenscar-thread.c (get_running_thread_msymbol): Change
return type.
(has_ravenscar_runtime, get_running_thread_id): Update.
* remote.c (remote_check_symbols): Update.
* sol-thread.c (ps_pglobal_lookup): Update.
* sol2-tdep.c (sol2_skip_solib_resolver): Update.
* solib-dsbt.c (lm_base): Update.
* solib-frv.c (lm_base, frv_relocate_section_addresses):
Update.
* solib-irix.c (locate_base): Update.
* solib-som.c (som_solib_create_inferior_hook)
(som_solib_desire_dynamic_linker_symbols, link_map_start):
Update.
* solib-spu.c (spu_enable_break): Update.
* solib-svr4.c (elf_locate_base, enable_break): Update.
* spu-tdep.c (spu_get_overlay_table, spu_catch_start)
(flush_ea_cache): Update.
* stabsread.c (define_symbol): Update.
* symfile.c (simple_read_overlay_table): Update.
* symtab.c (find_pc_sect_line): Update.
* tracepoint.c (scope_info): Update.
* tui-disasm.c (tui_get_begin_asm_address): Update.
* value.c (value_static_field): Update.
2013-10-15 01:53:29 +00:00
|
|
|
struct bound_minimal_symbol msym;
|
2008-10-20 15:48:17 +00:00
|
|
|
void* caller_context;
|
|
|
|
int status;
|
|
|
|
|
|
|
|
/* If already active, nothing more to do. */
|
|
|
|
if (dec_thread_active)
|
|
|
|
return;
|
|
|
|
|
|
|
|
msym = lookup_minimal_symbol ("__pthread_dbg_symtable", NULL, NULL);
|
use bound_minsym as result for lookup_minimal_symbol et al
This patch changes a few minimal symbol lookup functions to return a
bound_minimal_symbol rather than a pointer to the minsym. This change
helps prepare gdb for computing a minimal symbol's address at the
point of use.
Note that this changes even those functions that ostensibly search a
single objfile. That was necessary because, in fact, those functions
can search an objfile and its separate debug objfiles; and it is
important for the caller to know in which objfile the minimal symbol
was actually found.
The bulk of this patch is mechanical.
2014-02-26 Tom Tromey <tromey@redhat.com>
* ada-lang.c (ada_update_initial_language): Update.
(ada_main_name, ada_has_this_exception_support): Update.
* ada-tasks.c (ada_tasks_inferior_data_sniffer): Update.
* aix-thread.c (pdc_symbol_addrs, pd_enable): Update.
* arm-tdep.c (arm_skip_stub): Update.
* auxv.c (ld_so_xfer_auxv): Update.
* avr-tdep.c (avr_scan_prologue): Update.
* ax-gdb.c (gen_var_ref): Update.
* breakpoint.c (struct breakpoint_objfile_data)
<overlay_msym, longjmp_msym, terminate_msym, exception_msym>: Change
type to bound_minimal_symbol.
(create_overlay_event_breakpoint)
(create_longjmp_master_breakpoint)
(create_std_terminate_master_breakpoint)
(create_exception_master_breakpoint): Update.
* bsd-uthread.c (bsd_uthread_lookup_address): Update.
* c-exp.y (classify_name): Update.
* coffread.c (coff_symfile_read): Update.
* common/agent.c (agent_look_up_symbols): Update.
* d-lang.c (d_main_name): Update.
* dbxread.c (find_stab_function_addr, end_psymtab): Update.
* dec-thread.c (enable_dec_thread): Update.
* dwarf2loc.c (call_site_to_target_addr): Update.
* elfread.c (elf_gnu_ifunc_resolve_by_got): Update.
* eval.c (evaluate_subexp_standard): Update.
* findvar.c (struct minsym_lookup_data) <result>: Change type
to bound_minimal_symbol.
<objfile>: Remove.
(minsym_lookup_iterator_cb, default_read_var_value): Update.
* frame.c (inside_main_func): Update.
* frv-tdep.c (frv_frame_this_id): Update.
* gcore.c (call_target_sbrk): Update.
* glibc-tdep.c (glibc_skip_solib_resolver): Update.
* gnu-v3-abi.c (gnuv3_get_typeid, gnuv3_skip_trampoline):
Update.
* go-lang.c (go_main_name): Update.
* hppa-hpux-tdep.c (hppa_hpux_skip_trampoline_code)
(hppa_hpux_find_import_stub_for_addr): Update.
* hppa-tdep.c (hppa_extract_17, hppa_lookup_stub_minimal_symbol):
Update. Change return type.
* hppa-tdep.h (hppa_lookup_stub_minimal_symbol): Change return
type.
* jit.c (jit_breakpoint_re_set_internal): Update.
* linux-fork.c (inferior_call_waitpid, checkpoint_command):
Update.
* linux-nat.c (get_signo): Update.
* linux-thread-db.c (inferior_has_bug): Update
* m32c-tdep.c (m32c_return_value)
(m32c_m16c_address_to_pointer): Update.
* m32r-tdep.c (m32r_frame_this_id): Update.
* m68hc11-tdep.c (m68hc11_get_register_info): Update.
* machoread.c (macho_resolve_oso_sym_with_minsym): Update.
* minsyms.c (lookup_minimal_symbol_internal): Rename to
lookup_minimal_symbol. Change return type.
(lookup_minimal_symbol): Remove.
(lookup_bound_minimal_symbol): Update.
(lookup_minimal_symbol_text): Change return type.
(lookup_minimal_symbol_solib_trampoline): Change return type.
* minsyms.h (lookup_minimal_symbol, lookup_minimal_symbol_text)
(lookup_minimal_symbol_solib_trampoline): Change return type.
* mips-linux-tdep.c (mips_linux_skip_resolver): Update.
* objc-lang.c (lookup_objc_class, lookup_child_selector)
(value_nsstring, find_imps): Update.
* obsd-tdep.c (obsd_skip_solib_resolver): Update.
* p-lang.c (pascal_main_name): Update.
* ppc-linux-tdep.c (ppc_linux_spe_context_lookup): Update.
* ppc-sysv-tdep.c (convert_code_addr_to_desc_addr): Update.
* proc-service.c (ps_pglobal_lookup): Update.
* ravenscar-thread.c (get_running_thread_msymbol): Change
return type.
(has_ravenscar_runtime, get_running_thread_id): Update.
* remote.c (remote_check_symbols): Update.
* sol-thread.c (ps_pglobal_lookup): Update.
* sol2-tdep.c (sol2_skip_solib_resolver): Update.
* solib-dsbt.c (lm_base): Update.
* solib-frv.c (lm_base, frv_relocate_section_addresses):
Update.
* solib-irix.c (locate_base): Update.
* solib-som.c (som_solib_create_inferior_hook)
(som_solib_desire_dynamic_linker_symbols, link_map_start):
Update.
* solib-spu.c (spu_enable_break): Update.
* solib-svr4.c (elf_locate_base, enable_break): Update.
* spu-tdep.c (spu_get_overlay_table, spu_catch_start)
(flush_ea_cache): Update.
* stabsread.c (define_symbol): Update.
* symfile.c (simple_read_overlay_table): Update.
* symtab.c (find_pc_sect_line): Update.
* tracepoint.c (scope_info): Update.
* tui-disasm.c (tui_get_begin_asm_address): Update.
* value.c (value_static_field): Update.
2013-10-15 01:53:29 +00:00
|
|
|
if (msym.minsym == NULL)
|
2008-10-20 15:48:17 +00:00
|
|
|
{
|
|
|
|
debug ("enable_dec_thread: No __pthread_dbg_symtable");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
status = pthreadDebugContextInit (&caller_context, &debug_callbacks,
|
use bound_minsym as result for lookup_minimal_symbol et al
This patch changes a few minimal symbol lookup functions to return a
bound_minimal_symbol rather than a pointer to the minsym. This change
helps prepare gdb for computing a minimal symbol's address at the
point of use.
Note that this changes even those functions that ostensibly search a
single objfile. That was necessary because, in fact, those functions
can search an objfile and its separate debug objfiles; and it is
important for the caller to know in which objfile the minimal symbol
was actually found.
The bulk of this patch is mechanical.
2014-02-26 Tom Tromey <tromey@redhat.com>
* ada-lang.c (ada_update_initial_language): Update.
(ada_main_name, ada_has_this_exception_support): Update.
* ada-tasks.c (ada_tasks_inferior_data_sniffer): Update.
* aix-thread.c (pdc_symbol_addrs, pd_enable): Update.
* arm-tdep.c (arm_skip_stub): Update.
* auxv.c (ld_so_xfer_auxv): Update.
* avr-tdep.c (avr_scan_prologue): Update.
* ax-gdb.c (gen_var_ref): Update.
* breakpoint.c (struct breakpoint_objfile_data)
<overlay_msym, longjmp_msym, terminate_msym, exception_msym>: Change
type to bound_minimal_symbol.
(create_overlay_event_breakpoint)
(create_longjmp_master_breakpoint)
(create_std_terminate_master_breakpoint)
(create_exception_master_breakpoint): Update.
* bsd-uthread.c (bsd_uthread_lookup_address): Update.
* c-exp.y (classify_name): Update.
* coffread.c (coff_symfile_read): Update.
* common/agent.c (agent_look_up_symbols): Update.
* d-lang.c (d_main_name): Update.
* dbxread.c (find_stab_function_addr, end_psymtab): Update.
* dec-thread.c (enable_dec_thread): Update.
* dwarf2loc.c (call_site_to_target_addr): Update.
* elfread.c (elf_gnu_ifunc_resolve_by_got): Update.
* eval.c (evaluate_subexp_standard): Update.
* findvar.c (struct minsym_lookup_data) <result>: Change type
to bound_minimal_symbol.
<objfile>: Remove.
(minsym_lookup_iterator_cb, default_read_var_value): Update.
* frame.c (inside_main_func): Update.
* frv-tdep.c (frv_frame_this_id): Update.
* gcore.c (call_target_sbrk): Update.
* glibc-tdep.c (glibc_skip_solib_resolver): Update.
* gnu-v3-abi.c (gnuv3_get_typeid, gnuv3_skip_trampoline):
Update.
* go-lang.c (go_main_name): Update.
* hppa-hpux-tdep.c (hppa_hpux_skip_trampoline_code)
(hppa_hpux_find_import_stub_for_addr): Update.
* hppa-tdep.c (hppa_extract_17, hppa_lookup_stub_minimal_symbol):
Update. Change return type.
* hppa-tdep.h (hppa_lookup_stub_minimal_symbol): Change return
type.
* jit.c (jit_breakpoint_re_set_internal): Update.
* linux-fork.c (inferior_call_waitpid, checkpoint_command):
Update.
* linux-nat.c (get_signo): Update.
* linux-thread-db.c (inferior_has_bug): Update
* m32c-tdep.c (m32c_return_value)
(m32c_m16c_address_to_pointer): Update.
* m32r-tdep.c (m32r_frame_this_id): Update.
* m68hc11-tdep.c (m68hc11_get_register_info): Update.
* machoread.c (macho_resolve_oso_sym_with_minsym): Update.
* minsyms.c (lookup_minimal_symbol_internal): Rename to
lookup_minimal_symbol. Change return type.
(lookup_minimal_symbol): Remove.
(lookup_bound_minimal_symbol): Update.
(lookup_minimal_symbol_text): Change return type.
(lookup_minimal_symbol_solib_trampoline): Change return type.
* minsyms.h (lookup_minimal_symbol, lookup_minimal_symbol_text)
(lookup_minimal_symbol_solib_trampoline): Change return type.
* mips-linux-tdep.c (mips_linux_skip_resolver): Update.
* objc-lang.c (lookup_objc_class, lookup_child_selector)
(value_nsstring, find_imps): Update.
* obsd-tdep.c (obsd_skip_solib_resolver): Update.
* p-lang.c (pascal_main_name): Update.
* ppc-linux-tdep.c (ppc_linux_spe_context_lookup): Update.
* ppc-sysv-tdep.c (convert_code_addr_to_desc_addr): Update.
* proc-service.c (ps_pglobal_lookup): Update.
* ravenscar-thread.c (get_running_thread_msymbol): Change
return type.
(has_ravenscar_runtime, get_running_thread_id): Update.
* remote.c (remote_check_symbols): Update.
* sol-thread.c (ps_pglobal_lookup): Update.
* sol2-tdep.c (sol2_skip_solib_resolver): Update.
* solib-dsbt.c (lm_base): Update.
* solib-frv.c (lm_base, frv_relocate_section_addresses):
Update.
* solib-irix.c (locate_base): Update.
* solib-som.c (som_solib_create_inferior_hook)
(som_solib_desire_dynamic_linker_symbols, link_map_start):
Update.
* solib-spu.c (spu_enable_break): Update.
* solib-svr4.c (elf_locate_base, enable_break): Update.
* spu-tdep.c (spu_get_overlay_table, spu_catch_start)
(flush_ea_cache): Update.
* stabsread.c (define_symbol): Update.
* symfile.c (simple_read_overlay_table): Update.
* symtab.c (find_pc_sect_line): Update.
* tracepoint.c (scope_info): Update.
* tui-disasm.c (tui_get_begin_asm_address): Update.
* value.c (value_static_field): Update.
2013-10-15 01:53:29 +00:00
|
|
|
(void *) SYMBOL_VALUE_ADDRESS (msym.minsym),
|
2008-10-20 15:48:17 +00:00
|
|
|
&debug_context);
|
|
|
|
if (status != ESUCCESS)
|
|
|
|
{
|
|
|
|
debug ("enable_dec_thread: pthreadDebugContextInit -> %d",
|
|
|
|
status);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
push_target (&dec_thread_ops);
|
|
|
|
dec_thread_active = 1;
|
|
|
|
|
|
|
|
debug ("enable_dec_thread: Thread support enabled.");
|
|
|
|
}
|
|
|
|
|
2011-01-07 19:36:19 +00:00
|
|
|
/* Deactivate thread support. Do nothing if thread support is
|
2008-10-20 15:48:17 +00:00
|
|
|
already inactive. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
disable_dec_thread (void)
|
|
|
|
{
|
|
|
|
if (!dec_thread_active)
|
|
|
|
return;
|
|
|
|
|
|
|
|
pthreadDebugContextDestroy (debug_context);
|
|
|
|
unpush_target (&dec_thread_ops);
|
|
|
|
dec_thread_active = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* A structure that contains a thread ID and is associated
|
|
|
|
pthreadDebugThreadInfo_t data. */
|
|
|
|
|
|
|
|
struct dec_thread_info
|
|
|
|
{
|
|
|
|
pthreadDebugId_t thread;
|
|
|
|
pthreadDebugThreadInfo_t info;
|
|
|
|
};
|
|
|
|
typedef struct dec_thread_info dec_thread_info_s;
|
|
|
|
|
|
|
|
/* The list of user threads. */
|
|
|
|
|
|
|
|
DEF_VEC_O (dec_thread_info_s);
|
|
|
|
VEC(dec_thread_info_s) *dec_thread_list;
|
|
|
|
|
|
|
|
/* Release the memory used by the given VECP thread list pointer.
|
|
|
|
Then set *VECP to NULL. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
free_dec_thread_info_vec (VEC(dec_thread_info_s) **vecp)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct dec_thread_info *item;
|
|
|
|
VEC(dec_thread_info_s) *vec = *vecp;
|
|
|
|
|
|
|
|
for (i = 0; VEC_iterate (dec_thread_info_s, vec, i, item); i++)
|
|
|
|
xfree (item);
|
|
|
|
VEC_free (dec_thread_info_s, vec);
|
|
|
|
*vecp = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return a thread's ptid given its associated INFO. */
|
|
|
|
|
|
|
|
static ptid_t
|
|
|
|
ptid_build_from_info (struct dec_thread_info info)
|
|
|
|
{
|
|
|
|
int pid = ptid_get_pid (inferior_ptid);
|
|
|
|
|
|
|
|
return ptid_build (pid, 0, (long) info.thread);
|
|
|
|
}
|
|
|
|
|
2010-01-14 09:26:50 +00:00
|
|
|
/* Return non-zero if PTID is still alive.
|
|
|
|
|
|
|
|
Assumes that DEC_THREAD_LIST is up to date. */
|
|
|
|
static int
|
|
|
|
dec_thread_ptid_is_alive (ptid_t ptid)
|
|
|
|
{
|
|
|
|
pthreadDebugId_t tid = ptid_get_tid (ptid);
|
|
|
|
int i;
|
|
|
|
struct dec_thread_info *info;
|
|
|
|
|
|
|
|
if (tid == 0)
|
|
|
|
/* This is the thread corresponding to the process. This ptid
|
|
|
|
is always alive until the program exits. */
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
/* Search whether an entry with the same tid exists in the dec-thread
|
|
|
|
list of threads. If it does, then the thread is still alive.
|
|
|
|
No match found means that the thread must be dead, now. */
|
|
|
|
for (i = 0; VEC_iterate (dec_thread_info_s, dec_thread_list, i, info); i++)
|
|
|
|
if (info->thread == tid)
|
|
|
|
return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-10-20 15:48:17 +00:00
|
|
|
/* Recompute the list of user threads and store the result in
|
|
|
|
DEC_THREAD_LIST. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
update_dec_thread_list (void)
|
|
|
|
{
|
|
|
|
pthreadDebugId_t thread;
|
|
|
|
pthreadDebugThreadInfo_t info;
|
|
|
|
int res;
|
|
|
|
|
|
|
|
free_dec_thread_info_vec (&dec_thread_list);
|
|
|
|
res = pthreadDebugThdSeqInit (debug_context, &thread);
|
|
|
|
while (res == ESUCCESS)
|
|
|
|
{
|
|
|
|
|
|
|
|
res = pthreadDebugThdGetInfo (debug_context, thread, &info);
|
|
|
|
if (res != ESUCCESS)
|
|
|
|
warning (_("unable to get thread info, ignoring thread %ld"),
|
|
|
|
thread);
|
|
|
|
else if (info.kind == PTHREAD_DEBUG_THD_KIND_INITIAL
|
|
|
|
|| info.kind == PTHREAD_DEBUG_THD_KIND_NORMAL)
|
|
|
|
{
|
|
|
|
struct dec_thread_info *item =
|
|
|
|
xmalloc (sizeof (struct dec_thread_info));
|
|
|
|
|
|
|
|
item->thread = thread;
|
|
|
|
item->info = info;
|
|
|
|
VEC_safe_push (dec_thread_info_s, dec_thread_list, item);
|
|
|
|
}
|
|
|
|
res = pthreadDebugThdSeqNext (debug_context, &thread);
|
|
|
|
}
|
|
|
|
pthreadDebugThdSeqDestroy (debug_context);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* A callback to count the number of threads known to GDB. */
|
|
|
|
|
|
|
|
static int
|
|
|
|
dec_thread_count_gdb_threads (struct thread_info *ignored, void *context)
|
|
|
|
{
|
|
|
|
int *count = (int *) context;
|
|
|
|
|
2010-01-14 09:26:50 +00:00
|
|
|
*count = *count + 1;
|
2008-10-20 15:48:17 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* A callback that saves the given thread INFO at the end of an
|
|
|
|
array. The end of the array is given in the CONTEXT and is
|
|
|
|
incremented once the info has been added. */
|
|
|
|
|
|
|
|
static int
|
|
|
|
dec_thread_add_gdb_thread (struct thread_info *info, void *context)
|
|
|
|
{
|
|
|
|
struct thread_info ***listp = (struct thread_info ***) context;
|
|
|
|
|
|
|
|
**listp = info;
|
2010-01-14 09:26:50 +00:00
|
|
|
*listp = *listp + 1;
|
2008-10-20 15:48:17 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-04-20 23:14:12 +00:00
|
|
|
/* Implement the find_new_thread target_ops method. */
|
2008-10-20 15:48:17 +00:00
|
|
|
|
|
|
|
static void
|
2010-04-20 23:14:12 +00:00
|
|
|
dec_thread_find_new_threads (struct target_ops *ops)
|
2008-10-20 15:48:17 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct dec_thread_info *info;
|
|
|
|
|
|
|
|
update_dec_thread_list ();
|
2010-01-14 09:26:50 +00:00
|
|
|
for (i = 0; VEC_iterate (dec_thread_info_s, dec_thread_list, i, info); i++)
|
2008-10-20 15:48:17 +00:00
|
|
|
{
|
|
|
|
ptid_t ptid = ptid_build_from_info (*info);
|
|
|
|
|
|
|
|
if (!in_thread_list (ptid))
|
|
|
|
add_thread (ptid);
|
|
|
|
}
|
2010-04-20 23:14:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Resynchronize the list of threads known by GDB with the actual
|
|
|
|
list of threads reported by libpthread_debug. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
resync_thread_list (struct target_ops *ops)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int num_gdb_threads = 0;
|
|
|
|
struct thread_info **gdb_thread_list;
|
|
|
|
struct thread_info **next_thread_info;
|
|
|
|
|
|
|
|
/* Add new threads. */
|
|
|
|
dec_thread_find_new_threads (ops);
|
2008-10-20 15:48:17 +00:00
|
|
|
|
|
|
|
/* Remove threads that no longer exist. To help with the search,
|
|
|
|
we build an array of GDB threads, and then iterate over this
|
|
|
|
array. */
|
|
|
|
|
|
|
|
iterate_over_threads (dec_thread_count_gdb_threads,
|
|
|
|
(void *) &num_gdb_threads);
|
|
|
|
gdb_thread_list = alloca (num_gdb_threads * sizeof (struct thread_info *));
|
|
|
|
next_thread_info = gdb_thread_list;
|
|
|
|
iterate_over_threads (dec_thread_add_gdb_thread, (void *) &next_thread_info);
|
|
|
|
|
2010-01-14 09:26:50 +00:00
|
|
|
for (i = 0; i < num_gdb_threads; i++)
|
|
|
|
if (!dec_thread_ptid_is_alive (gdb_thread_list[i]->ptid))
|
2008-10-20 15:48:17 +00:00
|
|
|
delete_thread (gdb_thread_list[i]->ptid);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The "to_detach" method of the dec_thread_ops. */
|
|
|
|
|
|
|
|
static void
|
constify to_detach
This patch constifies the target_ops method to_detach.
This is a small cleanup, but also, I think, a bug-prevention fix,
since gdb already acts as if the "args" argument here was const.
In particular, top.c:quit_force calls kill_or_detach via
iterate_over_inferiors. kill_or_detach calls target_detach, passing
the same argument each time. So, if one of these methods was not
const-correct, then kill_or_detach would change its behavior in a
strange way.
I could not build every target I modified in this patch. I've
inspected them all by hand, though. Many targets do not use the
"args" parameter; a couple pass it to atoi; and a few pass it on to
the to_detach method of the target beneath. The only code that
required a real change was in linux-nat.c, and that only needed the
introduction of a temporary variable for const-correctness.
2013-11-08 Tom Tromey <tromey@redhat.com>
* aix-thread.c (aix_thread_detach): Update.
* corelow.c (core_detach): Update.
* darwin-nat.c (darwin_detach): Update.
* dec-thread.c (dec_thread_detach): Update.
* gnu-nat.c (gnu_detach): Update.
* go32-nat.c (go32_detach): Update.
* inf-ptrace.c (inf_ptrace_detach): Update.
* inf-ttrace.c (inf_ttrace_detach): Update.
* linux-fork.c (linux_fork_detach): Update.
* linux-fork.h (linux_fork_detach): Update.
* linux-nat.c (linux_nat_detach): Update. Introduce "tem"
local for const-correctness.
* linux-thread-db.c (thread_db_detach): Update.
* monitor.c (monitor_detach): Update.
* nto-procfs.c (procfs_detach): Update.
* procfs.c (procfs_detach): Update.
* record.c (record_detach): Update.
* record.h (record_detach): Update.
* remote-m32r-sdi.c (m32r_detach): Update.
* remote-mips.c (mips_detach): Update.
* remote-sim.c (gdbsim_detach): Update.
* remote.c (remote_detach_1, remote_detach)
(extended_remote_detach): Update.
* sol-thread.c (sol_thread_detach): Update.
* target.c (target_detach): Make "args" const.
(init_dummy_target): Update.
* target.h (struct target_ops) <to_detach>: Make argument const.
(target_detach): Likewise.
* windows-nat.c (windows_detach): Update.
2013-03-19 15:23:17 +00:00
|
|
|
dec_thread_detach (struct target_ops *ops, const char *args, int from_tty)
|
2008-10-20 15:48:17 +00:00
|
|
|
{
|
2009-03-05 23:37:20 +00:00
|
|
|
struct target_ops *beneath = find_target_beneath (ops);
|
|
|
|
|
2008-10-20 15:48:17 +00:00
|
|
|
debug ("dec_thread_detach");
|
|
|
|
|
|
|
|
disable_dec_thread ();
|
2009-03-05 23:37:20 +00:00
|
|
|
beneath->to_detach (beneath, args, from_tty);
|
2008-10-20 15:48:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Return the ptid of the thread that is currently active. */
|
|
|
|
|
|
|
|
static ptid_t
|
|
|
|
get_active_ptid (void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct dec_thread_info *info;
|
|
|
|
|
|
|
|
for (i = 0; VEC_iterate (dec_thread_info_s, dec_thread_list, i, info);
|
|
|
|
i++)
|
|
|
|
if (info->info.state == PTHREAD_DEBUG_STATE_RUNNING)
|
|
|
|
return ptid_build_from_info (*info);
|
|
|
|
|
|
|
|
/* No active thread found. This can happen when the program
|
|
|
|
has just exited. */
|
|
|
|
return null_ptid;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The "to_wait" method of the dec_thread_ops. */
|
|
|
|
|
|
|
|
static ptid_t
|
* linux-nat.c (linux_nat_wait): Adjust.
(linux_nat_pid_to_str): Adjust. Remove call to thread_db_init.
* linux-nat.h (thread_db_init): Delete declaration.
* linux-thread-db.c (target_beneath): Delete.
(thread_db_init): Delete.
(thread_db_detach): Use find_target_beneath.
(thread_db_wait): Adjust interface. Use find_target_beneath.
(thread_db_mourn_inferior): Use find_target_beneath.
(thread_db_can_async_p, thread_db_is_async_p, thread_db_async)
(thread_db_async_mask): Delete.
(thread_db_pid_to_str): Adjust interface. Use
find_target_beneath.
(thread_db_get_thread_local_address): Adjust interface. Use
find_target_beneath.
(init_thread_db_ops): Delete references to delete functions.
* target.c (update_current_target): Don't inherit or default
to_wait. Don't inherit to_pid_to_str and
to_get_thread_local_address.
(target_translate_tls_address): Look for a pushed target that
implements to_get_thread_local_address, and use it instead of
checking for target_get_thread_local_address_p.
(target_wait, target_pid_to_str): Reimplement as functions.
(dummy_pid_to_str): New.
(init_dummy_target): Register it.
(debug_to_wait): Delete.
* target.h (struct target_ops): Make to_wait, to_pid_to_str and
to_get_thread_local_address accept a pointer to struct target_ops.
(target_wait): Delete macro, and declare as function.
(target_pid_to_str): Likewise.
(target_get_thread_local_address)
(target_get_thread_local_address_p): Delete.
(noprocess): Add NORETURN and ATTR_NORETURN tags.
* inf-ptrace.c (inf_ptrace_wait): Adjust.
(inf_ptrace_pid_to_str): New.
(inf_ptrace_target): Use inf_ptrace_pid_to_str.
* aix-thread.c (aix_thread_wait, aix_thread_pid_to_str): Adjust.
* bsd-kvm.c (bsd_kvm_pid_to_str): Adjust.
* bsd-uthread.c (bsd_uthread_wait, bsd_uthread_pid_to_str):
Adjust.
* corelow.c (core_pid_to_str): Adjust.
* darwin-nat.c (darwin_wait, darwin_pid_to_str): Adjust.
* dec-thread.c (dec_thread_wait, dec_thread_pid_to_str): Adjust.
* gnu-nat.c (gnu_wait, gnu_pid_to_str): Adjust.
* go32-nat.c (go32_wait, go32_pid_to_str): Adjust.
* hpux-thread.c (hpux_thread_wait): Adjust.
* inf-ttrace.c (inf_ttrace_wait, inf_ttrace_pid_to_str): Adjust.
* monitor.c (monitor_wait, monitor_pid_to_str): Adjust.
* nto-procfs.c (procfs_wait, procfs_pid_to_str): Adjust.
* procfs.c (procfs_pid_to_str): Adjust.
* remote-m32r-sdi.c (m32r_wait, m32r_pid_to_str): Adjust.
* remote-mips.c (mips_wait): Adjust.
* remote-sim.c (gdbsim_wait, gdbsim_pid_to_str): Adjust.
* remote.c (remote_wait, remote_pid_to_str)
(remote_get_thread_local_address): Adjust.
* rs6000-nat.c (rs6000_wait): Adjust.
* sol-thread.c (procfs_pid_to_str): Adjust declaration.
(sol_thread_wait, solaris_pid_to_str): Adjust.
* spu-linux-nat.c (spu_child_wait): Adjust.
* windows-nat.c (windows_wait, windows_pid_to_str): Adjust.
2009-02-06 22:21:26 +00:00
|
|
|
dec_thread_wait (struct target_ops *ops,
|
2009-05-21 22:53:29 +00:00
|
|
|
ptid_t ptid, struct target_waitstatus *status, int options)
|
2008-10-20 15:48:17 +00:00
|
|
|
{
|
|
|
|
ptid_t active_ptid;
|
2009-03-05 23:37:20 +00:00
|
|
|
struct target_ops *beneath = find_target_beneath (ops);
|
2008-10-20 15:48:17 +00:00
|
|
|
|
|
|
|
debug ("dec_thread_wait");
|
|
|
|
|
2009-05-21 22:53:29 +00:00
|
|
|
ptid = beneath->to_wait (beneath, ptid, status, options);
|
2008-10-20 15:48:17 +00:00
|
|
|
|
2009-03-05 23:37:20 +00:00
|
|
|
/* The ptid returned by the target beneath us is the ptid of the process.
|
|
|
|
We need to find which thread is currently active and return its ptid. */
|
2010-04-20 23:14:12 +00:00
|
|
|
resync_thread_list (ops);
|
2008-10-20 15:48:17 +00:00
|
|
|
active_ptid = get_active_ptid ();
|
|
|
|
if (ptid_equal (active_ptid, null_ptid))
|
|
|
|
return ptid;
|
|
|
|
return active_ptid;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Fetch the general purpose and floating point registers for the given
|
|
|
|
thread TID, and store the result in GREGSET and FPREGSET. Return
|
|
|
|
zero if successful. */
|
|
|
|
|
|
|
|
static int
|
|
|
|
dec_thread_get_regsets (pthreadDebugId_t tid, gdb_gregset_t *gregset,
|
|
|
|
gdb_fpregset_t *fpregset)
|
|
|
|
{
|
|
|
|
int res;
|
|
|
|
pthreadDebugRegs_t regs;
|
|
|
|
pthreadDebugFregs_t fregs;
|
|
|
|
|
|
|
|
res = pthreadDebugThdGetReg (debug_context, tid, ®s);
|
|
|
|
if (res != ESUCCESS)
|
|
|
|
{
|
2009-03-05 23:37:20 +00:00
|
|
|
debug ("dec_thread_get_regsets: pthreadDebugThdGetReg -> %d", res);
|
2008-10-20 15:48:17 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
memcpy (gregset->regs, ®s, sizeof (regs));
|
|
|
|
|
|
|
|
res = pthreadDebugThdGetFreg (debug_context, tid, &fregs);
|
|
|
|
if (res != ESUCCESS)
|
|
|
|
{
|
2009-03-05 23:37:20 +00:00
|
|
|
debug ("dec_thread_get_regsets: pthreadDebugThdGetFreg -> %d", res);
|
2008-10-20 15:48:17 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
memcpy (fpregset->regs, &fregs, sizeof (fregs));
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The "to_fetch_registers" method of the dec_thread_ops.
|
|
|
|
|
|
|
|
Because the dec-thread debug API doesn't allow us to fetch
|
|
|
|
only one register, we simply ignore regno and fetch+supply all
|
|
|
|
registers. */
|
|
|
|
|
|
|
|
static void
|
2009-03-05 23:37:20 +00:00
|
|
|
dec_thread_fetch_registers (struct target_ops *ops,
|
|
|
|
struct regcache *regcache, int regno)
|
2008-10-20 15:48:17 +00:00
|
|
|
{
|
|
|
|
pthreadDebugId_t tid = ptid_get_tid (inferior_ptid);
|
|
|
|
gregset_t gregset;
|
|
|
|
fpregset_t fpregset;
|
|
|
|
int res;
|
|
|
|
|
|
|
|
debug ("dec_thread_fetch_registers (tid=%ld, regno=%d)", tid, regno);
|
|
|
|
|
|
|
|
|
|
|
|
if (tid == 0 || ptid_equal (inferior_ptid, get_active_ptid ()))
|
|
|
|
{
|
2009-03-05 23:37:20 +00:00
|
|
|
struct target_ops *beneath = find_target_beneath (ops);
|
|
|
|
|
|
|
|
beneath->to_fetch_registers (beneath, regcache, regno);
|
2008-10-20 15:48:17 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
res = dec_thread_get_regsets (tid, &gregset, &fpregset);
|
|
|
|
if (res != 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
supply_gregset (regcache, &gregset);
|
|
|
|
supply_fpregset (regcache, &fpregset);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Store the registers given in GREGSET and FPREGSET into the associated
|
|
|
|
general purpose and floating point registers of thread TID. Return
|
|
|
|
zero if successful. */
|
|
|
|
|
|
|
|
static int
|
|
|
|
dec_thread_set_regsets (pthreadDebugId_t tid, gdb_gregset_t gregset,
|
|
|
|
gdb_fpregset_t fpregset)
|
|
|
|
{
|
|
|
|
int res;
|
|
|
|
pthreadDebugRegs_t regs;
|
|
|
|
pthreadDebugFregs_t fregs;
|
|
|
|
|
|
|
|
memcpy (®s, gregset.regs, sizeof (regs));
|
|
|
|
res = pthreadDebugThdSetReg (debug_context, tid, ®s);
|
|
|
|
if (res != ESUCCESS)
|
|
|
|
{
|
2009-03-05 23:37:20 +00:00
|
|
|
debug ("dec_thread_set_regsets: pthreadDebugThdSetReg -> %d", res);
|
2008-10-20 15:48:17 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy (&fregs, fpregset.regs, sizeof (fregs));
|
|
|
|
res = pthreadDebugThdSetFreg (debug_context, tid, &fregs);
|
|
|
|
if (res != ESUCCESS)
|
|
|
|
{
|
2009-03-05 23:37:20 +00:00
|
|
|
debug ("dec_thread_set_regsets: pthreadDebugThdSetFreg -> %d", res);
|
2008-10-20 15:48:17 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The "to_store_registers" method of the dec_thread_ops.
|
|
|
|
|
|
|
|
Because the dec-thread debug API doesn't allow us to store
|
|
|
|
just one register, we store all the registers. */
|
|
|
|
|
|
|
|
static void
|
2009-03-05 23:37:20 +00:00
|
|
|
dec_thread_store_registers (struct target_ops *ops,
|
|
|
|
struct regcache *regcache, int regno)
|
2008-10-20 15:48:17 +00:00
|
|
|
{
|
|
|
|
pthreadDebugId_t tid = ptid_get_tid (inferior_ptid);
|
|
|
|
gregset_t gregset;
|
|
|
|
fpregset_t fpregset;
|
|
|
|
int res;
|
|
|
|
|
|
|
|
debug ("dec_thread_store_registers (tid=%ld, regno=%d)", tid, regno);
|
|
|
|
|
|
|
|
if (tid == 0 || ptid_equal (inferior_ptid, get_active_ptid ()))
|
|
|
|
{
|
2009-03-05 23:37:20 +00:00
|
|
|
struct target_ops *beneath = find_target_beneath (ops);
|
|
|
|
|
|
|
|
beneath->to_store_registers (beneath, regcache, regno);
|
2008-10-20 15:48:17 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: brobecker/2008-05-28: I wonder if we could simply check
|
|
|
|
in which register set the register is and then only store the
|
|
|
|
registers for that register set, instead of storing both register
|
|
|
|
sets. */
|
|
|
|
fill_gregset (regcache, &gregset, -1);
|
|
|
|
fill_fpregset (regcache, &fpregset, -1);
|
|
|
|
|
|
|
|
res = dec_thread_set_regsets (tid, gregset, fpregset);
|
|
|
|
if (res != 0)
|
|
|
|
warning (_("failed to store registers."));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The "to_mourn_inferior" method of the dec_thread_ops. */
|
|
|
|
|
|
|
|
static void
|
2009-03-05 23:37:20 +00:00
|
|
|
dec_thread_mourn_inferior (struct target_ops *ops)
|
2008-10-20 15:48:17 +00:00
|
|
|
{
|
2009-03-05 23:37:20 +00:00
|
|
|
struct target_ops *beneath = find_target_beneath (ops);
|
|
|
|
|
2008-10-20 15:48:17 +00:00
|
|
|
debug ("dec_thread_mourn_inferior");
|
|
|
|
|
|
|
|
disable_dec_thread ();
|
2009-03-05 23:37:20 +00:00
|
|
|
beneath->to_mourn_inferior (beneath);
|
2008-10-20 15:48:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* The "to_thread_alive" method of the dec_thread_ops. */
|
|
|
|
static int
|
2009-03-05 23:37:20 +00:00
|
|
|
dec_thread_thread_alive (struct target_ops *ops, ptid_t ptid)
|
2008-10-20 15:48:17 +00:00
|
|
|
{
|
|
|
|
debug ("dec_thread_thread_alive (tid=%ld)", ptid_get_tid (ptid));
|
|
|
|
|
|
|
|
/* The thread list maintained by GDB is up to date, since we update
|
|
|
|
it everytime we stop. So check this list. */
|
|
|
|
return in_thread_list (ptid);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The "to_pid_to_str" method of the dec_thread_ops. */
|
|
|
|
|
|
|
|
static char *
|
* linux-nat.c (linux_nat_wait): Adjust.
(linux_nat_pid_to_str): Adjust. Remove call to thread_db_init.
* linux-nat.h (thread_db_init): Delete declaration.
* linux-thread-db.c (target_beneath): Delete.
(thread_db_init): Delete.
(thread_db_detach): Use find_target_beneath.
(thread_db_wait): Adjust interface. Use find_target_beneath.
(thread_db_mourn_inferior): Use find_target_beneath.
(thread_db_can_async_p, thread_db_is_async_p, thread_db_async)
(thread_db_async_mask): Delete.
(thread_db_pid_to_str): Adjust interface. Use
find_target_beneath.
(thread_db_get_thread_local_address): Adjust interface. Use
find_target_beneath.
(init_thread_db_ops): Delete references to delete functions.
* target.c (update_current_target): Don't inherit or default
to_wait. Don't inherit to_pid_to_str and
to_get_thread_local_address.
(target_translate_tls_address): Look for a pushed target that
implements to_get_thread_local_address, and use it instead of
checking for target_get_thread_local_address_p.
(target_wait, target_pid_to_str): Reimplement as functions.
(dummy_pid_to_str): New.
(init_dummy_target): Register it.
(debug_to_wait): Delete.
* target.h (struct target_ops): Make to_wait, to_pid_to_str and
to_get_thread_local_address accept a pointer to struct target_ops.
(target_wait): Delete macro, and declare as function.
(target_pid_to_str): Likewise.
(target_get_thread_local_address)
(target_get_thread_local_address_p): Delete.
(noprocess): Add NORETURN and ATTR_NORETURN tags.
* inf-ptrace.c (inf_ptrace_wait): Adjust.
(inf_ptrace_pid_to_str): New.
(inf_ptrace_target): Use inf_ptrace_pid_to_str.
* aix-thread.c (aix_thread_wait, aix_thread_pid_to_str): Adjust.
* bsd-kvm.c (bsd_kvm_pid_to_str): Adjust.
* bsd-uthread.c (bsd_uthread_wait, bsd_uthread_pid_to_str):
Adjust.
* corelow.c (core_pid_to_str): Adjust.
* darwin-nat.c (darwin_wait, darwin_pid_to_str): Adjust.
* dec-thread.c (dec_thread_wait, dec_thread_pid_to_str): Adjust.
* gnu-nat.c (gnu_wait, gnu_pid_to_str): Adjust.
* go32-nat.c (go32_wait, go32_pid_to_str): Adjust.
* hpux-thread.c (hpux_thread_wait): Adjust.
* inf-ttrace.c (inf_ttrace_wait, inf_ttrace_pid_to_str): Adjust.
* monitor.c (monitor_wait, monitor_pid_to_str): Adjust.
* nto-procfs.c (procfs_wait, procfs_pid_to_str): Adjust.
* procfs.c (procfs_pid_to_str): Adjust.
* remote-m32r-sdi.c (m32r_wait, m32r_pid_to_str): Adjust.
* remote-mips.c (mips_wait): Adjust.
* remote-sim.c (gdbsim_wait, gdbsim_pid_to_str): Adjust.
* remote.c (remote_wait, remote_pid_to_str)
(remote_get_thread_local_address): Adjust.
* rs6000-nat.c (rs6000_wait): Adjust.
* sol-thread.c (procfs_pid_to_str): Adjust declaration.
(sol_thread_wait, solaris_pid_to_str): Adjust.
* spu-linux-nat.c (spu_child_wait): Adjust.
* windows-nat.c (windows_wait, windows_pid_to_str): Adjust.
2009-02-06 22:21:26 +00:00
|
|
|
dec_thread_pid_to_str (struct target_ops *ops, ptid_t ptid)
|
2008-10-20 15:48:17 +00:00
|
|
|
{
|
|
|
|
static char *ret = NULL;
|
|
|
|
|
|
|
|
if (ptid_get_tid (ptid) == 0)
|
2009-03-05 23:37:20 +00:00
|
|
|
{
|
|
|
|
struct target_ops *beneath = find_target_beneath (ops);
|
|
|
|
|
|
|
|
return beneath->to_pid_to_str (beneath, ptid);
|
|
|
|
}
|
2008-10-20 15:48:17 +00:00
|
|
|
|
|
|
|
/* Free previous return value; a new one will be allocated by
|
|
|
|
xstrprintf(). */
|
|
|
|
xfree (ret);
|
|
|
|
|
|
|
|
ret = xstrprintf (_("Thread %ld"), ptid_get_tid (ptid));
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* A "new-objfile" observer. Used to activate/deactivate dec-thread
|
|
|
|
support. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
dec_thread_new_objfile_observer (struct objfile *objfile)
|
|
|
|
{
|
|
|
|
if (objfile != NULL)
|
|
|
|
enable_dec_thread ();
|
|
|
|
else
|
|
|
|
disable_dec_thread ();
|
|
|
|
}
|
|
|
|
|
2009-03-05 23:42:32 +00:00
|
|
|
/* The "to_get_ada_task_ptid" method of the dec_thread_ops. */
|
|
|
|
|
|
|
|
static ptid_t
|
2013-12-18 04:36:30 +00:00
|
|
|
dec_thread_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
|
2009-03-05 23:42:32 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct dec_thread_info *info;
|
|
|
|
|
2014-02-20 07:56:35 +00:00
|
|
|
debug ("dec_thread_get_ada_task_ptid (struct target_ops *self,"
|
|
|
|
" lwp=0x%lx, thread=0x%lx)",
|
2009-03-05 23:42:32 +00:00
|
|
|
lwp, thread);
|
|
|
|
|
|
|
|
for (i = 0; VEC_iterate (dec_thread_info_s, dec_thread_list, i, info);
|
|
|
|
i++)
|
|
|
|
if (info->info.teb == (pthread_t) thread)
|
|
|
|
return ptid_build_from_info (*info);
|
2014-02-20 07:56:35 +00:00
|
|
|
|
2011-03-16 17:59:03 +00:00
|
|
|
warning (_("Could not find thread id from THREAD = 0x%lx"), thread);
|
2009-03-05 23:42:32 +00:00
|
|
|
return inferior_ptid;
|
|
|
|
}
|
|
|
|
|
2008-10-20 15:48:17 +00:00
|
|
|
static void
|
|
|
|
init_dec_thread_ops (void)
|
|
|
|
{
|
|
|
|
dec_thread_ops.to_shortname = "dec-threads";
|
|
|
|
dec_thread_ops.to_longname = _("DEC threads support");
|
|
|
|
dec_thread_ops.to_doc = _("DEC threads support");
|
|
|
|
dec_thread_ops.to_detach = dec_thread_detach;
|
|
|
|
dec_thread_ops.to_wait = dec_thread_wait;
|
|
|
|
dec_thread_ops.to_fetch_registers = dec_thread_fetch_registers;
|
|
|
|
dec_thread_ops.to_store_registers = dec_thread_store_registers;
|
|
|
|
dec_thread_ops.to_mourn_inferior = dec_thread_mourn_inferior;
|
|
|
|
dec_thread_ops.to_thread_alive = dec_thread_thread_alive;
|
2010-04-20 23:14:12 +00:00
|
|
|
dec_thread_ops.to_find_new_threads = dec_thread_find_new_threads;
|
2008-10-20 15:48:17 +00:00
|
|
|
dec_thread_ops.to_pid_to_str = dec_thread_pid_to_str;
|
|
|
|
dec_thread_ops.to_stratum = thread_stratum;
|
2009-03-05 23:42:32 +00:00
|
|
|
dec_thread_ops.to_get_ada_task_ptid = dec_thread_get_ada_task_ptid;
|
2008-10-20 15:48:17 +00:00
|
|
|
dec_thread_ops.to_magic = OPS_MAGIC;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_initialize_dec_thread (void)
|
|
|
|
{
|
|
|
|
init_dec_thread_ops ();
|
2013-08-05 16:54:27 +00:00
|
|
|
complete_target_initialization (&dec_thread_ops);
|
2008-10-20 15:48:17 +00:00
|
|
|
|
|
|
|
observer_attach_new_objfile (dec_thread_new_objfile_observer);
|
|
|
|
|
|
|
|
add_setshow_boolean_cmd ("dec-thread", class_maintenance, &debug_dec_thread,
|
|
|
|
_("Set debugging of DEC threads module."),
|
|
|
|
_("Show debugging of DEC threads module."),
|
|
|
|
_("Enables debugging output (used to debug GDB)."),
|
|
|
|
NULL, NULL,
|
|
|
|
&setdebuglist, &showdebuglist);
|
|
|
|
}
|