Art versions in the directory, and where they were build from ------------------------------------------------------------- See https://source.android.com/source/build-numbers.html for build numbers. Device names: angler: Nexus 6P mako: Nexus 4 art (default) ------------- Build from AOSP branch master. To update to a new AOSP master mkdir master cd master repo init -u https://android.googlesource.com/platform/manifest -b master repo sync -cq -j24 source build/envsetup.sh lunch aosp_angler-eng m -j24 m -j24 build-art m -j24 test-art-host Collected into tools/linux/art scripts/update-host-art.sh --android-checkout ~/android/master --art-dir art The precise info for the AOSP master used is in aosp_master_manifest.xml, which is produced using this command: repo manifest -o aosp_master_manifest.xml -r To reproduce that AOSP state, use the following commands: mkdir master cd master mkdir -p .repo/manifests cp /aosp_master_manifest.xml .repo/manifests repo init -u https://android.googlesource.com/platform/manifest -m aosp_master_manifest.xml art-7.0.0 --------- Build from branch android-7.0.0_r21 with the following patch: diff --git a/runtime/thread.cc b/runtime/thread.cc index 16f30cded..acdd995e9 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -554,6 +554,12 @@ void Thread::InstallImplicitProtection() { // AddressSanitizer does not like the part of this functions that reads every stack page. // Looks a lot like an out-of-bounds access. + // + // Accesses too far below the current machine register corresponding to the stack pointer (e.g., + // ESP on x86[-32], SP on ARM) might cause a SIGSEGV (at least on x86 with newer kernels). We + // thus have to move the stack pointer. We do this portably by using a recursive function with a + // large stack frame size. + // (Defensively) first remove the protection on the protected region as will want to read // and write it. Ignore errors. UnprotectStack(); @@ -561,12 +567,26 @@ void Thread::InstallImplicitProtection() { VLOG(threads) << "Need to map in stack for thread at " << std::hex << static_cast(pregion); - // Read every page from the high address to the low. - volatile uint8_t dont_optimize_this; - UNUSED(dont_optimize_this); - for (uint8_t* p = stack_top; p >= pregion; p -= kPageSize) { - dont_optimize_this = *p; - } + struct RecurseDownStack { + // This function has an intentionally large stack size. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wframe-larger-than=" + NO_INLINE + static void Touch(uintptr_t target) { + volatile size_t zero = 0; + // Use a large local volatile array to ensure a large frame size. Do not use anything close + // to a full page for ASAN. It would be nice to ensure the frame size is at most a page, but + // there is no pragma support for this. + volatile char space[kPageSize - 256]; + char sink ATTRIBUTE_UNUSED = space[zero]; + if (reinterpret_cast(space) >= target + kPageSize) { + Touch(target); + } + zero *= 2; // Try to avoid tail recursion. + } +#pragma GCC diagnostic pop + }; + RecurseDownStack::Touch(reinterpret_cast(pregion)); VLOG(threads) << "(again) installing stack protected region at " << std::hex << static_cast(pregion) << " to " << mkdir 7.0.0_r21 cd 7.0.0_r21 repo init -u https://android.googlesource.com/platform/manifest -b android-7.0.0_r21 repo sync -cq -j24 source build/envsetup.sh lunch aosp_angler-userdebug cd art cd .. m -j24 m -j24 build-art m -j24 test-art-host Collected into tools/linux/art-7.0.0. scripts/update-host-art.sh --android-checkout ~/android/7.0.0_r21 --art-dir art-7.0.0 art-6.0.1 --------- Build from branch android-6.0.1_r66 with the following patch: diff --git a/runtime/thread.cc b/runtime/thread.cc index 6e8f89cb4..788d717ca 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -357,20 +357,37 @@ void Thread::InstallImplicitProtection() { uint8_t* stack_top = reinterpret_cast(reinterpret_cast(&stack_himem) & ~(kPageSize - 1)); // Page containing current top of stack. + // + // Accesses too far below the current machine register corresponding to the stack pointer (e.g., + // ESP on x86[-32], SP on ARM) might cause a SIGSEGV (at least on x86 with newer kernels). We + // thus have to move the stack pointer. We do this portably by using a recursive function with a + // large stack frame size. + // First remove the protection on the protected region as will want to read and // write it. This may fail (on the first attempt when the stack is not mapped) // but we ignore that. UnprotectStack(); - // Map in the stack. This must be done by reading from the - // current stack pointer downwards as the stack may be mapped using VM_GROWSDOWN - // in the kernel. Any access more than a page below the current SP might cause - // a segv. - - // Read every page from the high address to the low. - for (uint8_t* p = stack_top; p >= pregion; p -= kPageSize) { - dont_optimize_this = *p; - } + struct RecurseDownStack { + // This function has an intentionally large stack size. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wframe-larger-than=" + NO_INLINE + static void Touch(uintptr_t target) { + volatile size_t zero = 0; + // Use a large local volatile array to ensure a large frame size. Do not use anything close + // to a full page for ASAN. It would be nice to ensure the frame size is at most a page, but + // there is no pragma support for this. + volatile char space[kPageSize - 256]; + char sink ATTRIBUTE_UNUSED = space[zero]; + if (reinterpret_cast(space) >= target + kPageSize) { + Touch(target); + } + zero *= 2; // Try to avoid tail recursion. + } +#pragma GCC diagnostic pop + }; + RecurseDownStack::Touch(reinterpret_cast(pregion)); VLOG(threads) << "installing stack protected region at " << std::hex << static_cast(pregion) << " to " << mkdir 6.0.1_r66 cd 6.0.1_r66 repo init -u https://android.googlesource.com/platform/manifest -b android-6.0.1_r66 repo sync -cq -j24 source build/envsetup.sh lunch aosp_angler-userdebug cd art cd .. m -j24 m -j24 build-art m -j24 test-art-host Collected into tools/linux/art-6.0.1. scripts/update-host-art.sh --android-checkout ~/android/6.0.1_r66 --art-dir art-6.0.1 art-5.1.1 --------- Build from branch 5.1.1_r19 with the following patch: diff --git a/runtime/thread.cc b/runtime/thread.cc index 2f474f7ae..f927ad7a3 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -257,20 +257,39 @@ void Thread::InstallImplicitProtection() { byte* stack_top = reinterpret_cast(reinterpret_cast(&stack_himem) & ~(kPageSize - 1)); // Page containing current top of stack. + // + // Accesses too far below the current machine register corresponding to the stack pointer (e.g., + // ESP on x86[-32], SP on ARM) might cause a SIGSEGV (at least on x86 with newer kernels). We + // thus have to move the stack pointer. We do this portably by using a recursive function with a + // large stack frame size. + // First remove the protection on the protected region as will want to read and // write it. This may fail (on the first attempt when the stack is not mapped) // but we ignore that. UnprotectStack(); - // Map in the stack. This must be done by reading from the - // current stack pointer downwards as the stack may be mapped using VM_GROWSDOWN - // in the kernel. Any access more than a page below the current SP might cause - // a segv. - - // Read every page from the high address to the low. - for (byte* p = stack_top; p >= pregion; p -= kPageSize) { - dont_optimize_this = *p; - } +#define NO_INLINE __attribute__ ((noinline)) +#define ATTRIBUTE_UNUSED __attribute__((__unused__)) + struct RecurseDownStack { + // This function has an intentionally large stack size. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wframe-larger-than=" + NO_INLINE + static void Touch(uintptr_t target) { + volatile size_t zero = 0; + // Use a large local volatile array to ensure a large frame size. Do not use anything close + // to a full page for ASAN. It would be nice to ensure the frame size is at most a page, but + // there is no pragma support for this. + volatile char space[kPageSize - 256]; + char sink ATTRIBUTE_UNUSED = space[zero]; + if (reinterpret_cast(space) >= target + kPageSize) { + Touch(target); + } + zero *= 2; // Try to avoid tail recursion. + } +#pragma GCC diagnostic pop + }; + RecurseDownStack::Touch(reinterpret_cast(pregion)); VLOG(threads) << "installing stack protected region at " << std::hex << static_cast(pregion) << " to " << mkdir 5.1.1_r19 cd 5.1.1_r19 repo init -u https://android.googlesource.com/platform/manifest -b android-5.1.1_r19 repo sync -cq -j24 source build/envsetup.sh lunch aosp_mako-userdebug cd art cd .. m -j24 m -j24 build-art m -j24 test-art-host Collected into tools/linux/art-5.1.1. scripts/update-host-art.sh --android-checkout ~/android/5.1.1_r19 --art-dir art-5.1.1 --android-product mako