Page 1 of 1

jit : Relocate large block of code.. at runtime ?

Posted: Fri Jul 10, 2015 4:29 am
by JulienDarc
Hello,

It will sound silly, and it actually is (at least borderline).

I want to relocate code at runtime. Yes, like something no one likes (virus) or something people are fond of (well.. jit).

Up to now, everytime I created self modifying code or code generation at runtime, it was through a pointer. That is very easy to get going (if you know the arch codes). But cache doesn't like it.

Now, I want the next step : as far as space locality is very important to the project I have, AND that the rewritten code doesn't fit in the address range the linker/loader has planned for the block I wish to replace, I need to move blocks.

I know I can memcpy. But still, how a call will work after that ? The whole addressing is screwed up.

How could I modify all the addresses at RUNTIME? The symbol table && sections are key here I guess.

This is the solution I want, as a training, no matter if hell has to be hammered to make it work. Even if stupid.

I use c/c++ and gcc (and libgccjit).

Thanks

Re: jit : Relocate large block of code.. at runtime ?

Posted: Fri Jul 10, 2015 4:52 am
by alexfru
If you keep the object file or its symbol and relocation info, then you can relocate its code. To make it easier, you should put the code that you want to relocate into a separate file, so it doesn't have hard-coded short addresses/offsets that you won't be able to extend.

Re: jit : Relocate large block of code.. at runtime ?

Posted: Fri Jul 10, 2015 5:36 am
by JulienDarc
Thanks alexfru,

So you mean :
0) Compiling my objects with -fPic
1) I locate the code I want to modify thanks to the objects info / elf headers
2) Overwrite this address range with the new code
3) Reload the other blocks after the modified range.

That way, no hardcoded addresses.

So if my modification happens at the beginning of the code, I will have to move the rest of the code thanks to those headers. Right ?

Seems good to me. There will be a performance hit during the reload/memcpy, but that is necessary and doesn't matter.

Did I exactly get your idea ?

I will read https://en.wikipedia.org/wiki/Relocatio ... science%29 by the way and dig around.

Re: jit : Relocate large block of code.. at runtime ?

Posted: Fri Jul 10, 2015 6:47 am
by bluemoon
Have you consider doing it with paging? cache won't complain it too.

Re: jit : Relocate large block of code.. at runtime ?

Posted: Fri Jul 10, 2015 7:17 am
by JulienDarc
Paging sounds good.

Hopefully it is easy to fill the tlb once with that strategy and avoid many complications. But it is very look alike to the technic i used already ( create obj code in a mmaped area, which could be on another page).

And dynamic relocation is not good enough after all, because there is the address resolution that needs to be done <-> overhead.

I need to hardcode the addresses at runtime. No runtime overhead except the moment the code is modified.

Maybe i will have to write some esoteric tool / funky plugin.. Except someone has an idea how i could hardcode addresses at runtime.

Update: that code has to be exportable between exact same configuration machines and to be the exact same code layout for maintenance purpose. Hence the need for hardcoded values to squeeze the last performance bit and letting different devs to debug in an organized manner.

Re: jit : Relocate large block of code.. at runtime ?

Posted: Fri Jul 10, 2015 11:55 am
by JulienDarc
One voodoo dance, and a parser / loader later, it is working.

I just compile my different blocks with -fPic, my parser sees it and do the addressing correction, and my loader do the right thing.
The jitted code is displaced according to my loader and the rest of the code overwrites the preceding code.
With the right assembly code to do the memcpy, It is very fast so it is almost transparent when it happens.

The os knows that it is happening and pauses the process. Once done, back to work.
Don't get me wrong, we are talking about MASSIVE re-engineering (creating/moving blocks around) of the code, monitoring cache lines and so on, not just address replacement and function inlining.

Everything at runtime.

I still use gcc as expected for the first pass. And don't bother hacking it. More code (which has to be done once), yes, but not too much.

Welcome back in modern programming (aside virus coding), self-modifying code !

Wonders.

Re: jit : Relocate large block of code.. at runtime ?

Posted: Fri Jul 10, 2015 12:48 pm
by embryo2
JulienDarc wrote:I want to relocate code at runtime.
Can you explain why do you need to relocate the code?

Re: jit : Relocate large block of code.. at runtime ?

Posted: Fri Jul 10, 2015 1:47 pm
by JulienDarc
..to let bad things happen.

More seriously, I need a very reactive code that optimizes itself very fast to a given signal. Like a brain..

Re: jit : Relocate large block of code.. at runtime ?

Posted: Sat Jul 11, 2015 11:50 am
by embryo2
JulienDarc wrote:I need a very reactive code that optimizes itself very fast to a given signal. Like a brain..
Good plans. I hope it will be possible to see some results.

Re: jit : Relocate large block of code.. at runtime ?

Posted: Sun Jul 12, 2015 12:37 am
by JulienDarc
Thanks for your encouragements embryo2 (well.. embryo should I write)!

I guess you will be hearing soon from the project :)

:wink:

Re: jit : Relocate large block of code.. at runtime ?

Posted: Mon Jul 13, 2015 6:08 am
by Combuster
I fully relocate all my binaries at load time, and for that I don't need to enable the generation of position-independent code (-fPIC, -fPIE) because that code has a severe performance impact at runtime. Instead I emit relocations in the final executable so the application loader can re-link it to a different address before actually copying it into memory. Relocating code during execution itself is only problematic when it has already been used and there might be dangling pointers to its original location - which is something PIC can't fix either.

Re: jit : Relocate large block of code.. at runtime ?

Posted: Mon Jul 20, 2015 3:29 pm
by JulienDarc
That is right Combuster,

I had to code a specific loader. We create the objects with the -c option and our loader keeps track of all the pointers and relative addressing.
The preparser (homegrown too), is able to modify the object code to make it correspond to the right address.

It is not trivial.
But..