Support AddressSanitizer instrumentation of LLVM JIT routines

The instrumentation produces helpful crash reports and detects more
issues.

This is expected to cause a 2x slowdown on average.

Bug: b/240465596
Change-Id: I8861a51344866c646580763cbd0c7a491143dbf9
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/67128
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Reactor/LLVMJIT.cpp b/src/Reactor/LLVMJIT.cpp
index d21cf22..ca0a5c8 100644
--- a/src/Reactor/LLVMJIT.cpp
+++ b/src/Reactor/LLVMJIT.cpp
@@ -36,6 +36,7 @@
 #include "llvm/Support/Host.h"
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Transforms/InstCombine/InstCombine.h"
+#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
 #include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/Transforms/Scalar/GVN.h"
@@ -62,6 +63,10 @@
     __pragma(warning(pop))
 #endif
 
+#if __has_feature(memory_sanitizer) || __has_feature(address_sanitizer)
+#	include <dlfcn.h>  // dlsym()
+#endif
+
 #ifndef REACTOR_ASM_EMIT_DIR
 #	define REACTOR_ASM_EMIT_DIR "./"
 #endif
@@ -77,12 +82,8 @@
 #endif
 
 #if __has_feature(memory_sanitizer)
-
-// TODO(b/155148722): Remove when we no longer unpoison any writes.
 #	include "sanitizer/msan_interface.h"
 
-#	include <dlfcn.h>  // dlsym()
-
 // MemorySanitizer uses thread-local storage (TLS) data arrays for passing around
 // the 'shadow' values of function arguments and return values. The LLVM JIT can't
 // access TLS directly, but it calls __emutls_get_address() to obtain the address.
@@ -590,7 +591,6 @@
 			functions.try_emplace("__emutls_v.__msan_va_arg_overflow_size_tls", reinterpret_cast<void *>(static_cast<uintptr_t>(rr::MSanTLS::va_arg_overflow_size)));
 			functions.try_emplace("__emutls_v.__msan_origin_tls", reinterpret_cast<void *>(static_cast<uintptr_t>(rr::MSanTLS::origin)));
 
-			// TODO(b/155148722): Remove when we no longer unpoison any writes.
 			functions.try_emplace("__msan_unpoison", reinterpret_cast<void *>(__msan_unpoison));
 			functions.try_emplace("__msan_unpoison_param", reinterpret_cast<void *>(__msan_unpoison_param));
 #endif
@@ -636,9 +636,9 @@
 				continue;
 			}
 
-#if __has_feature(memory_sanitizer)
-			// MemorySanitizer uses a dynamically linked runtime. Instrumented routines reference
-			// some symbols from this library. Look them up dynamically in the default namespace.
+#if __has_feature(memory_sanitizer) || __has_feature(address_sanitizer)
+			// Sanitizers use a dynamically linked runtime. Instrumented routines reference some
+			// symbols from this library. Look them up dynamically in the default namespace.
 			// Note this approach should not be used for other symbols, since they might not be
 			// visible (e.g. due to static linking), we may wish to provide an alternate
 			// implementation, and/or it would be a security vulnerability.
@@ -933,6 +933,11 @@
 		pm.addPass(llvm::createModuleToFunctionPassAdaptor(llvm::MemorySanitizerPass(msanOpts)));
 	}
 
+	if(__has_feature(address_sanitizer))
+	{
+		pm.addPass(llvm::ModuleAddressSanitizerPass(llvm::AddressSanitizerOptions{}));
+	}
+
 	pm.run(*module, mam);
 #else  // Legacy pass manager
 	llvm::legacy::PassManager passManager;
@@ -959,6 +964,11 @@
 		passManager.add(llvm::createMemorySanitizerLegacyPassPass(msanOpts));
 	}
 
+	if(__has_feature(address_sanitizer))
+	{
+		passManager.add(llvm::createAddressSanitizerFunctionPass());
+	}
+
 	passManager.run(*module);
 #endif
 }
diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp
index 6512b0d..54bbebc 100644
--- a/src/Reactor/LLVMReactor.cpp
+++ b/src/Reactor/LLVMReactor.cpp
@@ -503,6 +503,11 @@
 #endif
 	}
 
+	if(__has_feature(address_sanitizer))
+	{
+		func->addFnAttr(llvm::Attribute::SanitizeAddress);
+	}
+
 	func->addFnAttr("warn-stack-size", "524288");  // Warn when a function uses more than 512 KiB of stack memory
 
 	return func;
