diff options
Diffstat (limited to 'gdb/testsuite/gdb.base/tls-multiobj.exp')
-rw-r--r-- | gdb/testsuite/gdb.base/tls-multiobj.exp | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.base/tls-multiobj.exp b/gdb/testsuite/gdb.base/tls-multiobj.exp new file mode 100644 index 0000000..97acb33 --- /dev/null +++ b/gdb/testsuite/gdb.base/tls-multiobj.exp @@ -0,0 +1,230 @@ +# Copyright 2024 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 $::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 $::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 + } + } +} |