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 

pointers getting nutz !

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



Joined: 22 Apr 2004
Posts: 230

PostPosted: Thu Jan 13, 2005 7:34 pm    Post subject: pointers getting nutz ! Reply with quote

I currently have some strange behaviour with pointers to different data types ..

So le'ts try to explain myself as simple as possible ! let's say that I have one function with the following prototype :
Quote:

void* get_something(_u32 parameter);

And that can return a pointer to either a u8, u16, u32 (depeding of the case, and this is not the case in which the returned value type is not the exptected one), Then this fct is called by an other one like :

Quote:

_u16 myFct(_u32 parameter)
{

_u16* ptr = get_something(parameter);

if (ptr == NULL)
return 0;
else
return *ptr;
}

In the above case the expected return value is a u16, so it should work, but calling it result in garbages in *ptr, and only a bad hack like the following one allow to get the correct return value....
Casting have no effect, and compiler keep complains on "casting pointers from different sizes" if I cast it.
Quote:

_u16 myFct(_u32 parameter)
{

_u8* ptr = get_something(parameter);

if (ptr == NULL)
return 0;
else
return ptr[1]<<8|ptr[0];
}

So just declaring it as a u8...

I have similar fct that are waiting for a u8 and u32...
only _u8 is working fine, as it "seems" to be the only possible things returned, but for _u32 value, the only way to make it working is to apply the same kind of stuff that above...

What is the problem ?? This code is working just fine when compiled and ran on a PC..

Is it me, or is there any issue with pointer in the GCC, SDK ??

thanks..
Back to top
View user's profile Send private message Visit poster's website
pixel



Joined: 30 Jan 2004
Posts: 791

PostPosted: Thu Jan 13, 2005 8:01 pm    Post subject: Reply with quote

It all depends on what your "void *" is pointing at. You have to know something: on MIPS processors, memory access (load and store) has to be aligned. That is:

Code:
u8 tab[6] = {1, 2, 3, 4, 5, 6};
u32 * p = &tab[2];
u32 a = *p;


This piece of code will perfectly work on any x86, but won't on PS2. Most probably will generate an exception though, instead of having a random behavior like you're experiencing.
_________________
pixel: A mischievous magical spirit associated with screen displays. The computer industry has frequently borrowed from mythology. Witness the sprites in computer graphics, the demons in artificial intelligence and the trolls in the marketing department.
Back to top
View user's profile Send private message
Guest






PostPosted: Thu Jan 13, 2005 8:06 pm    Post subject: Reply with quote

Try return (_u16)*ptr;

Pixel, are you sure alignment is the issue here ? I thought the compiler should automatically generate instructions to handle unaligned load/stores ?
I am wondering that it simply isn't casting the return value properly.

If alignment was the issue, then a bus-error should be generated.

But the problem is certainly due to each architectures native word size and unaligned load/store handling. :) But should be able to code a program around that.
Back to top
evilo



Joined: 22 Apr 2004
Posts: 230

PostPosted: Thu Jan 13, 2005 8:10 pm    Post subject: Reply with quote

That's exactly the kind of stuff done inside the function...

hmm... I didn't know that memory aligment was also applying in this case..

is there any workaround, except the one I used (shtg more clean) ??

thanks for your answer.
Back to top
View user's profile Send private message Visit poster's website
Guest






PostPosted: Thu Jan 13, 2005 8:19 pm    Post subject: Reply with quote

evilo wrote:
That's exactly the kind of stuff done inside the function...

hmm... I didn't know that memory aligment was also applying in this case..

is there any workaround, except the one I used (shtg more clean) ??

thanks for your answer.


Did you try what I suggested ?

The alignment issue here is how the compiler by default does casting (or lack thereof) when moving the return value from your function (32 bits) to the u16 variable (16 bits).
Back to top
evilo



Joined: 22 Apr 2004
Posts: 230

PostPosted: Thu Jan 13, 2005 8:21 pm    Post subject: Reply with quote

yes sorry gorim...

Quote:

_u16* ptr =(_u16* ) get_something(parameter);
if (ptr == NULL)
return 0;
else
return (_u16)*ptr;



the effect is the same... I get it back as a u8 but casted to u16 ...
Back to top
View user's profile Send private message Visit poster's website
Guest






