Path: utzoo!utgpu!attcan!uunet!samsung!usc!apple!marc From: marc@Apple.COM (Mark Dawson) Newsgroups: comp.sys.mac.programmer Subject: Re: Tail patches Message-ID: <36250@apple.Apple.COM> Date: 6 Nov 89 15:40:39 GMT References: <1459@sequent.cs.qmc.ac.uk> Organization: Apple Computer Inc, Cupertino, CA Lines: 57 In article <1459@sequent.cs.qmc.ac.uk> jeremyr@cs.qmc.ac.uk (Jeremy Roussak) writes: > >I hope the net will pardon my ignorance, but I have seen a few comments >recently about "tail patching" of traps and have a couple of questions: > >1. What exactly are "tail patches"? >2. If they are what I suspect they are, why are they bad? > 1. There are times that you may wish to replace or modify a Mac trap call (Say for example, _Write). Suppose you have this horribly gross program that passes the volume name, instead of the drive # to the _Write call. You could write an intercept routine that would decode this name into the correct drive # and drive refnum for the "real" system _Write call. It would then call the system _Write (This would be a "head" patch). You could direct the system _Write to return to another piece of code (the "tail" patch) to do some special cleanup if there was some error. The problem with the "tail" patch is that there is some possibility that an Apple patch to that routine (to fix some bug/enhance it) might be checking the return address to see if it should do something. Since your return address would be on the stack first, this check would fail. Before I worked at Apple I did use both the "head" and "tail" patches; I didn't see anyway around them. I also never ran into this "return address check". I am always crossing my fingers, hoping this case will never happen (it would REALLY break my code). Someone else in Apple will have to comment on if they know of any of patches that DO check the return addresses. I don't know of any, but I don't claim to know the whole system. Below is a snippet of code to do head & tail patches. ; ; get address of system trap ; move.l WRITE_TRAP,D0 ; WRITE_TRAP = $A003 (_Write) _GetTrapAddress lea SysTrapAdd,A1 move.l A0,(A1) ; save system trap @ ; ; make system _Write goto my trap ; move.l WRITE_TRAP,D0 ; WRITE_TRAP = $A003 (_Write) lea MyWriteTrap,A0 _SetTrapAddress .... .... ; ; My write trap...does translation before & after call ; MyWriteTrap bsr DoDecode ; adjust parm block pea AfterWrite ; write to return to move.l SysTrapAdd,-(sp) RTS ; goto system routine AfterWrite bsr DoCleanUp RTS ; return to system