ladybird/Tests/LibELF/TLSUse.cpp
Daniel Bertalan c63fe0e1f1 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.
2023-08-18 16:20:13 +02:00

49 lines
1.2 KiB
C++

/*
* 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();
}