From 91f4908067686c28e10894d4bd6042c0a452bf24 Mon Sep 17 00:00:00 2001
From: Richard Braakman <richard.braakman@jollamobile.com>
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 2253d50..b5d04a4 100644
--- a/hybris/tests/test_hwcomposer.cpp
+++ b/hybris/tests/test_hwcomposer.cpp
@@ -29,6 +29,23 @@
 #include <malloc.h>
 #include <sync/sync.h>
 
+/* 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;       \
@@ -343,7 +360,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
@@ -369,6 +386,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;
 }
 
 // vim:ts=4:sw=4:noexpandtab
-- 
2.15.1

