From dd95903bd734aed6407f682aa843a293814d2ec5 Mon Sep 17 00:00:00 2001 From: Richard Braakman Date: Wed, 1 Nov 2017 23:35:31 +0300 Subject: [PATCH 2/3] [tests] Regression test for EGL-glibc TLS conflict bionic and glibc have different layouts for TLS space. Since libEGL used a bionic slot directly (in inlined code), libhybris's hooks didn't translate it properly and libEGL ended up overwriting some unrelated thread-local values in glibc. The problem only showed up when linking with libGLESv2 (which pulls in libEGL), not when linking with libEGL directly. That's why the test was added to test_glesv2.c --- hybris/tests/test_hwcomposer.cpp | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/hybris/tests/test_hwcomposer.cpp b/hybris/tests/test_hwcomposer.cpp index 68917db..695291e 100644 --- a/hybris/tests/test_hwcomposer.cpp +++ b/hybris/tests/test_hwcomposer.cpp @@ -32,6 +32,23 @@ #include #include +/* Regression test: make sure that there's no conflict between + * the TLS (thread-local storage) slots used via libEGL/bionic + * and the TLS space allocated by the host toolchain. The array + * declared here should remain unchanged regardless of GL activity. + * Since this array is the first __thread storage declared in the main + * program, glibc will allocate it before any others. + */ +#define SLOT_FILLER (void *) 0x11122111 /* arbitrary non-zero value */ +#define S SLOT_FILLER +__thread void *tls_space[64] = { + S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, + S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, + S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, + S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, +}; +#undef S + const char vertex_src [] = " \ attribute vec4 position; \ @@ -346,7 +363,7 @@ int main(int argc, char **argv) glClearColor ( 1. , 1. , 1. , 1.); // background color float phase = 0; int i, oldretire = -1, oldrelease = -1, oldrelease2 = -1; - for (i=0; i<1020*60; ++i) { + for (i=0; i<60*60; ++i) { glClear(GL_COLOR_BUFFER_BIT); glUniform1f ( phase_loc , phase ); // write the value of phase to the shaders phase phase = fmodf ( phase + 0.5f , 2.f * 3.141f ); // and update the local variable @@ -372,6 +389,18 @@ int main(int argc, char **argv) printf("terminated\n"); android_dlclose(baz); #endif + + int bad_tls = 0; + for (i=0; i<64; ++i) { + if (tls_space[i] != SLOT_FILLER) { + printf("TLS array slot %d polluted: %p\n", i, tls_space[i]); + bad_tls++; + } + } + if (bad_tls) + return 1; + + return 0; } #else -- 2.23.0