I want to raise an exception in a X64 asm block.
Lets assume I have a function like so:
function Example(Values: array of integer): integer;
asm
or rcx,rcx
jz @error
....
I know I can just read the pointer and get a AV, however I want to raise a more descriptive error.
I could make an additional function and call that one:
asm
or rcx,rcx
jz @error
....
@error:
mov ecx, 1
mov rdx, ErrorString
jmp RaiseError
....
function RaiseError(code: integer; const Msg: string);
begin
case code of
1: raise EEmptyArrayError.Create(Msg);
However the error will then occur outside the function in which is was caused. How do I get the exception to (seem to) originate from inside the Example
function.
Note that this is X64, so all the SEH answers that apply to X86 are no good because X64 uses VEH.
The full syntax of raise is:
raise Exception at address
All you need to do is to pass the current IP as a parameter and the error proc can pass that on to the exception.
You can get the RIP using lea rax, [rip]
.
Thus the code becomes:
asm
or rcx,rcx
jz @error
....
@error:
mov ecx, 1
mov rdx, ErrorString
lea r8,[rip]
jmp RaiseError
....
function RaiseError(code: integer; const Msg: string; address: pointer);
begin
case code of
1: raise EEmptyArrayError.Create(Msg) at address;
Of course in this case it's easier to use
function RaiseError(code: integer; const Msg: string);
begin
case code of
1: raise EEmptyArrayError.Create(Msg) at ReturnAddress;
Note
In this case if you keep the jmp the error will seem to originate from the calling routine, in this case that's actually correct. If you want the exception to point the guilty finger at your asm code then use a call.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With