mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-12-19 01:19:41 +08:00
New test - gdb.base/tls-dlobj.exp
This test exercises musl_link_map_to_tls_module_id() and glibc_link_map_to_tls_module_id(), both of which are in solib-svr4.c. Prior to writing this test, I had only written what is now named 'musl_link_map_to_tls_module_id' and it worked for both GLIBC and MUSL. Once I wrote this new test, tls-dlobj.exp, there were a number of tests which didn't work with GLIBC. This led me to write a GLIBC-specific link map to module id function, i.e, 'glibc_link_map_to_tls_module_id'. It only has one compilation scenario, in which the pthread(s) library is used - as noted in a comment, it became too much of a hassle to try to KFAIL things, though it certainly could have been done in much the same was as was done in gdb.base/multiobj.exp. It didn't seem that important to do so, however, since I believe that the other tests have adequate coverage for different compilation scenarios. Tested-By: Luis Machado <luis.machado@arm.com> Approved-By: Luis Machado <luis.machado@arm.com>
This commit is contained in:
87
gdb/testsuite/gdb.base/tls-dlobj-lib.c
Normal file
87
gdb/testsuite/gdb.base/tls-dlobj-lib.c
Normal file
@@ -0,0 +1,87 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* This program needs to be compiled with preprocessor symbol set to
|
||||
a small integer, e.g. "gcc -DN=1 ..." With N defined, the CONCAT2
|
||||
and CONCAT3 macros will construct suitable names for the global
|
||||
variables and functions. */
|
||||
|
||||
#define CONCAT2(a,b) CONCAT2_(a,b)
|
||||
#define CONCAT2_(a,b) a ## b
|
||||
|
||||
#define CONCAT3(a,b,c) CONCAT3_(a,b,c)
|
||||
#define CONCAT3_(a,b,c) a ## b ## c
|
||||
|
||||
/* For N=1, this ends up being...
|
||||
__thread int tls_lib1_tbss_1;
|
||||
__thread int tls_lib1_tbss_2;
|
||||
__thread int tls_lib1_tdata_1 = 196;
|
||||
__thread int tls_lib1_tdata_2 = 197; */
|
||||
|
||||
__thread int CONCAT3(tls_lib, N, _tbss_1);
|
||||
__thread int CONCAT3(tls_lib, N, _tbss_2);
|
||||
__thread int CONCAT3(tls_lib, N, _tdata_1) = CONCAT2(N, 96);
|
||||
__thread int CONCAT3(tls_lib, N, _tdata_2) = CONCAT2(N, 97);
|
||||
|
||||
/* Substituting for N, define function:
|
||||
|
||||
int get_tls_libN_var (int which) . */
|
||||
|
||||
int
|
||||
CONCAT3(get_tls_lib, N, _var) (int which)
|
||||
{
|
||||
switch (which)
|
||||
{
|
||||
case 0:
|
||||
return -1;
|
||||
case 1:
|
||||
return CONCAT3(tls_lib, N, _tbss_1);
|
||||
case 2:
|
||||
return CONCAT3(tls_lib, N, _tbss_2);
|
||||
case 3:
|
||||
return CONCAT3(tls_lib, N, _tdata_1);
|
||||
case 4:
|
||||
return CONCAT3(tls_lib, N, _tdata_2);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Substituting for N, define function:
|
||||
|
||||
void set_tls_libN_var (int which, int val) . */
|
||||
|
||||
void
|
||||
CONCAT3(set_tls_lib, N, _var) (int which, int val)
|
||||
{
|
||||
switch (which)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
CONCAT3(tls_lib, N, _tbss_1) = val;
|
||||
break;
|
||||
case 2:
|
||||
CONCAT3(tls_lib, N, _tbss_2) = val;
|
||||
break;
|
||||
case 3:
|
||||
CONCAT3(tls_lib, N, _tdata_1) = val;
|
||||
break;
|
||||
case 4:
|
||||
CONCAT3(tls_lib, N, _tdata_2) = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
311
gdb/testsuite/gdb.base/tls-dlobj.c
Normal file
311
gdb/testsuite/gdb.base/tls-dlobj.c
Normal file
@@ -0,0 +1,311 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef void (*setter_ftype) (int which, int val);
|
||||
|
||||
__thread int tls_main_tbss_1;
|
||||
__thread int tls_main_tbss_2;
|
||||
__thread int tls_main_tdata_1 = 96;
|
||||
__thread int tls_main_tdata_2 = 97;
|
||||
|
||||
extern void set_tls_lib10_var (int which, int val);
|
||||
extern void set_tls_lib11_var (int which, int val);
|
||||
|
||||
volatile int data;
|
||||
|
||||
static void
|
||||
set_tls_main_var (int which, int val)
|
||||
{
|
||||
switch (which)
|
||||
{
|
||||
case 1:
|
||||
tls_main_tbss_1 = val;
|
||||
break;
|
||||
case 2:
|
||||
tls_main_tbss_2 = val;
|
||||
break;
|
||||
case 3:
|
||||
tls_main_tdata_1 = val;
|
||||
break;
|
||||
case 4:
|
||||
tls_main_tdata_2 = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
use_it (int a)
|
||||
{
|
||||
data = a;
|
||||
}
|
||||
|
||||
static void *
|
||||
load_dso (char *dso_name, int n, setter_ftype *setterp)
|
||||
{
|
||||
char buf[80];
|
||||
void *sym;
|
||||
void *handle = dlopen (dso_name, RTLD_NOW | RTLD_GLOBAL);
|
||||
if (handle == NULL)
|
||||
{
|
||||
fprintf (stderr, "dlopen of DSO '%s' failed: %s\n", dso_name, dlerror ());
|
||||
exit (1);
|
||||
}
|
||||
sprintf (buf, "set_tls_lib%d_var", n);
|
||||
sym = dlsym (handle, buf);
|
||||
assert (sym != NULL);
|
||||
*setterp = sym;
|
||||
|
||||
/* Some libc implementations (for some architectures) refuse to
|
||||
initialize TLS data structures (specifically, the DTV) without
|
||||
first calling dlsym on one of the TLS symbols. */
|
||||
sprintf (buf, "tls_lib%d_tdata_1", n);
|
||||
assert (dlsym (handle, buf) != NULL);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int i, status;
|
||||
setter_ftype s0, s1, s2, s3, s4, s10, s11;
|
||||
void *h1 = load_dso (OBJ1, 1, &s1);
|
||||
void *h2 = load_dso (OBJ2, 2, &s2);
|
||||
void *h3 = load_dso (OBJ3, 3, &s3);
|
||||
void *h4 = load_dso (OBJ4, 4, &s4);
|
||||
s0 = set_tls_main_var;
|
||||
s10 = set_tls_lib10_var;
|
||||
s11 = set_tls_lib11_var;
|
||||
|
||||
use_it (0); /* main-breakpoint-1 */
|
||||
|
||||
/* Set TLS variables in main program and all libraries. */
|
||||
for (i = 1; i <= 4; i++)
|
||||
s0 (i, 10 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s1 (i, 110 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s2 (i, 210 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s3 (i, 310 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s4 (i, 410 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s10 (i, 1010 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s11 (i, 1110 + i);
|
||||
|
||||
use_it (0); /* main-breakpoint-2 */
|
||||
|
||||
/* Unload lib2 and lib3. */
|
||||
status = dlclose (h2);
|
||||
assert (status == 0);
|
||||
status = dlclose (h3);
|
||||
assert (status == 0);
|
||||
|
||||
/* Set TLS variables in main program and in libraries which are still
|
||||
loaded. */
|
||||
for (i = 1; i <= 4; i++)
|
||||
s0 (i, 20 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s1 (i, 120 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s4 (i, 420 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s10 (i, 1020 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s11 (i, 1120 + i);
|
||||
|
||||
use_it (0); /* main-breakpoint-3 */
|
||||
|
||||
/* Load lib3. */
|
||||
h3 = load_dso (OBJ3, 3, &s3);
|
||||
|
||||
/* Set TLS vars again; currently, only lib2 is not loaded. */
|
||||
for (i = 1; i <= 4; i++)
|
||||
s0 (i, 30 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s1 (i, 130 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s3 (i, 330 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s4 (i, 430 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s10 (i, 1030 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s11 (i, 1130 + i);
|
||||
|
||||
use_it (0); /* main-breakpoint-4 */
|
||||
|
||||
/* Unload lib1 and lib4; load lib2. */
|
||||
status = dlclose (h1);
|
||||
assert (status == 0);
|
||||
status = dlclose (h4);
|
||||
assert (status == 0);
|
||||
h2 = load_dso (OBJ2, 2, &s2);
|
||||
|
||||
/* Set TLS vars; currently, lib2 and lib3 are loaded,
|
||||
lib1 and lib4 are not. */
|
||||
for (i = 1; i <= 4; i++)
|
||||
s0 (i, 40 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s2 (i, 240 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s3 (i, 340 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s10 (i, 1040 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s11 (i, 1140 + i);
|
||||
|
||||
use_it (0); /* main-breakpoint-5 */
|
||||
|
||||
/* Load lib4 and lib1. Unload lib2. */
|
||||
h4 = load_dso (OBJ4, 4, &s4);
|
||||
h1 = load_dso (OBJ1, 1, &s1);
|
||||
status = dlclose (h2);
|
||||
assert (status == 0);
|
||||
|
||||
/* Set TLS vars; currently, lib1, lib3, and lib4 are loaded;
|
||||
lib2 is not loaded. */
|
||||
for (i = 1; i <= 4; i++)
|
||||
s0 (i, 50 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s1 (i, 150 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s3 (i, 350 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s4 (i, 450 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s10 (i, 1050 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s11 (i, 1150 + i);
|
||||
|
||||
use_it (0); /* main-breakpoint-6 */
|
||||
|
||||
/* Load lib2, unload lib1, lib3, and lib4; then load lib3 again. */
|
||||
h2 = load_dso (OBJ2, 2, &s2);
|
||||
status = dlclose (h1);
|
||||
assert (status == 0);
|
||||
status = dlclose (h3);
|
||||
assert (status == 0);
|
||||
status = dlclose (h4);
|
||||
assert (status == 0);
|
||||
h3 = load_dso (OBJ3, 3, &s3);
|
||||
|
||||
/* Set TLS vars; currently, lib2 and lib3 are loaded;
|
||||
lib1 and lib4 are not loaded. */
|
||||
for (i = 1; i <= 4; i++)
|
||||
s0 (i, 60 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s2 (i, 260 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s3 (i, 360 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s10 (i, 1060 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s11 (i, 1160 + i);
|
||||
|
||||
use_it (0); /* main-breakpoint-7 */
|
||||
|
||||
/* Unload lib3 and lib2, then (re)load lib4, lib3, lib2, and lib1,
|
||||
in that order. */
|
||||
status = dlclose (h3);
|
||||
assert (status == 0);
|
||||
status = dlclose (h2);
|
||||
assert (status == 0);
|
||||
h4 = load_dso (OBJ4, 4, &s4);
|
||||
h3 = load_dso (OBJ3, 3, &s3);
|
||||
h2 = load_dso (OBJ2, 2, &s2);
|
||||
h1 = load_dso (OBJ1, 1, &s1);
|
||||
|
||||
/* Set TLS vars; currently, lib1, lib2, lib3, and lib4 are all
|
||||
loaded. */
|
||||
for (i = 1; i <= 4; i++)
|
||||
s0 (i, 70 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s1 (i, 170 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s2 (i, 270 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s3 (i, 370 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s4 (i, 470 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s10 (i, 1070 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s11 (i, 1170 + i);
|
||||
|
||||
use_it (0); /* main-breakpoint-8 */
|
||||
|
||||
/* Unload lib3, lib1, and lib4. */
|
||||
status = dlclose (h3);
|
||||
assert (status == 0);
|
||||
status = dlclose (h1);
|
||||
assert (status == 0);
|
||||
status = dlclose (h4);
|
||||
assert (status == 0);
|
||||
|
||||
/* Set TLS vars; currently, lib2 is loaded; lib1, lib3, and lib4 are
|
||||
not. */
|
||||
for (i = 1; i <= 4; i++)
|
||||
s0 (i, 80 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s2 (i, 280 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s10 (i, 1080 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s11 (i, 1180 + i);
|
||||
|
||||
use_it (0); /* main-breakpoint-9 */
|
||||
|
||||
/* Load lib3, unload lib2, load lib4. */
|
||||
h3 = load_dso (OBJ3, 3, &s3);
|
||||
status = dlclose (h2);
|
||||
assert (status == 0);
|
||||
h4 = load_dso (OBJ4, 4, &s4);
|
||||
|
||||
/* Set TLS vars; currently, lib3 and lib4 are loaded; lib1 and lib2
|
||||
are not. */
|
||||
for (i = 1; i <= 4; i++)
|
||||
s0 (i, 90 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s3 (i, 390 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s4 (i, 490 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s10 (i, 1090 + i);
|
||||
for (i = 1; i <= 4; i++)
|
||||
s11 (i, 1190 + i);
|
||||
|
||||
use_it (0); /* main-breakpoint-10 */
|
||||
|
||||
/* Attempt to keep variables in the main program from being optimized
|
||||
away. */
|
||||
use_it (tls_main_tbss_1);
|
||||
use_it (tls_main_tbss_2);
|
||||
use_it (tls_main_tdata_1);
|
||||
use_it (tls_main_tdata_2);
|
||||
|
||||
use_it (100); /* main-breakpoint-last */
|
||||
|
||||
return 0;
|
||||
}
|
||||
378
gdb/testsuite/gdb.base/tls-dlobj.exp
Normal file
378
gdb/testsuite/gdb.base/tls-dlobj.exp
Normal file
@@ -0,0 +1,378 @@
|
||||
# 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.
|
||||
|
||||
# Test that the GDB-internal TLS link map to module id mapping code
|
||||
# works correctly when debugging a program which is linked against
|
||||
# shared objects and which also loads and unloads other shared objects
|
||||
# in different orders. For targets which have GDB-internal TLS
|
||||
# support, it'll check both GDB-internal TLS support as well as that
|
||||
# provided by a helper library such as libthread_db.
|
||||
|
||||
source $srcdir/$subdir/tls-common.exp.tcl
|
||||
|
||||
require allow_shlib_tests
|
||||
|
||||
standard_testfile
|
||||
|
||||
set libsrc "${srcdir}/${subdir}/${testfile}-lib.c"
|
||||
|
||||
# These will be dlopen'd:
|
||||
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"]
|
||||
set lib4obj [standard_output_file "${testfile}4-lib.so"]
|
||||
|
||||
# These will be dynamically linked with the main program:
|
||||
set lib10obj [standard_output_file "${testfile}10-lib.so"]
|
||||
set lib11obj [standard_output_file "${testfile}11-lib.so"]
|
||||
|
||||
# Due to problems with some versions of glibc, we expect some tests to
|
||||
# fail due to TLS storage not being allocated/initialized. Test
|
||||
# command CMD using regular expression RE, and use XFAIL instead of
|
||||
# FAIL when the relevant RE is matched and COND is true when evaluated
|
||||
# in the upper level.
|
||||
|
||||
proc gdb_test_with_xfail { cmd re cond} {
|
||||
gdb_test_multiple $cmd $cmd {
|
||||
-re -wrap $re {
|
||||
pass $gdb_test_name
|
||||
}
|
||||
-re -wrap "The inferior has not yet allocated storage for thread-local variables.*" {
|
||||
if [ uplevel 1 [list expr $cond]] {
|
||||
xfail $gdb_test_name
|
||||
} else {
|
||||
fail $gdb_test_name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc do_tests {force_internal_tls} {
|
||||
clean_restart $::binfile
|
||||
if ![runto_main] {
|
||||
return
|
||||
}
|
||||
|
||||
if $force_internal_tls {
|
||||
gdb_test_no_output "maint set force-internal-tls-address-lookup on"
|
||||
}
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "main-breakpoint-1"]
|
||||
gdb_continue_to_breakpoint "main-breakpoint-1"
|
||||
|
||||
with_test_prefix "before assignments" {
|
||||
gdb_test "print tls_main_tbss_1" ".* = 0"
|
||||
gdb_test "print tls_main_tbss_2" ".* = 0"
|
||||
gdb_test "print tls_main_tdata_1" ".* = 96"
|
||||
gdb_test "print tls_main_tdata_2" ".* = 97"
|
||||
|
||||
# For these tests, where we're attempting to access TLS vars
|
||||
# in a dlopen'd library, but before assignment to any of the
|
||||
# vars, so it could happen that storage hasn't been allocated
|
||||
# yet. But it might also work. (When testing against MUSL,
|
||||
# things just work; GLIBC ends to produce the TLS error.) So
|
||||
# accept either the right answer or a TLS error message.
|
||||
|
||||
set tlserr "The inferior has not yet allocated storage for thread-local variables.*"
|
||||
foreach n {1 2 3 4} {
|
||||
gdb_test "print tls_lib${n}_tbss_1" \
|
||||
"0|${tlserr}"
|
||||
gdb_test "print tls_lib${n}_tbss_2" \
|
||||
"0|${tlserr}"
|
||||
gdb_test "print tls_lib${n}_tdata_1" \
|
||||
"96|${tlserr}"
|
||||
gdb_test "print tls_lib${n}_tdata_2" \
|
||||
"97|${tlserr}"
|
||||
}
|
||||
foreach n {10 11} {
|
||||
gdb_test "print tls_lib${n}_tbss_1" ".* = 0"
|
||||
gdb_test "print tls_lib${n}_tbss_2" ".* = 0"
|
||||
gdb_test "print tls_lib${n}_tdata_1" ".* = ${n}96"
|
||||
gdb_test "print tls_lib${n}_tdata_2" ".* = ${n}97"
|
||||
}
|
||||
}
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "main-breakpoint-2"]
|
||||
gdb_continue_to_breakpoint "main-breakpoint-2"
|
||||
|
||||
with_test_prefix "at main-breakpoint-2" {
|
||||
gdb_test "print tls_main_tbss_1" ".* = 11"
|
||||
gdb_test "print tls_main_tbss_2" ".* = 12"
|
||||
gdb_test "print tls_main_tdata_1" ".* = 13"
|
||||
gdb_test "print tls_main_tdata_2" ".* = 14"
|
||||
|
||||
foreach n {1 2 3 4 10 11} {
|
||||
gdb_test "print tls_lib${n}_tbss_1" ".* = ${n}11"
|
||||
gdb_test "print tls_lib${n}_tbss_2" ".* = ${n}12"
|
||||
gdb_test "print tls_lib${n}_tdata_1" ".* = ${n}13"
|
||||
gdb_test "print tls_lib${n}_tdata_2" ".* = ${n}14"
|
||||
}
|
||||
}
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "main-breakpoint-3"]
|
||||
gdb_continue_to_breakpoint "main-breakpoint-3"
|
||||
|
||||
# At this point lib2 and lib3 have been unloaded. Also, TLS vars
|
||||
# in remaining libraries have been changed.
|
||||
|
||||
with_test_prefix "at main-breakpoint-3" {
|
||||
gdb_test "print tls_main_tbss_1" ".* = 21"
|
||||
gdb_test "print tls_main_tbss_2" ".* = 22"
|
||||
gdb_test "print tls_main_tdata_1" ".* = 23"
|
||||
gdb_test "print tls_main_tdata_2" ".* = 24"
|
||||
|
||||
foreach n {1 4 10 11} {
|
||||
gdb_test "print tls_lib${n}_tbss_1" ".* = ${n}21"
|
||||
gdb_test "print tls_lib${n}_tbss_2" ".* = ${n}22"
|
||||
gdb_test "print tls_lib${n}_tdata_1" ".* = ${n}23"
|
||||
gdb_test "print tls_lib${n}_tdata_2" ".* = ${n}24"
|
||||
}
|
||||
}
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "main-breakpoint-4"]
|
||||
gdb_continue_to_breakpoint "main-breakpoint-4"
|
||||
|
||||
# lib3 has been loaded again; lib2 is the only one not loaded.
|
||||
|
||||
with_test_prefix "at main-breakpoint-4" {
|
||||
gdb_test "print tls_main_tbss_1" ".* = 31"
|
||||
gdb_test "print tls_main_tbss_2" ".* = 32"
|
||||
gdb_test "print tls_main_tdata_1" ".* = 33"
|
||||
gdb_test "print tls_main_tdata_2" ".* = 34"
|
||||
|
||||
set cond { $n == 3 }
|
||||
foreach n {1 3 4 10 11} {
|
||||
gdb_test_with_xfail "print tls_lib${n}_tbss_1" ".* = ${n}31" $cond
|
||||
gdb_test_with_xfail "print tls_lib${n}_tbss_2" ".* = ${n}32" $cond
|
||||
gdb_test_with_xfail "print tls_lib${n}_tdata_1" ".* = ${n}33" $cond
|
||||
gdb_test_with_xfail "print tls_lib${n}_tdata_2" ".* = ${n}34" $cond
|
||||
}
|
||||
}
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "main-breakpoint-5"]
|
||||
gdb_continue_to_breakpoint "main-breakpoint-5"
|
||||
|
||||
# lib2 and lib3 are loaded; lib1 and lib4 are not.
|
||||
|
||||
with_test_prefix "at main-breakpoint-5" {
|
||||
gdb_test "print tls_main_tbss_1" ".* = 41"
|
||||
gdb_test "print tls_main_tbss_2" ".* = 42"
|
||||
gdb_test "print tls_main_tdata_1" ".* = 43"
|
||||
gdb_test "print tls_main_tdata_2" ".* = 44"
|
||||
|
||||
set cond { $n == 2 || $n == 3 }
|
||||
foreach n {2 3 10 11} {
|
||||
gdb_test_with_xfail "print tls_lib${n}_tbss_1" ".* = ${n}41" $cond
|
||||
gdb_test_with_xfail "print tls_lib${n}_tbss_2" ".* = ${n}42" $cond
|
||||
gdb_test_with_xfail "print tls_lib${n}_tdata_1" ".* = ${n}43" $cond
|
||||
gdb_test_with_xfail "print tls_lib${n}_tdata_2" ".* = ${n}44" $cond
|
||||
}
|
||||
}
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "main-breakpoint-6"]
|
||||
gdb_continue_to_breakpoint "main-breakpoint-6"
|
||||
|
||||
# lib1, lib3 and lib4 are loaded; lib2 is not loaded.
|
||||
|
||||
with_test_prefix "at main-breakpoint-6" {
|
||||
gdb_test "print tls_main_tbss_1" ".* = 51"
|
||||
gdb_test "print tls_main_tbss_2" ".* = 52"
|
||||
gdb_test "print tls_main_tdata_1" ".* = 53"
|
||||
gdb_test "print tls_main_tdata_2" ".* = 54"
|
||||
|
||||
set cond { $n == 1 || $n == 3 || $n == 4}
|
||||
foreach n {1 3 4 10 11} {
|
||||
gdb_test_with_xfail "print tls_lib${n}_tbss_1" ".* = ${n}51" $cond
|
||||
gdb_test_with_xfail "print tls_lib${n}_tbss_2" ".* = ${n}52" $cond
|
||||
gdb_test_with_xfail "print tls_lib${n}_tdata_1" ".* = ${n}53" $cond
|
||||
gdb_test_with_xfail "print tls_lib${n}_tdata_2" ".* = ${n}54" $cond
|
||||
}
|
||||
}
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "main-breakpoint-7"]
|
||||
gdb_continue_to_breakpoint "main-breakpoint-7"
|
||||
|
||||
# lib2 and lib3 are loaded; lib1 and lib4 are not.
|
||||
|
||||
with_test_prefix "at main-breakpoint-7" {
|
||||
gdb_test "print tls_main_tbss_1" ".* = 61"
|
||||
gdb_test "print tls_main_tbss_2" ".* = 62"
|
||||
gdb_test "print tls_main_tdata_1" ".* = 63"
|
||||
gdb_test "print tls_main_tdata_2" ".* = 64"
|
||||
|
||||
set cond { $n == 2 || $n == 3 }
|
||||
foreach n {2 3 10 11} {
|
||||
gdb_test_with_xfail "print tls_lib${n}_tbss_1" ".* = ${n}61" $cond
|
||||
gdb_test_with_xfail "print tls_lib${n}_tbss_2" ".* = ${n}62" $cond
|
||||
gdb_test_with_xfail "print tls_lib${n}_tdata_1" ".* = ${n}63" $cond
|
||||
gdb_test_with_xfail "print tls_lib${n}_tdata_2" ".* = ${n}64" $cond
|
||||
}
|
||||
}
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "main-breakpoint-8"]
|
||||
gdb_continue_to_breakpoint "main-breakpoint-8"
|
||||
|
||||
# lib1, lib2, lib3, and lib4 are all loaded.
|
||||
|
||||
with_test_prefix "at main-breakpoint-8" {
|
||||
gdb_test "print tls_main_tbss_1" ".* = 71"
|
||||
gdb_test "print tls_main_tbss_2" ".* = 72"
|
||||
gdb_test "print tls_main_tdata_1" ".* = 73"
|
||||
gdb_test "print tls_main_tdata_2" ".* = 74"
|
||||
|
||||
foreach n {1 2 3 4 10 11} {
|
||||
gdb_test "print tls_lib${n}_tbss_1" ".* = ${n}71"
|
||||
gdb_test "print tls_lib${n}_tbss_2" ".* = ${n}72"
|
||||
gdb_test "print tls_lib${n}_tdata_1" ".* = ${n}73"
|
||||
gdb_test "print tls_lib${n}_tdata_2" ".* = ${n}74"
|
||||
}
|
||||
}
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "main-breakpoint-9"]
|
||||
gdb_continue_to_breakpoint "main-breakpoint-9"
|
||||
|
||||
# lib2 is loaded; lib1, lib3, and lib4 are not.
|
||||
|
||||
with_test_prefix "at main-breakpoint-9" {
|
||||
gdb_test "print tls_main_tbss_1" ".* = 81"
|
||||
gdb_test "print tls_main_tbss_2" ".* = 82"
|
||||
gdb_test "print tls_main_tdata_1" ".* = 83"
|
||||
gdb_test "print tls_main_tdata_2" ".* = 84"
|
||||
|
||||
foreach n {2 10 11} {
|
||||
gdb_test "print tls_lib${n}_tbss_1" ".* = ${n}81"
|
||||
gdb_test "print tls_lib${n}_tbss_2" ".* = ${n}82"
|
||||
gdb_test "print tls_lib${n}_tdata_1" ".* = ${n}83"
|
||||
gdb_test "print tls_lib${n}_tdata_2" ".* = ${n}84"
|
||||
}
|
||||
}
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "main-breakpoint-10"]
|
||||
gdb_continue_to_breakpoint "main-breakpoint-10"
|
||||
|
||||
# lib3 and lib4 are loaded; lib1 and lib2 are not.
|
||||
|
||||
with_test_prefix "at main-breakpoint-10" {
|
||||
gdb_test "print tls_main_tbss_1" ".* = 91"
|
||||
gdb_test "print tls_main_tbss_2" ".* = 92"
|
||||
gdb_test "print tls_main_tdata_1" ".* = 93"
|
||||
gdb_test "print tls_main_tdata_2" ".* = 94"
|
||||
|
||||
set cond { $n == 3 || $n == 4 }
|
||||
foreach n {3 4 10 11} {
|
||||
gdb_test_with_xfail "print tls_lib${n}_tbss_1" ".* = ${n}91" $cond
|
||||
gdb_test_with_xfail "print tls_lib${n}_tbss_2" ".* = ${n}92" $cond
|
||||
gdb_test_with_xfail "print tls_lib${n}_tdata_1" ".* = ${n}93" $cond
|
||||
gdb_test_with_xfail "print tls_lib${n}_tdata_2" ".* = ${n}94" $cond
|
||||
}
|
||||
}
|
||||
|
||||
# gdb_interact
|
||||
|
||||
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 "print tls_main_tbss_1" ".* = 91"
|
||||
gdb_test "print tls_main_tbss_2" ".* = 92"
|
||||
gdb_test "print tls_main_tdata_1" ".* = 93"
|
||||
gdb_test "print tls_main_tdata_2" ".* = 94"
|
||||
|
||||
set cond { $n == 3 || $n == 4 }
|
||||
foreach n {3 4 10 11} {
|
||||
gdb_test_with_xfail "print tls_lib${n}_tbss_1" ".* = ${n}91" $cond
|
||||
gdb_test_with_xfail "print tls_lib${n}_tbss_2" ".* = ${n}92" $cond
|
||||
gdb_test_with_xfail "print tls_lib${n}_tdata_1" ".* = ${n}93" $cond
|
||||
gdb_test_with_xfail "print tls_lib${n}_tdata_2" ".* = ${n}94" $cond
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Build shared objects for dlopen:
|
||||
if { [gdb_compile_shlib $libsrc $lib1obj [list debug additional_flags=-DN=1]] != "" } {
|
||||
untested "failed to compile shared object"
|
||||
return -1
|
||||
}
|
||||
if { [gdb_compile_shlib $libsrc $lib2obj [list debug additional_flags=-DN=2]] != "" } {
|
||||
untested "failed to compile shared object"
|
||||
return -1
|
||||
}
|
||||
if { [gdb_compile_shlib $libsrc $lib3obj [list debug additional_flags=-DN=3]] != "" } {
|
||||
untested "failed to compile shared object"
|
||||
return -1
|
||||
}
|
||||
if { [gdb_compile_shlib $libsrc $lib4obj [list debug additional_flags=-DN=4]] != "" } {
|
||||
untested "failed to compile shared object"
|
||||
return -1
|
||||
}
|
||||
|
||||
# Build shared objects to link against main program:
|
||||
if { [gdb_compile_shlib $libsrc $lib10obj [list debug additional_flags=-DN=10]] != "" } {
|
||||
untested "failed to compile shared object"
|
||||
return -1
|
||||
}
|
||||
if { [gdb_compile_shlib $libsrc $lib11obj [list debug additional_flags=-DN=11]] != "" } {
|
||||
untested "failed to compile shared object"
|
||||
return -1
|
||||
}
|
||||
|
||||
# Use gdb_compile_pthreads to build and link the main program for
|
||||
# testing. It's also possible to run the tests using plain old
|
||||
# gdb_compile, but this adds complexity with setting up additional
|
||||
# KFAILs. (When run using GLIBC versions earlier than 2.34, a program
|
||||
# that's not dynamically linked against libpthread will lack a working
|
||||
# libthread_db, and, therefore, won't be able to access thread local
|
||||
# storage without GDB-internal TLS support. Additional complications
|
||||
# arise from when testing on x86_64 with -m32, which tends to work
|
||||
# okay on GLIBC 2.34 and newer, but not older versions. It gets messy
|
||||
# to properly sort out all of these cases.)
|
||||
#
|
||||
# This test was originally written to do it both ways, i.e. with both
|
||||
# both gdb_compile and gdb_compile_pthreads, but the point of this
|
||||
# test is to check that the link map address to TLS module id mapping
|
||||
# code works correctly in programs which use lots of dlopen and
|
||||
# dlclose calls in various orders - and that can be done using just
|
||||
# gdb_compile_pthreads.
|
||||
|
||||
if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \
|
||||
[list debug shlib_load \
|
||||
shlib=${lib10obj} \
|
||||
shlib=${lib11obj} \
|
||||
additional_flags=-DOBJ1=\"${lib1obj}\" \
|
||||
additional_flags=-DOBJ2=\"${lib2obj}\" \
|
||||
additional_flags=-DOBJ3=\"${lib3obj}\" \
|
||||
additional_flags=-DOBJ4=\"${lib4obj}\" \
|
||||
]] != "" } {
|
||||
untested "failed to compile"
|
||||
} else {
|
||||
foreach_with_prefix force_internal_tls $internal_tls_iters {
|
||||
do_tests $force_internal_tls
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user