[comp.sys.mac.programmer] trap patches

s-zeerox@steer.calstate.edu (Stan Malyshev) (11/26/90)

Does anyone have any SIMPLE code to illustrate a trap patch via and INIT?
My creation bombs (ID = 02) at startup, and I can't figure out what's 
wrong.  Arrghhhh!

(oops, I meant "an" INIT (line 1))

Thanks in advance,

Stan.
--
---------------------------
Stan Malyshev                    When mountain bikes are outlawed,
s-zeerox@steer.calstate.edu           only outlaws will ride mountain bikes.
---------------------------

stevec@Apple.COM (Steve Christensen) (11/27/90)

s-zeerox@steer.calstate.edu (Stan Malyshev) writes:
>Does anyone have any SIMPLE code to illustrate a trap patch via and INIT?
>My creation bombs (ID = 02) at startup, and I can't figure out what's 
>wrong.  Arrghhhh!

Here's a quickie in assembly:


Start	BRA	Setup

;  here's  a patch that calls the original code and then does its thing

Patch1	JSR	$12345678		; call original trap code
	MOVEM.L	savedRegs,-(SP)		; save all registers we use
	...				; do whatever is needed
	MOVEM.L	(SP)+,savedRegs		; restore registers we used
	RTS

;  here's a patch that does its thing and then falls thru into original code

Patch2	MOVEM.L	savedRegs,-(SP)		; save all registers we use
	...				; do whatever is needed
	MOVEM.L	(SP)+,savedRegs		; restore registers we used
ToOld	JMP	$12345678		; jump to original trap code

;  here's the installation code

Setup	MOVE.W	#Trap1Num,D0		; get the address of the trap to patch
	_GetTrapAddress
	LEA	Patch1+2,A1		; point to the JSR address
	MOVE.L	A0,(A1)			;  and save the original code's address
	LEA	Patch1,A0		; point the trap to our code
	MOVE.W	#Trap1Num,D0
	_SetTrapAddress

	MOVE.W	#Trap2Num,D0		; get the address of the trap to patch
	_GetTrapAddress
	LEA	ToOld+2,A1		; point to the JMP address
	MOVE.L	A0,(A1)			;  and save the original code's address
	LEA	Patch2,A0		; point the trap to our code
	MOVE.W	#Trap2Num,D0
	_SetTrapAddress

	LEA	Start,A0		; point to the start of this block
	_RecoverHandle			;  and use it to get the handle back
	MOVE.L	A0,-(SP)		; detach the block so it doesn't go
	_DetachResource			;  away when the INIT file closes
	RTS

Note that the code is modified.  This is an easy illustration, and you could
instead save the original trap addresses in your variables and jump thru
that.  It's also very important that the "system heap" and "locked" bits for
this INIT resource are checked, otherwise it will be trashed or moved...

steve

-- 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  whoami?     Steve Christensen
  snail:      Apple Computer, 20525 Mariani Ave, MS-81CS, Cupertino, CA 95035
  internet:   stevec@apple.com
  AppleLink:  stevec
  CompuServe: 76174,1712

robert@polari.UUCP (robert) (12/01/90)

In article <46831@apple.Apple.COM>, stevec@Apple.COM (Steve Christensen) writes:
> s-zeerox@steer.calstate.edu (Stan Malyshev) writes:
> >Does anyone have any SIMPLE code to illustrate a trap patch via and INIT?
> >My creation bombs (ID = 02) at startup, and I can't figure out what's
> >wrong.  Arrghhhh!
>
> Here's a quickie in assembly:

    This example looks very useful, but my BIG problem right now is
 that what I need to do requires patching routines in the Standard File
 package. Pack3 is a complex trap. Apparently, calls to Pack3 involve
 passing a routine "selector" of some kind. I haven't found any 
 documentation on this. Does anyone have any information? Any examples
 or pointers to examples? A sharp razor?

                                            Robert Riebman

|***********************************************************************|
|Robert Riebman                    |  robert@polari                     |
|Northwest Information Technology  | (...uw-beaver!sumax!polari!robert) |
|P.O. Box 3156                     |                                    |
|Redmond, WA     98073             |         "Hack and Enjoy"           |
|***********************************************************************|

jwwalker@opusc.csd.scarolina.edu (Jim Walker) (12/02/90)

In article <2818@polari.UUCP> robert@polari.UUCP (robert) writes:
[stuff deleted]
>
>    This example looks very useful, but my BIG problem right now is
> that what I need to do requires patching routines in the Standard File
> package. Pack3 is a complex trap. Apparently, calls to Pack3 involve
> passing a routine "selector" of some kind. I haven't found any 
> documentation on this. Does anyone have any information? Any examples
> or pointers to examples? A sharp razor?
>
>                                            Robert Riebman

(I tried to mail this reply, but it bounced.)

Here is some THINK C code for the relevant parts of a Pack3 patch I wrote.

typedef enum {
	SFPut = 1,
	SFGet,
	SFPPut,
	SFPGet
};

pascal void my_SF()
{
	int		selector;
	register Point	*where;
	int			dlog_id;
	
	/* since this is a trap routine, we must preserve the registers */
	asm {
		movem.l	a1-a5/d0-d7, -(SP)	; a7 is SP
		LEA 	main, A4		; set up globals
		move.w	8(A6), selector
	}
	
	
	switch (selector)
	{
		case SFGet:
			asm {
				lea	32(A6), where
			}
			dlog_id = getDlgID;
			break;
		case SFPut:
			asm {
				LEA	26(A6), where
			}
			dlog_id = putDlgID;
			break;
		case SFPPut:
			asm {
				lea	32(A6), where
				move.w	14(A6), dlog_id
			}
			break;
		case SFPGet:
			asm {
				LEA	38(A6), where
				move.w	14(A6), dlog_id
			}
			break;
	}
	
	/*  Most of your patch goes here */
	
	asm {
		move.l	Old_SF, A0
		movem.l	(SP)+, a1-a5/d0-d7	; restore registers
		unlk	A6
		JMP	(A0)			; jump to Old_SF
	}
}

-- 
  -- Jim Walker 76367.2271@compuserve.com