Support TLS variables on FreeBSD/arm.

Derive the pointer to the DTV array from the tpidruro register.
This commit is contained in:
John Baldwin
2022-05-03 16:05:10 -07:00
parent 099fbce0ac
commit 2e686a74dc

View File

@ -27,6 +27,7 @@
#include "auxv.h"
#include "fbsd-tdep.h"
#include "gdbcore.h"
#include "inferior.h"
#include "osabi.h"
#include "solib-svr4.h"
#include "trad-frame.h"
@ -226,6 +227,30 @@ arm_fbsd_core_read_description (struct gdbarch *gdbarch,
return arm_fbsd_read_description_auxv (target, tls != nullptr);
}
/* Implement the get_thread_local_address gdbarch method. */
static CORE_ADDR
arm_fbsd_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid,
CORE_ADDR lm_addr, CORE_ADDR offset)
{
arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);
struct regcache *regcache;
regcache = get_thread_arch_regcache (current_inferior ()->process_target (),
ptid, gdbarch);
target_fetch_registers (regcache, tdep->tls_regnum);
ULONGEST tpidruro;
if (regcache->cooked_read (tdep->tls_regnum, &tpidruro) != REG_VALID)
error (_("Unable to fetch %%tpidruro"));
/* %tpidruro points to the TCB whose first member is the dtv
pointer. */
CORE_ADDR dtv_addr = tpidruro;
return fbsd_get_thread_local_address (gdbarch, dtv_addr, lm_addr, offset);
}
/* Implement the 'init_osabi' method of struct gdb_osabi_handler. */
static void
@ -251,6 +276,14 @@ arm_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
(gdbarch, arm_fbsd_iterate_over_regset_sections);
set_gdbarch_core_read_description (gdbarch, arm_fbsd_core_read_description);
if (tdep->tls_regnum > 0)
{
set_gdbarch_fetch_tls_load_module_address (gdbarch,
svr4_fetch_objfile_link_map);
set_gdbarch_get_thread_local_address (gdbarch,
arm_fbsd_get_thread_local_address);
}
/* Single stepping. */
set_gdbarch_software_single_step (gdbarch, arm_software_single_step);
}