mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
This commit adds non-architecture-specific support for internal TLS address lookup for targets which register their support with the new file svr4-tls-tdep.c. By "internal", I mean support which does not rely on libthread_db. Knowledge of how to traverse TLS data structures is contained in this commit along with the next commit containing architecture specific knowledge regarding TLS offsets, registers, and such. The new function 'svr4_tls_get_thread_local_address' is a gdbarch method. It should be passed as an argument to set_gdbarch_get_thread_local_address in architecture specific <arch>-linux-tdep.c files which wish to offer internal TLS support. The architecture specific tdep files need to define a get_tls_dtv_addr method - as the name suggests, it needs to return the address of the DTV (dynamic thread vector) via architecture specific means. This usually entails fetching the thread pointer via a register or registers assigned to this purpose, and then using that value to locate the address of the DTV from within the TCB (thread control block). Additionally, some architectures also need to provide a DTP offset, which is used by the MUSL C library to adjust the value obtained from a DTV entry to that of the start of the TLS block for a particular thread. This is provided, when necessary, by a get_tls_dtp_offset method. Both methods, get_tls_dtv_addr and get_tls_dtp_offset, are registered with data structures maintained by linux-tdep.c via the new function svr4_tls_register_tls_methods(). Thus, for example, on RISC-V, riscv_linux_init_abi() will make the following two calls, the first for registering the internal get_thread_local_address gdbarch method and the second for registering riscv-specific methods for obtaining the DTV address and DTP offset: set_gdbarch_get_thread_local_address (gdbarch, svr4_tls_get_thread_local_address); svr4_tls_register_tls_methods (info, gdbarch, riscv_linux_get_tls_dtv_addr, riscv_linux_get_tls_dtp_offset); Internal TLS support is provided for two C libraries, GLIBC, and MUSL. Details for accessing the various TLS data structures differ between these libraries. As a consequence, linux-tdep.h defines a new enum, svr4_tls_libc, with values svr4_tls_libc_unknown, svr4_tls_libc_musl, and svr4_tls_libc_glibc. A new static function libc_tls_sniffer uses heuristics to (try to) decide whether a program was linked against GLIBC or MUSL. Working out what the heuristics should be, especially for statically linked binaries, turned out to be harder than I thought it would be. A new maintenance setting, force-internal-tls-address-lookup, has been added, which, when set to 'on', will (as the name suggests) force the internal TLS lookup mechanisms to be used. Otherwise, if thread_db support is available (via the thread stratum), that will be preferred since it should be more accurate. I expect that this setting will be mostly used by test cases in the GDB test suite. The new test cases that are part of this series all use it, with iterations using both 'on' and 'off' for all of the tests therein. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=24548 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31563 Tested-By: Luis Machado <luis.machado@arm.com> Approved-By: Luis Machado <luis.machado@arm.com>
60 lines
2.0 KiB
C
60 lines
2.0 KiB
C
/* Target-dependent code for GNU/Linux, architecture independent.
|
|
|
|
Copyright (C) 2025 Free Software Foundation, Inc.
|
|
|
|
This file is part of GDB.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
#ifndef GDB_SVR4_TLS_TDEP_H
|
|
#define GDB_SVR4_TLS_TDEP_H
|
|
|
|
/* C library variants for TLS lookup. */
|
|
|
|
enum svr4_tls_libc
|
|
{
|
|
svr4_tls_libc_unknown,
|
|
svr4_tls_libc_musl,
|
|
svr4_tls_libc_glibc
|
|
};
|
|
|
|
/* Function type for "get_tls_dtv_addr" method. */
|
|
|
|
typedef CORE_ADDR (get_tls_dtv_addr_ftype) (struct gdbarch *gdbarch,
|
|
ptid_t ptid,
|
|
enum svr4_tls_libc libc);
|
|
|
|
/* Function type for "get_tls_dtp_offset" method. */
|
|
|
|
typedef CORE_ADDR (get_tls_dtp_offset_ftype) (struct gdbarch *gdbarch,
|
|
ptid_t ptid,
|
|
enum svr4_tls_libc libc);
|
|
|
|
/* Register architecture specific methods for fetching the TLS DTV
|
|
and TLS DTP, used by linux_get_thread_local_address. */
|
|
|
|
extern void svr4_tls_register_tls_methods
|
|
(struct gdbarch_info info, struct gdbarch *gdbarch,
|
|
get_tls_dtv_addr_ftype *get_tls_dtv_addr,
|
|
get_tls_dtp_offset_ftype *get_tls_dtp_offset = nullptr);
|
|
|
|
/* Used as a gdbarch method for get_thread_local_address when the tdep
|
|
file also defines a suitable method for obtaining the TLS DTV.
|
|
See linux_init_abi(), above. */
|
|
CORE_ADDR
|
|
svr4_tls_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid,
|
|
CORE_ADDR lm_addr, CORE_ADDR offset);
|
|
|
|
#endif /* GDB_SVR4_TLS_TDEP_H */
|