boinc/lib/mac/QBacktrace.c
/*	PowerPC Stack Frame Basics
	--------------------------
	
	
						Offset	Size	Purpose
						------	----	-------
	low memory
	fp == sp == r1 ->	0		X		pointer to next frame
						X		X		place to save CR
						2X		X		place to save LR
						3X		2X		reserved
						5X		X		place to save TOC (CFM only)
	high memory
	
						where X is the address size (4 bytes for 32-bits, 
						8 bytes for 64-bits)
					
	To get from one frame to the next, you have to indirect an offset 
	of 0.  To extract the PC from a frame (which, notably, is the 
	address of the code running in that frame, not a return address), you 
	have to indirect an offset of 2X bytes (8 or 16).
	
	There's enough commonality between 32- and 64-bit PowerPC architectures 
	that it's easy to handle them both with the same code.
*/
PowerPC Stack Frame Basics
Offset  Size    Purpose

low memory
fp == sp == r1 ->       0               X               pointer to next frame
X               X               place to save CR
2X              X               place to save LR
3X              2X              reserved
5X              X               place to save TOC (CFM only)
high memory



To get from one frame to the next, you have to indirect an offset
of 0.  To extract the PC from a frame (which, notably, is the
address of the code running in that frame, not a return address), you
have to indirect an offset of 2X bytes (8 or 16).

There's enough commonality between 32- and 64-bit PowerPC architectures
that it's easy to handle them both with the same code.
PowerPC Stack Frame Basics Offset Size Purpose low memory fp == sp == r1 - > 0 X pointer to next frame X X place to save CR 2X X place to save LR 3X 2X reserved 5X X place to save TOC ( CFM only ) high memory To get from one frame to the next you have to indirect an offset of 0 . To extract the PC from a frame ( which notably is the address of the code running in that frame not a return address ) you have to indirect an offset of 2X bytes ( 8 or 16 ) . There ' s enough commonality between 32 - and 64 - bit PowerPC architectures that it ' s easy to handle them both with the same code .
static bool PowerPCIsSystemCall(QBTContext *context, QTMAddr pc)
{
	int			err;
	bool		isSystemCall;
	int			count;
	uint8_t		inst[4];
	isSystemCall = false;
	count = 0;
	do {
		err = context->readBytes(context, pc, &inst, sizeof(inst));
		if (err == 0) {
			isSystemCall = (inst[0] == 0x44)		
			            && (inst[1] == 0x00)		
						&& (inst[2] == 0x00)		
						&& (inst[3] == 0x02);		
		}
		if ( (err == 0) && ! isSystemCall ) {
			count += 1;
			pc -= sizeof(inst);
		}
	} while ( (err == 0) && ! isSystemCall && (count < 3) );
	err = 0;
	return isSystemCall;
}
static bool PowerPCIsSystemCall ( QBTContext * context , QTMAddr pc ) { int err ; bool isSystemCall ; int count ; uint8_t inst [ 4 ] ; isSystemCall = false ; count = 0 ; do { err = context -> readBytes ( context , pc , & inst , sizeof ( inst ) ) ; if ( err == 0 ) { isSystemCall = ( inst [ 0 ] == 0x44 ) && ( inst [ 1 ] == 0x00 ) && ( inst [ 2 ] == 0x00 ) && ( inst [ 3 ] == 0x02 ) ; } if ( ( err == 0 ) && ! isSystemCall ) { count += 1 ; pc -= sizeof ( inst ) ; } } while ( ( err == 0 ) && ! isSystemCall && ( count < 3 ) ) ; err = 0 ; return isSystemCall ; }
PowerPC Stack Frame Basics
Offset  Size    Purpose
  
low memory
fp == sp == r1 ->       0               X               pointer to next frame
X               X               place to save CR
2X              X               place to save LR
3X              2X              reserved
5X              X               place to save TOC (CFM only)
high memory
PowerPC Stack Frame Basics Offset Size Purpose low memory fp == sp == r1 - > 0 X pointer to next frame X X place to save CR 2X X place to save LR 3X 2X reserved 5X X place to save TOC ( CFM only ) high memory
// Using the PC from the thread state, walk back through  // the code stream for 3 instructions looking for a "sc" instruction.  // If we find one, it's almost certain that we're in a system call  // frameless leaf routine. // PPC "sc" instruction // PPC instructions are always big  // endian, so we compare it byte at  // time for endian neutrality