aboutsummaryrefslogtreecommitdiff
path: root/gdb/i386-fbsd-tdep.c
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2019-03-12 13:39:02 -0700
committerJohn Baldwin <jhb@FreeBSD.org>2019-03-12 13:45:48 -0700
commitce25aa57a3cdd028be5868423e6e55506ccd1053 (patch)
treed72c8af64c8d5538ad2a82dcaebacfcab3ec3dbb /gdb/i386-fbsd-tdep.c
parentf5424cfa7e9337a6cb02a1f83c9feea0995c5350 (diff)
downloadgdb-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/i386-fbsd-tdep.c')
-rw-r--r--gdb/i386-fbsd-tdep.c29
1 files changed, 29 insertions, 0 deletions
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