diff options
author | John Baldwin <jhb@FreeBSD.org> | 2019-03-12 13:39:02 -0700 |
---|---|---|
committer | John Baldwin <jhb@FreeBSD.org> | 2019-03-12 13:45:48 -0700 |
commit | f5424cfa7e9337a6cb02a1f83c9feea0995c5350 (patch) | |
tree | 56e48f7e78cd5dd52b187aa3b4153e6a5480c15d /gdb/amd64-fbsd-tdep.c | |
parent | 945f3901b5889e57edf5a2ee25acb51f0078a719 (diff) | |
download | gdb-f5424cfa7e9337a6cb02a1f83c9feea0995c5350.zip gdb-f5424cfa7e9337a6cb02a1f83c9feea0995c5350.tar.gz gdb-f5424cfa7e9337a6cb02a1f83c9feea0995c5350.tar.bz2 |
Support TLS variables on FreeBSD/amd64.
Use the fs_base register to fetch the address of a thread's tcb and
calculate the address of the DTV array. This value is then passed to
fbsd_get_thread_local_address to compute the final variable address.
Note that fs_base is currently only available via the native target as
core dumps on FreeBSD do not store the value of fs_base.
gdb/ChangeLog:
* amd64-fbsd-tdep.c (amd64fbsd_get_thread_local_address): New.
(amd64fbsd_init_abi): Install gdbarch
"fetch_tls_load_module_address" and "get_thread_local_address"
methods.
Diffstat (limited to 'gdb/amd64-fbsd-tdep.c')
-rw-r--r-- | gdb/amd64-fbsd-tdep.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/gdb/amd64-fbsd-tdep.c b/gdb/amd64-fbsd-tdep.c index 403e650..7e2e9ed 100644 --- a/gdb/amd64-fbsd-tdep.c +++ b/gdb/amd64-fbsd-tdep.c @@ -204,6 +204,26 @@ amd64fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch, &amd64fbsd_xstateregset, "XSAVE extended state", cb_data); } +/* Implement the get_thread_local_address gdbarch method. */ + +static CORE_ADDR +amd64fbsd_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid, + CORE_ADDR lm_addr, CORE_ADDR offset) +{ + struct regcache *regcache; + + regcache = get_thread_arch_regcache (ptid, gdbarch); + + target_fetch_registers (regcache, AMD64_FSBASE_REGNUM); + + ULONGEST fsbase; + if (regcache->cooked_read (AMD64_FSBASE_REGNUM, &fsbase) != REG_VALID) + error (_("Unable to fetch %%fsbase")); + + CORE_ADDR dtv_addr = fsbase + gdbarch_ptr_bit (gdbarch) / 8; + return fbsd_get_thread_local_address (gdbarch, dtv_addr, lm_addr, offset); +} + static void amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { @@ -241,6 +261,11 @@ amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* FreeBSD uses SVR4-style shared libraries. */ set_solib_svr4_fetch_link_map_offsets (gdbarch, svr4_lp64_fetch_link_map_offsets); + + set_gdbarch_fetch_tls_load_module_address (gdbarch, + svr4_fetch_objfile_link_map); + set_gdbarch_get_thread_local_address (gdbarch, + amd64fbsd_get_thread_local_address); } void |