Jump to content
  • 0

gcc/nOVL relocations missing?


DeathBasket
 Share

Question

I'm having this error when writing actors in C; it has happened a few times before when I've edited actors using assembly code but the errors appeared much less often. There doesn't seem to be any problems with my code but when I have compiled it and converted to an overlay there are usually a few bits of relocation data missing though most of them are there. It's not that much of a hassle to fix this manually, but when it needs to be done every time I want to change some of the code in my actor it does become a hassle.

I just wanted to know if anybody else has come across the same problem or knows why this happens or how to fix it. I'm not a C expert (only just really started learning a bit) so I acknowledge that I may be doing something wrong somewhere. Thanks.

Link to comment
Share on other sites

10 answers to this question

Recommended Posts

  • 0

I'm pretty sure you were knowledgeable to do this, but by some weird event you may have missed it:

When compiling binaries for use as an overlay, you must add the switch -G 0 to prevent it from putting symbols in the small data section, as $gp relative relocations are obviously unimplemented. When linking a binary into an ELF file that is to be converted to an overlay, you must remember to retain all the relocation information with the flag --emit-relocs.

 

^^ Taken from: http://64.vg/dr/node/5

 

I seriously doubt that that was the problem, though, since I'm pretty sure you know what you're doing.

 

EDIT:

I haven't read the source code of this thoroughly, but it may aid you in reconstructing the relocation data: http://code.google.com/p/vg64tools/source/browse/n64/z_snippets/z_ovl_adapt.c

Link to comment
Share on other sites

  • 0

Thanks, but none of those is the source of my problem...

The problem is either than gcc is not writing some relocation data to the files or that nOVL is for some reason not reading some entries properly. I haven't properly looked at where the error is occurring yet, but it happens a lot when I use if/else, goto or return statements in my code and when I look at the disassembly in Nemu it seems to be mostly (or only?) jump and load/store instructions that aren't being relocated properly. The rest seem to work fine. I don't remember what the solution was when I ran into this before when using assembly, but I doubt it would be something I have much control over when using C.

Link to comment
Share on other sites

  • 0

Bringing this up again after a long time...

 

So anyway, I'm still having these issues and they definitely seem to be related to using if/else. I know most people aren't into custom actors or hacking with C or whatever but I'm posting in the hope that somebody else may have seen similar errors or know anything about it by now...

I was able to do

but as I said before, I had to fix certain parts of it manually. The trouble is that a load of the lui/lw/sw etc. instructions don't get relocated. If it's any help, the function getting messed up looks like this:

 

u16 f1(u32 z_gp, struct z64_actor_t * a)
{
	 /* set message number for text */


	 if (count==20)
	 {
	    count=0;
	    msg_no = (u16)(z_rand()*367.0f);
	 };
	
	 count+=1;
	
	 return msg_no;
}
Link to comment
Share on other sites

  • 0

Not to go off-topic, but what exactly are relocations and how do you know when to generate one? Maybe we could fix nOVL's source...

 

I seem to have this idea that relocations are made whenever there is a need to store or load data from a virtual offset or whenever you need to make function call to a function within the actor. Basically, anything having to do with virtual offsets when transfered to RAM. Is this correct? I'm too lazy to look up the definition.

Link to comment
Share on other sites

  • 0

Bringing this up again after a long time...

 

So anyway, I'm still having these issues and they definitely seem to be related to using if/else. I know most people aren't into custom actors or hacking with C or whatever but I'm posting in the hope that somebody else may have seen similar errors or know anything about it by now...

I was able to do

but as I said before, I had to fix certain parts of it manually. The trouble is that a load of the lui/lw/sw etc. instructions don't get relocated. If it's any help, the function getting messed up looks like this:

 

u16 f1(u32 z_gp, struct z64_actor_t * a)
{
	 /* set message number for text */


	 if (count==20)
	 {
	 count=0;
	 msg_no = (u16)(z_rand()*367.0f);
	 };
	
	 count+=1;
	
	 return msg_no;
}
The culprit is possibly floating point numbers. There is an oddity in the GCC compiler that loads floats from data sections instead of immediates, requiring additional relocations (see: http://gcc.gnu.org/....msg00084.html. Notice how all mips-gcc devs ignored it :( )

 

Try this, just to see what happens:

u16 f1(u32 z_gp, struct z64_actor_t * a)
{
    /* set message number for text */
    float msg_no;
    int v = 0;

    if( count == 20 )
    {
        count = 0;
        v = 367;
        msg_no = z_rand() * v;
        v = (int)msg_no;
    }
	
    count ++;
	
    return (u16)v;
}
Link to comment
Share on other sites

  • 0

That is possibly the case but the problem seems to persist whatever way I change the code. Using the code you posted the compiler is doing the same thing by putting 367.0 in the data section and then not loading other variables correctly (see image below). This is bugging me because it's really going to hinder development of more complicated actors like NPCs or enemies, etc. once I have all the knowledge I need to properly write those.

 

Posted Image

 

I'm thinking to combat this I may as well write some program to redo all the relocation data myself... :(

 

Edit: did that and it works but in a pretty haphazard sort of way... I guess I will test it out more thoroughly another time.

Edited by DeathBasket
Link to comment
Share on other sites

  • 0

It's difficult to say whether it actually works properly though since it's mainly based on assumptions, ex. every lui instruction with a parameter 80xx (>=8080) is taken to be the upper half of an address within the actor (usually true but there's always a possibility it may not be). Relocations outside of the text section of the actor are kept the same. It worked in this case but may not work in others, I really need to add more checking and test it out on a longer piece of code before I can determine its worth or think about releasing it...

Link to comment
Share on other sites

 Share

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.