mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 01:47:35 +00:00
Tests/LibELF: Test loading libraries with dynamic TLS
The setup is a bit peculiar: both the definition and the use site of these TLS variables have to be in a shared library, otherwise the linker might relax the global-dynamic access mode to something that doesn't require a `__tls_get_addr` call.
This commit is contained in:
parent
ad9e674fa0
commit
c63fe0e1f1
4 changed files with 106 additions and 6 deletions
48
Tests/LibELF/TLSUse.cpp
Normal file
48
Tests/LibELF/TLSUse.cpp
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Daniel Bertalan <dani@danielbertalan.dev>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibTest/Macros.h>
|
||||
#include <LibThreading/Thread.h>
|
||||
|
||||
// Defined in TLSDef.cpp
|
||||
extern __thread int one;
|
||||
extern __thread int two;
|
||||
extern __thread int three;
|
||||
[[gnu::tls_model("initial-exec")]] extern __thread int four;
|
||||
extern void check_increment_worked();
|
||||
|
||||
static void check_initial()
|
||||
{
|
||||
EXPECT_EQ(one, 1);
|
||||
EXPECT_EQ(two, 2);
|
||||
EXPECT_EQ(three, 3);
|
||||
EXPECT_EQ(four, 4);
|
||||
}
|
||||
|
||||
// This checks the basic functionality of thread-local variables:
|
||||
// - TLS variables with a static initializer have the correct value on program startup
|
||||
// - TLS variables are set to their initial values in a new thread
|
||||
// - relocations refer to the correct variables
|
||||
// - accessing an initial-exec variable from a DSO works even if
|
||||
// it's not declared as initial-exec at the use site
|
||||
// FIXME: Test C++11 thread_local variables with dynamic initializers
|
||||
void run_test();
|
||||
void run_test()
|
||||
{
|
||||
check_initial();
|
||||
++one;
|
||||
++two;
|
||||
++three;
|
||||
++four;
|
||||
check_increment_worked();
|
||||
|
||||
auto second_thread = Threading::Thread::construct([] {
|
||||
check_initial();
|
||||
return 0;
|
||||
});
|
||||
second_thread->start();
|
||||
(void)second_thread->join();
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue