From patchwork Wed Nov 27 01:52:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Myers X-Patchwork-Id: 101938 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4FA1F3858D37 for ; Wed, 27 Nov 2024 01:54:27 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4FA1F3858D37 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=WHD+Q65d X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id D2CAE3858D37 for ; Wed, 27 Nov 2024 01:53:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D2CAE3858D37 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org D2CAE3858D37 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732672395; cv=none; b=YYQLxyi93OGJAw2S5HPJyslpEqCLYCc+MmQfuW4fKiktO0RJO3Zi1gvPIoF/x4YE9wxVqNjz06SicDgJwEFm1zpYn2BShwSeSlswTusm8zhnH0f7bY/HQMvf8l3lHZr8K1AF+lQP5iui60ClcbX5neya6ioVmIbTELhrV4WMSNs= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732672395; c=relaxed/simple; bh=Ugvd2ac+Z16ewy9KGT+bBYWp3YxDvN6kpxOO/c/DcJA=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=YveUyUxGZ8/RvpOHWVkkdSEMHRSY6hGDON0mNz0cMeGIJ20DIA7TlCWD7eESRF+rxslQJI3rSQpNa3QXPRYv5jNOPcGPiUtc1yY+4IdtX0mdrjerB/pL6a4ED4kx6s9dN1AMKr1WIq+KTC+CmdNrwzWXSlH5X6iHtP0ubH4ZLiQ= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D2CAE3858D37 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1732672394; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type; bh=nvjCXyK5oYQ0rL0LRB+RKkX36wlLok4oaNdON2rkJhY=; b=WHD+Q65dPOy+5wUVfIHu3KPZ9YDznekTXCLz9/uUODQD5h615sNTEJrQCeMP0rK6z+ZoCB BClbItJ8WUMCh3X/oV24rlwsHgkrz1j9hCREq20Esd4aujr+uE8s/78paXSKLvGLmNl4O4 JoYznurif4+GRBh6KaAlLWtpSaaeTPk= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-26-iCxIE5CBNNavxd6U3IIV_g-1; Tue, 26 Nov 2024 20:53:11 -0500 X-MC-Unique: iCxIE5CBNNavxd6U3IIV_g-1 X-Mimecast-MFC-AGG-ID: iCxIE5CBNNavxd6U3IIV_g Received: by mail-wr1-f71.google.com with SMTP id ffacd0b85a97d-382412f3e62so3257270f8f.3 for ; Tue, 26 Nov 2024 17:53:11 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732672389; x=1733277189; h=mime-version:message-id:subject:to:from:date:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=nvjCXyK5oYQ0rL0LRB+RKkX36wlLok4oaNdON2rkJhY=; b=JbUREQLti1wnn3IcW5HEd9fZaFC7afw+i0iQ6aqaN5xyhVvv2konpsc4Fc8yNPKWma j16CG9YDr1YvjpsNeC9zLlu5EdG1fI6eCn7JsbCshCSP1XVrQjQNtYHdxYuZdd1KoDvw zcXElw9j7q4Bp3IzGjNwGW1kEduMU7FMFeIWL5s61aDk4fmKwTBIbCincnUhvQpIJ7iH I13xmHql6qt9Op1NP8jMsMnq/cknNJFOkehZBRUM5293ulQ4WM74dwMS2Eo/sMKJjakR PM+65Xr/F1fGl4bOEmhS+j5FwOIDYBo6dHRrGxdrW4XmhOxeFosH2k+a427unzGyQAty b4nQ== X-Gm-Message-State: AOJu0YzdLefAWlJJBoh4WELgzGAf0xVEm3WKvH8SNDEDaz8VLpelzG+b v9qx81YsKZjmyz1gSBMAf466vlLza96+KzRierakC5qcLvqF7iUOhSFU+pKbj/mqpi5j6oU6DSX PV8bse4j7k0Z9VbLfqX8PmF7Y0qmCjcz5NwEjQ2ii3VhvyZ/RSP4MXeHxZKgOZzwizucgg4J6pA gBmEChirOoEil9N6ZdFLiBu4FsmRzhtYoFWB1tqC9ENQ== X-Gm-Gg: ASbGnctfLudqxyJU5ucSEXsuyruhk34LvCTWYNUu8TSe5o8NLALophdjO6IvlXm1dxL Ht3W57RXHDnQU2aDB8Sy4ytNgPgWEQUFYcUu+sWly5ULeOv4GZl1G3qMpPF2kXnCm+bZLX874mk dyDiKGjQqgoCL0NN1fWu10mlIIYoVeXMWh+RnufFhtsmyvTJM6E7mIZbTZTCWgXXdpIlCuva/4x GbAP5mqrGhLNTjIQocAqsB1XrXFyL+LwEtB8ZGIK9WcFh2l3qKaKUgwZfPRxbF1HpAeeyr4lc+r y0VcXg== X-Received: by 2002:a5d:588f:0:b0:382:3dc7:2eeb with SMTP id ffacd0b85a97d-385c6eb7a7bmr680717f8f.4.1732672389190; Tue, 26 Nov 2024 17:53:09 -0800 (PST) X-Google-Smtp-Source: AGHT+IGPOtATSCAcweyZ+X1v5cTenYTTf4biiROVnKqSOvB9hZT/PwdT2KLWnraBq0Dxhvu99EF0Ow== X-Received: by 2002:a5d:588f:0:b0:382:3dc7:2eeb with SMTP id ffacd0b85a97d-385c6eb7a7bmr680704f8f.4.1732672388438; Tue, 26 Nov 2024 17:53:08 -0800 (PST) Received: from digraph.polyomino.org.uk (digraph.polyomino.org.uk. [2001:8b0:bf73:93f7::51bb:e332]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825faf9f59sm14791333f8f.34.2024.11.26.17.53.06 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Nov 2024 17:53:07 -0800 (PST) Received: from jsm28 (helo=localhost) by digraph.polyomino.org.uk with local-esmtp (Exim 4.97) (envelope-from ) id 1tG7E7-0000000FJmy-0EZr for libc-alpha@sourceware.org; Wed, 27 Nov 2024 01:52:23 +0000 Date: Wed, 27 Nov 2024 01:52:23 +0000 (UTC) From: Joseph Myers To: libc-alpha@sourceware.org Subject: Add further test of TLS Message-ID: <44639369-5c00-4ebb-288d-18400de53451@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: Lp4flRjaBxiJW4_OX2TScpZIkK4OK27gvVTM6ZxsG7Y_1732672390 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-9.0 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org Add an additional test of TLS variables, with different alignment, accessed from different modules. The idea of the alignment test is similar to tst-tlsalign and the same code is shared for setting up test variables, but unlike the tst-tlsalign code, there are multiple threads and variables are accessed from multiple objects to verify that they get a consistent notion of the address of an object within a thread. Threads are repeatedly created and shut down to verify proper initialization in each new thread. The test is also repeated with TLS descriptors when supported. (However, only initial-exec TLS is covered in this test.) Tested for x86_64. Reviewed-by: H.J. Lu diff --git a/elf/Makefile b/elf/Makefile index ba6b022a2f..45d7e9da8b 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -481,6 +481,8 @@ tests += \ tst-tls19 \ tst-tls20 \ tst-tls21 \ + tst-tls22 \ + tst-tls22-gnu2 \ tst-tlsalign \ tst-tlsalign-extern \ tst-tlsgap \ @@ -681,9 +683,15 @@ tst-tls-many-dynamic-modules-dep-bad = \ extra-test-objs += \ $(tlsmod17a-modules:=.os) \ $(tlsmod18a-modules:=.os) \ + tst-tls22-mod1-vars.os \ + tst-tls22-mod2-vars.os \ + tst-tls22-vars.o \ tst-tlsalign-vars.o \ # extra-test-objs test-extras += \ + tst-tls22-mod1-vars \ + tst-tls22-mod2-vars \ + tst-tls22-vars \ tst-tlsalign-vars \ tst-tlsmod17a \ tst-tlsmod18a \ @@ -955,6 +963,10 @@ modules-names += \ tst-tls19mod3 \ tst-tls20mod-bad \ tst-tls21mod \ + tst-tls22-mod1 \ + tst-tls22-mod1-gnu2 \ + tst-tls22-mod2 \ + tst-tls22-mod2-gnu2 \ tst-tlsalign-lib \ tst-tlsgap-mod0 \ tst-tlsgap-mod1 \ @@ -3189,3 +3201,27 @@ tst-rtld-no-malloc-audit-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so # Any shared object should do. tst-rtld-no-malloc-preload-ENV = LD_PRELOAD=$(objpfx)tst-auditmod1.so + +$(objpfx)tst-tls22: $(objpfx)tst-tls22-vars.o $(objpfx)tst-tls22-mod1.so \ + $(objpfx)tst-tls22-mod2.so $(shared-thread-library) +$(objpfx)tst-tls22-mod1.so: $(objpfx)tst-tls22-mod1.os \ + $(objpfx)tst-tls22-mod1-vars.os $(objpfx)tst-tls22-mod2.so +$(objpfx)tst-tls22-mod2.so: $(objpfx)tst-tls22-mod2.os \ + $(objpfx)tst-tls22-mod2-vars.os +$(objpfx)tst-tls22-gnu2: $(objpfx)tst-tls22-vars.o \ + $(objpfx)tst-tls22-mod1-gnu2.so $(objpfx)tst-tls22-mod2-gnu2.so \ + $(shared-thread-library) +$(objpfx)tst-tls22-mod1-gnu2.so: $(objpfx)tst-tls22-mod1-gnu2.os \ + $(objpfx)tst-tls22-mod1-vars.os $(objpfx)tst-tls22-mod2-gnu2.so +$(objpfx)tst-tls22-mod2-gnu2.so: $(objpfx)tst-tls22-mod2-gnu2.os \ + $(objpfx)tst-tls22-mod2-vars.os +ifneq (no,$(have-mtls-descriptor)) +CFLAGS-tst-tls22-gnu2.c += -mtls-dialect=$(have-mtls-descriptor) +CFLAGS-tst-tls22-mod1-gnu2.c += -mtls-dialect=$(have-mtls-descriptor) +CFLAGS-tst-tls22-mod2-gnu2.c += -mtls-dialect=$(have-mtls-descriptor) +endif +# These reference symbols from the main executable. +tst-tls22-mod1.so-no-z-defs = yes +tst-tls22-mod1-gnu2.so-no-z-defs = yes +tst-tls22-mod2.so-no-z-defs = yes +tst-tls22-mod2-gnu2.so-no-z-defs = yes diff --git a/elf/tst-tls22-gnu2.c b/elf/tst-tls22-gnu2.c new file mode 100644 index 0000000000..d9ce6df0b2 --- /dev/null +++ b/elf/tst-tls22-gnu2.c @@ -0,0 +1 @@ +#include diff --git a/elf/tst-tls22-mod1-gnu2.c b/elf/tst-tls22-mod1-gnu2.c new file mode 100644 index 0000000000..0b085fe175 --- /dev/null +++ b/elf/tst-tls22-mod1-gnu2.c @@ -0,0 +1 @@ +#include diff --git a/elf/tst-tls22-mod1-vars.c b/elf/tst-tls22-mod1-vars.c new file mode 100644 index 0000000000..bdb7358287 --- /dev/null +++ b/elf/tst-tls22-mod1-vars.c @@ -0,0 +1,9 @@ +#include + +#define tdata1 mod1_tdata1 +#define tdata2 mod1_tdata2 +#define tdata3 mod1_tdata3 +#define tbss1 mod1_tbss1 +#define tbss2 mod1_tbss2 +#define tbss3 mod1_tbss3 +#include diff --git a/elf/tst-tls22-mod1.c b/elf/tst-tls22-mod1.c new file mode 100644 index 0000000000..3a47d7bbc6 --- /dev/null +++ b/elf/tst-tls22-mod1.c @@ -0,0 +1,27 @@ +/* Test TLS with varied alignment and multiple modules and threads. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +void +test_mod1 (struct one_thread_data *data, int base_val) +{ + STORE_ADDRS (&data->mod1_self, mod1); + STORE_ADDRS (&data->exe_from_mod1, exe); + STORE_ADDRS (&data->mod2_from_mod1, mod2); +} diff --git a/elf/tst-tls22-mod2-gnu2.c b/elf/tst-tls22-mod2-gnu2.c new file mode 100644 index 0000000000..a5260e0616 --- /dev/null +++ b/elf/tst-tls22-mod2-gnu2.c @@ -0,0 +1 @@ +#include diff --git a/elf/tst-tls22-mod2-vars.c b/elf/tst-tls22-mod2-vars.c new file mode 100644 index 0000000000..9ef3452bba --- /dev/null +++ b/elf/tst-tls22-mod2-vars.c @@ -0,0 +1,9 @@ +#include + +#define tdata1 mod2_tdata1 +#define tdata2 mod2_tdata2 +#define tdata3 mod2_tdata3 +#define tbss1 mod2_tbss1 +#define tbss2 mod2_tbss2 +#define tbss3 mod2_tbss3 +#include diff --git a/elf/tst-tls22-mod2.c b/elf/tst-tls22-mod2.c new file mode 100644 index 0000000000..5d26d592b0 --- /dev/null +++ b/elf/tst-tls22-mod2.c @@ -0,0 +1,26 @@ +/* Test TLS with varied alignment and multiple modules and threads. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +void +test_mod2 (struct one_thread_data *data, int base_val) +{ + STORE_ADDRS (&data->mod2_self, mod2); + STORE_ADDRS (&data->exe_from_mod2, exe); +} diff --git a/elf/tst-tls22-vars.c b/elf/tst-tls22-vars.c new file mode 100644 index 0000000000..2ad3ee7a3b --- /dev/null +++ b/elf/tst-tls22-vars.c @@ -0,0 +1,9 @@ +#include + +#define tdata1 exe_tdata1 +#define tdata2 exe_tdata2 +#define tdata3 exe_tdata3 +#define tbss1 exe_tbss1 +#define tbss2 exe_tbss2 +#define tbss3 exe_tbss3 +#include diff --git a/elf/tst-tls22.c b/elf/tst-tls22.c new file mode 100644 index 0000000000..35a8cd82b2 --- /dev/null +++ b/elf/tst-tls22.c @@ -0,0 +1,147 @@ +/* Test TLS with varied alignment and multiple modules and threads. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + +static void +check_addrs_align (const struct obj_addrs *addrs) +{ + TEST_COMPARE (addrs->addr_tdata1 & (__alignof__ (int) - 1), 0); + TEST_COMPARE (addrs->addr_tdata2 & 0xf, 0); + TEST_COMPARE (addrs->addr_tdata3 & 0xfff, 0); + TEST_COMPARE (addrs->addr_tbss1 & (__alignof__ (int) - 1), 0); + TEST_COMPARE (addrs->addr_tbss2 & 0xf, 0); + TEST_COMPARE (addrs->addr_tbss3 & 0xfff, 0); +} + +static void +check_addrs_same (const struct obj_addrs *addrs1, + const struct obj_addrs *addrs2) +{ + TEST_COMPARE (addrs1->addr_tdata1, addrs2->addr_tdata1); + TEST_COMPARE (addrs1->addr_tdata2, addrs2->addr_tdata2); + TEST_COMPARE (addrs1->addr_tdata3, addrs2->addr_tdata3); + TEST_COMPARE (addrs1->addr_tbss1, addrs2->addr_tbss1); + TEST_COMPARE (addrs1->addr_tbss2, addrs2->addr_tbss2); + TEST_COMPARE (addrs1->addr_tbss3, addrs2->addr_tbss3); +} + +static void +check_vals_before (const struct obj_values *vals) +{ + TEST_COMPARE (vals->val_tdata1, 1); + TEST_COMPARE (vals->val_tdata2, 2); + TEST_COMPARE (vals->val_tdata3, 4); + TEST_COMPARE (vals->val_tbss1, 0); + TEST_COMPARE (vals->val_tbss2, 0); + TEST_COMPARE (vals->val_tbss3, 0); +} + +static void +check_vals_after (const struct obj_values *vals, int base_val) +{ + TEST_COMPARE (vals->val_tdata1, base_val); + TEST_COMPARE (vals->val_tdata2, base_val + 1); + TEST_COMPARE (vals->val_tdata3, base_val + 2); + TEST_COMPARE (vals->val_tbss1, base_val + 3); + TEST_COMPARE (vals->val_tbss2, base_val + 4); + TEST_COMPARE (vals->val_tbss3, base_val + 5); +} + +static void +check_one_thread (const struct one_thread_data *data, int base_val) +{ + check_vals_before (&data->exe_before); + check_vals_before (&data->mod1_before); + check_vals_before (&data->mod2_before); + check_vals_after (&data->exe_after, base_val); + check_vals_after (&data->mod1_after, base_val); + check_vals_after (&data->mod2_after, base_val); + check_addrs_align (&data->exe_self); + check_addrs_same (&data->exe_self, &data->exe_from_mod1); + check_addrs_same (&data->exe_self, &data->exe_from_mod2); + check_addrs_align (&data->mod1_self); + check_addrs_same (&data->mod1_self, &data->mod1_from_exe); + check_addrs_align (&data->mod2_self); + check_addrs_same (&data->mod2_self, &data->mod2_from_exe); + check_addrs_same (&data->mod2_self, &data->mod2_from_mod1); +} + +static void * +thread_func (void *arg) +{ + int base_val = (int) (intptr_t) arg + 10; + struct one_thread_data data; + /* Record the addresses of variables as seen from the main + executable (which should be the same as seen from the other + modules), and their initial values. */ + STORE_ADDRS (&data.exe_self, exe); + STORE_ADDRS (&data.mod1_from_exe, mod1); + STORE_ADDRS (&data.mod2_from_exe, mod2); + STORE_VALUES (&data.exe_before, exe); + STORE_VALUES (&data.mod1_before, mod1); + STORE_VALUES (&data.mod2_before, mod2); + /* Overwrite the value of variables. */ + OVERWRITE_VALUES (exe, base_val); + OVERWRITE_VALUES (mod1, base_val); + OVERWRITE_VALUES (mod2, base_val); + /* Record the addresses of variables as seen from other modules. */ + test_mod1 (&data, base_val); + test_mod2 (&data, base_val); + /* Record the overwritten values (thus making sure that no other + thread running in parallel has changed this thread's values). */ + STORE_VALUES (&data.exe_after, exe); + STORE_VALUES (&data.mod1_after, mod1); + STORE_VALUES (&data.mod2_after, mod2); + /* Check all the addresses and values recorded. */ + check_one_thread (&data, base_val); + return NULL; +} + +#define NUM_ITERS 50 +#define NUM_THREADS 16 + +/* For NUM_ITERS iterations, repeatedly create NUM_THREADS threads. + In each thread, we determine the addresses of TLS objects (both + from the module defining those objects and from other modules), and + their initial values, and store in values that are then read back; + we check that each object's address is the same regardless of the + module in which it is determined, that alignment of objects is as + required, and that the values of objects are as expected. */ + +static int +do_test (void) +{ + for (size_t i = 0; i < NUM_ITERS; i++) + { + pthread_t threads[NUM_THREADS]; + for (size_t j = 0; j < NUM_THREADS; j++) + threads[j] = xpthread_create (NULL, thread_func, (void *) j); + /* Also run checks in the main thread, but only once because + those values don't get reinitialized. */ + if (i == 0) + thread_func ((void *) NUM_THREADS); + for (size_t j = 0; j < NUM_THREADS; j++) + xpthread_join (threads[j]); + } + return 0; +} + +#include diff --git a/elf/tst-tls22.h b/elf/tst-tls22.h new file mode 100644 index 0000000000..24b2e0a0b6 --- /dev/null +++ b/elf/tst-tls22.h @@ -0,0 +1,115 @@ +/* Test TLS with varied alignment and multiple modules and threads: header. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef TST_TLS22_H +#define TST_TLS22_H + +#include + +extern __thread int exe_tdata1 __attribute__ ((tls_model ("initial-exec"))); +extern __thread int exe_tdata2 __attribute__ ((tls_model ("initial-exec"))); +extern __thread int exe_tdata3 __attribute__ ((tls_model ("initial-exec"))); +extern __thread int exe_tbss1 __attribute__ ((tls_model ("initial-exec"))); +extern __thread int exe_tbss2 __attribute__ ((tls_model ("initial-exec"))); +extern __thread int exe_tbss3 __attribute__ ((tls_model ("initial-exec"))); +extern __thread int mod1_tdata1 __attribute__ ((tls_model ("initial-exec"))); +extern __thread int mod1_tdata2 __attribute__ ((tls_model ("initial-exec"))); +extern __thread int mod1_tdata3 __attribute__ ((tls_model ("initial-exec"))); +extern __thread int mod1_tbss1 __attribute__ ((tls_model ("initial-exec"))); +extern __thread int mod1_tbss2 __attribute__ ((tls_model ("initial-exec"))); +extern __thread int mod1_tbss3 __attribute__ ((tls_model ("initial-exec"))); +extern __thread int mod2_tdata1 __attribute__ ((tls_model ("initial-exec"))); +extern __thread int mod2_tdata2 __attribute__ ((tls_model ("initial-exec"))); +extern __thread int mod2_tdata3 __attribute__ ((tls_model ("initial-exec"))); +extern __thread int mod2_tbss1 __attribute__ ((tls_model ("initial-exec"))); +extern __thread int mod2_tbss2 __attribute__ ((tls_model ("initial-exec"))); +extern __thread int mod2_tbss3 __attribute__ ((tls_model ("initial-exec"))); + +/* Structure to store the addresses of one set of TLS objects in one + thread, as seen by one module in the program. */ +struct obj_addrs +{ + uintptr_t addr_tdata1, addr_tdata2, addr_tdata3; + uintptr_t addr_tbss1, addr_tbss2, addr_tbss3; +}; + +/* Structure to store the values of one set of TLS objects in one + thread. */ +struct obj_values +{ + uintptr_t val_tdata1, val_tdata2, val_tdata3; + uintptr_t val_tbss1, val_tbss2, val_tbss3; +}; + +/* Structure to store all the data about TLS objects in one + thread. */ +struct one_thread_data +{ + struct obj_addrs exe_self, exe_from_mod1, exe_from_mod2; + struct obj_addrs mod1_self, mod1_from_exe; + struct obj_addrs mod2_self, mod2_from_exe, mod2_from_mod1; + struct obj_values exe_before, mod1_before, mod2_before; + struct obj_values exe_after, mod1_after, mod2_after; +}; + +/* Store the addresses of variables prefixed by PFX in the structure + pointed to by DST. */ +#define STORE_ADDRS(DST, PFX) \ + do \ + { \ + (DST)->addr_tdata1 = (uintptr_t) &PFX ## _tdata1; \ + (DST)->addr_tdata2 = (uintptr_t) &PFX ## _tdata2; \ + (DST)->addr_tdata3 = (uintptr_t) &PFX ## _tdata3; \ + (DST)->addr_tbss1 = (uintptr_t) &PFX ## _tbss1; \ + (DST)->addr_tbss2 = (uintptr_t) &PFX ## _tbss2; \ + (DST)->addr_tbss3 = (uintptr_t) &PFX ## _tbss3; \ + } \ + while (0) + +/* Store the values of variables prefixed by PFX in the structure + pointed to by DST. */ +#define STORE_VALUES(DST, PFX) \ + do \ + { \ + (DST)->val_tdata1 = PFX ## _tdata1; \ + (DST)->val_tdata2 = PFX ## _tdata2; \ + (DST)->val_tdata3 = PFX ## _tdata3; \ + (DST)->val_tbss1 = PFX ## _tbss1; \ + (DST)->val_tbss2 = PFX ## _tbss2; \ + (DST)->val_tbss3 = PFX ## _tbss3; \ + } \ + while (0) + +/* Overwrite the values of variables prefixed by PFX with values + starting with VAL. */ +#define OVERWRITE_VALUES(PFX, VAL) \ + do \ + { \ + PFX ## _tdata1 = (VAL); \ + PFX ## _tdata2 = (VAL) + 1; \ + PFX ## _tdata3 = (VAL) + 2; \ + PFX ## _tbss1 = (VAL) + 3; \ + PFX ## _tbss2 = (VAL) + 4; \ + PFX ## _tbss3 = (VAL) + 5; \ + } \ + while (0) + +void test_mod1 (struct one_thread_data *data, int base_val); +void test_mod2 (struct one_thread_data *data, int base_val); + +#endif /* TST_TLS22_H */