The code which generates a dynamic array on the stack in the middle of a procedure (which I never would have suspected you could do in Pascal) appears to corrupt the stack in a way which makes ReturnAddress(0) either return bogus numbers or crash with a bus error. Or more accurately, assigning to sections of the created array corrupts the stack.
I don't know if this is a PowerPC only issue, or applies to other platforms as well.
This code:
program peter103;
uses GPC;
procedure Test( ParameterCount: Integer ); var i: Integer; begin WriteLn( StdErr, 'T1 ', ParameterCount, ' ', ReturnAddr2Hex(ReturnAddress (0)) ); var CProcessParameters: array [0 .. ParameterCount + 1] of CString; WriteLn( StdErr, 'T2 ', ParameterCount, ' ', Low(CProcessParameters), ' ', High(CProcessParameters), ' ', ReturnAddr2Hex(ReturnAddress (0)) ); CProcessParameters[0] := nil; for i := 1 to ParameterCount do CProcessParameters[i] := nil; WriteLn( StdErr, 'T3 ', ParameterCount, ' ', Low(CProcessParameters), ' ', High(CProcessParameters), ' ', ReturnAddr2Hex(ReturnAddress (0)) ); end;
var i: Integer; begin for i := 0 to 10 do Test( i ); end.
will either crash in the last ReturnAddress with a bus error, fail with a range check if ReturnAddress decides to return nil (because ReturnAddr2Hex range checks if passed 0 as a parameter) or return a different bogus number (different to the two previous addresses).
I discovered this as it affects Pipe in pipes.pas which is used by gp.
The code for the creation of CProcessParameters is:
lwz r2,12520(r30) addi r2,r2,1 stw r2,12448(r30) lwz r0,12448(r30) cmpwi cr7,r0,0 bge cr7,L5 bl L__p_SubrangeError$stub L5: lwz r0,12448(r30) slwi r2,r0,2 addi r2,r2,4 stw r1,12452(r30) addi r2,r2,15 addi r0,r2,15 srwi r0,r0,4 slwi r0,r0,4 lwz r2,0(r1) neg r0,r0 stwux r2,r1,r0 addi r2,r1,56 addi r0,r2,15 srwi r0,r0,4 slwi r2,r0,4 stw r2,12456(r30)
I'm afraid this taxes my PPC decoding and ABI abilities past the limits, so I can't actually tell where the problem in the code is.
Moving the definition of CProcessParameters into the variable section does not change the behaviour.
Could someone try duplicating this Linux or Windows perhaps to see if it is PPC only, or can anyone read enough PPC to figure out if the code is correct or not?
I'll keep trying to pin down exactly what is wrong...
Thanks, Peter.