[RFC] Move TLS load module addr fetching to dwarf2loc.c

Kevin Buettner
2005-03-24T19:45:55Z

This patch implements some changes required for remote TLS support.
Late last year, Andrew requested that I change the interface of
target_get_thread_local_address(). See:

http://sources.redhat.com/ml/gdb-patches/2004-12/msg00337.html

In that message, Andrew wrote:

inferior.get_thread_local_address should take the raw address (to
match the packet) and not the objfile parameter. The thread code
can then extract the necessary address and call the target vector
with it. Of course the linux nat code would also need to be
adjusted.

The patch below makes that interface change, moves the fetching of the
TLS load module from linux-thread-db.c to dwarf2loc.c, and adjusts the
various GNU/Linux targets (except for FRV) so that TLS support is enabled.
TLS support for GNU/Linux on FRV will be forthcoming -- it uses a
different shared library mechanism than the other GNU/Linux targets
and thus requires a separate patch.

Comments?

* gdbarch.sh (fetch_tls_load_module_address): New architecture method.
* gdbarch.c, gdbarch.h: Regenerate.
* dwarf2loc.c (dwarf_expr_tls_address): Fetch TLS load module
address and pass this address, instead of the objfile address, to
target_get_thread_local_address().
* linux-thread-db.c (thread_db_get_thread_local_address): Change
second parameter from type ``struct objfile *'' to CORE_ADDR. Do
not call svr4_fetch_objfile_link_map() to fetch the load module
address.
* target.h (struct target_ops): Change second parameter of
``to_get_thread_local_address'' from ``struct objfile *'' to
``CORE_ADDR''.
* alpha-linux-tdep.c (solib-svr4.h): Include.
(alpha_linux_init_abi): Register TLS load module fetcher.
* amd64-linux-tdep.c (amd64_linux_init_abi): Likewise.
* hppa-linux-tdep.c (hppa_linux_init_abi): Likewise.
* i386-linux-tdep.c (i386_linux_init_abi): Likewise.
* ia64-linux-tdep.c (solib-svr4.h): Include.
(ia64_linux_init_abi): Register TLS load module fetcher.
* m32r-linux-tdep.c (m32r_linux_init_abi): Likewise.
* m68klinux-tdep.c (m68k_linux_init_abi): Likewise.
* mips-linux-tdep.c (mips_linux_init_abi): Likewise.
* sparc-linux-tdep.c (sparc32_linux_init_abi): Likewise.
* sparc64-linux-tdep.c (solib-svr4.h): Include.
(sparc64_linux_init_abi): Register TLS load module fetcher.
* Makefile.in (alpha-linux-tdep.o, ia64-linux-tdep.o)
(sparc-linux-tdep.o): Update dependencies.

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.707
diff -u -p -r1.707 Makefile.in
--- Makefile.in 18 Mar 2005 21:03:38 -0000 1.707
+++ Makefile.in 24 Mar 2005 19:07:51 -0000
@@ -1668,7 +1668,7 @@ alphabsd-tdep.o: alphabsd-tdep.c $(defs_
alphafbsd-tdep.o: alphafbsd-tdep.c $(defs_h) $(value_h) $(osabi_h) \
$(alpha_tdep_h)
alpha-linux-tdep.o: alpha-linux-tdep.c $(defs_h) $(frame_h) $(gdb_assert_h) \
- $(osabi_h) $(alpha_tdep_h)
+ $(osabi_h) $(solib_svr4_h) $(alpha_tdep_h)
alpha-mdebug-tdep.o: alpha-mdebug-tdep.c $(defs_h) $(frame_h) \
$(frame_unwind_h) $(frame_base_h) $(symtab_h) $(gdbcore_h) \
$(block_h) $(gdb_assert_h) $(alpha_tdep_h) $(mdebugread_h)
@@ -2087,7 +2087,7 @@ ia64-linux-nat.o: ia64-linux-nat.c $(def
$(target_h) $(gdbcore_h) $(regcache_h) $(ia64_tdep_h) $(gdb_wait_h) \
$(gregset_h)
ia64-linux-tdep.o: ia64-linux-tdep.c $(defs_h) $(ia64_tdep_h) \
- $(arch_utils_h) $(gdbcore_h) $(regcache_h) $(osabi_h)
+ $(arch_utils_h) $(gdbcore_h) $(regcache_h) $(osabi_h) $(solib_svr4_h)
ia64-tdep.o: ia64-tdep.c $(defs_h) $(inferior_h) $(gdbcore_h) \
$(arch_utils_h) $(floatformat_h) $(regcache_h) $(reggroups_h) \
$(frame_h) $(frame_base_h) $(frame_unwind_h) $(doublest_h) \
@@ -2566,7 +2566,7 @@ sparc64fbsd-tdep.o: sparc64fbsd-tdep.c $
sparc64-linux-nat.o: sparc64-linux-nat.c $(defs_h) $(sparc64_tdep_h) \
$(sparc_nat_h)
sparc64-linux-tdep.o: sparc64-linux-tdep.c $(defs_h) $(gdbarch_h) $(osabi_h) \
- $(sparc64_tdep_h)
+ $(solib_svr4_h) $(sparc64_tdep_h)
sparc64-nat.o: sparc64-nat.c $(defs_h) $(gdbarch_h) $(sparc64_tdep_h) \
$(sparc_nat_h)
sparc64nbsd-nat.o: sparc64nbsd-nat.c $(defs_h) $(regcache_h) $(target_h) \
Index: alpha-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/alpha-linux-tdep.c,v
retrieving revision 1.14
diff -u -p -r1.14 alpha-linux-tdep.c
--- alpha-linux-tdep.c 1 May 2004 15:34:49 -0000 1.14
+++ alpha-linux-tdep.c 24 Mar 2005 19:07:51 -0000
@@ -22,6 +22,7 @@
#include "frame.h"
#include "gdb_assert.h"
#include "osabi.h"
+#include "solib-svr4.h"

#include "alpha-tdep.h"

@@ -140,6 +141,10 @@ alpha_linux_init_abi (struct gdbarch_inf
tdep->pc_in_sigtramp = alpha_linux_pc_in_sigtramp;
tdep->jb_pc = 2;
tdep->jb_elt_size = 8;
+
+ /* Enable TLS support. */
+ set_gdbarch_fetch_tls_load_module_address (gdbarch,
+ svr4_fetch_objfile_link_map);
}

void
Index: amd64-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/amd64-linux-tdep.c,v
retrieving revision 1.8
diff -u -p -r1.8 amd64-linux-tdep.c
--- amd64-linux-tdep.c 16 Feb 2005 02:17:02 -0000 1.8
+++ amd64-linux-tdep.c 24 Mar 2005 19:07:51 -0000
@@ -218,6 +218,10 @@ amd64_linux_init_abi (struct gdbarch_inf
/* GNU/Linux uses SVR4-style shared libraries. */
set_solib_svr4_fetch_link_map_offsets
(gdbarch, svr4_lp64_fetch_link_map_offsets);
+
+ /* Enable TLS support. */
+ set_gdbarch_fetch_tls_load_module_address (gdbarch,
+ svr4_fetch_objfile_link_map);
}
\f

Index: arm-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-linux-tdep.c,v
retrieving revision 1.44
diff -u -p -r1.44 arm-linux-tdep.c
--- arm-linux-tdep.c 7 Feb 2005 00:09:52 -0000 1.44
+++ arm-linux-tdep.c 24 Mar 2005 19:07:51 -0000
@@ -485,6 +485,10 @@ arm_linux_init_abi (struct gdbarch_info
/* Shared library handling. */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
+
+ /* Enable TLS support. */
+ set_gdbarch_fetch_tls_load_module_address (gdbarch,
+ svr4_fetch_objfile_link_map);
}

void
Index: dwarf2loc.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2loc.c,v
retrieving revision 1.25
diff -u -p -r1.25 dwarf2loc.c
--- dwarf2loc.c 20 Mar 2005 20:30:35 -0000 1.25
+++ dwarf2loc.c 24 Mar 2005 19:07:51 -0000
@@ -188,7 +188,8 @@ dwarf_expr_tls_address (void *baton, COR
struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
volatile CORE_ADDR addr = 0;

- if (target_get_thread_local_address_p ())
+ if (target_get_thread_local_address_p ()
+ && gdbarch_fetch_tls_load_module_address_p (current_gdbarch))
{
ptid_t ptid = inferior_ptid;
struct objfile *objfile = debaton->objfile;
@@ -196,7 +197,21 @@ dwarf_expr_tls_address (void *baton, COR

TRY_CATCH (ex, RETURN_MASK_ALL)
{
- addr = target_get_thread_local_address (ptid, objfile, offset);
+ CORE_ADDR lm_addr;
+
+ /* Fetch the load module address for this objfile. */
+ lm_addr = gdbarch_fetch_tls_load_module_address (current_gdbarch,
+ objfile);
+ /* If it's 0, throw the appropriate exception. */
+ if (lm_addr == 0)
+ {
+ struct exception e
+ = { RETURN_ERROR, TLS_LOAD_MODULE_NOT_FOUND_ERROR, 0 };
+
+ throw_exception (e);
+ }
+
+ addr = target_get_thread_local_address (ptid, lm_addr, offset);
}
/* If an error occurred, print TLS related messages here. Otherwise,
throw the error to some higher catcher. */
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.356
diff -u -p -r1.356 gdbarch.sh
--- gdbarch.sh 24 Feb 2005 13:51:31 -0000 1.356
+++ gdbarch.sh 24 Mar 2005 19:07:52 -0000
@@ -566,6 +566,9 @@ v:=:CORE_ADDR:decr_pc_after_break:::0:::
v:=:CORE_ADDR:deprecated_function_start_offset:::0:::0

m::void:remote_translate_xfer_address:struct regcache *regcache, CORE_ADDR gdb_addr, int gdb_len, CORE_ADDR *rem_addr, int *rem_len:regcache, gdb_addr, gdb_len, rem_addr, rem_len::generic_remote_translate_xfer_address::0
+
+# Fetch the target specific address used to represent a load module.
+F:=:CORE_ADDR:fetch_tls_load_module_address:struct objfile *objfile:objfile
#
v:=:CORE_ADDR:frame_args_skip:::0:::0
M::CORE_ADDR:unwind_pc:struct frame_info *next_frame:next_frame
Index: hppa-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/hppa-linux-tdep.c,v
retrieving revision 1.13
diff -u -p -r1.13 hppa-linux-tdep.c
--- hppa-linux-tdep.c 11 Feb 2005 04:05:50 -0000 1.13
+++ hppa-linux-tdep.c 24 Mar 2005 19:07:52 -0000
@@ -618,6 +618,10 @@ hppa_linux_init_abi (struct gdbarch_info
frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
#endif
+
+ /* Enable TLS support. */
+ set_gdbarch_fetch_tls_load_module_address (gdbarch,
+ svr4_fetch_objfile_link_map);
}

void
Index: i386-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-linux-tdep.c,v
retrieving revision 1.44
diff -u -p -r1.44 i386-linux-tdep.c
--- i386-linux-tdep.c 11 Feb 2005 04:05:51 -0000 1.44
+++ i386-linux-tdep.c 24 Mar 2005 19:07:52 -0000
@@ -437,6 +437,10 @@ i386_linux_init_abi (struct gdbarch_info
set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);

dwarf2_frame_set_signal_frame_p (gdbarch, i386_linux_dwarf_signal_frame_p);
+
+ /* Enable TLS support. */
+ set_gdbarch_fetch_tls_load_module_address (gdbarch,
+ svr4_fetch_objfile_link_map);
}

/* Provide a prototype to silence -Wmissing-prototypes. */
Index: ia64-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ia64-linux-tdep.c,v
retrieving revision 1.8
diff -u -p -r1.8 ia64-linux-tdep.c
--- ia64-linux-tdep.c 5 Jan 2005 22:51:47 -0000 1.8
+++ ia64-linux-tdep.c 24 Mar 2005 19:07:52 -0000
@@ -25,6 +25,7 @@
#include "gdbcore.h"
#include "regcache.h"
#include "osabi.h"
+#include "solib-svr4.h"

/* The sigtramp code is in a non-readable (executable-only) region
of memory called the ``gate page''. The addresses in question
@@ -124,6 +125,10 @@ ia64_linux_init_abi (struct gdbarch_info
tdep->sigcontext_register_address = ia64_linux_sigcontext_register_address;

set_gdbarch_write_pc (gdbarch, ia64_linux_write_pc);
+
+ /* Enable TLS support. */
+ set_gdbarch_fetch_tls_load_module_address (gdbarch,
+ svr4_fetch_objfile_link_map);
}

void
Index: linux-thread-db.c
===================================================================
RCS file: /cvs/src/src/gdb/linux-thread-db.c,v
retrieving revision 1.5
diff -u -p -r1.5 linux-thread-db.c
--- linux-thread-db.c 18 Mar 2005 21:03:39 -0000 1.5
+++ linux-thread-db.c 24 Mar 2005 19:07:52 -0000
@@ -1230,18 +1230,18 @@ thread_db_pid_to_str (ptid_t ptid)
return normal_pid_to_str (ptid);
}

-/* Get the address of the thread local variable in OBJFILE which is
- stored at OFFSET within the thread local storage for thread PTID. */
+/* 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. */

static CORE_ADDR
-thread_db_get_thread_local_address (ptid_t ptid, struct objfile *objfile,
+thread_db_get_thread_local_address (ptid_t ptid,
+ CORE_ADDR lm,
CORE_ADDR offset)
{
if (is_thread (ptid))
{
td_err_e err;
void *address;
- CORE_ADDR lm;
struct thread_info *thread_info;

/* glibc doesn't provide the needed interface. */
@@ -1253,17 +1253,8 @@ thread_db_get_thread_local_address (ptid
throw_exception (e);
}

- /* Get the address of the link map for this objfile. */
- lm = svr4_fetch_objfile_link_map (objfile);
-
- /* Whoops, we couldn't find one. Bail out. */
- if (!lm)
- {
- struct exception e
- = { RETURN_ERROR, TLS_LOAD_MODULE_NOT_FOUND_ERROR, 0 };
-
- throw_exception (e);
- }
+ /* Caller should have verified that lm != 0. */
+ gdb_assert (lm != 0);

/* Get info about the thread. */
thread_info = find_thread_pid (ptid);
@@ -1302,7 +1293,7 @@ thread_db_get_thread_local_address (ptid
}

if (target_beneath->to_get_thread_local_address)
- return target_beneath->to_get_thread_local_address (ptid, objfile, offset);
+ return target_beneath->to_get_thread_local_address (ptid, lm, offset);
else
{
struct exception e
Index: m32r-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/m32r-linux-tdep.c,v
retrieving revision 1.2
diff -u -p -r1.2 m32r-linux-tdep.c
--- m32r-linux-tdep.c 12 Nov 2004 01:00:41 -0000 1.2
+++ m32r-linux-tdep.c 24 Mar 2005 19:07:52 -0000
@@ -419,6 +419,10 @@ m32r_linux_init_abi (struct gdbarch_info
/* Core file support. */
set_gdbarch_regset_from_core_section
(gdbarch, m32r_linux_regset_from_core_section);
+
+ /* Enable TLS support. */
+ set_gdbarch_fetch_tls_load_module_address (gdbarch,
+ svr4_fetch_objfile_link_map);
}

/* Provide a prototype to silence -Wmissing-prototypes. */
Index: m68klinux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/m68klinux-tdep.c,v
retrieving revision 1.15
diff -u -p -r1.15 m68klinux-tdep.c
--- m68klinux-tdep.c 21 Nov 2004 01:51:16 -0000 1.15
+++ m68klinux-tdep.c 24 Mar 2005 19:07:52 -0000
@@ -306,6 +306,10 @@ m68k_linux_init_abi (struct gdbarch_info
set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);

set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
+
+ /* Enable TLS support. */
+ set_gdbarch_fetch_tls_load_module_address (gdbarch,
+ svr4_fetch_objfile_link_map);
}

void
Index: mips-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-linux-tdep.c,v
retrieving revision 1.38
diff -u -p -r1.38 mips-linux-tdep.c
--- mips-linux-tdep.c 11 Feb 2005 18:13:51 -0000 1.38
+++ mips-linux-tdep.c 24 Mar 2005 19:07:52 -0000
@@ -1195,6 +1195,10 @@ mips_linux_init_abi (struct gdbarch_info
set_gdbarch_skip_solib_resolver (gdbarch, mips_linux_skip_resolver);

set_gdbarch_software_single_step (gdbarch, mips_software_single_step);
+
+ /* Enable TLS support. */
+ set_gdbarch_fetch_tls_load_module_address (gdbarch,
+ svr4_fetch_objfile_link_map);
}

void
Index: ppc-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-linux-tdep.c,v
retrieving revision 1.72
diff -u -p -r1.72 ppc-linux-tdep.c
--- ppc-linux-tdep.c 11 Feb 2005 04:06:01 -0000 1.72
+++ ppc-linux-tdep.c 24 Mar 2005 19:07:53 -0000
@@ -1111,6 +1111,10 @@ ppc_linux_init_abi (struct gdbarch_info
tramp_frame_prepend_unwinder (gdbarch, &ppc64_linux_sighandler_tramp_frame);
}
set_gdbarch_regset_from_core_section (gdbarch, ppc_linux_regset_from_core_section);
+
+ /* Enable TLS support. */
+ set_gdbarch_fetch_tls_load_module_address (gdbarch,
+ svr4_fetch_objfile_link_map);
}

void
Index: sparc-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc-linux-tdep.c,v
retrieving revision 1.8
diff -u -p -r1.8 sparc-linux-tdep.c
--- sparc-linux-tdep.c 10 Oct 2004 17:56:12 -0000 1.8
+++ sparc-linux-tdep.c 24 Mar 2005 19:07:53 -0000
@@ -266,6 +266,10 @@ sparc32_linux_init_abi (struct gdbarch_i
set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big);

frame_unwind_append_sniffer (gdbarch, sparc32_linux_sigtramp_frame_sniffer);
+
+ /* Enable TLS support. */
+ set_gdbarch_fetch_tls_load_module_address (gdbarch,
+ svr4_fetch_objfile_link_map);
}

/* Provide a prototype to silence -Wmissing-prototypes. */
Index: sparc64-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc64-linux-tdep.c,v
retrieving revision 1.3
diff -u -p -r1.3 sparc64-linux-tdep.c
--- sparc64-linux-tdep.c 10 Oct 2004 19:50:59 -0000 1.3
+++ sparc64-linux-tdep.c 24 Mar 2005 19:07:53 -0000
@@ -22,6 +22,7 @@
#include "defs.h"
#include "gdbarch.h"
#include "osabi.h"
+#include "solib-svr4.h"

#include "sparc64-tdep.h"

@@ -35,6 +36,10 @@ sparc64_linux_init_abi (struct gdbarch_i

/* ... but doesn't have kernel-assisted single-stepping support. */
set_gdbarch_software_single_step (gdbarch, sparc_software_single_step);
+
+ /* Enable TLS support. */
+ set_gdbarch_fetch_tls_load_module_address (gdbarch,
+ svr4_fetch_objfile_link_map);
}

/* Provide a prototype to silence -Wmissing-prototypes. */
Index: target.h
===================================================================
RCS file: /cvs/src/src/gdb/target.h,v
retrieving revision 1.68
diff -u -p -r1.68 target.h
--- target.h 27 Jan 2005 20:09:10 -0000 1.68
+++ target.h 24 Mar 2005 19:07:53 -0000
@@ -411,7 +411,7 @@ struct target_ops
thread-local storage hasn't been allocated yet, this function
may return an error. */
CORE_ADDR (*to_get_thread_local_address) (ptid_t ptid,
- struct objfile *objfile,
+ CORE_ADDR load_module_addr,
CORE_ADDR offset);

/* Perform partial transfers on OBJECT. See target_read_partial