forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

how is the $gp register set?

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
willow :--)



Joined: 13 Jan 2007
Posts: 126

PostPosted: Thu Mar 25, 2010 11:48 am    Post subject: how is the $gp register set? Reply with quote

I'm trying to change the value of the $gp register at runtime and am having a hard time doing it. I think I'm changing the value in a thread A but it gets reinitialized in a thread B.

I think I need more insight on when that register gets changed.
What I'm trying to do:
starting a thread that uses a different $gp than the code that spawned it.

My understanding:
The value of GP is attached to a module (see: modinfo in PSPLink).
Every thread that belongs to a module (how does the PSP knows which thread belongs to which module? Ram boundaries ?) uses that value for GP.

Since all threads use different code, they need to re-set the various registers they use. How are these values stored and retrieved?

My interest currently is in $gp, but I'm thinking that other registers such as $fp, $sp... are the same...

Here's how I imagine it works:
- Thread 1 starts
- Thread1 restores its registers from ???
- Thread1 does stuff
- Thread1 pauses
- Thread1 stores its current registers to ???
- Thread 2 starts
- Thread 2 restores its registers from ???
- Thread 2 does stuff...
-...

my guess for gp:
When a thread is created, the kernel(?) looks for the position of the code calling it in Ram (probably ra?) and gets the moduleid based on that. It then gets the value of GP from the module info, and that's how gp is initialized.
I'd like to know if that's correct and if any code or documentation regarding this process is available somewhere.

So my questions are:
1) Is my understanding roughly correct?
2) How does the registers save/restore sequence work? What are the sce* functions that deal with that, if any?
3) When a thread starts, how are the initial register values computed? (especially $gp)
_________________
Wagic. Play that card game against an AI on your PSP
Back to top
View user's profile Send private message
willow :--)



Joined: 13 Jan 2007
Posts: 126

PostPosted: Thu Mar 25, 2010 1:51 pm    Post subject: Reply with quote

I think I can find partial answers to my question in this file:
http://svn.lan.st/utopia/threadman/threadman.c

I'll ask more questions after studying this

Edit:
I think that's the interesting part for me, threads are not taking GP from the thread that spawned them, but from the module they belong to.
I think this answers my questions for now

Code:

  SceModule *mod = sceKernelFindModuleByAddress(entry);
  thinfo->gpreg = mod ? mod->unk_68 : GET_GP;

_________________
Wagic. Play that card game against an AI on your PSP
Back to top
View user's profile Send private message
willow :--)



Joined: 13 Jan 2007
Posts: 126

PostPosted: Sun Mar 28, 2010 10:25 pm    Post subject: Reply with quote

Just in case somebody encounters the same kind of issue as me: I ended up bypassing the issue by doing the following:

- load some code outside of any "module" ram boundaries. That function (run) takes an address and jumps to it
- When I want to start a thread with a different GP, I set the value of GP to whatever I want, and start a thread of "run", asking it to launch the actual function.

When creating the thread, the kernel realizes I'm attempting to load a function outside of any module boundaries (run), and therefore gets the current GP value instead of that from a module
_________________
Wagic. Play that card game against an AI on your PSP
Back to top
View user's profile Send private message
Coldbird



Joined: 08 Feb 2007
Posts: 155

PostPosted: Mon Mar 29, 2010 12:33 am    Post subject: Reply with quote

Wow... thats a pretty evil workaround isn't it?
Judging from what you said you rely on a fallback GP detection function inside the firmware? Tricky.
_________________
Been gone for some time. Now I'm back. Someone mind getting me up-2-date?
Back to top
View user's profile Send private message MSN Messenger
Davee



Joined: 22 Jun 2009
Posts: 59

PostPosted: Mon Mar 29, 2010 12:36 am    Post subject: Reply with quote

Below is for 5.03. It should work for other firmwares too though, I don't pay much attention to internal threadman :P

Code:
/*
   This will change a threads GP reg (theoretically).
   Usage:
      SceUID thid = sceKernelCreateThread(...);
      change_thread_gp(thid, gp);
      sceKernelStartThread();
   
   Although it may work after the thread has started.
*/

int change_thread_gp(SceUID thid, u32 gp)
{
   uidControlBlock *uidcb;
   
   if (!gp)
   {
      asm volatile ("move %0, $gp\n" : "=r" (gp));
   }
   
   if (sceKernelGetUIDcontrolBlock(thid, *uidcb) != 0) //SysMemForKernel_523E300A
   {
      /* error */
      return -1;
   }
   
   u32 *threadman_struct = (u32 *)((u32)uidcb + (uidcb->type->size * 4));
   threadman_struct[212/4] = gp;
   return 0;
}


