/* * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. *
*/
void StackOverflow::initialize_stack_zone_sizes() { // Stack zone sizes must be page aligned.
size_t page_size = os::vm_page_size();
// We need to adapt the configured number of stack protection pages to the // actual OS page size. We must do this before setting up minimal stack // sizes etc. in os::init_2(). The option values are given in 4K units, // matching the smallest page size in supported platforms.
size_t unit = 4*K;
assert(_stack_red_zone_size == 0, "This should be called only once.");
_stack_red_zone_size = align_up(StackRedPages * unit, page_size);
assert(_stack_yellow_zone_size == 0, "This should be called only once.");
_stack_yellow_zone_size = align_up(StackYellowPages * unit, page_size);
assert(_stack_reserved_zone_size == 0, "This should be called only once.");
_stack_reserved_zone_size = align_up(StackReservedPages * unit, page_size);
// The shadow area is not allocated or protected, so // it needs not be page aligned. // But the stack bang currently assumes that it is a // multiple of page size. This guarantees that the bang // loop touches all pages in the shadow zone. // This can be guaranteed differently, as well. E.g., if // the page size is a multiple of 4K, banging in 4K steps // suffices to touch all pages. (Some pages are banged // several times, though.)
assert(_stack_shadow_zone_size == 0, "This should be called only once.");
_stack_shadow_zone_size = align_up(StackShadowPages * unit, page_size);
}
bool StackOverflow::stack_guards_enabled() const { #ifdef ASSERT if (os::uses_stack_guard_pages() &&
!(DisablePrimordialThreadGuardPages && os::is_primordial_thread())) {
assert(_stack_guard_state != stack_guard_unused, "guard pages must be in use");
} #endif return _stack_guard_state == stack_guard_enabled;
}
assert(is_aligned(low_addr, os::vm_page_size()), "Stack base should be the start of a page");
assert(is_aligned(len, os::vm_page_size()), "Stack size should be a multiple of page size");
int must_commit = os::must_commit_stack_guard_pages(); // warning("Guarding at " PTR_FORMAT " for len " SIZE_FORMAT "\n", low_addr, len);
if (must_commit && !os::create_stack_guard_pages((char *) low_addr, len)) {
log_warning(os, thread)("Attempt to allocate stack guard pages failed."); return;
}
// The base notation is from the stack's point of view, growing downward. // We need to adjust it to work correctly with guard_memory()
address base = stack_reserved_zone_base() - stack_reserved_zone_size();
// Simply return if called for a thread that does not use guard pages. if (_stack_guard_state != stack_guard_enabled) return;
// The base notation is from the stack's point of view, growing downward. // We need to adjust it to work correctly with guard_memory()
address base = stack_reserved_zone_base() - stack_reserved_zone_size();
if (os::unguard_memory((char *)base, stack_reserved_zone_size())) {
_stack_guard_state = stack_guard_reserved_disabled;
} else {
warning("Attempt to unguard stack reserved zone failed.");
}
}
void StackOverflow::enable_stack_yellow_reserved_zone() {
assert(_stack_guard_state != stack_guard_unused, "must be using guard pages.");
assert(_stack_guard_state != stack_guard_enabled, "already enabled");
// The base notation is from the stacks point of view, growing downward. // We need to adjust it to work correctly with guard_memory()
address base = stack_red_zone_base();
if (os::guard_memory((char *) base, stack_yellow_reserved_zone_size())) {
_stack_guard_state = stack_guard_enabled;
} else {
warning("Attempt to guard stack yellow zone failed.");
}
}
void StackOverflow::disable_stack_yellow_reserved_zone() {
assert(_stack_guard_state != stack_guard_unused, "must be using guard pages.");
assert(_stack_guard_state != stack_guard_yellow_reserved_disabled, "already disabled");
// Simply return if called for a thread that does not use guard pages. if (_stack_guard_state == stack_guard_unused) return;
// The base notation is from the stacks point of view, growing downward. // We need to adjust it to work correctly with guard_memory()
address base = stack_red_zone_base();
if (os::unguard_memory((char *)base, stack_yellow_reserved_zone_size())) {
_stack_guard_state = stack_guard_yellow_reserved_disabled;
} else {
warning("Attempt to unguard stack yellow zone failed.");
}
}
void StackOverflow::disable_stack_red_zone() { // The base notation is from the stacks point of view, growing downward. // We need to adjust it to work correctly with guard_memory()
assert(_stack_guard_state != stack_guard_unused, "must be using guard pages.");
address base = stack_red_zone_base() - stack_red_zone_size(); if (!os::unguard_memory((char *)base, stack_red_zone_size())) {
warning("Attempt to unguard stack red zone failed.");
}
}
bool StackOverflow::reguard_stack(address cur_sp) { if (_stack_guard_state != stack_guard_yellow_reserved_disabled
&& _stack_guard_state != stack_guard_reserved_disabled) { returntrue; // Stack already guarded or guard pages not needed.
}
// Java code never executes within the yellow zone: the latter is only // there to provoke an exception during stack banging. If java code // is executing there, either StackShadowPages should be larger, or // some exception code in c1, c2 or the interpreter isn't unwinding // when it should.
guarantee(cur_sp > stack_reserved_zone_base(), "not enough space to reguard - increase StackShadowPages"); if (_stack_guard_state == stack_guard_yellow_reserved_disabled) {
enable_stack_yellow_reserved_zone(); if (reserved_stack_activation() != stack_base()) {
set_reserved_stack_activation(stack_base());
}
} elseif (_stack_guard_state == stack_guard_reserved_disabled) {
set_reserved_stack_activation(stack_base());
enable_stack_reserved_zone();
} returntrue;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.