summaryrefslogtreecommitdiff
path: root/lib/sanitizer_common/sanitizer_mac.cc
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2016-10-05 20:33:59 +0000
committerAnna Zaks <ganna@apple.com>2016-10-05 20:33:59 +0000
commit3b0bbeea7fd5e297a4501289a78164dea58842d2 (patch)
tree2559d72990a325cf5efc9d5e675ddc12620f7b4f /lib/sanitizer_common/sanitizer_mac.cc
parent79a96a3eecb0ce87ca70051dbb37e82f311187db (diff)
[asan] Reapply: Switch to using dynamic shadow offset on iOS
The VM layout is not stable between iOS version releases, so switch to dynamic shadow offset. Differential Revision: https://reviews.llvm.org/D25218 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@283375 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common/sanitizer_mac.cc')
-rw-r--r--lib/sanitizer_common/sanitizer_mac.cc50
1 files changed, 49 insertions, 1 deletions
diff --git a/lib/sanitizer_common/sanitizer_mac.cc b/lib/sanitizer_common/sanitizer_mac.cc
index 6b513486c..0de994ae2 100644
--- a/lib/sanitizer_common/sanitizer_mac.cc
+++ b/lib/sanitizer_common/sanitizer_mac.cc
@@ -72,12 +72,23 @@ extern "C" {
#include <unistd.h>
#include <util.h>
-// from <crt_externs.h>, but we don't have that file on iOS
+// From <crt_externs.h>, but we don't have that file on iOS.
extern "C" {
extern char ***_NSGetArgv(void);
extern char ***_NSGetEnviron(void);
}
+// From <mach/mach_vm.h>, but we don't have that file on iOS.
+extern "C" {
+ extern kern_return_t mach_vm_region_recurse (
+ vm_map_t target_task,
+ mach_vm_address_t *address,
+ mach_vm_size_t *size,
+ natural_t *nesting_depth,
+ vm_region_recurse_info_t info,
+ mach_msg_type_number_t *infoCnt);
+}
+
namespace __sanitizer {
#include "sanitizer_syscall_generic.inc"
@@ -742,6 +753,43 @@ char **GetArgv() {
return *_NSGetArgv();
}
+uptr FindAvailableMemoryRange(uptr shadow_size,
+ uptr alignment,
+ uptr left_padding) {
+ typedef vm_region_submap_short_info_data_64_t RegionInfo;
+ enum { kRegionInfoSize = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64 };
+ // Start searching for available memory region past PAGEZERO, which is
+ // 4KB on 32-bit and 4GB on 64-bit.
+ mach_vm_address_t start_address =
+ (SANITIZER_WORDSIZE == 32) ? 0x000000001000 : 0x000100000000;
+
+ mach_vm_address_t address = start_address;
+ mach_vm_address_t free_begin = start_address;
+ kern_return_t kr = KERN_SUCCESS;
+ while (kr == KERN_SUCCESS) {
+ mach_vm_size_t vmsize = 0;
+ natural_t depth = 0;
+ RegionInfo vminfo;
+ mach_msg_type_number_t count = kRegionInfoSize;
+ kr = mach_vm_region_recurse(mach_task_self(), &address, &vmsize, &depth,
+ (vm_region_info_t)&vminfo, &count);
+ if (free_begin != address) {
+ // We found a free region [free_begin..address-1].
+ uptr shadow_address = RoundUpTo((uptr)free_begin + left_padding,
+ alignment);
+ if (shadow_address + shadow_size < (uptr)address) {
+ return shadow_address;
+ }
+ }
+ // Move to the next region.
+ address += vmsize;
+ free_begin = address;
+ }
+
+ // We looked at all free regions and could not find one large enough.
+ return 0;
+}
+
// FIXME implement on this platform.
void GetMemoryProfile(fill_profile_f cb, uptr *stats, uptr stats_size) { }