blob: eb3721ee4a059dd2a810e241db4a4be3c7ff8310 [file] [log] [blame]
# Copyright 2024-2025 Free Software Foundation, Inc.
# 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.
# Using different compilation/linking scenarios, attempt to access
# thread-local variables in a non-threaded program using multiple
# shared objects.
source $srcdir/$subdir/tls-common.exp.tcl
standard_testfile
set lib1src "${srcdir}/${subdir}/${testfile}1.c"
set lib2src "${srcdir}/${subdir}/${testfile}2.c"
set lib3src "${srcdir}/${subdir}/${testfile}3.c"
set lib1obj [standard_output_file "${testfile}1-lib.so"]
set lib2obj [standard_output_file "${testfile}2-lib.so"]
set lib3obj [standard_output_file "${testfile}3-lib.so"]
proc do_tests {force_internal_tls {do_kfail_tls_access 0}} {
clean_restart
gdb_load $::binfile
if ![runto_main] {
return
}
if $force_internal_tls {
gdb_test_no_output "maint set force-internal-tls-address-lookup on"
}
if { $do_kfail_tls_access && [istarget "*-*-linux*"] } {
# Turn off do_kfail_tls_access when libthread_db is loaded.
# This can happen for the default case when testing x86_64
# w/ -m32 using glibc versions 2.34 or newer.
gdb_test_multiple "maint check libthread-db" "Check for loaded libthread_db" {
-re -wrap "libthread_db integrity checks passed." {
set do_kfail_tls_access 0
pass $gdb_test_name
}
-re -wrap "No libthread_db loaded" {
pass $gdb_test_name
}
}
# Also turn off do_kfail_tls_access when connected to a
# gdbserver and we observe that accessing a TLS variable
# works.
if [target_is_gdbserver] {
gdb_test_multiple "print tls_main_tbss_1" \
"Check TLS accessibility when connected to a gdbserver" {
-re -wrap "= 0" {
set do_kfail_tls_access 0
pass $gdb_test_name
}
-re -wrap "Remote target failed to process qGetTLSAddr request" {
pass $gdb_test_name
}
}
}
}
gdb_breakpoint [gdb_get_line_number "main-breakpoint-1"]
gdb_continue_to_breakpoint "main-breakpoint-1"
set t $do_kfail_tls_access
set m "tls not available"
with_test_prefix "before assignments" {
gdb_test_with_kfail "print tls_main_tbss_1" ".* = 0" $t $m
gdb_test_with_kfail "print tls_main_tbss_2" ".* = 0" $t $m
gdb_test_with_kfail "print tls_main_tdata_1" ".* = 96" $t $m
gdb_test_with_kfail "print tls_main_tdata_2" ".* = 97" $t $m
gdb_test_with_kfail "print tls_lib1_tbss_1" ".* = 0" $t $m
gdb_test_with_kfail "print tls_lib1_tbss_2" ".* = 0" $t $m
gdb_test_with_kfail "print tls_lib1_tdata_1" ".* = 196" $t $m
gdb_test_with_kfail "print tls_lib1_tdata_2" ".* = 197" $t $m
gdb_test_with_kfail "print tls_lib2_tbss_1" ".* = 0" $t $m
gdb_test_with_kfail "print tls_lib2_tbss_2" ".* = 0" $t $m
gdb_test_with_kfail "print tls_lib2_tdata_1" ".* = 296" $t $m
gdb_test_with_kfail "print tls_lib2_tdata_2" ".* = 297" $t $m
gdb_test_with_kfail "print tls_lib3_tbss_1" ".* = 0" $t $m
gdb_test_with_kfail "print tls_lib3_tbss_2" ".* = 0" $t $m
gdb_test_with_kfail "print tls_lib3_tdata_1" ".* = 396" $t $m
gdb_test_with_kfail "print tls_lib3_tdata_2" ".* = 397" $t $m
}
gdb_breakpoint [gdb_get_line_number "main-breakpoint-2"]
gdb_continue_to_breakpoint "main-breakpoint-2"
with_test_prefix "after assignments" {
gdb_test_with_kfail "print tls_main_tbss_1" ".* = 51" $t $m
gdb_test_with_kfail "print tls_main_tbss_2" ".* = 52" $t $m
gdb_test_with_kfail "print tls_main_tdata_1" ".* = 53" $t $m
gdb_test_with_kfail "print tls_main_tdata_2" ".* = 54" $t $m
gdb_test_with_kfail "print tls_lib1_tbss_1" ".* = 151" $t $m
gdb_test_with_kfail "print tls_lib1_tbss_2" ".* = 152" $t $m
gdb_test_with_kfail "print tls_lib1_tdata_1" ".* = 153" $t $m
gdb_test_with_kfail "print tls_lib1_tdata_2" ".* = 154" $t $m
gdb_test_with_kfail "print tls_lib2_tbss_1" ".* = 251" $t $m
gdb_test_with_kfail "print tls_lib2_tbss_2" ".* = 252" $t $m
gdb_test_with_kfail "print tls_lib2_tdata_1" ".* = 253" $t $m
gdb_test_with_kfail "print tls_lib2_tdata_2" ".* = 254" $t $m
gdb_test_with_kfail "print tls_lib3_tbss_1" ".* = 351" $t $m
gdb_test_with_kfail "print tls_lib3_tbss_2" ".* = 352" $t $m
gdb_test_with_kfail "print tls_lib3_tdata_1" ".* = 353" $t $m
gdb_test_with_kfail "print tls_lib3_tdata_2" ".* = 354" $t $m
}
set corefile ${::binfile}.core
set core_supported 0
if { ![is_remote host] } {
set core_supported [gdb_gcore_cmd $corefile "save corefile"]
}
# Finish test early if no core file was made.
if !$core_supported {
return
}
clean_restart
gdb_load $::binfile
set core_loaded [gdb_core_cmd $corefile "load corefile"]
if { $core_loaded == -1 } {
return
}
with_test_prefix "core file" {
if $force_internal_tls {
gdb_test_no_output "maint set force-internal-tls-address-lookup on"
}
gdb_test_with_kfail "print tls_main_tbss_1" ".* = 51" $t $m
gdb_test_with_kfail "print tls_main_tbss_2" ".* = 52" $t $m
gdb_test_with_kfail "print tls_main_tdata_1" ".* = 53" $t $m
gdb_test_with_kfail "print tls_main_tdata_2" ".* = 54" $t $m
gdb_test_with_kfail "print tls_lib1_tbss_1" ".* = 151" $t $m
gdb_test_with_kfail "print tls_lib1_tbss_2" ".* = 152" $t $m
gdb_test_with_kfail "print tls_lib1_tdata_1" ".* = 153" $t $m
gdb_test_with_kfail "print tls_lib1_tdata_2" ".* = 154" $t $m
gdb_test_with_kfail "print tls_lib2_tbss_1" ".* = 251" $t $m
gdb_test_with_kfail "print tls_lib2_tbss_2" ".* = 252" $t $m
gdb_test_with_kfail "print tls_lib2_tdata_1" ".* = 253" $t $m
gdb_test_with_kfail "print tls_lib2_tdata_2" ".* = 254" $t $m
gdb_test_with_kfail "print tls_lib3_tbss_1" ".* = 351" $t $m
gdb_test_with_kfail "print tls_lib3_tbss_2" ".* = 352" $t $m
gdb_test_with_kfail "print tls_lib3_tdata_1" ".* = 353" $t $m
gdb_test_with_kfail "print tls_lib3_tdata_2" ".* = 354" $t $m
}
}
if { [gdb_compile_shlib $lib1src $lib1obj {debug}] != "" } {
untested "failed to compile shared object"
return -1
}
if { [gdb_compile_shlib $lib2src $lib2obj {debug}] != "" } {
untested "failed to compile shared object"
return -1
}
if { [gdb_compile_shlib $lib3src $lib3obj {debug}] != "" } {
untested "failed to compile shared object"
return -1
}
# Certain linux target architectures implement support for internal
# TLS lookup which is used when thread stratum support (via
# libthread_db) is missing or when the linux-only GDB maintenance
# setting 'force-internal-tls-address-lookup' is 'on'. Thus for some
# of the testing scenarios, such as statically linked executables,
# this internal support will be used. Set 'do_kfail_tls_access' to 1
# for those architectures which don't implement internal tls support.
if {[istarget *-*-linux*]
&& ![is_any_target {*}$internal_tls_linux_targets]} {
set do_kfail_tls_access 1
} elseif {[istarget *-*-linux*] && [is_x86_like_target]} {
# This covers the case of x86_64 with -m32:
set do_kfail_tls_access 1
} else {
set do_kfail_tls_access 0
}
set binprefix $binfile
with_test_prefix "default" {
set binfile $binprefix-default
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \
[list debug shlib=${lib1obj} \
shlib=${lib2obj} \
shlib=${lib3obj}]] != "" } {
untested "failed to compile"
} else {
foreach_with_prefix force_internal_tls $internal_tls_iters {
# Depending on glibc version, it might not be appropriate
# for do_kfail_tls_access to be set here. That will be
# handled in 'do_tests', disabling it if necessary.
#
# Specifically, glibc versions 2.34 and later have the
# thread library (and libthread_db availability) in
# programs not linked against libpthread.so
do_tests $force_internal_tls $do_kfail_tls_access
}
}
}
with_test_prefix "pthreads" {
set binfile $binprefix-pthreads
if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \
[list debug shlib=${lib1obj} \
shlib=${lib2obj} \
shlib=${lib3obj}]] != "" } {
untested "failed to compile"
} else {
foreach_with_prefix force_internal_tls $internal_tls_iters {
do_tests $force_internal_tls
}
}
}