This is all theoretical. Alternatively, you could hook the LoadCoreForKernel_6C00BE57 which gets the gp to set from the module.
Back to top
View user's profile Send private message
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Mon Mar 29, 2010 12:45 am    Post subject: Reply with quote

DELETED

Last edited by hlide on Mon Mar 29, 2010 12:48 am; edited 1 time in total
Back to top
View user's profile Send private message
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Mon Mar 29, 2010 12:46 am    Post subject: Reply with quote

DELETED - i had a spurious message telling me a PHP bug...

Last edited by hlide on Mon Mar 29, 2010 12:47 am; edited 1 time in total
Back to top
View user's profile Send private message
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Mon Mar 29, 2010 12:46 am    Post subject: Reply with quote

willow :--) wrote:
I think I can find partial answers to my question in this file:
http://svn.lan.st/utopia/threadman/threadman.c

I'll ask more questions after studying this

Edit:
I think that's the interesting part for me, threads are not taking GP from the thread that spawned them, but from the module they belong to.
I think this answers my questions for now

Code:

  SceModule *mod = sceKernelFindModuleByAddress(entry);
  thinfo->gpreg = mod ? mod->unk_68 : GET_GP;


Do you want to use $gp as an allocatable/temporary register for *Dead*alusX64 (I couldn't resist) ?

you set $gp in thread A. There is a switch to thread B (it's normal $gp si no the same) then there is another switch to thread A : does $gp change ? if not, that's okay. I remember POPS uses $gp a lot and still it has several threads. So i'm kind suspicious it can be changed internally after switching back to thread A.

And I don't see any point for $gp being the same in thread A and B since it shouldn't be used as the usual way other OS does.

And don't forget to use options "-G0 -nogpopt" (or something like that).
Back to top
View user's profile Send private message
sauron_le_noir



Joined: 05 Jul 2008
Posts: 229

PostPosted: Mon Mar 29, 2010 1:29 am    Post subject: Reply with quote

-mgpopt
-mno-gpopt
Use (do not use) GP-relative accesses for symbols that are known to be in a small data section; see -G, -mlocal-sdata and -mextern-sdata. -mgpopt is the default for all configurations.

-mno-gpopt is useful for cases where the $gp register might not hold the value of _gp. For example, if the code is part of a library that might be used in a boot monitor, programs that call boot monitor routines will pass an unknown value in $gp. (In such situations, the boot monitor itself would usually be compiled with -G0.)

-mno-gpopt implies -mno-local-sdata and -mno-extern-sdata.
Back to top
View user's profile Send private message Send e-mail MSN Messenger
SilverSpring



Joined: 27 Feb 2007
Posts: 115

PostPosted: Mon Mar 29, 2010 1:48 am    Post subject: Reply with quote

Davee wrote:

This is all theoretical. Alternatively, you could hook the LoadCoreForKernel_6C00BE57 which gets the gp to set from the module.


*cough*0xA6D40F56 sceKernelGetModuleGPByAddressForKernel*cough*

That's the real name before the NID's got randomised of course. LoadCoreForKernel_6C00BE57 is the 5.xx randomised version.
_________________
PSP PRX LibDocs
Back to top
View user's profile Send private message Visit poster's website
Davee



Joined: 22 Jun 2009
Posts: 59

PostPosted: Mon Mar 29, 2010 1:50 am    Post subject: Reply with quote

SilverSpring wrote:
Davee wrote:

This is all theoretical. Alternatively, you could hook the LoadCoreForKernel_6C00BE57 which gets the gp to set from the module.


*cough*0xA6D40F56 sceKernelGetModuleGPByAddressForKernel*cough*

That's the real name before the NID's got randomised of course. LoadCoreForKernel_6C00BE57 is the 5.xx randomised version.


>:D
Back to top
View user's profile Send private message
willow :--)



Joined: 13 Jan 2007
Posts: 126

PostPosted: Mon Mar 29, 2010 8:03 am    Post subject: Reply with quote

Davee wrote:



if (sceKernelGetUIDcontrolBlock(thid, *uidcb) != 0) //SysMemForKernel_523E300A

[...]
This is all theoretical. Alternatively, you could hook the LoadCoreForKernel_6C00BE57 which gets the gp to set from the module.

I'm going to assume those are both Kernel functions, and I'm in user mode, so that wouldn't work for me

Edit: Coldbird: yes, that's exactly what I'm doing, relying on the fallback mechanism in the firmware
_________________
Wagic. Play that card game against an AI on your PSP


Last edited by willow :--) on Mon Mar 29, 2010 10:20 pm; edited 1 time in total
Back to top
View user's profile Send private message
m0skit0



Joined: 02 Jun 2009
Posts: 226

PostPosted: Mon Mar 29, 2010 8:59 am    Post subject: Reply with quote

