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 | ce25aa57a3cdd028be5868423e6e55506ccd1053 (patch) | |
tree | d72c8af64c8d5538ad2a82dcaebacfcab3ec3dbb /gdb | |
parent | f5424cfa7e9337a6cb02a1f83c9feea0995c5350 (diff) | |
download | gdb-ce25aa57a3cdd028be5868423e6e55506ccd1053.zip gdb-ce25aa57a3cdd028be5868423e6e55506ccd1053.tar.gz gdb-ce25aa57a3cdd028be5868423e6e55506ccd1053.tar.bz2 |
Support TLS variables on FreeBSD/i386.
Derive the pointer to the DTV array from the gs_base register. As
with FreeBSD/amd64, gs_base is currently only available via the native
target.
gdb/ChangeLog:
* i386-fbsd-tdep.c (i386fbsd_get_thread_local_address): New.
(i386fbsd_init_abi): Install gdbarch
"fetch_tls_load_module_address" and "get_thread_local_address"
methods.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/i386-fbsd-tdep.c | 29 |
2 files changed, 36 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2268dd2..b26f554 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,12 @@ 2019-03-12 John Baldwin <jhb@FreeBSD.org> + * i386-fbsd-tdep.c (i386fbsd_get_thread_local_address): New. + (i386fbsd_init_abi): Install gdbarch + "fetch_tls_load_module_address" and "get_thread_local_address" + methods. + +2019-03-12 John Baldwin <jhb@FreeBSD.org> + * 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" diff --git a/gdb/i386-fbsd-tdep.c b/gdb/i386-fbsd-tdep.c index ac57e73..f274847 100644 --- a/gdb/i386-fbsd-tdep.c +++ b/gdb/i386-fbsd-tdep.c @@ -320,6 +320,30 @@ i386fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch, "XSAVE extended state", cb_data); } +/* Implement the get_thread_local_address gdbarch method. */ + +static CORE_ADDR +i386fbsd_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid, + CORE_ADDR lm_addr, CORE_ADDR offset) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + struct regcache *regcache; + + if (tdep->fsbase_regnum == -1) + error (_("Unable to fetch %%gsbase")); + + regcache = get_thread_arch_regcache (ptid, gdbarch); + + target_fetch_registers (regcache, tdep->fsbase_regnum + 1); + + ULONGEST gsbase; + if (regcache->cooked_read (tdep->fsbase_regnum + 1, &gsbase) != REG_VALID) + error (_("Unable to fetch %%gsbase")); + + CORE_ADDR dtv_addr = gsbase + gdbarch_ptr_bit (gdbarch) / 8; + return fbsd_get_thread_local_address (gdbarch, dtv_addr, lm_addr, offset); +} + static void i386fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { @@ -418,6 +442,11 @@ i386fbsd4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_core_read_description (gdbarch, i386fbsd_core_read_description); + + set_gdbarch_fetch_tls_load_module_address (gdbarch, + svr4_fetch_objfile_link_map); + set_gdbarch_get_thread_local_address (gdbarch, + i386fbsd_get_thread_local_address); } void |