@@ -4021,7 +4026,7 @@
 	auto promisePtrTy = promiseTy->getPointerTo();
 
 	jit->function = rr::createFunction("coroutine_begin", handleTy, T(Params));
-#if LLVM_VERSION_MAJOR >= 15
+#if LLVM_VERSION_MAJOR >= 16
 	jit->function->setPresplitCoroutine();
 #else
 	jit->function->addFnAttr("coroutine.presplit", "0");
diff --git a/third_party/llvm-10.0/Android.bp b/third_party/llvm-10.0/Android.bp
index 306285e..5030e4b 100644
--- a/third_party/llvm-10.0/Android.bp
+++ b/third_party/llvm-10.0/Android.bp
@@ -628,6 +628,7 @@
         "llvm/lib/Support/SmallPtrSet.cpp",
         "llvm/lib/Support/SmallVector.cpp",
         "llvm/lib/Support/SourceMgr.cpp",
+        "llvm/lib/Support/SpecialCaseList.cpp",
         "llvm/lib/Support/Statistic.cpp",
         "llvm/lib/Support/StringExtras.cpp",
         "llvm/lib/Support/StringMap.cpp",
@@ -640,6 +641,7 @@
         "llvm/lib/Support/TimeProfiler.cpp",
         "llvm/lib/Support/Timer.cpp",
         "llvm/lib/Support/ToolOutputFile.cpp",
+        "llvm/lib/Support/TrigramIndex.cpp",
         "llvm/lib/Support/Triple.cpp",
         "llvm/lib/Support/Twine.cpp",
         "llvm/lib/Support/Unicode.cpp",
@@ -683,12 +685,21 @@
         "llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp",
         "llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp",
         "llvm/lib/Transforms/InstCombine/InstructionCombining.cpp",
+        "llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp",
+        "llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp",
         "llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp",
+        "llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp",
+        "llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp",
+        "llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp",
         "llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp",
         "llvm/lib/Transforms/Instrumentation/InstrOrderFile.cpp",
         "llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp",
+        "llvm/lib/Transforms/Instrumentation/Instrumentation.cpp",
+        "llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp",
         "llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp",
         "llvm/lib/Transforms/Instrumentation/PGOMemOPSizeOpt.cpp",
+        "llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp",
+        "llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp",
         "llvm/lib/Transforms/Instrumentation/ValueProfileCollector.cpp",
         "llvm/lib/Transforms/IPO/ArgumentPromotion.cpp",
         "llvm/lib/Transforms/IPO/Attributor.cpp",
@@ -767,6 +778,7 @@
         "llvm/lib/Transforms/Scalar/SROA.cpp",
         "llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp",
         "llvm/lib/Transforms/Scalar/WarnMissedTransforms.cpp",
+        "llvm/lib/Transforms/Utils/ASanStackFrameLayout.cpp",
         "llvm/lib/Transforms/Utils/BasicBlockUtils.cpp",
         "llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp",
         "llvm/lib/Transforms/Utils/BuildLibCalls.cpp",
diff --git a/third_party/llvm-10.0/BUILD.gn b/third_party/llvm-10.0/BUILD.gn
index 6c40b2c..59e5230 100644
--- a/third_party/llvm-10.0/BUILD.gn
+++ b/third_party/llvm-10.0/BUILD.gn
@@ -738,14 +738,23 @@
     "llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp",
     "llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp",
     "llvm/lib/Transforms/InstCombine/InstructionCombining.cpp",
+    "llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp",
+    "llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp",
     "llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp",
+    "llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp",
+    "llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp",
+    "llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp",
     "llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp",
     "llvm/lib/Transforms/Instrumentation/InstrOrderFile.cpp",
     "llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp",
+    "llvm/lib/Transforms/Instrumentation/Instrumentation.cpp",
     "llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp",
     "llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp",
     "llvm/lib/Transforms/Instrumentation/PGOMemOPSizeOpt.cpp",
+    "llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp",
+    "llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp",
     "llvm/lib/Transforms/Instrumentation/ValueProfileCollector.cpp",
+    "llvm/lib/Transforms/Utils/ASanStackFrameLayout.cpp",
     "llvm/lib/Transforms/Utils/BasicBlockUtils.cpp",
     "llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp",
     "llvm/lib/Transforms/Utils/BuildLibCalls.cpp",
@@ -918,6 +927,7 @@
     "llvm/lib/Support/SmallPtrSet.cpp",
     "llvm/lib/Support/SmallVector.cpp",
     "llvm/lib/Support/SourceMgr.cpp",
