summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2017-11-16 02:52:19 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2017-11-16 02:52:19 +0000
commitdeab6967a3f165683d6d067cb4f2134886299c7a (patch)
tree84f66fded4402f24a04ba028ce51aac44de70c42 /lib
parent98668e97e7eb0604b86d4e608317c20798b14a01 (diff)
[asan] Fallback to non-ifunc dynamic shadow on android<22.
Summary: Android < 22 does not support ifunc. Reviewers: pcc Subscribers: srhines, kubamracek, hiraditya, llvm-commits Differential Revision: https://reviews.llvm.org/D40116 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@318369 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/asan/asan_linux.cc11
-rw-r--r--lib/asan/asan_premap_shadow.cc9
-rw-r--r--lib/asan/asan_premap_shadow.h2
3 files changed, 19 insertions, 3 deletions
diff --git a/lib/asan/asan_linux.cc b/lib/asan/asan_linux.cc
index 902c64cc4..8ce4b96c2 100644
--- a/lib/asan/asan_linux.cc
+++ b/lib/asan/asan_linux.cc
@@ -83,7 +83,7 @@ void *AsanDoesNotSupportStaticLinkage() {
}
#if ASAN_PREMAP_SHADOW
-uptr FindDynamicShadowStart() {
+uptr FindPremappedShadowStart() {
uptr granularity = GetMmapGranularity();
uptr shadow_start = reinterpret_cast<uptr>(&__asan_shadow);
uptr shadow_size = PremapShadowSize();
@@ -93,8 +93,14 @@ uptr FindDynamicShadowStart() {
IncreaseTotalMmap(shadow_size + granularity);
return shadow_start;
}
-#else
+#endif
+
uptr FindDynamicShadowStart() {
+#if ASAN_PREMAP_SHADOW
+ if (!PremapShadowFailed())
+ return FindPremappedShadowStart();
+#endif
+
uptr granularity = GetMmapGranularity();
uptr alignment = granularity * 8;
uptr left_padding = granularity;
@@ -112,7 +118,6 @@ uptr FindDynamicShadowStart() {
return shadow_start;
}
-#endif
void AsanApplyToGlobals(globals_op_fptr op, const void *needle) {
UNIMPLEMENTED();
diff --git a/lib/asan/asan_premap_shadow.cc b/lib/asan/asan_premap_shadow.cc
index 0e66eeef1..2d20c3b8c 100644
--- a/lib/asan/asan_premap_shadow.cc
+++ b/lib/asan/asan_premap_shadow.cc
@@ -50,6 +50,15 @@ uptr PremapShadow() {
return shadow_start;
}
+bool PremapShadowFailed() {
+ uptr shadow = reinterpret_cast<uptr>(&__asan_shadow);
+ uptr resolver = reinterpret_cast<uptr>(&__asan_premap_shadow);
+ // shadow == resolver is how Android KitKat and older handles ifunc.
+ // shadow == 0 just in case.
+ if (shadow == 0 || shadow == resolver)
+ return true;
+ return false;
+}
} // namespace __asan
extern "C" {
diff --git a/lib/asan/asan_premap_shadow.h b/lib/asan/asan_premap_shadow.h
index 6349e04ae..41acbdbbb 100644
--- a/lib/asan/asan_premap_shadow.h
+++ b/lib/asan/asan_premap_shadow.h
@@ -20,9 +20,11 @@
namespace __asan {
// Conservative upper limit.
uptr PremapShadowSize();
+bool PremapShadowFailed();
}
#endif
extern "C" INTERFACE_ATTRIBUTE void __asan_shadow();
+extern "C" decltype(__asan_shadow)* __asan_premap_shadow();
#endif // ASAN_PREMAP_SHADOW_H