Dynamic Recompilation Question

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
cWeasle
Posts: 2
Joined: Fri Aug 15, 2008 9:23 am

Dynamic Recompilation Question

Post by cWeasle »

First off as a new member of this community I'd like to say hi and that I hope to contribute quality homebrews for everyone to enjoy.

Now to the niddy-gritty:

I'm working on a project that would involve dynamic recompilation, but I have hit an early snag that I hope someone can help me with. I want to be able to load machine code from a file, load it in ram, jump to that memory address, then jump back. Sounds simple. I start in C to open the file and copy it to ram, then use its pointer address as an argument (addr) in the below inline asm.

Code: Select all

asm(
	"la $a0, skip\n"
	"or %0, $a0, $zero\n"	//load the address of skip: into output variable b
	"j cont\n"
	"skip:\n"
	"jr $ra\n"
	"cont:\n"
	"jalr $a0\n"		//option A
//	"jalr %3\n"		//option B
	"lw %1, 0(%3)\n"	//load the value at addr into output variable c
	"lw %2, 0($a0)\n"	//load the value at skip: into output variable d
	:"=r" (b), "=r" (c), "=r" (d)
	:"r" (addr)
	:"%ra", "%sp", "%fp", "%at", "%a0", "%t0", "%t1", "%s0" //got lazy with the clobber list
);
By the way for testing purposes, the only thing in the file being loaded is

Code: Select all

jr $ra
nop
Running what I referred to as option A in the above code where the program jumps to skip and back, i get this output.

skip address: 0x08900440 value: 0x03E00008
file address: 0x08918fd0 value: 0x03E00008

(So pretty much the same thing except the address.)

However, when I try option B where it tries to jump to the ram content of the file, it locks up. Why does this happen and how can I get it to run what i'm trying to inject?
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

When you make code, you have to flush the data cache, and invalidate the code cache. If you don't the code might not really be there.
Mihawk
Posts: 29
Joined: Tue Apr 03, 2007 2:04 am

Post by Mihawk »

Code: Select all

...
   "j cont\n" 
   "skip:\n" 
   "jr $ra\n" 
   "cont:\n" 
   "jalr $a0\n"      //option A
...
Not sure if this is part of your problem, but what about the delay slots of those jump instructions? Are nops inserted automaticaly when compiling this or should you put at least a nop after each (cause if I see this right, in this case the first two jumps have another jump in their delay slot, that's not allowed IIRC)?
Ask and it will be given to you; seek and you will find; knock and the door will be opened to you.
cWeasle
Posts: 2
Joined: Fri Aug 15, 2008 9:23 am

Post by cWeasle »

Yep, that did it. Adding sceKernelDcacheWritebackInvalidateRange(const void *p, unsigned int size) right before the inline asm fixed it. Thanks J.F.

The nops are added automatically, and i had manually added one in my file.
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Re: Dynamic Recompilation Question

Post by hlide »

i usually prefer not let asm reorder and insert "nop" instructions as you cannot control it. So i use ".set noreorder" and insert myself "nop" if necessary in delayslots. For someone who is used to read MIPS disassembly code, your code is too much disturbing to read.
cWeasle wrote:

Code: Select all

la $a0, skip
or %0, $a0, $zero
j cont
skip:
jr $ra
cont:
jalr $a0
jalr %3
lw %1, 0&#40;%3&#41; <--- this is a delayslot or not !? this is unreadable !
lw %2, 0&#40;$a0&#41;
==>

Code: Select all

.set push
.set noreorder // don't let asm to reorder or insert nop
la $a0, skip
j cont
or %0, $a0, $zero // take advantage of a delay slot
skip&#58;
jr $ra
nop
cont&#58;
jalr $a0
nop
jalr %3
nop
lw %1, 0&#40;%3&#41; // If executed after call otherwise just remove previous "nop"
lw %2, 0&#40;$a0&#41;
.set pop
[/quote]
Post Reply