-
Notifications
You must be signed in to change notification settings - Fork 2.7k
[x86/Linux] Revise asmhelper.S using macro #8523
Changes from 1 commit
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 |
---|---|---|
|
@@ -35,3 +35,31 @@ C_FUNC(\Name\()_End): | |
.global C_FUNC(\Name\()_End) | ||
LEAF_END \Name, \Section | ||
.endm | ||
|
||
.macro PROLOG_BEG | ||
push ebp | ||
mov ebp, esp | ||
.cfi_def_cfa_offset 0 | ||
.endm | ||
|
||
.macro PROLOG_PUSH Reg | ||
push \Reg | ||
.cfi_adjust_cfa_offset -4 | ||
.cfi_rel_offset \Reg, 0 | ||
.endm | ||
|
||
.macro PROLOG_END | ||
.cfi_def_cfa_offset 4 | ||
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 should be 8, see my comment in the PROLOG_BEG 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. Thank you for comment. I'll revise those macros as you commented. |
||
.cfi_def_cfa_register ebp | ||
.endm | ||
|
||
.macro EPILOG_BEG | ||
.endm | ||
|
||
.macro EPILOG_POP Reg | ||
pop \Reg | ||
.endm | ||
|
||
.macro EPILOG_END | ||
pop ebp | ||
.endm |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,32 +11,39 @@ | |
// | ||
.macro STUB_PROLOG | ||
// push ebp-frame | ||
push ebp | ||
mov ebp, esp | ||
PROLOG_BEG | ||
|
||
// save CalleeSavedRegisters | ||
push ebx | ||
push esi | ||
push edi | ||
PROLOG_PUSH ebx | ||
PROLOG_PUSH esi | ||
PROLOG_PUSH edi | ||
|
||
// push ArgumentRegisters | ||
push ecx | ||
push edx | ||
PROLOG_PUSH ecx | ||
PROLOG_PUSH edx | ||
|
||
// set frame pointer | ||
PROLOG_END | ||
.endm | ||
|
||
// | ||
// FramedMethodFrame epilog | ||
// | ||
.macro STUB_EPILOG | ||
// restore stack pointer | ||
EPILOG_BEG | ||
|
||
// pop ArgumentRegisters | ||
pop edx | ||
pop ecx | ||
EPILOG_POP edx | ||
EPILOG_POP ecx | ||
|
||
// pop CalleeSavedRegisters | ||
pop edi | ||
pop esi | ||
pop ebx | ||
pop ebp | ||
EPILOG_POP edi | ||
EPILOG_POP esi | ||
EPILOG_POP ebx | ||
|
||
// pop ebp-frame | ||
EPILOG_END | ||
.endm | ||
|
||
// | ||
|
@@ -392,8 +399,14 @@ LEAF_END ArrayOpStubTypeMismatchException, _TEXT | |
// ------------------------------------------------------------------------------ | ||
// void STDCALL CallDescrWorkerInternal(CallDescrWorkerParams * pParams) | ||
NESTED_ENTRY CallDescrWorkerInternal, _TEXT, NoHandler | ||
PROLOG_BEG | ||
PROLOG_PUSH eax | ||
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 don't need to push EAX, EDX and ECX here. They are not expected to be preserved. I have taken a look at a C function compiled by both clang and gcc and they don't preserve these registers either (and use them) 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. (As you already mentioned) I found that STDCALL requires only EBX to be preserved. I'll revise the code. |
||
PROLOG_PUSH ebx | ||
PROLOG_PUSH ecx | ||
PROLOG_PUSH edx | ||
PROLOG_END | ||
|
||
mov ebx, [esp + 4] // pParams = esp + 4 | ||
mov ebx, [esp + ((2 + 4) * 4)] | ||
|
||
// copy the stack | ||
mov ecx, [ebx +CallDescrData__numStackSlots] | ||
|
@@ -445,6 +458,12 @@ LOCAL_LABEL(ReturnsInt): | |
mov [ebx + CallDescrData__returnValue + 4], edx | ||
|
||
LOCAL_LABEL(Epilog): | ||
EPILOG_BEG | ||
EPILOG_POP edx | ||
EPILOG_POP ecx | ||
EPILOG_POP ebx | ||
EPILOG_POP eax | ||
EPILOG_END | ||
ret 4 | ||
|
||
LOCAL_LABEL(ReturnsFloat): | ||
|
@@ -944,23 +963,28 @@ NESTED_ENTRY VirtualMethodFixupStub, _TEXT, NoHandler | |
sub eax, 5 | ||
|
||
// Push ebp frame to get good callstack under debugger | ||
push ebp | ||
mov ebp, esp | ||
PROLOG_BEG | ||
|
||
// Preserve argument registers | ||
push ecx | ||
push edx | ||
PROLOG_PUSH ecx | ||
PROLOG_PUSH edx | ||
|
||
// Set frame pointer | ||
PROLOG_END | ||
|
||
push eax // address of the thunk | ||
push ecx // this ptr | ||
call C_FUNC(VirtualMethodFixupWorker) | ||
|
||
// Restore stack pointer | ||
EPILOG_BEG | ||
|
||
// Restore argument registers | ||
pop edx | ||
pop ecx | ||
EPILOG_POP edx | ||
EPILOG_POP ecx | ||
|
||
// Pop ebp frame | ||
pop ebp | ||
EPILOG_END | ||
|
||
PATCH_LABEL VirtualMethodFixupPatchLabel | ||
// Proceed to execute the actual method. | ||
|
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.
This is not correct. The CFA by definition is the ESP of the caller right before it made the call. You are setting the CFA here to the location where the EBP was pushed.
You need to set the offset to 8 (the pushed EBP plus the return address).
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.
And you need to also define the offset of EBP here