@@ -459,6 +459,11 @@ struct thread_info *find_thread_by_handle (struct value *thread_handle,
/* Finds the first thread of the specified inferior. */
extern struct thread_info *first_thread_of_inferior (inferior *inf);
+/* Return thread handle of type TYPE given thread THR. Returns NULL if
+ there is no handle and throw an error if there is a size mismatch. */
+struct value *thread_to_thread_handle (struct thread_info *thr,
+ struct type *type);
+
/* Find thread parent. */
struct thread_info * thread_parent (struct thread_info *thread);
@@ -105,6 +105,7 @@ public:
thread_info *thread_handle_to_thread_info (const gdb_byte *thread_handle,
int handle_len,
inferior *inf) override;
+ gdb::byte_vector thread_info_to_thread_handle (struct thread_info *) override;
};
thread_db_target::thread_db_target ()
@@ -1695,6 +1696,24 @@ thread_db_target::thread_handle_to_thread_info (const gdb_byte *thread_handle,
return NULL;
}
+/* Return the thread handle associated the thread_info pointer TP. */
+
+gdb::byte_vector
+thread_db_target::thread_info_to_thread_handle (struct thread_info *tp)
+{
+ thread_db_thread_info *priv = get_thread_db_thread_info (tp);
+
+ if (priv == NULL)
+ return gdb::byte_vector ();
+
+ int handle_size = sizeof (priv->tid);
+ gdb::byte_vector rv (handle_size);
+
+ memcpy (rv.data (), &priv->tid, handle_size);
+
+ return rv;
+}
+
/* Get the address of the thread local variable in load module LM which
is stored at OFFSET within the thread local storage for thread PTID. */
@@ -499,6 +499,9 @@ public:
int handle_len,
inferior *inf) override;
+ gdb::byte_vector thread_info_to_thread_handle (struct thread_info *tp)
+ override;
+
void stop (ptid_t) override;
void interrupt () override;
@@ -14093,6 +14096,13 @@ remote_target::thread_handle_to_thread_info (const gdb_byte *thread_handle,
return NULL;
}
+gdb::byte_vector
+remote_target::thread_info_to_thread_handle (struct thread_info *tp)
+{
+ remote_thread_info *priv = get_remote_thread_info (tp);
+ return priv->thread_handle;
+}
+
bool
remote_target::can_async_p ()
{
@@ -184,6 +184,8 @@
target_debug_do_print (host_address_to_string (X))
#define target_debug_print_thread_info_pp(X) \
target_debug_do_print (host_address_to_string (X))
+#define target_debug_print_gdb_byte_vector(X) \
+ target_debug_do_print (host_address_to_string (X.data ()))
static void
target_debug_print_struct_target_waitstatus_p (struct target_waitstatus *status)
@@ -70,6 +70,7 @@ struct dummy_target : public target_ops
const char *extra_thread_info (thread_info *arg0) override;
const char *thread_name (thread_info *arg0) override;
thread_info *thread_handle_to_thread_info (const gdb_byte *arg0, int arg1, inferior *arg2) override;
+ gdb::byte_vector thread_info_to_thread_handle (struct thread_info *arg0) override;
void stop (ptid_t arg0) override;
void interrupt () override;
void pass_ctrlc () override;
@@ -237,6 +238,7 @@ struct debug_target : public target_ops
const char *extra_thread_info (thread_info *arg0) override;
const char *thread_name (thread_info *arg0) override;
thread_info *thread_handle_to_thread_info (const gdb_byte *arg0, int arg1, inferior *arg2) override;
+ gdb::byte_vector thread_info_to_thread_handle (struct thread_info *arg0) override;
void stop (ptid_t arg0) override;
void interrupt () override;
void pass_ctrlc () override;
@@ -1858,6 +1860,32 @@ debug_target::thread_handle_to_thread_info (const gdb_byte *arg0, int arg1, infe
return result;
}
+gdb::byte_vector
+target_ops::thread_info_to_thread_handle (struct thread_info *arg0)
+{
+ return this->beneath ()->thread_info_to_thread_handle (arg0);
+}
+
+gdb::byte_vector
+dummy_target::thread_info_to_thread_handle (struct thread_info *arg0)
+{
+ return gdb::byte_vector ();
+}
+
+gdb::byte_vector
+debug_target::thread_info_to_thread_handle (struct thread_info *arg0)
+{
+ gdb::byte_vector result;
+ fprintf_unfiltered (gdb_stdlog, "-> %s->thread_info_to_thread_handle (...)\n", this->beneath ()->shortname ());
+ result = this->beneath ()->thread_info_to_thread_handle (arg0);
+ fprintf_unfiltered (gdb_stdlog, "<- %s->thread_info_to_thread_handle (", this->beneath ()->shortname ());
+ target_debug_print_struct_thread_info_p (arg0);
+ fputs_unfiltered (") = ", gdb_stdlog);
+ target_debug_print_gdb_byte_vector (result);
+ fputs_unfiltered ("\n", gdb_stdlog);
+ return result;
+}
+
void
target_ops::stop (ptid_t arg0)
{
@@ -2147,6 +2147,12 @@ target_thread_handle_to_thread_info (const gdb_byte *thread_handle,
handle_len, inf);
}
+gdb::byte_vector
+target_thread_info_to_thread_handle (struct thread_info *tip)
+{
+ return current_top_target ()->thread_info_to_thread_handle (tip);
+}
+
void
target_resume (ptid_t ptid, int step, enum gdb_signal signal)
{
@@ -658,6 +658,8 @@ struct target_ops
int,
inferior *inf)
TARGET_DEFAULT_RETURN (NULL);
+ virtual gdb::byte_vector thread_info_to_thread_handle (struct thread_info *)
+ TARGET_DEFAULT_RETURN (gdb::byte_vector ());
virtual void stop (ptid_t)
TARGET_DEFAULT_IGNORE ();
virtual void interrupt ()
@@ -1863,6 +1865,10 @@ extern const char *target_thread_name (struct thread_info *);
extern struct thread_info *target_thread_handle_to_thread_info
(const gdb_byte *thread_handle, int handle_len, struct inferior *inf);
+/* Given a thread, return the thread handle. */
+extern gdb::byte_vector target_thread_info_to_thread_handle
+ (struct thread_info *);
+
/* Attempts to find the pathname of the executable file
that was run to create a specified process.
@@ -46,6 +46,7 @@
#include <algorithm>
#include "common/gdb_optional.h"
#include "extension.h"
+#include "gdbtypes.h"
/* Definition of struct thread_info exported to gdbthread.h. */
@@ -532,6 +533,27 @@ find_thread_by_handle (struct value *thread_handle, struct inferior *inf)
inf);
}
+/* See gdbthread.h. */
+
+struct value *
+thread_to_thread_handle (struct thread_info *thr, struct type *type)
+{
+ gdb::byte_vector hv = target_thread_info_to_thread_handle (thr);
+
+ if (hv.size () == 0)
+ return NULL;
+
+ check_typedef (type);
+ if (hv.size () != TYPE_LENGTH (type))
+ error (_("Thread handle size mismatch: Expecting %d, got %zu instead"),
+ TYPE_LENGTH (type), hv.size ());
+
+ struct value *rv = allocate_value (type);
+ memcpy (value_contents_raw (rv), hv.data (), hv.size ());
+
+ return rv;
+}
+
/*
* Thread iterator function.
*