From c0d4e00b35409c757f0d240bafe69d7c7cdf2c3d Mon Sep 17 00:00:00 2001 From: Wolfgang Thaller Date: Sat, 9 Dec 2023 11:37:32 +0100 Subject: [PATCH] add LocalStatic test case --- AutomatedTests/CMakeLists.txt | 3 ++ AutomatedTests/LocalStatic.cc | 61 +++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 AutomatedTests/LocalStatic.cc diff --git a/AutomatedTests/CMakeLists.txt b/AutomatedTests/CMakeLists.txt index c79aedb75a..cef0494c5a 100644 --- a/AutomatedTests/CMakeLists.txt +++ b/AutomatedTests/CMakeLists.txt @@ -90,3 +90,6 @@ test(${CMAKE_CURRENT_BINARY_DIR}/PascalTrapCPP.cc PROPERTIES PASS_REGULAR_EXPRES configure_file(PascalString.c PascalStringCPP.cc) test(PascalString.c PROPERTIES PASS_REGULAR_EXPRESSION "OK") test(${CMAKE_CURRENT_BINARY_DIR}/PascalStringCPP.cc PROPERTIES PASS_REGULAR_EXPRESSION "OK") + +test(LocalStatic.cc PROPERTIES PASS_REGULAR_EXPRESSION "OK") +set_target_properties(LocalStatic PROPERTIES COMPILE_FLAGS -fno-exceptions) # just to make assembly easier to read diff --git a/AutomatedTests/LocalStatic.cc b/AutomatedTests/LocalStatic.cc new file mode 100644 index 0000000000..3556f85c43 --- /dev/null +++ b/AutomatedTests/LocalStatic.cc @@ -0,0 +1,61 @@ +#include "Test.h" + +/* + +This test case is intended to check for one particular binutils/xcoff problem: + +Without a patch, GNU ld fails to allocate space for weak uninitialized csects [BS], +and therefore puts both at the same address. + +Minimal example: + + .weak _one[BS] + .csect _one[BS] +_one: + .space 4 + .weak _two[BS] + .csect _two[BS] +_two: + .space 4 + + +powerpc-apple-macos-as test.s > test.o +powerpc-apple-macos-ld -r test.o -o linked.o +powerpc-apple-macos-objdump -t -h linked.o + +Observe the size of the .bss section and the addresses of symbols _one and _two. + +This test case tests for it using a thread-safe local static variable in an inline +function, which boils down to a pair of weakly-linked uninitialized csects as above. + + */ + + +// noinline so that it doesn't get optimized away +__attribute__((noinline)) int foo() +{ + return 42; +} + +// the `inline` triggers a problem. +// the static var and its guard variable are marked `.weak`, +// and the XCOFF linker puts them at the same address. +inline int bar() +{ + static int cachedFoo = foo(); + return cachedFoo; +} + +// wrap it in a noinline function to make reading the assembly easier. + __attribute__((noinline)) int baz() +{ + return bar(); +} + +int main() +{ + if (baz() != 42) + TestLog("NO"); + else + TestLog("OK"); +}