+    "llvm/lib/Support/SpecialCaseList.cpp",
     "llvm/lib/Support/Statistic.cpp",
     "llvm/lib/Support/StringExtras.cpp",
     "llvm/lib/Support/StringMap.cpp",
@@ -930,6 +940,7 @@
     "llvm/lib/Support/TimeProfiler.cpp",
     "llvm/lib/Support/Timer.cpp",
     "llvm/lib/Support/ToolOutputFile.cpp",
+    "llvm/lib/Support/TrigramIndex.cpp",
     "llvm/lib/Support/Triple.cpp",
     "llvm/lib/Support/Twine.cpp",
     "llvm/lib/Support/Unicode.cpp",
diff --git a/third_party/llvm-10.0/CMakeLists.txt b/third_party/llvm-10.0/CMakeLists.txt
index bda5362..3ea8d6a 100644
--- a/third_party/llvm-10.0/CMakeLists.txt
+++ b/third_party/llvm-10.0/CMakeLists.txt
@@ -631,6 +631,7 @@
     ${LLVM_DIR}/lib/Support/SmallPtrSet.cpp
     ${LLVM_DIR}/lib/Support/SmallVector.cpp
     ${LLVM_DIR}/lib/Support/SourceMgr.cpp
+    ${LLVM_DIR}/lib/Support/SpecialCaseList.cpp
     ${LLVM_DIR}/lib/Support/Statistic.cpp
     ${LLVM_DIR}/lib/Support/StringExtras.cpp
     ${LLVM_DIR}/lib/Support/StringMap.cpp
@@ -643,6 +644,7 @@
     ${LLVM_DIR}/lib/Support/TimeProfiler.cpp
     ${LLVM_DIR}/lib/Support/Timer.cpp
     ${LLVM_DIR}/lib/Support/ToolOutputFile.cpp
+    ${LLVM_DIR}/lib/Support/TrigramIndex.cpp
     ${LLVM_DIR}/lib/Support/Triple.cpp
     ${LLVM_DIR}/lib/Support/Twine.cpp
     ${LLVM_DIR}/lib/Support/Unicode.cpp
@@ -686,14 +688,22 @@
     ${LLVM_DIR}/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
     ${LLVM_DIR}/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
     ${LLVM_DIR}/lib/Transforms/InstCombine/InstructionCombining.cpp
+    ${LLVM_DIR}/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+    ${LLVM_DIR}/lib/Transforms/Instrumentation/BoundsChecking.cpp
     ${LLVM_DIR}/lib/Transforms/Instrumentation/ControlHeightReduction.cpp
+    ${LLVM_DIR}/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
+    ${LLVM_DIR}/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+    ${LLVM_DIR}/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
     ${LLVM_DIR}/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp
     ${LLVM_DIR}/lib/Transforms/Instrumentation/InstrOrderFile.cpp
     ${LLVM_DIR}/lib/Transforms/Instrumentation/InstrProfiling.cpp
+    ${LLVM_DIR}/lib/Transforms/Instrumentation/Instrumentation.cpp
+    ${LLVM_DIR}/lib/Transforms/Instrumentation/MemorySanitizer.cpp
     ${LLVM_DIR}/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
     ${LLVM_DIR}/lib/Transforms/Instrumentation/PGOMemOPSizeOpt.cpp
+    ${LLVM_DIR}/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+    ${LLVM_DIR}/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
     ${LLVM_DIR}/lib/Transforms/Instrumentation/ValueProfileCollector.cpp
-    ${LLVM_DIR}/lib/Transforms/Instrumentation/MemorySanitizer.cpp
     ${LLVM_DIR}/lib/Transforms/IPO/ArgumentPromotion.cpp
     ${LLVM_DIR}/lib/Transforms/IPO/Attributor.cpp
     ${LLVM_DIR}/lib/Transforms/IPO/BarrierNoopPass.cpp
@@ -771,6 +781,7 @@
     ${LLVM_DIR}/lib/Transforms/Scalar/SROA.cpp
     ${LLVM_DIR}/lib/Transforms/Scalar/TailRecursionElimination.cpp
     ${LLVM_DIR}/lib/Transforms/Scalar/WarnMissedTransforms.cpp
+    ${LLVM_DIR}/lib/Transforms/Utils/ASanStackFrameLayout.cpp
     ${LLVM_DIR}/lib/Transforms/Utils/BasicBlockUtils.cpp
     ${LLVM_DIR}/lib/Transforms/Utils/BreakCriticalEdges.cpp
     ${LLVM_DIR}/lib/Transforms/Utils/BuildLibCalls.cpp