Skip to content
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

Is possible to jmp inside a created JIT? #323

Closed
crazynds opened this issue Feb 13, 2021 · 4 comments
Closed

Is possible to jmp inside a created JIT? #323

crazynds opened this issue Feb 13, 2021 · 4 comments

Comments

@crazynds
Copy link

I developed a program that creates several JIT functions.
Currently when developing these JIT functions, there are cases where within a JIT x' function I want to jump from other area in x' function, in which case I use a simple jmp or call. But now I have to go from a JIT function y' to the function x' at a certain point.
Is it possible that within the function y 'implement some call or jmp that references function x' at that specific point? Is it possible to take the position of the function after it is created in memory and discover the position where I want to enter the function x '?

What I want can be exemplified by the following code snippets, but they must be functions created separately, and the function x would be created before the function y. Ex:
-function x':
0. inc rax

  1. add rax,rbx
  2. xor rbx,rbx
  3. return

-function y':
0. dec rax

  1. call x' function at 2 line
  2. return
@kobalicek
Copy link
Member

kobalicek commented Feb 14, 2021

What kind of tool do you use to generate the function - Assembler or Compiler?

With Assembler this should be possible with using labels - you simply create a Label and then call that Label. If the functions are not generated in a single CodeHolder instance you can still create label and then query for its relative distance from the beginning of the code - then it's again callable (it would be base address + label offset). Use CodeHolder::labelOffset(label) method to get the relative distance.

With Compiler this is not possible as each function has prolog/epilog and you can only jump (call) to the beginning of the function.

@crazynds
Copy link
Author

I use Assembler to generate the jit function.

I test some code, and work, but i don't know if this is the correct method.

JitRuntime rt;
Function fn1,fn2;
uint64_t position;
{
	//First function X
	CodeHolder code;
	code.init(rt.environment());
	Assembler a(&code);
	Label label = a.newLabel();
	a.xor_(rax,rax);
	a.bind(label);
	a.inc(rax);
	a.ret();
	Error err = rt.add(&fn1, &code);
	position = fn1+code.labelOffset(label); //Function address + offset position
	if (err) return 1;
}

{
	//Second function Y
	CodeHolder code;
	code.init(rt.environment());
	Assembler a(&code);
	a.mov(rax,2);
	a.jmp(position);
	Error err = rt.add(&fn2, &code);
	if (err) return 1;
}


int result = fn2();
printf("%d\n", result);

rt.release(fn1);
rt.release(fn2);

@kobalicek
Copy link
Member

Yes that's a possibility - another possibility is to use the same CodeHolder to generate both functions and use the Label directly in the call.

I would recommend loading the address to register before the call though as JitAllocator has no guarantees about where the code will be allocated (so +- 2GB is not guaranteed).

@crazynds
Copy link
Author

Ok, this resolve the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants