From e8dc2c2ae3d2129dcd06674f2b513c7d49878d3b Mon Sep 17 00:00:00 2001 From: roland Date: Mon, 27 Feb 2012 09:17:44 +0100 Subject: [PATCH] 7147740: add assertions to check stack alignment on VM entry from generated code (x64) Summary: check stack alignment on VM entry on x64. Reviewed-by: kvn, never --- src/cpu/x86/vm/stubGenerator_x86_64.cpp | 16 +++++++++++ src/cpu/x86/vm/stubRoutines_x86_64.cpp | 1 + src/cpu/x86/vm/stubRoutines_x86_64.hpp | 6 ++++ src/os/solaris/vm/os_solaris.cpp | 9 ------ src/os/windows/vm/os_windows.cpp | 10 ------- src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp | 5 ++++ src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp | 5 ++++ src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp | 5 ++++ src/os_cpu/linux_x86/vm/os_linux_x86.cpp | 8 ++++++ src/os_cpu/linux_zero/vm/os_linux_zero.cpp | 5 ++++ .../solaris_sparc/vm/os_solaris_sparc.cpp | 14 ++++++++++ src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp | 14 ++++++++++ src/os_cpu/solaris_x86/vm/solaris_x86_32.il | 6 ++++ src/os_cpu/solaris_x86/vm/solaris_x86_64.il | 6 ++++ src/os_cpu/windows_x86/vm/os_windows_x86.cpp | 28 +++++++++++++++++++ src/share/vm/runtime/interfaceSupport.hpp | 3 ++ src/share/vm/runtime/os.hpp | 2 ++ 17 files changed, 124 insertions(+), 19 deletions(-) diff --git a/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/src/cpu/x86/vm/stubGenerator_x86_64.cpp index d68bdac6d..9d9472200 100644 --- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp @@ -710,6 +710,21 @@ class StubGenerator: public StubCodeGenerator { return start; } + // Support for intptr_t get_previous_sp() + // + // This routine is used to find the previous stack pointer for the + // caller. + address generate_get_previous_sp() { + StubCodeMark mark(this, "StubRoutines", "get_previous_sp"); + address start = __ pc(); + + __ movptr(rax, rsp); + __ addptr(rax, 8); // return address is at the top of the stack. + __ ret(0); + + return start; + } + //---------------------------------------------------------------------------------------------------- // Support for void verify_mxcsr() // @@ -3060,6 +3075,7 @@ class StubGenerator: public StubCodeGenerator { // platform dependent StubRoutines::x86::_get_previous_fp_entry = generate_get_previous_fp(); + StubRoutines::x86::_get_previous_sp_entry = generate_get_previous_sp(); StubRoutines::x86::_verify_mxcsr_entry = generate_verify_mxcsr(); diff --git a/src/cpu/x86/vm/stubRoutines_x86_64.cpp b/src/cpu/x86/vm/stubRoutines_x86_64.cpp index 182872b88..782dc9063 100644 --- a/src/cpu/x86/vm/stubRoutines_x86_64.cpp +++ b/src/cpu/x86/vm/stubRoutines_x86_64.cpp @@ -43,6 +43,7 @@ // a description of how to extend it, see the stubRoutines.hpp file. address StubRoutines::x86::_get_previous_fp_entry = NULL; +address StubRoutines::x86::_get_previous_sp_entry = NULL; address StubRoutines::x86::_verify_mxcsr_entry = NULL; diff --git a/src/cpu/x86/vm/stubRoutines_x86_64.hpp b/src/cpu/x86/vm/stubRoutines_x86_64.hpp index 3d2a4fb9a..7737c4eee 100644 --- a/src/cpu/x86/vm/stubRoutines_x86_64.hpp +++ b/src/cpu/x86/vm/stubRoutines_x86_64.hpp @@ -41,6 +41,7 @@ class x86 { private: static address _get_previous_fp_entry; + static address _get_previous_sp_entry; static address _verify_mxcsr_entry; static address _f2i_fixup; @@ -61,6 +62,11 @@ class x86 { return _get_previous_fp_entry; } + static address get_previous_sp_entry() + { + return _get_previous_sp_entry; + } + static address verify_mxcsr_entry() { return _verify_mxcsr_entry; diff --git a/src/os/solaris/vm/os_solaris.cpp b/src/os/solaris/vm/os_solaris.cpp index c47d37433..31bd41862 100644 --- a/src/os/solaris/vm/os_solaris.cpp +++ b/src/os/solaris/vm/os_solaris.cpp @@ -1013,15 +1013,6 @@ extern "C" void breakpoint() { // use debugger to set breakpoint here } -// Returns an estimate of the current stack pointer. Result must be guaranteed to -// point into the calling threads stack, and be no lower than the current stack -// pointer. -address os::current_stack_pointer() { - volatile int dummy; - address sp = (address)&dummy + 8; // %%%% need to confirm if this is right - return sp; -} - static thread_t main_thread; // Thread start routine for all new Java threads diff --git a/src/os/windows/vm/os_windows.cpp b/src/os/windows/vm/os_windows.cpp index 970aab747..de38c6c12 100644 --- a/src/os/windows/vm/os_windows.cpp +++ b/src/os/windows/vm/os_windows.cpp @@ -324,16 +324,6 @@ extern "C" void breakpoint() { os::breakpoint(); } -// Returns an estimate of the current stack pointer. Result must be guaranteed -// to point into the calling threads stack, and be no lower than the current -// stack pointer. - -address os::current_stack_pointer() { - int dummy; - address sp = (address)&dummy; - return sp; -} - // os::current_stack_base() // // Returns the base of the stack, which is the stack's diff --git a/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp b/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp index 06ba58075..12d6871ca 100644 --- a/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp +++ b/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp @@ -1126,3 +1126,8 @@ void os::setup_fpu() { : "r" (fpu_cntrl) : "memory"); #endif // !AMD64 } + +#ifndef PRODUCT +void os::verify_stack_alignment() { +} +#endif diff --git a/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp b/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp index ff5b32dbf..4bb5a8abb 100644 --- a/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp +++ b/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp @@ -562,3 +562,8 @@ extern "C" { } }; #endif // !_LP64 + +#ifndef PRODUCT +void os::verify_stack_alignment() { +} +#endif diff --git a/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp b/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp index 62131ee6f..11c90e522 100644 --- a/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp +++ b/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp @@ -756,3 +756,8 @@ size_t os::Linux::default_guard_size(os::ThreadType thr_type) { // guard page, only enable glibc guard page for non-Java threads. return (thr_type == java_thread ? 0 : page_size()); } + +#ifndef PRODUCT +void os::verify_stack_alignment() { +} +#endif diff --git a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp index ba484b9fd..93bb1f459 100644 --- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp +++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp @@ -862,3 +862,11 @@ void os::setup_fpu() { : "r" (fpu_cntrl) : "memory"); #endif // !AMD64 } + +#ifndef PRODUCT +void os::verify_stack_alignment() { +#ifdef AMD64 + assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment"); +#endif +} +#endif diff --git a/src/os_cpu/linux_zero/vm/os_linux_zero.cpp b/src/os_cpu/linux_zero/vm/os_linux_zero.cpp index 32c2d0a51..203090ce0 100644 --- a/src/os_cpu/linux_zero/vm/os_linux_zero.cpp +++ b/src/os_cpu/linux_zero/vm/os_linux_zero.cpp @@ -506,3 +506,8 @@ extern "C" { } }; #endif // !_LP64 + +#ifndef PRODUCT +void os::verify_stack_alignment() { +} +#endif diff --git a/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp b/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp index 971f600fe..752daf7bf 100644 --- a/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp +++ b/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp @@ -251,6 +251,15 @@ frame os::get_sender_for_C_frame(frame* fr) { return frame(fr->sender_sp(), frame::unpatchable, fr->sender_pc()); } +// Returns an estimate of the current stack pointer. Result must be guaranteed to +// point into the calling threads stack, and be no lower than the current stack +// pointer. +address os::current_stack_pointer() { + volatile int dummy; + address sp = (address)&dummy + 8; // %%%% need to confirm if this is right + return sp; +} + frame os::current_frame() { intptr_t* sp = StubRoutines::Sparc::flush_callers_register_windows_func()(); frame myframe(sp, frame::unpatchable, @@ -815,3 +824,8 @@ add_func_t* os::atomic_add_func = os::atomic_add_bootstrap; __asm__ __volatile__ ("wr %%g0, 0, %%fprs \n\t" : : :); } #endif //defined(__sparc) && defined(COMPILER2) + +#ifndef PRODUCT +void os::verify_stack_alignment() { +} +#endif diff --git a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp index 78e93ea66..ec047c16b 100644 --- a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp +++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp @@ -237,6 +237,12 @@ frame os::get_sender_for_C_frame(frame* fr) { return frame(fr->sender_sp(), fr->link(), fr->sender_pc()); } +extern "C" intptr_t *_get_current_sp(); // in .il file + +address os::current_stack_pointer() { + return (address)_get_current_sp(); +} + extern "C" intptr_t *_get_current_fp(); // in .il file frame os::current_frame() { @@ -954,3 +960,11 @@ void os::setup_fpu() { _solaris_raw_setup_fpu(fpu_cntrl); } #endif // AMD64 + +#ifndef PRODUCT +void os::verify_stack_alignment() { +#ifdef AMD64 + assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment"); +#endif +} +#endif diff --git a/src/os_cpu/solaris_x86/vm/solaris_x86_32.il b/src/os_cpu/solaris_x86/vm/solaris_x86_32.il index b635a8292..9b0f07da3 100644 --- a/src/os_cpu/solaris_x86/vm/solaris_x86_32.il +++ b/src/os_cpu/solaris_x86/vm/solaris_x86_32.il @@ -37,6 +37,12 @@ movl %gs:0, %eax .end + // Get current sp + .inline _get_current_sp,0 + .volatile + movl %esp, %eax + .end + // Get current fp .inline _get_current_fp,0 .volatile diff --git a/src/os_cpu/solaris_x86/vm/solaris_x86_64.il b/src/os_cpu/solaris_x86/vm/solaris_x86_64.il index fb7946b8c..89809bc54 100644 --- a/src/os_cpu/solaris_x86/vm/solaris_x86_64.il +++ b/src/os_cpu/solaris_x86/vm/solaris_x86_64.il @@ -30,6 +30,12 @@ movq %fs:0, %rax .end + // Get current sp + .inline _get_current_sp,0 + .volatile + movq %rsp, %rax + .end + // Get current fp .inline _get_current_fp,0 .volatile diff --git a/src/os_cpu/windows_x86/vm/os_windows_x86.cpp b/src/os_cpu/windows_x86/vm/os_windows_x86.cpp index 960ceab66..52fe243ee 100644 --- a/src/os_cpu/windows_x86/vm/os_windows_x86.cpp +++ b/src/os_cpu/windows_x86/vm/os_windows_x86.cpp @@ -370,6 +370,26 @@ frame os::get_sender_for_C_frame(frame* fr) { return frame(fr->sender_sp(), fr->link(), fr->sender_pc()); } +#ifndef AMD64 +// Returns an estimate of the current stack pointer. Result must be guaranteed +// to point into the calling threads stack, and be no lower than the current +// stack pointer. +address os::current_stack_pointer() { + int dummy; + address sp = (address)&dummy; + return sp; +} +#else +// Returns the current stack pointer. Accurate value needed for +// os::verify_stack_alignment(). +address os::current_stack_pointer() { + typedef address get_sp_func(); + get_sp_func* func = CAST_TO_FN_PTR(get_sp_func*, + StubRoutines::x86::get_previous_sp_entry()); + return (*func)(); +} +#endif + #ifndef AMD64 intptr_t* _get_previous_fp() { @@ -546,3 +566,11 @@ void os::setup_fpu() { __asm fldcw fpu_cntrl_word; #endif // !AMD64 } + +#ifndef PRODUCT +void os::verify_stack_alignment() { +#ifdef AMD64 + assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment"); +#endif +} +#endif diff --git a/src/share/vm/runtime/interfaceSupport.hpp b/src/share/vm/runtime/interfaceSupport.hpp index e1001eea1..2875ee0eb 100644 --- a/src/share/vm/runtime/interfaceSupport.hpp +++ b/src/share/vm/runtime/interfaceSupport.hpp @@ -436,6 +436,7 @@ class RuntimeHistogramElement : public HistogramElement { #define VM_LEAF_BASE(result_type, header) \ TRACE_CALL(result_type, header) \ debug_only(NoHandleMark __hm;) \ + os::verify_stack_alignment(); \ /* begin of body */ @@ -445,6 +446,7 @@ class RuntimeHistogramElement : public HistogramElement { TRACE_CALL(result_type, header) \ HandleMarkCleaner __hm(thread); \ Thread* THREAD = thread; \ + os::verify_stack_alignment(); \ /* begin of body */ @@ -454,6 +456,7 @@ class RuntimeHistogramElement : public HistogramElement { TRACE_CALL(result_type, header) \ debug_only(NoHandleMark __hm;) \ Thread* THREAD = thread; \ + os::verify_stack_alignment(); \ /* begin of body */ diff --git a/src/share/vm/runtime/os.hpp b/src/share/vm/runtime/os.hpp index e77f3ce91..dd163e9a9 100644 --- a/src/share/vm/runtime/os.hpp +++ b/src/share/vm/runtime/os.hpp @@ -404,6 +404,8 @@ class os: AllStatic { static address current_stack_base(); static size_t current_stack_size(); + static void verify_stack_alignment() PRODUCT_RETURN; + static int message_box(const char* title, const char* message); static char* do_you_want_to_debug(const char* message); -- GitLab