diff options
| -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) { |