diff options
author | 2016-08-11 18:35:58 -0700 | |
---|---|---|
committer | 2016-08-11 20:54:35 -0700 | |
commit | d12622811508a468ad52a9939b50bdfd51bb47ac (patch) | |
tree | a93bc96ba67110a18770480c0ef85174dff7e264 | |
parent | 9d32586b52893a82c5094821d32c4f2d4d201795 (diff) |
ART: Configure stack guard size in the Makefile
Configure the stack guard reserved size through defines set in
the Makefile. This can be used to increase the gap depending on
the configuration, which may be required to safely support Java
stack overflows in instrumented builds.
Bug: 30766843
Change-Id: Icdd3209e3a261ea8383ef8eab38153255339b04a
Test: m test-art-host
-rw-r--r-- | build/Android.common_build.mk | 46 | ||||
-rw-r--r-- | runtime/arch/instruction_set.cc | 47 |
2 files changed, 78 insertions, 15 deletions
diff --git a/build/Android.common_build.mk b/build/Android.common_build.mk index 73951643e4..d38fad6248 100644 --- a/build/Android.common_build.mk +++ b/build/Android.common_build.mk @@ -264,20 +264,45 @@ art_debug_asflags := -UNDEBUG art_host_non_debug_cflags := $(art_non_debug_cflags) art_target_non_debug_cflags := $(art_non_debug_cflags) +### +# Frame size +### + +# Size of the stack-overflow gap. +ART_STACK_OVERFLOW_GAP_arm := 8192 +ART_STACK_OVERFLOW_GAP_arm64 := 8192 +ART_STACK_OVERFLOW_GAP_mips := 16384 +ART_STACK_OVERFLOW_GAP_mips64 := 16384 +ART_STACK_OVERFLOW_GAP_x86 := 8192 +ART_STACK_OVERFLOW_GAP_x86_64 := 8192 +ART_COMMON_STACK_OVERFLOW_DEFINES := \ + -DART_STACK_OVERFLOW_GAP_arm=$(ART_STACK_OVERFLOW_GAP_arm) \ + -DART_STACK_OVERFLOW_GAP_arm64=$(ART_STACK_OVERFLOW_GAP_arm64) \ + -DART_STACK_OVERFLOW_GAP_mips=$(ART_STACK_OVERFLOW_GAP_mips) \ + -DART_STACK_OVERFLOW_GAP_mips64=$(ART_STACK_OVERFLOW_GAP_mips64) \ + -DART_STACK_OVERFLOW_GAP_x86=$(ART_STACK_OVERFLOW_GAP_x86) \ + -DART_STACK_OVERFLOW_GAP_x86_64=$(ART_STACK_OVERFLOW_GAP_x86_64) \ + +# Larger frame-size for host builds today. +ART_HOST_FRAME_SIZE_LIMIT := 2700 +ART_TARGET_FRAME_SIZE_LIMIT := 1736 + +# Frame size adaptations for instrumented builds. +ifdef SANITIZE_TARGET + ART_TARGET_FRAME_SIZE_LIMIT := 6400 +endif + +# Add frame-size checks for non-debug builds. ifeq ($(HOST_OS),linux) - # Larger frame-size for host clang builds today ifneq ($(ART_COVERAGE),true) ifneq ($(NATIVE_COVERAGE),true) - art_host_non_debug_cflags += -Wframe-larger-than=2700 - ifdef SANITIZE_TARGET - art_target_non_debug_cflags += -Wframe-larger-than=6400 - else - art_target_non_debug_cflags += -Wframe-larger-than=1736 - endif + art_host_non_debug_cflags += -Wframe-larger-than=$(ART_HOST_FRAME_SIZE_LIMIT) + art_target_non_debug_cflags += -Wframe-larger-than=$(ART_TARGET_FRAME_SIZE_LIMIT) endif endif endif + ART_HOST_CFLAGS := $(art_cflags) ART_TARGET_CFLAGS := $(art_cflags) @@ -294,6 +319,10 @@ endif ART_HOST_CFLAGS += -DART_BASE_ADDRESS=$(LIBART_IMG_HOST_BASE_ADDRESS) ART_HOST_CFLAGS += -DART_DEFAULT_INSTRUCTION_SET_FEATURES=default $(art_host_cflags) +ART_HOST_CFLAGS += -DART_FRAME_SIZE_LIMIT=$(ART_HOST_FRAME_SIZE_LIMIT) \ + $(ART_COMMON_STACK_OVERFLOW_DEFINES) + + ifndef LIBART_IMG_TARGET_BASE_ADDRESS $(error LIBART_IMG_TARGET_BASE_ADDRESS unset) endif @@ -301,6 +330,9 @@ endif ART_TARGET_CFLAGS += -DART_TARGET \ -DART_BASE_ADDRESS=$(LIBART_IMG_TARGET_BASE_ADDRESS) \ +ART_TARGET_CFLAGS += -DART_FRAME_SIZE_LIMIT=$(ART_TARGET_FRAME_SIZE_LIMIT) \ + $(ART_COMMON_STACK_OVERFLOW_DEFINES) + ifeq ($(ART_TARGET_LINUX),true) # Setting ART_TARGET_LINUX to true compiles art/ assuming that the target device # will be running linux rather than android. diff --git a/runtime/arch/instruction_set.cc b/runtime/arch/instruction_set.cc index 81ca010423..b35e0889e4 100644 --- a/runtime/arch/instruction_set.cc +++ b/runtime/arch/instruction_set.cc @@ -18,6 +18,7 @@ // Explicitly include our own elf.h to avoid Linux and other dependencies. #include "../elf.h" +#include "base/bit_utils.h" #include "globals.h" namespace art { @@ -113,14 +114,44 @@ size_t GetInstructionSetAlignment(InstructionSet isa) { } } -static constexpr size_t kDefaultStackOverflowReservedBytes = 16 * KB; -static constexpr size_t kMipsStackOverflowReservedBytes = kDefaultStackOverflowReservedBytes; -static constexpr size_t kMips64StackOverflowReservedBytes = kDefaultStackOverflowReservedBytes; - -static constexpr size_t kArmStackOverflowReservedBytes = 8 * KB; -static constexpr size_t kArm64StackOverflowReservedBytes = 8 * KB; -static constexpr size_t kX86StackOverflowReservedBytes = 8 * KB; -static constexpr size_t kX86_64StackOverflowReservedBytes = 8 * KB; +#if !defined(ART_STACK_OVERFLOW_GAP_arm) || !defined(ART_STACK_OVERFLOW_GAP_arm64) || \ + !defined(ART_STACK_OVERFLOW_GAP_mips) || !defined(ART_STACK_OVERFLOW_GAP_mips64) || \ + !defined(ART_STACK_OVERFLOW_GAP_x86) || !defined(ART_STACK_OVERFLOW_GAP_x86_64) +#error "Missing defines for stack overflow gap" +#endif + +static constexpr size_t kArmStackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_arm; +static constexpr size_t kArm64StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_arm64; +static constexpr size_t kMipsStackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_mips; +static constexpr size_t kMips64StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_mips64; +static constexpr size_t kX86StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_x86; +static constexpr size_t kX86_64StackOverflowReservedBytes = ART_STACK_OVERFLOW_GAP_x86_64; + +static_assert(IsAligned<kPageSize>(kArmStackOverflowReservedBytes), "ARM gap not page aligned"); +static_assert(IsAligned<kPageSize>(kArm64StackOverflowReservedBytes), "ARM64 gap not page aligned"); +static_assert(IsAligned<kPageSize>(kMipsStackOverflowReservedBytes), "Mips gap not page aligned"); +static_assert(IsAligned<kPageSize>(kMips64StackOverflowReservedBytes), + "Mips64 gap not page aligned"); +static_assert(IsAligned<kPageSize>(kX86StackOverflowReservedBytes), "X86 gap not page aligned"); +static_assert(IsAligned<kPageSize>(kX86_64StackOverflowReservedBytes), + "X86_64 gap not page aligned"); + +#if !defined(ART_FRAME_SIZE_LIMIT) +#error "ART frame size limit missing" +#endif + +// TODO: Should we require an extra page (RoundUp(SIZE) + kPageSize)? +static_assert(ART_FRAME_SIZE_LIMIT < kArmStackOverflowReservedBytes, "Frame size limit too large"); +static_assert(ART_FRAME_SIZE_LIMIT < kArm64StackOverflowReservedBytes, + "Frame size limit too large"); +static_assert(ART_FRAME_SIZE_LIMIT < kMipsStackOverflowReservedBytes, + "Frame size limit too large"); +static_assert(ART_FRAME_SIZE_LIMIT < kMips64StackOverflowReservedBytes, + "Frame size limit too large"); +static_assert(ART_FRAME_SIZE_LIMIT < kX86StackOverflowReservedBytes, + "Frame size limit too large"); +static_assert(ART_FRAME_SIZE_LIMIT < kX86_64StackOverflowReservedBytes, + "Frame size limit too large"); size_t GetStackOverflowReservedBytes(InstructionSet isa) { switch (isa) { |