PostPosted: Thu Jan 13, 2005 8:25 pm    Post subject: Reply with quote

I bet the problem is inside get_something()....


code code! show me!
Back to top
evilo



Joined: 22 Apr 2004
Posts: 230

PostPosted: Thu Jan 13, 2005 8:31 pm    Post subject: Reply with quote

lol... :)

Quote:

id* translate_address_read(_u32 address)
{
address &= 0xFFFFFF;


if (address == 0x8008)
ram[0x8008] = (_u8)((abs(TIMER_HINT_RATE - (int)timer_hint)) >> 2);

if (address <= RAM_END)
return ram + address;

// ===================================

//Get EEPROM status?
if (eepromStatusEnable)
{
eepromStatusEnable = FALSE;
if (address == 0x220000 || address == 0x230000)
{
eepromStatus = 0xFFFFFFFF;
return &eepromStatus;
}
}

//ROM (LOW)
if (rom.data && address >= ROM_START && address <= ROM_END)
{
if (address <= ROM_START + rom.length)
return rom.data + (address - ROM_START);
else
return NULL;
}

//ROM (HIGH)
if (rom.data && address >= HIROM_START && address <= HIROM_END)
{
if (address <= HIROM_START + (rom.length - 0x200000))
return rom.data + 0x200000 + (address - HIROM_START);
else
return NULL;
}

// ===================================

//BIOS Access?
if ((address & 0xFF0000) == 0xFF0000)
return bios + (address & 0xFFFF); // BIOS ROM

// ===================================

//Signal a flash memory error
if (memory_unlock_flash_write)
memory_flash_error = TRUE;

return NULL;
}


ram is declared as _u8 ram[]
eepromStatus is delacred as _u32;

code is working like a charm on pc, and this is typically the case that pixel showed before.. I don't think there is any clue apart rewriting the code in a completely different way..
Back to top
View user's profile Send private message Visit poster's website
Guest






PostPosted: Thu Jan 13, 2005 8:42 pm    Post subject: Reply with quote

Where exactly in the code is eepromStatus declared ?

I see you returning &eepromStatus. If it is declared inside the function, you are returning a pointer to the stack and that will be corrupted surely. The only way to prevent that is to declared eepromStatus statically or outside of any function. Since stack corruption manifests in weird and random ways, its quite likely it can work fine on a PC but fail elsewhere.

Other than that, not sure what the rom structure looks like, but nothing else looks obviously wrong. :)
Back to top
evilo



Joined: 22 Apr 2004
Posts: 230

PostPosted: Thu Jan 13, 2005 9:15 pm    Post subject: Reply with quote

eepromStatus is a global static variable,

rom.data is a u8 array

hmm ;)
Back to top
View user's profile Send private message Visit poster's website
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Fri Jan 14, 2005 3:05 am    Post subject: Reply with quote

Two things:

1 - What is the address when it goes bonkers? Maybe it is an alignment issue.
2 - Why don't you just look at the generated code?

For 1, look at it this way. The value is a pointer. How is the code supposed to know what it will be? If the address is a constant like a variable address, code to handle unaligned access can be generated. However, there's no way to do that with a pointer. YOU have to do that.

u16 access_word(u16* address) {
if ((u32)address & 1) {
u8 *ptr = (u8*)address;
return (u16)(ptr[1]<<8 | ptr[0]);
} else
return *address;
}

See? YOU handle the alignment yourself because YOU can determine the alignment where the compiler can't.
Back to top
View user's profile Send private message AIM Address
mrbrown



Joined: 17 Jan 2004
Posts: 1536

PostPosted: Fri Jan 14, 2005 3:30 am    Post subject: Reply with quote

Yes, just post the assembly of the function, so folks will stop trying to guess at what's going on.

And here someone told me not too long ago that knowing asm for the CPU you're dealing with isn't important :P.
_________________
"He was warned..."
Back to top
View user's profile Send private message
dreamtime



Joined: 02 Feb 2004
Posts: 15
Location: Melbourne, Australia

PostPosted: Fri Jan 21, 2005 12:55 pm    Post subject: Reply with quote

Did you guys work out what the problem with this was?
I think I remember having similar problems around 2 years ago and came up with a solution :)
I'd need to see exactly how all your globals are declared.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PS2 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