Effectvely, he means only user-mode access. Nice trick btw, you didn't explain it to me on our official thread xD
_________________
The Incredible Bill Gates wrote:
The obvious mathematical breakthrough would be development of an easy way to factor large prime numbers.
Back to top
View user's profile Send private message
Davee



Joined: 22 Jun 2009
Posts: 59

PostPosted: Mon Mar 29, 2010 9:23 am    Post subject: Reply with quote

willow :--) wrote:
Davee wrote:



if (sceKernelGetUIDcontrolBlock(thid, *uidcb) != 0) //SysMemForKernel_523E300A

[...]
This is all theoretical. Alternatively, you could hook the LoadCoreForKernel_6C00BE57 which gets the gp to set from the module.

I'm going to assume those are both Kernel functions, and I'm in user mode, so that wouldn't work for me

Edit: Coolbird: yes, that's exactly what I'm doing, relying on the fallback mechanism in the firmware


Ah well, maybe that should of been stated in the original post ;)
Back to top
View user's profile Send private message
willow :--)



Joined: 13 Jan 2007
Posts: 126

PostPosted: Mon Mar 29, 2010 9:54 am    Post subject: Reply with quote

Yes, that important point was lacking in my original post, sorry about that.
_________________
Wagic. Play that card game against an AI on your PSP
Back to top
View user's profile Send private message
Coldbird



Joined: 08 Feb 2007
Posts: 155

PostPosted: Mon Mar 29, 2010 8:11 pm    Post subject: Reply with quote

It's Coldbird................ why the hell does everyone think it's Coolbird.... *shakes his head and sighs*

That aside, how did you figure out the fallback mechanism in the first place?
Did you do a asm dive yourself and found it via reversal or did Mathieulh and Co. take it off you with Project Utopia?
_________________
Been gone for some time. Now I'm back. Someone mind getting me up-2-date?
Back to top
View user's profile Send private message MSN Messenger
willow :--)



Joined: 13 Jan 2007
Posts: 126

PostPosted: Mon Mar 29, 2010 10:21 pm    Post subject: Reply with quote

Coldbird wrote:
It's Coldbird................ why the hell does everyone think it's Coolbird.... *shakes his head and sighs*

woops, sorry about that, edited my post.

Quote:

That aside, how did you figure out the fallback mechanism in the first place?
Did you do a asm dive yourself and found it via reversal or did Mathieulh and Co. take it off you with Project Utopia?

The utopia project is open source, so I just dug into it, assuming it's mostly a reverse from the OFW. (I don't have cool reverse-engineer skills yet)
_________________
Wagic. Play that card game against an AI on your PSP
Back to top
View user's profile Send private message
Coldbird



Joined: 08 Feb 2007
Posts: 155

PostPosted: Mon Mar 29, 2010 11:38 pm    Post subject: Reply with quote

I must admit I am very interested in the Utopia Project and have been monitoring it from afar for some time now...

But thats mostly because I AM a big fan of opensource software in the first place so...

I see I see. Well I do dig a lot into asm myself, atleast I know enough to find my way around...

The only thing still a big mystery to myself is how gcc / g++ compiles more than 4 arguments in mips... :-/

Oh how I wished mips would use a argument stack like x86......... lol.
_________________
Been gone for some time. Now I'm back. Someone mind getting me up-2-date?
Back to top
View user's profile Send private message MSN Messenger
coyotebean



Joined: 05 Dec 2009
Posts: 26

PostPosted: Mon Mar 29, 2010 11:46 pm    Post subject: Reply with quote

Coldbird wrote:
The only thing still a big mystery to myself is how gcc / g++ compiles more than 4 arguments in mips... :-/

Oh how I wished mips would use a argument stack like x86......... lol.

After $a0 to $a3, then $t0 to $t3, then uses the stack.
_________________
GBASP x1, GBM x2, NDSL x2, PSP 100X x3, PSP 200X x5, PSP 300X x3, PSP Go x2, Wii x1
Back to top
View user's profile Send private message
Coldbird



Joined: 08 Feb 2007
Posts: 155

PostPosted: Mon Mar 29, 2010 11:52 pm    Post subject: Reply with quote

Thanks! Another mystery solved!
_________________
Been gone for some time. Now I'm back. Someone mind getting me up-2-date?
Back to top
View user's profile Send private message MSN Messenger
noob81



Joined: 07 Mar 2010
Posts: 1

PostPosted: Tue Mar 30, 2010 11:21 am    Post subject: Reply with quote

Coldbird wrote:

The only thing still a big mystery to myself is how gcc / g++ compiles more than 4 arguments in mips... :-/


Have been wondering the same thing myself :P Thanks for the tip, coyotebean.
_________________
n00b81
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group