[x64] Fix up offset of stack alloc in prolog for unwind info.
- [x64] Track offset of stack alloc in prolog within emitted functions. - [x64] Don't use hardcoded offset of stack alloc in prolog in generated unwind info.
This commit is contained in:
parent
0dc4a13db3
commit
24321dbcd9
|
@ -2,7 +2,7 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
* Copyright 2019 Ben Vanik. All rights reserved. *
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
@ -409,6 +409,7 @@ HostToGuestThunk X64ThunkEmitter::EmitHostToGuestThunk() {
|
||||||
|
|
||||||
struct _code_offsets {
|
struct _code_offsets {
|
||||||
size_t prolog;
|
size_t prolog;
|
||||||
|
size_t prolog_stack_alloc;
|
||||||
size_t body;
|
size_t body;
|
||||||
size_t epilog;
|
size_t epilog;
|
||||||
size_t tail;
|
size_t tail;
|
||||||
|
@ -424,6 +425,7 @@ HostToGuestThunk X64ThunkEmitter::EmitHostToGuestThunk() {
|
||||||
mov(qword[rsp + 8 * 1], rcx);
|
mov(qword[rsp + 8 * 1], rcx);
|
||||||
sub(rsp, stack_size);
|
sub(rsp, stack_size);
|
||||||
|
|
||||||
|
code_offsets.prolog_stack_alloc = getSize();
|
||||||
code_offsets.body = getSize();
|
code_offsets.body = getSize();
|
||||||
|
|
||||||
// Save nonvolatile registers.
|
// Save nonvolatile registers.
|
||||||
|
@ -453,6 +455,8 @@ HostToGuestThunk X64ThunkEmitter::EmitHostToGuestThunk() {
|
||||||
func_info.code_size.body = code_offsets.epilog - code_offsets.body;
|
func_info.code_size.body = code_offsets.epilog - code_offsets.body;
|
||||||
func_info.code_size.epilog = code_offsets.tail - code_offsets.epilog;
|
func_info.code_size.epilog = code_offsets.tail - code_offsets.epilog;
|
||||||
func_info.code_size.tail = getSize() - code_offsets.tail;
|
func_info.code_size.tail = getSize() - code_offsets.tail;
|
||||||
|
func_info.prolog_stack_alloc_offset =
|
||||||
|
code_offsets.prolog_stack_alloc - code_offsets.prolog;
|
||||||
func_info.stack_size = stack_size;
|
func_info.stack_size = stack_size;
|
||||||
|
|
||||||
void* fn = Emplace(func_info);
|
void* fn = Emplace(func_info);
|
||||||
|
@ -467,6 +471,7 @@ GuestToHostThunk X64ThunkEmitter::EmitGuestToHostThunk() {
|
||||||
|
|
||||||
struct _code_offsets {
|
struct _code_offsets {
|
||||||
size_t prolog;
|
size_t prolog;
|
||||||
|
size_t prolog_stack_alloc;
|
||||||
size_t body;
|
size_t body;
|
||||||
size_t epilog;
|
size_t epilog;
|
||||||
size_t tail;
|
size_t tail;
|
||||||
|
@ -479,6 +484,7 @@ GuestToHostThunk X64ThunkEmitter::EmitGuestToHostThunk() {
|
||||||
// rsp + 0 = return address
|
// rsp + 0 = return address
|
||||||
sub(rsp, stack_size);
|
sub(rsp, stack_size);
|
||||||
|
|
||||||
|
code_offsets.prolog_stack_alloc = getSize();
|
||||||
code_offsets.body = getSize();
|
code_offsets.body = getSize();
|
||||||
|
|
||||||
// Save off volatile registers.
|
// Save off volatile registers.
|
||||||
|
@ -504,6 +510,8 @@ GuestToHostThunk X64ThunkEmitter::EmitGuestToHostThunk() {
|
||||||
func_info.code_size.body = code_offsets.epilog - code_offsets.body;
|
func_info.code_size.body = code_offsets.epilog - code_offsets.body;
|
||||||
func_info.code_size.epilog = code_offsets.tail - code_offsets.epilog;
|
func_info.code_size.epilog = code_offsets.tail - code_offsets.epilog;
|
||||||
func_info.code_size.tail = getSize() - code_offsets.tail;
|
func_info.code_size.tail = getSize() - code_offsets.tail;
|
||||||
|
func_info.prolog_stack_alloc_offset =
|
||||||
|
code_offsets.prolog_stack_alloc - code_offsets.prolog;
|
||||||
func_info.stack_size = stack_size;
|
func_info.stack_size = stack_size;
|
||||||
|
|
||||||
void* fn = Emplace(func_info);
|
void* fn = Emplace(func_info);
|
||||||
|
@ -519,6 +527,7 @@ ResolveFunctionThunk X64ThunkEmitter::EmitResolveFunctionThunk() {
|
||||||
|
|
||||||
struct _code_offsets {
|
struct _code_offsets {
|
||||||
size_t prolog;
|
size_t prolog;
|
||||||
|
size_t prolog_stack_alloc;
|
||||||
size_t body;
|
size_t body;
|
||||||
size_t epilog;
|
size_t epilog;
|
||||||
size_t tail;
|
size_t tail;
|
||||||
|
@ -531,6 +540,7 @@ ResolveFunctionThunk X64ThunkEmitter::EmitResolveFunctionThunk() {
|
||||||
// rsp + 0 = return address
|
// rsp + 0 = return address
|
||||||
sub(rsp, stack_size);
|
sub(rsp, stack_size);
|
||||||
|
|
||||||
|
code_offsets.prolog_stack_alloc = getSize();
|
||||||
code_offsets.body = getSize();
|
code_offsets.body = getSize();
|
||||||
|
|
||||||
// Save volatile registers
|
// Save volatile registers
|
||||||
|
@ -557,6 +567,8 @@ ResolveFunctionThunk X64ThunkEmitter::EmitResolveFunctionThunk() {
|
||||||
func_info.code_size.body = code_offsets.epilog - code_offsets.body;
|
func_info.code_size.body = code_offsets.epilog - code_offsets.body;
|
||||||
func_info.code_size.epilog = code_offsets.tail - code_offsets.epilog;
|
func_info.code_size.epilog = code_offsets.tail - code_offsets.epilog;
|
||||||
func_info.code_size.tail = getSize() - code_offsets.tail;
|
func_info.code_size.tail = getSize() - code_offsets.tail;
|
||||||
|
func_info.prolog_stack_alloc_offset =
|
||||||
|
code_offsets.prolog_stack_alloc - code_offsets.prolog;
|
||||||
func_info.stack_size = stack_size;
|
func_info.stack_size = stack_size;
|
||||||
|
|
||||||
void* fn = Emplace(func_info);
|
void* fn = Emplace(func_info);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
* Copyright 2019 Ben Vanik. All rights reserved. *
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
* Copyright 2019 Ben Vanik. All rights reserved. *
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
@ -33,6 +33,7 @@ struct EmitFunctionInfo {
|
||||||
size_t tail;
|
size_t tail;
|
||||||
size_t total;
|
size_t total;
|
||||||
} code_size;
|
} code_size;
|
||||||
|
size_t prolog_stack_alloc_offset; // offset of instruction after stack alloc
|
||||||
size_t stack_size;
|
size_t stack_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Copyright 2015 Ben Vanik. All rights reserved. *
|
* Copyright 2019 Ben Vanik. All rights reserved. *
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
@ -248,6 +248,10 @@ void Win32X64CodeCache::InitializeUnwindEntry(
|
||||||
|
|
||||||
assert_true(func_info.code_size.prolog < 256); // needs to fit into a uint8_t
|
assert_true(func_info.code_size.prolog < 256); // needs to fit into a uint8_t
|
||||||
auto prolog_size = static_cast<uint8_t>(func_info.code_size.prolog);
|
auto prolog_size = static_cast<uint8_t>(func_info.code_size.prolog);
|
||||||
|
assert_true(func_info.prolog_stack_alloc_offset <
|
||||||
|
256); // needs to fit into a uint8_t
|
||||||
|
auto prolog_stack_alloc_offset =
|
||||||
|
static_cast<uint8_t>(func_info.prolog_stack_alloc_offset);
|
||||||
|
|
||||||
if (!func_info.stack_size) {
|
if (!func_info.stack_size) {
|
||||||
// https://docs.microsoft.com/en-us/cpp/build/exception-handling-x64#struct-unwind_info
|
// https://docs.microsoft.com/en-us/cpp/build/exception-handling-x64#struct-unwind_info
|
||||||
|
@ -268,8 +272,7 @@ void Win32X64CodeCache::InitializeUnwindEntry(
|
||||||
|
|
||||||
// https://docs.microsoft.com/en-us/cpp/build/exception-handling-x64#struct-unwind_code
|
// https://docs.microsoft.com/en-us/cpp/build/exception-handling-x64#struct-unwind_code
|
||||||
unwind_code = &unwind_info->UnwindCode[unwind_info->CountOfCodes++];
|
unwind_code = &unwind_info->UnwindCode[unwind_info->CountOfCodes++];
|
||||||
unwind_code->CodeOffset =
|
unwind_code->CodeOffset = prolog_stack_alloc_offset;
|
||||||
14; // end of instruction + 1 == offset of next instruction
|
|
||||||
unwind_code->UnwindOp = UWOP_ALLOC_SMALL;
|
unwind_code->UnwindOp = UWOP_ALLOC_SMALL;
|
||||||
unwind_code->OpInfo = func_info.stack_size / 8 - 1;
|
unwind_code->OpInfo = func_info.stack_size / 8 - 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -285,8 +288,7 @@ void Win32X64CodeCache::InitializeUnwindEntry(
|
||||||
|
|
||||||
// https://docs.microsoft.com/en-us/cpp/build/exception-handling-x64#struct-unwind_code
|
// https://docs.microsoft.com/en-us/cpp/build/exception-handling-x64#struct-unwind_code
|
||||||
unwind_code = &unwind_info->UnwindCode[unwind_info->CountOfCodes++];
|
unwind_code = &unwind_info->UnwindCode[unwind_info->CountOfCodes++];
|
||||||
unwind_code->CodeOffset =
|
unwind_code->CodeOffset = prolog_stack_alloc_offset;
|
||||||
7; // end of instruction + 1 == offset of next instruction
|
|
||||||
unwind_code->UnwindOp = UWOP_ALLOC_LARGE;
|
unwind_code->UnwindOp = UWOP_ALLOC_LARGE;
|
||||||
unwind_code->OpInfo = 0; // One slot for size
|
unwind_code->OpInfo = 0; // One slot for size
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
* Copyright 2019 Ben Vanik. All rights reserved. *
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
@ -163,6 +163,7 @@ bool X64Emitter::Emit(HIRBuilder* builder, EmitFunctionInfo& func_info) {
|
||||||
|
|
||||||
struct _code_offsets {
|
struct _code_offsets {
|
||||||
size_t prolog;
|
size_t prolog;
|
||||||
|
size_t prolog_stack_alloc;
|
||||||
size_t body;
|
size_t body;
|
||||||
size_t epilog;
|
size_t epilog;
|
||||||
size_t tail;
|
size_t tail;
|
||||||
|
@ -183,6 +184,9 @@ bool X64Emitter::Emit(HIRBuilder* builder, EmitFunctionInfo& func_info) {
|
||||||
stack_size_ = stack_size;
|
stack_size_ = stack_size;
|
||||||
|
|
||||||
sub(rsp, (uint32_t)stack_size);
|
sub(rsp, (uint32_t)stack_size);
|
||||||
|
|
||||||
|
code_offsets.prolog_stack_alloc = getSize();
|
||||||
|
|
||||||
mov(qword[rsp + StackLayout::GUEST_CTX_HOME], GetContextReg());
|
mov(qword[rsp + StackLayout::GUEST_CTX_HOME], GetContextReg());
|
||||||
mov(qword[rsp + StackLayout::GUEST_RET_ADDR], rcx);
|
mov(qword[rsp + StackLayout::GUEST_RET_ADDR], rcx);
|
||||||
mov(qword[rsp + StackLayout::GUEST_CALL_RET_ADDR], 0);
|
mov(qword[rsp + StackLayout::GUEST_CALL_RET_ADDR], 0);
|
||||||
|
@ -275,6 +279,8 @@ bool X64Emitter::Emit(HIRBuilder* builder, EmitFunctionInfo& func_info) {
|
||||||
func_info.code_size.body = code_offsets.epilog - code_offsets.body;
|
func_info.code_size.body = code_offsets.epilog - code_offsets.body;
|
||||||
func_info.code_size.epilog = code_offsets.tail - code_offsets.epilog;
|
func_info.code_size.epilog = code_offsets.tail - code_offsets.epilog;
|
||||||
func_info.code_size.tail = getSize() - code_offsets.tail;
|
func_info.code_size.tail = getSize() - code_offsets.tail;
|
||||||
|
func_info.prolog_stack_alloc_offset =
|
||||||
|
code_offsets.prolog_stack_alloc - code_offsets.prolog;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
* Copyright 2019 Ben Vanik. All rights reserved. *
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue