New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for 64-bit Windows builds #16261
Changes from 9 commits
862ba43
bf420e5
bf76e00
ad2f67f
9bdaf0b
081991e
a12b235
5a24ee8
cb55279
cd2003f
881bfb1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -125,7 +125,7 @@ extern fn stack_exhausted() { | |
} | ||
|
||
#[inline(always)] | ||
pub unsafe fn record_stack_bounds(stack_lo: uint, stack_hi: uint) { | ||
pub unsafe fn record_stack_bounds_green(stack_lo: uint, stack_hi: uint) { | ||
// When the old runtime had segmented stacks, it used a calculation that was | ||
// "limit + RED_ZONE + FUDGE". The red zone was for things like dynamic | ||
// symbol resolution, llvm function calls, etc. In theory this red zone | ||
|
@@ -154,6 +154,11 @@ pub unsafe fn record_stack_bounds(stack_lo: uint, stack_hi: uint) { | |
} | ||
} | ||
|
||
#[inline(always)] | ||
pub unsafe fn record_stack_bounds(stack_lo: uint, _stack_hi: uint) { | ||
record_sp_limit(stack_lo + RED_ZONE); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why was this introduced? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is to allow setting morestack stack limit from libnative without touching Windows's stack bounds TIB fields (gs:0x08 and gs:0x10). Since libnative relies on os-managed stacks, it should not mess with these. Currently it doesn't even do it correctly, because gs:0x10 is supposed to be the commit limit, not the reserve limit, as @klutzy had explained here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If that's the case, this function needs to have some comments to justify its existence and explain what it's doing. Also, if the other function is wrong, why not just delete it? Surely it must be doing something? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The original function is still needed for libgreen, because it creates stacks from scratch. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thinking about this, could you just update libnative to call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mean Maybe call libnative variant There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, that sounds good to me. I think that the green/native naming is a bit of a misnomer, but There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you also add a comment to the function explaining how its different from the others? |
||
|
||
/// Records the current limit of the stack as specified by `end`. | ||
/// | ||
/// This is stored in an OS-dependent location, likely inside of the thread | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -227,7 +227,7 @@ fn rust_exception_class() -> uw::_Unwind_Exception_Class { | |
// This is achieved by overriding the return value in search phase to always | ||
// say "catch!". | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this comment is outdated with respect to there being two personality functions now used by the "try function"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No there's still two. We just no longer use |
||
|
||
#[cfg(not(target_arch = "arm"), not(test))] | ||
#[cfg(not(target_arch = "arm"), not(windows, target_arch = "x86_64"), not(test))] | ||
#[doc(hidden)] | ||
#[allow(visible_private_types)] | ||
pub mod eabi { | ||
|
@@ -244,7 +244,8 @@ pub mod eabi { | |
} | ||
|
||
#[lang="eh_personality"] | ||
extern fn eh_personality( | ||
#[no_mangle] // referenced from rust_try.ll | ||
extern fn rust_eh_personality( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This may have been a rebase gone awry There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, that's intentional. |
||
version: c_int, | ||
actions: uw::_Unwind_Action, | ||
exception_class: uw::_Unwind_Exception_Class, | ||
|
@@ -260,21 +261,19 @@ pub mod eabi { | |
|
||
#[no_mangle] // referenced from rust_try.ll | ||
pub extern "C" fn rust_eh_personality_catch( | ||
version: c_int, | ||
_version: c_int, | ||
actions: uw::_Unwind_Action, | ||
exception_class: uw::_Unwind_Exception_Class, | ||
ue_header: *mut uw::_Unwind_Exception, | ||
context: *mut uw::_Unwind_Context | ||
_exception_class: uw::_Unwind_Exception_Class, | ||
_ue_header: *mut uw::_Unwind_Exception, | ||
_context: *mut uw::_Unwind_Context | ||
) -> uw::_Unwind_Reason_Code | ||
{ | ||
|
||
if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase | ||
uw::_URC_HANDLER_FOUND // catch! | ||
} | ||
else { // cleanup phase | ||
unsafe { | ||
__gcc_personality_v0(version, actions, exception_class, ue_header, | ||
context) | ||
} | ||
uw::_URC_INSTALL_CONTEXT | ||
} | ||
} | ||
} | ||
|
@@ -299,7 +298,7 @@ pub mod eabi { | |
} | ||
|
||
#[lang="eh_personality"] | ||
#[no_mangle] // so we can reference it by name from middle/trans/base.rs | ||
#[no_mangle] // referenced from rust_try.ll | ||
pub extern "C" fn rust_eh_personality( | ||
version: c_int, | ||
actions: uw::_Unwind_Action, | ||
|
@@ -316,29 +315,26 @@ pub mod eabi { | |
|
||
#[no_mangle] // referenced from rust_try.ll | ||
pub extern "C" fn rust_eh_personality_catch( | ||
version: c_int, | ||
_version: c_int, | ||
actions: uw::_Unwind_Action, | ||
exception_class: uw::_Unwind_Exception_Class, | ||
ue_header: *mut uw::_Unwind_Exception, | ||
context: *mut uw::_Unwind_Context | ||
_exception_class: uw::_Unwind_Exception_Class, | ||
_ue_header: *mut uw::_Unwind_Exception, | ||
_context: *mut uw::_Unwind_Context | ||
) -> uw::_Unwind_Reason_Code | ||
{ | ||
if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase | ||
uw::_URC_HANDLER_FOUND // catch! | ||
} | ||
else { // cleanup phase | ||
unsafe { | ||
__gcc_personality_sj0(version, actions, exception_class, ue_header, | ||
context) | ||
} | ||
uw::_URC_INSTALL_CONTEXT | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was this intentional? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. |
||
} | ||
} | ||
} | ||
|
||
|
||
// ARM EHABI uses a slightly different personality routine signature, | ||
// but otherwise works the same. | ||
#[cfg(target_arch = "arm", not(test), not(target_os = "ios"))] | ||
#[cfg(target_arch = "arm", not(target_os = "ios", not(test)))] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. does nested There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't think so. It's a typo. :( |
||
#[allow(visible_private_types)] | ||
pub mod eabi { | ||
use uw = libunwind; | ||
|
@@ -352,7 +348,8 @@ pub mod eabi { | |
} | ||
|
||
#[lang="eh_personality"] | ||
extern "C" fn eh_personality( | ||
#[no_mangle] // referenced from rust_try.ll | ||
extern "C" fn rust_eh_personality( | ||
state: uw::_Unwind_State, | ||
ue_header: *mut uw::_Unwind_Exception, | ||
context: *mut uw::_Unwind_Context | ||
|
@@ -366,19 +363,117 @@ pub mod eabi { | |
#[no_mangle] // referenced from rust_try.ll | ||
pub extern "C" fn rust_eh_personality_catch( | ||
state: uw::_Unwind_State, | ||
ue_header: *mut uw::_Unwind_Exception, | ||
context: *mut uw::_Unwind_Context | ||
_ue_header: *mut uw::_Unwind_Exception, | ||
_context: *mut uw::_Unwind_Context | ||
) -> uw::_Unwind_Reason_Code | ||
{ | ||
if (state as c_int & uw::_US_ACTION_MASK as c_int) | ||
== uw::_US_VIRTUAL_UNWIND_FRAME as c_int { // search phase | ||
uw::_URC_HANDLER_FOUND // catch! | ||
} | ||
else { // cleanup phase | ||
unsafe { | ||
__gcc_personality_v0(state, ue_header, context) | ||
uw::_URC_INSTALL_CONTEXT | ||
} | ||
} | ||
} | ||
|
||
// Win64 SEH (see http://msdn.microsoft.com/en-us/library/1eyas8tf.aspx) | ||
// | ||
// This looks a bit convoluted because rather than implementing a native SEH handler, | ||
// GCC reuses the same personality routine as for the other architectures by wrapping it | ||
// with an "API translator" layer (_GCC_specific_handler). | ||
|
||
#[cfg(windows, target_arch = "x86_64", not(test))] | ||
#[allow(visible_private_types)] | ||
#[allow(non_camel_case_types)] | ||
#[allow(unused_variable)] | ||
#[allow(uppercase_variables)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These could probably just be combined to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, is you prefer it that way. |
||
pub mod eabi { | ||
use uw = libunwind; | ||
use libc::{c_void, c_int}; | ||
|
||
struct EXCEPTION_RECORD; | ||
struct CONTEXT; | ||
struct DISPATCHER_CONTEXT; | ||
|
||
#[repr(C)] | ||
enum EXCEPTION_DISPOSITION { | ||
ExceptionContinueExecution, | ||
ExceptionContinueSearch, | ||
ExceptionNestedException, | ||
ExceptionCollidedUnwind | ||
} | ||
|
||
type _Unwind_Personality_Fn = | ||
extern "C" fn( | ||
version: c_int, | ||
actions: uw::_Unwind_Action, | ||
exception_class: uw::_Unwind_Exception_Class, | ||
ue_header: *mut uw::_Unwind_Exception, | ||
context: *mut uw::_Unwind_Context | ||
) -> uw::_Unwind_Reason_Code; | ||
|
||
extern "C" { | ||
fn __gcc_personality_seh0( | ||
exceptionRecord: *mut EXCEPTION_RECORD, | ||
establisherFrame: *mut c_void, | ||
contextRecord: *mut CONTEXT, | ||
dispatcherContext: *mut DISPATCHER_CONTEXT | ||
) -> EXCEPTION_DISPOSITION; | ||
|
||
fn _GCC_specific_handler( | ||
exceptionRecord: *mut EXCEPTION_RECORD, | ||
establisherFrame: *mut c_void, | ||
contextRecord: *mut CONTEXT, | ||
dispatcherContext: *mut DISPATCHER_CONTEXT, | ||
personality: _Unwind_Personality_Fn | ||
) -> EXCEPTION_DISPOSITION; | ||
} | ||
|
||
#[lang="eh_personality"] | ||
#[no_mangle] // referenced from rust_try.ll | ||
extern "C" fn rust_eh_personality( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
exceptionRecord: *mut EXCEPTION_RECORD, | ||
establisherFrame: *mut c_void, | ||
contextRecord: *mut CONTEXT, | ||
dispatcherContext: *mut DISPATCHER_CONTEXT | ||
) -> EXCEPTION_DISPOSITION | ||
{ | ||
unsafe { | ||
__gcc_personality_seh0(exceptionRecord, establisherFrame, | ||
contextRecord, dispatcherContext) | ||
} | ||
} | ||
|
||
#[no_mangle] // referenced from rust_try.ll | ||
pub extern "C" fn rust_eh_personality_catch( | ||
exceptionRecord: *mut EXCEPTION_RECORD, | ||
establisherFrame: *mut c_void, | ||
contextRecord: *mut CONTEXT, | ||
dispatcherContext: *mut DISPATCHER_CONTEXT | ||
) -> EXCEPTION_DISPOSITION | ||
{ | ||
extern "C" fn inner( | ||
_version: c_int, | ||
actions: uw::_Unwind_Action, | ||
_exception_class: uw::_Unwind_Exception_Class, | ||
_ue_header: *mut uw::_Unwind_Exception, | ||
_context: *mut uw::_Unwind_Context | ||
) -> uw::_Unwind_Reason_Code | ||
{ | ||
if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase | ||
uw::_URC_HANDLER_FOUND // catch! | ||
} | ||
else { // cleanup phase | ||
uw::_URC_INSTALL_CONTEXT | ||
} | ||
} | ||
|
||
unsafe { | ||
_GCC_specific_handler(exceptionRecord, establisherFrame, | ||
contextRecord, dispatcherContext, | ||
inner) | ||
} | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is changed by the line? (was this causing problem on some environments?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Purely cosmetic. Since we are now on mingw64, I thought we should use its' triple for consistency.