[futurebasic] Re: Generic Trap Patch

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : March 1998 : Group Archive : Group : All Groups

From: Mark Goodes <wave@...>
Date: Sat, 28 Mar 1998 00:45:37 -0500
>If you find assembler easier than DCODs, then maybe you can help me with
>my "Generic" trap patch (below).  It seems to work when applied in an
>application, but not from an INIT.  I have spent many hours in MacsBug
>trying to work out why?  Any assembler help welcome!

The problem could be with the way that you install the patch--that's where
I've had some recent troubles.  Put a BEEP call in your patch to make sure
it is indeed being called.

Another major problem I've had with INIT's is getting access to my
globals--as you've probably gathered from my two previous posts in this
thread.  So the next thing you should do is make sure that the values of
your variables are non-zero.  You can do this by putting each variable into
a register and dropping into Macsbug, like this:
` (save old registers first)
` move.l (sp)+,^ReturnAddress&
` move.l ^ReturnAddress&,d0
CALL DEBUGGER  ; then look at d0 to make sure it is non-zero, then type "g"
` (restore registers)

Outside of this, the main mistake you're making is not giving the Toolbox
routine the proper return address.  /*I've inserted inline comments below
using this syntax to make it easier to read.*/

---Copy of your code--
CLEAR LOCAL
LOCAL FN GetMyGlobal
  theRealTrap& = gOldTrapPtr&
END FN = theRealTrap&

"Generic Patch"
LONG IF gOldTrapPtr& <> 0
    `   MOVE.L  (SP)+,^ReturnAddress&   /*Here you are leaving the stack
bare without any return address on it.  See the correction below.*/
    `   movem.l     d0-d7/a0-a6,-(sp)
    myReal& = FN GetMyGlobal   /* I'm not sure why you need a separate FN
for this.  But again, check to see that myReal& is non-zero. */
    `   movem.l     (sp)+,d0-d7/a0-a6
    CALL myReal&     /*Here you are jumping to the Toolbox routine but
without a return address on the stack.  So when the Toolbox routine
attempts to return it will crash.*/
    `     MOVE.L  ^ReturnAddress&,-(SP) /*Too late!*/
  RETURN
END IF
---

I'm a little worried about the way you're calling the original routine--you
seem to be using it as both a head patch and a tail patch.  Unless that's
part of your original generic concept, it seems like overkill.
Nonetheless, the suggested routine below does both.  (I'm also paranoid
about using FB commands because I can't see which registers are being
affected, so I put in the extra safety measure of not using any FB syntax
before or after saving the registers.)  I haven't tested this, but
hopefully it will help you correct your bug anyway.

"Generic Patch"
LONG IF gOldTrapPtr& <> 0

  /* Head patch */
    `  move.l (sp)+,^ReturnAddress&  /* Save return address if FB will give
you access to your variables */
   ` clr.l -(sp)     ; space to replace old return address with your own
  `  clr.l -(sp)     ; space to store real Toolbox address to jump to later
   `   movem.l     d0-d7/a0-a6,-(sp)
   ` move.l  ^gOldTrapPtr&,60(sp)    /* put real Toolbox address on the
stack in front of the saved registers  */
   myTailPatchAddr&=LINE "My tail patch"  /*get the address of your tail
patch*/
   ` move.l  ^myTailPatchAddr&,64(sp)  /* put your tail patch address on
stack so that the Toolbox routine will jump back there*/
   /*... Insert patch code here--be sure to not corrupt the stack... */
    `   movem.l     (sp)+,d0-d7/a0-a6
    ` rts  ; jump to Toolbox trap

    /* Tail patch */
    "My tail patch" /*program control will return here after the Toolbox
trap executes*/
    ` clr.l -(sp)  /* Space for return address */
    ` movem.l  d0-d7/a0-a6,-(sp)
    ` move.l ^ReturnAddress&,60(sp)      ; put saved return address on stack
    /*...Insert tail patch code here--if there is supposed to be a return
value, be sure to set up the stack and/or registers properly before you
exit... */
    ` movem.l (sp)+,d0-d7/a0-a6
    ` rts  ; jump back to original program
END IF

____________
wave (Toronto, Canada)
Much better at "OOPS!" programming than OOP programming.