osborn@ux1.lbl.gov (James R Osborn) (05/29/91)
Just what exactly is the preferred method for applying a tail patch to a Toolbox routine? I've read all sorts of stuff that waves its (metaphorically speaking) hands and never explicitly says how to do it. Maybe I've missed a tech note that describes the process? Here is something that I have done that worked but seems incredibly unelegant and kludgey: using an init (this part seems ok to me): load the patch routine into the system heap with the init DetachResource it HNoPurge it HLock it save original trap address in the patch routine's header set the trap address to point at the patch then in the patch: the patch routine gets passed the appropriate arguments for the trap being patched do my preprocessing, whatever it is set trap address to original trap address (from header) call trap, passing appropriate arguments, and saving result (if necessary) set trap address back to this patch return result (if necessary) Why did I do it this way? Because I used C and was too lazy to figure out how to call the trap routine directly myself using assembly. I presume the preferred method is to push the appropriate arguments onto the stack (pascal fashion) and then JSR to the original trap? Then I wouldn't be SetTrapAddress'ing all over the place. Would my psuedo-code above then be preferred? (Or am I totally or even partially blowing it? 8^) -- James .------------------------------.--------------------------------------. | James R. Osborn | It just goes to show you it's always | | Lawrence Berkeley Laboratory | something. Either it's baffling | | osborn@ux1.lbl.gov | tech notes or your mac is smoking. | | (415) 548-8464 | It's always something... | '------------------------------'--------------------------------------'
CXT105@psuvm.psu.edu (Christopher Tate) (05/29/91)
You might want to download the file "screensaversource.c.hqx" from the
anonymous ftp site at mac.archive.umich.edu. It's the source code to
a screen saver that I wrote as a project for the Penn State Center for
Academic Computing. As a screen saver it's no great shakes, but (IMHO)
it's a very clean example of a trap patch.
The code is written for THINK C. If you're using MPW or Zortech, it'll
probably be kind of tricky to get it working. THINK C, unlike the others,
generates A4-relative addressing for standalone code, to avoid having to
muck with A5. However, the actual mechanics of the trap patch should be
fairly evident.
You can find that file in the directory "/mac/development/source".
Also, you may want to get hold of the Usenet Mac Programmers' Guide, a
compilation of useful stuff that has appeared here over the past couple
of years. It's available from sumex-aim.stanford.edu, and possible from
mac.archive.umich.edu. The editor is Matt Mora, mxmora@unix.sri.com,
in case you can't find a copy elsewhere. The UMPG does have a fair
amount of info on trap patching and suchlike.
-------
Christopher Tate | Mercy (noun):
| The infrequent art of turning
Bitnet: cxt105@psuvm | thumbs-up on your opponent at
Uucp: ...!psuvax1!psuvm.bitnet!cxt105 | the end of your rapier.
dplatt@ntg.com (Dave Platt) (05/30/91)
In article <13613@dog.ee.lbl.gov> osborn@ux1.lbl.gov (James R Osborn) writes: >Just what exactly is the preferred method for applying a >tail patch to a Toolbox routine? There is NO preferred method for tail-patching. It should not be done. > I've read all sorts of >stuff that waves its (metaphorically speaking) hands and >never explicitly says how to do it. That's because you shouldn't. The reason is as follows. The Mac startup code installs a bunch of patches, to correct bugs in the ROM toolbox routines and to add new functionality. Usually, these patches operate by replacing the affected routine... when you call the modified trap, the patch code is executed instead of the code in the ROM. However, there are cases in which it's undesirable to install this sort of patch... usually because the bug is buried deep in the middle of a large routine, and it would be necessary to replace an entire multi-kilobyte routine to fix the bug. Instead, the Toolbox maintainers examine the code in error, find a trap that _it_ calls, and then install a head patch in that (secondary) trap. The secondary patch checks the stack to see where it's being called from. If it's called from any location other than the location of the bug, it does nothing... it just jumps to the original trap-handler. If it was called from the routine that has the bug, it runs some code which corrects the effect of the bug somehow, and then branches to the original trap-handler. Now... consider what happens if _you_ install a tail-patch to the secondary trap. If that trap is called from the buggy code, then your patch takes control, does something, and then calls the routine it had superceded... which, in this case, will be the secondary bug-fixing patch. This patch will check to see whether it was called from the location where the bug exists. The answer will be "no"... because it was called from _your_ patch. The result? If you install a tail-patch on a trap that Apple is using as a secondary bug-fixer, then you will _disable_ Apple's bug fix! The machine on which you're running will probably exhibit odd symptoms, due to the fact that a necessary patch has been partially or completely disabled. >Here is something that I have done that worked but seems >incredibly unelegant and kludgey: > >using an init (this part seems ok to me): > >load the patch routine into the system heap with the init >DetachResource it >HNoPurge it >HLock it >save original trap address in the patch routine's header >set the trap address to point at the patch > >then in the patch: > >the patch routine gets passed the appropriate arguments > for the trap being patched >do my preprocessing, whatever it is >set trap address to original trap address (from header) >call trap, passing appropriate arguments, and saving > result (if necessary) >set trap address back to this patch >return result (if necessary) This is the traditional way to do a tail patch. >Why did I do it this way? Because I used C and was too lazy >to figure out how to call the trap routine directly myself >using assembly. I presume the preferred method is to push >the appropriate arguments onto the stack (pascal fashion) >and then JSR to the original trap? As I say, there is _no_ preferred method. It's a technique which should not be used. -- Dave Platt VOICE: (415) 813-8917 Domain: dplatt@ntg.com UUCP: ...apple!ntg!dplatt USNAIL: New Technologies Group Inc. 2468 Embarcardero Way, Palo Alto CA 94303
osborn@ux1.lbl.gov (James R Osborn) (05/30/91)
In article <13613@dog.ee.lbl.gov> osborn@ux1.lbl.gov (James R Osborn) writes: > >Just what exactly is the preferred method for applying a >tail patch to a Toolbox routine? I've read all sorts of ^^^^^^^^^^ OOOPS! I was blowing it in that I meant to say "HEAD PATCH"! >Would my psuedo-code above then be preferred? (Or am I totally >or even partially blowing it? 8^) > >-- James > So am I to understand correctly that my example (according to Dave Platt) is an ok example of a "TAIL PATCH"?! OOOOPS! So I did a tail patch when I meant to do a head patch - OOOOPS! Now I think I understand the difference. So what I really want is to have the original trap finish up: Set the trap address to point at my patch do my thing in my patch jmp to the original trap so that IT returns to the original caller Is this right? Sorry for the blooper 8^( -- James .------------------------------.--------------------------------------. | James R. Osborn | It just goes to show you it's always | | Lawrence Berkeley Laboratory | something. Either it's baffling | | osborn@ux1.lbl.gov | tech notes or your mac is smoking. | | (415) 548-8464 | It's always something... | '------------------------------'--------------------------------------' NO wonder my mac is smoking ....
alexr@apple.com (Alexander M. Rosenberg) (05/30/91)
I'm gonna get shot for this, but... In article <772@goblin.ntg.com>, dplatt@ntg.com (Dave Platt) writes: > > In article <13613@dog.ee.lbl.gov> osborn@ux1.lbl.gov (James R Osborn) writes: > > >Just what exactly is the preferred method for applying a > >tail patch to a Toolbox routine? > > There is NO preferred method for tail-patching. It should not be done. > This isn't really true. Rule #627 about tail patching: If your code _only_ works under System 7.0 anyway (and the patch installation code aborts if you aren't under 7.0), then _most_ tail patches are safe. Before you try to tail patch something, watch what SetTrapAddress does. You may notice that it preserves "come-from" patches (the kind you don't want to tail patch) for _most_ traps. Again: 1.) Check before you try. 2.) Only 7.0. 3.) Not official (read: may change). --------------------------------------------------------------------------- - Alexander M. Rosenberg - INTERNET: alexr@apple.com - Yoyodyne - - 330 1/2 Waverley St. - UUCP:ucbvax!apple!alexr - Propulsion - - Palo Alto, CA 94301 - - Systems - - (415) 329-8463 - Nobody is my employer so - :-) - - (408) 974-3110 - nobody cares what I say. - -
chuck@brain.UUCP (Chuck Shotton) (05/30/91)
In article <772@goblin.ntg.com>, dplatt@ntg.com (Dave Platt) writes: > This is the traditional way to do a tail patch. > [deleted] > As I say, there is _no_ preferred method. It's a technique which should > not be used. > Is there a preferred method for patching traps at all? ----------------------------------------------------------------------- Chuck Shotton Internet: cshotton@girch1.med.uth.tmc.edu