* 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:
Daniel Jacobowitz 2006-10-17 16:02:27 +00:00
parent 5bd2f6e2a6
commit dae5f5cf4b
13 changed files with 2164 additions and 2673 deletions

View File

@ -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.

View File

@ -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"
])])

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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"

View File

@ -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

View File

@ -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
};

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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 ()
{