[PATCH 0/9] Support for thread-local variables on FreeBSD

John Baldwin
2019-01-22T18:43:46Z

This series adds support for thread-local variables on a few FreeBSD
architectures. Unlike other platforms, this patch series does not
rely on libthread_db but uses a different approach. It instead relies
on an architecture-specific method to locate an individual thread's
DTV array of TLS block pointers. The code to locate the specific TLS
block for an object file is shared in a helper function (patch 5) that
the per-architecture methods invoke after locating the DTV array.
Unlike the libthread_db approach, this permits examining TLS variables
of single-threaded variables and supports arbitrary cross debugging
(subject to the relevant registers being available from a core dump).
This did require introducing a new gdbarch method to resolve a TLS
variable address used instead of a target method (patch 4).

For FreeBSD/i386, TLS variables are stored relative to the %gs segment
register. This requires access to the base address of %gs to locate
the DTV array. To facilitate this, the first two patches add support
for the %fs_base and %gs_base registers on i386. I did test this on
Linux x86-64 where it introduces no new regressions in the test suite
in my testing.

There are some limitations in the FreeBSD TLS support:

1) FreeBSD/amd64 and FreeBSD/i386 do not currently include the
%fs_base and %gs_base registers in core dumps, so TLS only works
for "live" processes currently.

2) TLS variables in the executable didn't work for me on FreeBSD/riscv,
but this appears to be a compiler bug as the variable did not have
a valid DW_at_location in the dwarf info. TLS variables in libc
worked fine both live and with core dumps.

3) For FreeBSD/powerpc, I was only able to test powerpc64 using a
cross-debugger on amd64.

John Baldwin (9):
Support the fs_base and gs_base registers on i386.
Support fs_base and gs_base on FreeBSD/i386.
Handle TLS variable lookups when using separate debug object files.
Add a new gdbarch method to resolve the address of TLS variables.
Add a helper function to resolve TLS variable addresses for FreeBSD.
Support TLS variables on FreeBSD/amd64.
Support TLS variables on FreeBSD/i386.
Support TLS variables on FreeBSD/riscv.
Support TLS variables on FreeBSD/powerpc.

gdb/ChangeLog | 96 ++++++++++++++++++
gdb/amd64-bsd-nat.c | 26 +++--
gdb/amd64-fbsd-nat.c | 4 +-
gdb/amd64-fbsd-tdep.c | 25 +++++
gdb/amd64-tdep.c | 10 +-
gdb/arch/i386.c | 6 +-
gdb/arch/i386.h | 3 +-
gdb/fbsd-tdep.c | 146 +++++++++++++++++++++++++++
gdb/fbsd-tdep.h | 10 ++
gdb/features/i386/32bit-segments.c | 15 +++
gdb/features/i386/32bit-segments.xml | 12 +++
gdb/gdbarch.c | 32 ++++++
gdb/gdbarch.h | 6 ++
gdb/gdbarch.sh | 1 +
gdb/gdbserver/ChangeLog | 8 ++
gdb/gdbserver/linux-x86-tdesc.c | 2 +-
gdb/gdbserver/lynx-i386-low.c | 2 +-
gdb/gdbserver/nto-x86-low.c | 2 +-
gdb/gdbserver/win32-i386-low.c | 2 +-
gdb/i386-bsd-nat.c | 54 ++++++++++
gdb/i386-fbsd-nat.c | 2 +-
gdb/i386-fbsd-tdep.c | 31 +++++-
gdb/i386-go32-tdep.c | 2 +-
gdb/i386-linux-tdep.c | 2 +-
gdb/i386-tdep.c | 33 ++++--
gdb/i386-tdep.h | 12 ++-
gdb/ppc-fbsd-tdep.c | 35 +++++++
gdb/riscv-fbsd-tdep.c | 27 +++++
gdb/solib-svr4.c | 5 +
gdb/target.c | 13 ++-
30 files changed, 580 insertions(+), 44 deletions(-)
create mode 100644 gdb/features/i386/32bit-segments.c
create mode 100644 gdb/features/i386/32bit-segments.xml

--
2.19.2