[compiler-rt] r225215 - tests: correct builtins test if built under -mthumb on ARM

Saleem Abdulrasool compnerd at compnerd.org
Mon Jan 5 13:54:50 PST 2015


Author: compnerd
Date: Mon Jan  5 15:54:50 2015
New Revision: 225215

URL: http://llvm.org/viewvc/llvm-project?rev=225215&view=rev
Log:
tests: correct builtins test if built under -mthumb on ARM

The clear_cache and enable_execute_stack tests attempt to memcpy the definition
of a function into a buffer before executing the function.  The problem with
this approach is that on some targets (ARM with thumb mode compilation, MIPS
with MIPS16 codegen or uMIPS), you would use a pointer which is incorrect (it
would be off-by-one) due to the ISA selection being encoded into the address.
This ensures that the function address is retrieved correctly in all cases.

Modified:
    compiler-rt/trunk/test/builtins/Unit/clear_cache_test.c
    compiler-rt/trunk/test/builtins/Unit/enable_execute_stack_test.c

Modified: compiler-rt/trunk/test/builtins/Unit/clear_cache_test.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/builtins/Unit/clear_cache_test.c?rev=225215&r1=225214&r2=225215&view=diff
==============================================================================
--- compiler-rt/trunk/test/builtins/Unit/clear_cache_test.c (original)
+++ compiler-rt/trunk/test/builtins/Unit/clear_cache_test.c Mon Jan  5 15:54:50 2015
@@ -38,7 +38,18 @@ int func2()
     return 2;
 }
 
-
+void *__attribute__((noinline))
+memcpy_f(void *dst, const void *src, size_t n) {
+// ARM and MIPS nartually align functions, but use the LSB for ISA selection
+// (THUMB, MIPS16/uMIPS respectively).  Ensure that the ISA bit is ignored in
+// the memcpy
+#if defined(__arm__) || defined(__mips__)
+  return (void *)((uintptr_t)memcpy(dst, (void *)((uintptr_t)src & ~1), n) |
+                  ((uintptr_t)src & 1));
+#else
+  return memcpy(dst, (void *)((uintptr_t)src), n);
+#endif
+}
 
 unsigned char execution_buffer[128];
 
@@ -59,16 +70,14 @@ int main()
         return 1;
 
     // verify you can copy and execute a function
-    memcpy(execution_buffer, (void *)(uintptr_t)&func1, 128);
+    pfunc f1 = (pfunc)memcpy_f(execution_buffer, func1, 128);
     __clear_cache(execution_buffer, &execution_buffer[128]);
-    pfunc f1 = (pfunc)(uintptr_t)execution_buffer;
     if ((*f1)() != 1)
         return 1;
 
     // verify you can overwrite a function with another
-    memcpy(execution_buffer, (void *)(uintptr_t)&func2, 128);
+    pfunc f2 = (pfunc)memcpy_f(execution_buffer, func2, 128);
     __clear_cache(execution_buffer, &execution_buffer[128]);
-    pfunc f2 = (pfunc)(uintptr_t)execution_buffer;
     if ((*f2)() != 2)
         return 1;
 

Modified: compiler-rt/trunk/test/builtins/Unit/enable_execute_stack_test.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/builtins/Unit/enable_execute_stack_test.c?rev=225215&r1=225214&r2=225215&view=diff
==============================================================================
--- compiler-rt/trunk/test/builtins/Unit/enable_execute_stack_test.c (original)
+++ compiler-rt/trunk/test/builtins/Unit/enable_execute_stack_test.c Mon Jan  5 15:54:50 2015
@@ -45,8 +45,18 @@ int func2()
     return 2;
 }
 
-
-
+void *__attribute__((noinline))
+memcpy_f(void *dst, const void *src, size_t n) {
+// ARM and MIPS nartually align functions, but use the LSB for ISA selection
+// (THUMB, MIPS16/uMIPS respectively).  Ensure that the ISA bit is ignored in
+// the memcpy
+#if defined(__arm__) || defined(__mips__)
+  return (void *)((uintptr_t)memcpy(dst, (void *)((uintptr_t)src & ~1), n) |
+                  ((uintptr_t)src & 1));
+#else
+  return memcpy(dst, (void *)((uintptr_t)src), n);
+#endif
+}
 
 int main()
 {
@@ -55,16 +65,14 @@ int main()
     __enable_execute_stack(execution_buffer);
 	
     // verify you can copy and execute a function
-    memcpy(execution_buffer, (void *)(uintptr_t)&func1, 128);
+    pfunc f1 = (pfunc)memcpy_f(execution_buffer, func1, 128);
     __clear_cache(execution_buffer, &execution_buffer[128]);
-    pfunc f1 = (pfunc)(uintptr_t)execution_buffer;
     if ((*f1)() != 1)
         return 1;
 
     // verify you can overwrite a function with another
-    memcpy(execution_buffer, (void *)(uintptr_t)&func2, 128);
+    pfunc f2 = (pfunc)memcpy_f(execution_buffer, func2, 128);
     __clear_cache(execution_buffer, &execution_buffer[128]);
-    pfunc f2 = (pfunc)(uintptr_t)execution_buffer;
     if ((*f2)() != 2)
         return 1;
 





More information about the llvm-commits mailing list