* acinclude.m4 (SRV_CHECK_TLS_GET_ADDR): New.
* configure.ac: Use it. Define HAVE_TD_THR_TLS_GET_ADDR. * config.in, configure: Regenerated. * inferiors.c (gdb_id_to_thread): New function. (gdb_id_to_thread_id): Use it. * linux-low.c (linux_target_ops): Use thread_db_get_tls_address. * linux-low.h (struct process_info): Add th member. (thread_db_get_tls_address): New prototype. * remote-utils.c (decode_address): Make non-static. * server.c (handle_query): Handle qGetTLSAddr. * server.h (gdb_id_to_thread, decode_address): New prototypes. * target.h (struct target_ops): Add get_tls_address. * thread-db.c (maybe_attach_thread): Save the thread handle. (thread_db_get_tls_address): New.
This commit is contained in:
parent
5bd2f6e2a6
commit
dae5f5cf4b
@ -1,3 +1,20 @@
|
||||
2006-10-17 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* acinclude.m4 (SRV_CHECK_TLS_GET_ADDR): New.
|
||||
* configure.ac: Use it. Define HAVE_TD_THR_TLS_GET_ADDR.
|
||||
* config.in, configure: Regenerated.
|
||||
* inferiors.c (gdb_id_to_thread): New function.
|
||||
(gdb_id_to_thread_id): Use it.
|
||||
* linux-low.c (linux_target_ops): Use thread_db_get_tls_address.
|
||||
* linux-low.h (struct process_info): Add th member.
|
||||
(thread_db_get_tls_address): New prototype.
|
||||
* remote-utils.c (decode_address): Make non-static.
|
||||
* server.c (handle_query): Handle qGetTLSAddr.
|
||||
* server.h (gdb_id_to_thread, decode_address): New prototypes.
|
||||
* target.h (struct target_ops): Add get_tls_address.
|
||||
* thread-db.c (maybe_attach_thread): Save the thread handle.
|
||||
(thread_db_get_tls_address): New.
|
||||
|
||||
2006-09-28 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* linux-low.c (PTRACE_GETSIGINFO, PTRACE_SETSIGINFO): Define.
|
||||
|
@ -41,3 +41,23 @@ AC_DEFUN([SRV_CHECK_THREAD_DB],
|
||||
])
|
||||
LIBS="$old_LIBS"
|
||||
])])
|
||||
|
||||
AC_DEFUN([SRV_CHECK_TLS_GET_ADDR],
|
||||
[AC_CACHE_CHECK([for thread_db_tls_get_addr],[srv_cv_tls_get_addr],
|
||||
[old_LIBS="$LIBS"
|
||||
LIBS="$LIBS $srv_cv_thread_db"
|
||||
AC_TRY_LINK(
|
||||
[void ps_pglobal_lookup() {}
|
||||
void ps_pdread() {}
|
||||
void ps_pdwrite() {}
|
||||
void ps_lgetregs() {}
|
||||
void ps_lsetregs() {}
|
||||
void ps_lgetfpregs() {}
|
||||
void ps_lsetfpregs() {}
|
||||
void ps_get_thread_area() {}
|
||||
void ps_getpid() {}],
|
||||
[td_thr_tls_get_addr();],
|
||||
[srv_cv_tls_get_addr=yes],
|
||||
[srv_cv_tls_get_addr=no])
|
||||
LIBS="$old_LIBS"
|
||||
])])
|
||||
|
@ -92,6 +92,9 @@
|
||||
/* Define to 1 if you have the <sys/wait.h> header file. */
|
||||
#undef HAVE_SYS_WAIT_H
|
||||
|
||||
/* Define if td_thr_tls_get_addr is available. */
|
||||
#undef HAVE_TD_THR_TLS_GET_ADDR
|
||||
|
||||
/* Define if TD_VERSION is available. */
|
||||
#undef HAVE_TD_VERSION
|
||||
|
||||
|
4658
gdb/gdbserver/configure
vendored
4658
gdb/gdbserver/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -115,6 +115,7 @@ if test "$srv_linux_thread_db" = "yes"; then
|
||||
srv_linux_thread_db=no
|
||||
else
|
||||
srv_libs="$srv_cv_thread_db"
|
||||
SRV_CHECK_TLS_GET_ADDR
|
||||
fi
|
||||
old_LDFLAGS="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS -rdynamic"
|
||||
@ -133,6 +134,10 @@ if test "$srv_linux_thread_db" = "yes"; then
|
||||
if test $gdbsrv_cv_have_td_version = yes; then
|
||||
AC_DEFINE(HAVE_TD_VERSION, 1, [Define if TD_VERSION is available.])
|
||||
fi
|
||||
|
||||
if test "$srv_cv_tls_get_addr"; then
|
||||
AC_DEFINE(HAVE_TD_THR_TLS_GET_ADDR, 1, [Define if td_thr_tls_get_addr is available.])
|
||||
fi
|
||||
fi
|
||||
|
||||
GDBSERVER_DEPFILES="$srv_regobj $srv_tgtobj $srv_thread_depfiles"
|
||||
|
@ -144,8 +144,8 @@ thread_to_gdb_id (struct thread_info *thread)
|
||||
return thread->gdb_id;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
gdb_id_to_thread_id (unsigned int gdb_id)
|
||||
struct thread_info *
|
||||
gdb_id_to_thread (unsigned int gdb_id)
|
||||
{
|
||||
struct inferior_list_entry *inf = all_threads.head;
|
||||
|
||||
@ -153,11 +153,19 @@ gdb_id_to_thread_id (unsigned int gdb_id)
|
||||
{
|
||||
struct thread_info *thread = get_thread (inf);
|
||||
if (thread->gdb_id == gdb_id)
|
||||
return inf->id;
|
||||
return thread;
|
||||
inf = inf->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
gdb_id_to_thread_id (unsigned int gdb_id)
|
||||
{
|
||||
struct thread_info *thread = gdb_id_to_thread (gdb_id);
|
||||
|
||||
return thread ? thread->entry.id : 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1652,6 +1652,13 @@ static struct target_ops linux_target_ops = {
|
||||
linux_stopped_data_address,
|
||||
#if defined(__UCLIBC__) && !defined(__UCLIBC_HAS_MMU__)
|
||||
linux_read_offsets,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
#ifdef USE_THREAD_DB
|
||||
thread_db_get_tls_address,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -18,6 +18,10 @@
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#ifdef HAVE_THREAD_DB_H
|
||||
#include <thread_db.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LINUX_REGSETS
|
||||
typedef void (*regset_fill_func) (void *);
|
||||
typedef void (*regset_store_func) (const void *);
|
||||
@ -124,6 +128,11 @@ struct process_info
|
||||
and then processed and cleared in linux_resume_one_process. */
|
||||
|
||||
struct thread_resume *resume;
|
||||
|
||||
#ifdef HAVE_THREAD_DB_H
|
||||
/* The thread handle, used for e.g. TLS access. */
|
||||
td_thrhandle_t th;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern struct inferior_list all_processes;
|
||||
@ -131,3 +140,5 @@ extern struct inferior_list all_processes;
|
||||
void linux_attach_lwp (unsigned long pid, unsigned long tid);
|
||||
|
||||
int thread_db_init (void);
|
||||
int thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset,
|
||||
CORE_ADDR load_module, CORE_ADDR *address);
|
||||
|
@ -279,7 +279,7 @@ unhexify (char *bin, const char *hex, int count)
|
||||
return i;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
decode_address (CORE_ADDR *addrp, const char *start, int len)
|
||||
{
|
||||
CORE_ADDR addr;
|
||||
|
@ -254,6 +254,65 @@ handle_query (char *own_buf, int *new_packet_len_p)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Thread-local storage support. */
|
||||
if (the_target->get_tls_address != NULL
|
||||
&& strncmp ("qGetTLSAddr:", own_buf, 12) == 0)
|
||||
{
|
||||
char *p = own_buf + 12;
|
||||
CORE_ADDR parts[3], address = 0;
|
||||
int i, err;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
char *p2;
|
||||
int len;
|
||||
|
||||
if (p == NULL)
|
||||
break;
|
||||
|
||||
p2 = strchr (p, ',');
|
||||
if (p2)
|
||||
{
|
||||
len = p2 - p;
|
||||
p2++;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = strlen (p);
|
||||
p2 = NULL;
|
||||
}
|
||||
|
||||
decode_address (&parts[i], p, len);
|
||||
p = p2;
|
||||
}
|
||||
|
||||
if (p != NULL || i < 3)
|
||||
err = 1;
|
||||
else
|
||||
{
|
||||
struct thread_info *thread = gdb_id_to_thread (parts[0]);
|
||||
|
||||
if (thread == NULL)
|
||||
err = 2;
|
||||
else
|
||||
err = the_target->get_tls_address (thread, parts[1], parts[2],
|
||||
&address);
|
||||
}
|
||||
|
||||
if (err == 0)
|
||||
{
|
||||
sprintf (own_buf, "%llx", address);
|
||||
return;
|
||||
}
|
||||
else if (err > 0)
|
||||
{
|
||||
write_enn (own_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Otherwise, pretend we do not understand this packet. */
|
||||
}
|
||||
|
||||
/* Otherwise we didn't know what packet it was. Say we didn't
|
||||
understand it. */
|
||||
own_buf[0] = 0;
|
||||
|
@ -105,6 +105,7 @@ void add_thread (unsigned long thread_id, void *target_data, unsigned int);
|
||||
unsigned int thread_id_to_gdb_id (unsigned long);
|
||||
unsigned int thread_to_gdb_id (struct thread_info *);
|
||||
unsigned long gdb_id_to_thread_id (unsigned int);
|
||||
struct thread_info *gdb_id_to_thread (unsigned int);
|
||||
void clear_inferiors (void);
|
||||
struct inferior_list_entry *find_inferior
|
||||
(struct inferior_list *,
|
||||
@ -152,6 +153,7 @@ void new_thread_notify (int id);
|
||||
void dead_thread_notify (int id);
|
||||
void prepare_resume_reply (char *buf, char status, unsigned char sig);
|
||||
|
||||
void decode_address (CORE_ADDR *addrp, const char *start, int len);
|
||||
void decode_m_packet (char *from, CORE_ADDR * mem_addr_ptr,
|
||||
unsigned int *len_ptr);
|
||||
void decode_M_packet (char *from, CORE_ADDR * mem_addr_ptr,
|
||||
|
@ -163,6 +163,15 @@ struct target_ops
|
||||
time. */
|
||||
|
||||
int (*read_offsets) (CORE_ADDR *text, CORE_ADDR *data);
|
||||
|
||||
/* Fetch the address associated with a specific thread local storage
|
||||
area, determined by the specified THREAD, OFFSET, and LOAD_MODULE.
|
||||
Stores it in *ADDRESS and returns zero on success; otherwise returns
|
||||
an error code. A return value of -1 means this system does not
|
||||
support the operation. */
|
||||
|
||||
int (*get_tls_address) (struct thread_info *thread, CORE_ADDR offset,
|
||||
CORE_ADDR load_module, CORE_ADDR *address);
|
||||
};
|
||||
|
||||
extern struct target_ops *the_target;
|
||||
|
@ -266,6 +266,7 @@ found:
|
||||
process->lwpid = ti_p->ti_lid;
|
||||
|
||||
process->thread_known = 1;
|
||||
process->th = *th_p;
|
||||
err = td_thr_event_enable (th_p, 1);
|
||||
if (err != TD_OK)
|
||||
error ("Cannot enable thread event reporting for %d: %s",
|
||||
@ -319,6 +320,33 @@ thread_db_look_up_symbols (void)
|
||||
look_up_one_symbol (*sym_list, &unused);
|
||||
}
|
||||
|
||||
int
|
||||
thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset,
|
||||
CORE_ADDR load_module, CORE_ADDR *address)
|
||||
{
|
||||
#if HAVE_TD_THR_TLS_GET_ADDR
|
||||
psaddr_t addr;
|
||||
td_err_e err;
|
||||
struct process_info *process;
|
||||
|
||||
process = get_thread_process (thread);
|
||||
if (!process->thread_known)
|
||||
return TD_NOTHR;
|
||||
|
||||
err = td_thr_tls_get_addr (&process->th, (psaddr_t) load_module, offset,
|
||||
&addr);
|
||||
if (err == TD_OK)
|
||||
{
|
||||
*address = (CORE_ADDR) addr;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return err;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
thread_db_init ()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user