fjo@ttrdf.UUCP (Frank Owen ) (10/07/88)
What is the proper way to patch the GetNextEvent() trap for compatibility with MultiFinder?. I have created an INIT that patches this call. The first thing that the patch does is call the old GetNextEvent, (the one that was there at INIT time.). The purpose of the patch is to translate the CapsLock modifier into the command-key modifier. My patch still seems to be in there (the desired result occurs), but it introduces long delays and curious behaviour when running under MultiFinder. The two specific weird things are : 1) If I have the Finder as the top window, and then obscure an icon on the desktop, then expose it again, the icon does NOT get redrawn until it gets selected again. 2) While running LightSpeed C's debugger, if I enter an expression in the Data window, the watch cursor comes up, and stays there forever, UNTIL you mouse-down a few times on another application's window. Then when you re-activate the debugger window the expresion in the data window is correctly evaluated and displayed. I am running from System Tools 5.0. (The first official Multifinder). All above behaviour ceases if I either remove my INIT, or run without MultiFinder. Any ideas? Frank Owen (..!att!ttrdf!fjo) -- Frank Owen (fjo@ttrdf) 312-982-2182 AT&T Bell Laboratories 5555 Touhy Ave., Skokie, IL 60077 PATH: ...!att!ttrdf!fjo
bob@eecs.nwu.edu (Bob Hablutzel) (10/09/88)
> What is the proper way to patch the GetNextEvent() trap for > compatibility with MultiFinder?. I have created an INIT that > patches this call. The first thing that the patch does is call the > old GetNextEvent, (the one that was there at INIT time.). > The purpose of the patch is to translate the CapsLock modifier into > the command-key modifier. - symptoms deleted - > Any ideas? Ideas are easy. Solutions come harder. :-) The problem here is that you have written a "tail patch". This is a critter that does it's work _after_ the original ROM routine. These are verboten, since some of Apple's patches to the OS rely on the return address of the call. (I'm not kidding, and for more information why, see a recent issue BYTE which had a long article on MultiFinder. Yeah, I said BYTE.) Try this: there is a low memory global called jGNEFilterProc, or something real close to that. It is called just before _GetNextEvent returns, with A1 pointing to the event record in question. (At least, this is very close to the truth - I'm writting this from memory, without documentation). Bob Hablutzel BOB@NUACC.ACNS.NWU.EDU Disclaimer: I'd never write a practical joke INIT with this information. Nope. Not me.
jkjl@munnari.oz (John Lim) (10/10/88)
In article <747@ttrdf.UUCP>, fjo@ttrdf.UUCP (Frank Owen ) writes: > > What is the proper way to patch the GetNextEvent() trap for > compatibility with MultiFinder?. I have created an INIT that > patches this call. The first thing that the patch does is call the > old GetNextEvent, (the one that was there at INIT time.). > Have you patched WaitNextEvent. Some programs call WaitNextEvent exclusively, ignoring GetNextEvent. However WaitNextEvent calls GetNextEvent. This might cause the timing of the events to go out of synch as described in my message to lsr@Apple. john lim
jln@eecs.nwu.edu (John Norstad) (10/11/88)
> What is the proper way to patch the GetNextEvent() trap for > compatibility with MultiFinder?. I have created an INIT that > patches this call. The first thing that the patch does is call the > old GetNextEvent, (the one that was there at INIT time.). > The purpose of the patch is to translate the CapsLock modifier into > the command-key modifier. > My patch still seems to be in there (the desired result occurs), but > it introduces long delays and curious behaviour when running under MultiFinder. > The two specific weird things are : > 1) If I have the Finder as the top window, and then obscure an icon on > the desktop, then expose it again, the icon does NOT get redrawn until > it gets selected again. > 2) While running LightSpeed C's debugger, if I enter an expression in the > Data window, the watch cursor comes up, and stays there forever, > UNTIL you mouse-down a few times on another application's window. > Then when you re-activate the debugger window the expresion in the > data window is correctly evaluated and displayed. > > I am running from System Tools 5.0. (The first official Multifinder). > All above behaviour ceases if I either remove my INIT, or run without > MultiFinder. > > Any ideas? > > Frank Owen (..!att!ttrdf!fjo) I had exactly the same problem, and posted a note on comp.sys.mac on August 3. For your edification, here's the relevant part of my earlier note: I recently patched GetNextEvent, and noticed that under MultiFinder it wasn't working quite perfectly. Under MF, when a desktop icon (disk or trash) was uncovered after a window drag, it wasn't being redrawn. After much investigation I discovered that in this particular circumstance MF was expecting GetNextEvent to return a full zero word if the function result was false. This is much stricter than the usual rule for Boolean values on the stack, which says that only the low-order bit of the high-order byte of the word is significant. The ROM version of GetNextEvent does indeed always return a full zero word if the function result is false, but my patch, which was written in a high-level language, was only setting the high-order byte of the function result. I added some in-line assembly language code to clear the low-order byte, and this fixed the problem. You should also pay heed to Bob Hablutzel's reply to your note. These so-called "tail patches" are frowned upon. In the case of System 6.0, which I use, GetNextEvent is not involved in any of the "come from" patches, so it's OK to write your own tail patch. But it may break in future releases. John Norstad Academic Computing and Network Services Northwestern University Bitnet: JLN@NUACC Internet: JLN@NUACC.ACNS.NWU.EDU
anson@spray.CalComp.COM (Ed Anson) (10/11/88)
In article <10050022@eecs.nwu.edu> bob@eecs.nwu.edu (Bob Hablutzel) writes: >> What is the proper way to patch the GetNextEvent() trap for >> compatibility with MultiFinder?. I have created an INIT that > [ bunch of stuff deleted ] > >The problem here is that you have written a "tail patch". This is a critter >that does it's work _after_ the original ROM routine. These are verboten, since >some of Apple's patches to the OS rely on the return address of the call. I know that tail patches are officially forbidden, but I have written a successful one for GetNextEvent. Yes, I know Apple promises they'll maybe break it some day. But today it works. I'm afraid I missed the original posting, so I don't know what the the poster's particular problem is. What I'm still trying to figure out is this: Why does Apple persist in forbidding a very useful type of patch? Just so they can continue to use a kludge in their own patches? The necessity of such a proscription has still not been explained to my satisfaction. The opinions expressed above are my own, and not those of my employer. (But you knew that!) -- ===================================================================== Ed Anson, Calcomp Display Products Division, Hudson NH 03051 (603) 885-8712, anson@elrond.CalComp.COM
bob@eecs.nwu.edu (Bob Hablutzel) (10/11/88)
>>> What is the proper way to patch the GetNextEvent() trap for >>> compatibility with MultiFinder?. I have created an INIT that >> [ bunch of stuff deleted ] >> >>The problem here is that you have written a "tail patch". This is a critter >>that does it's work _after_ the original ROM routine. These are verboten, since >>some of Apple's patches to the OS rely on the return address of the call. >What I'm still trying to figure out is this: Why does Apple persist in >forbidding a very useful type of patch? Just so they can continue to use >a kludge in their own patches? The necessity of such a proscription has >still not been explained to my satisfaction. The reason is that the OS is burned into ROMs. ROMs have the annoying property of being hard to patch at startup time. Thus, is a bug is found in the ROM code, Apple is left with two choices: 1) Patch the entire trap the bug is in. This is, of course, the best idea, and the reason that _GetTrapAddress /_SetTrapAddress were originally included in the system. However, there are cases when the trap to be patched is very large (in terms of ROM code), and the patch would eat up an equal amount of RAM. This is especially the case when the bug is in the middle, or toward the end, of large traps. In this case, route 2 is taken: 2) Find some small trap called at about the area of the bug in the large trap, and patch this trap to check to see where it's called from, and if it's called from the buggy large trap, do some additional work for the buggy trap (to fix the bug), and maybe even change the return address to bypass the buggy code. This, needless to say, saves space in RAM, but has the unpleasant side affect of requiring the trap return address to be constant (remember, we're dealing with ROM addresses here) for the patch to work. Thus, tail patching will cause the patch to fail, and possibly bring back old bugs from the dead. Bob Hablutzel BOB@NUACC.ACNS.NWU.EDU Disclaimer: Night of the unliving bug. Scary thought, eh?
alexis@ccnysci.UUCP (Alexis Rosen) (10/12/88)
In article <10050024@eecs.nwu.edu> jln@eecs.nwu.edu (John Norstad) writes: >> What is the proper way to patch the GetNextEvent() trap for >> compatibility with MultiFinder? >> The two specific weird things are : >> 1) If I have the Finder as the top window, and then obscure an icon on >> the desktop, then expose it again, the icon does NOT get redrawn until >> it gets selected again. >> 2) While running LightSpeed C's debugger, if I enter an expression in the >> Data window, the watch cursor comes up, and stays there forever, >> UNTIL you mouse-down a few times on another application's window. >> Then when you re-activate the debugger window the expresion in the >> data window is correctly evaluated and displayed. >> I am running from System Tools 5.0. (The first official Multifinder). >> Frank Owen (..!att!ttrdf!fjo) > >I had exactly the same problem, and posted a note on comp.sys.mac on August 3. >[explains that you need to clear the low-order byte of the returned word] I missed this when it first came around, but you may be interested to know that If you try to run MultiFinder 1.0 and System 4.2 with _Finder 5.5_ it will work properly- except for the bug you just described. I wonder what Apple is doing in the current Finder that breaks all the rules? How about tail-patching various file system traps? It might be amusing to run really old Finders (1.1g, maybe) with MultiFinder and see just how long they last before dying. (Maybe not too amusing, especially if they take your hard disk with them...) ---- Alexis Rosen {allegra,philabs,cmcl2}!phri\ Writing from {harpo,cmcl2}!cucard!dasys1!alexis The Big Electric Cat {portal,well,sun}!hoptoad/ Public UNIX Best path: uunet!dasys1!alexis Or try: alexis@ccnysci.UUCP alexis@ccnysci.BITNET
anson@spray.CalComp.COM (Ed Anson) (10/12/88)
In article <10050025@eecs.nwu.edu> bob@eecs.nwu.edu (Bob Hablutzel) writes: >>What I'm still trying to figure out is this: Why does Apple persist in >>forbidding a very useful type of patch? > >The reason is that [very lucid explanation not repeated here.] Thank you, Bob. Now I understand. But I still don't like it :-( There are some traps (like GetNextEvent) which are usefully patched at the end. There are lots of people (like me) who want to accomplish something that can only be accomplished by tail patching this trap. So our application works today, but may someday cause strange failures in other areas. I hope that it's unlikely for GetNextEvent to cause such a problem, because if it does then my only solution to another problem goes away. As I understand it (now), the only traps which must not be tail patched are those which: 1. Are relatively small, and 2. Are called from other (bigger) traps. Is it thus possible for Apple to classify traps according to these criteria, and to declare some traps as safe for tail patching? I would hope that GetNextEvent could be declared safe. Anyone from Apple want to comment on this issue? I guess it's unavoidable, but it's still annoying that subtle new rules keep popping up, documented in obscure places: 1. Avoid tail patches. 2. Call GetNextEvent three or four times before opening a window. 3. Don't use the application events for application events. These (and possibly other) new rules have broken, or threaten to break, useful things for me. In some cases, those things were already written according to the rules in effect at the time. I know that most of these changes were necessary in some way to make new things work, and I'm willing to live with that. But I would appreciate it if the impact of some changes could be reduced. I would rather see the rules modified to something like: 1. Avoid tail patches, except for the following traps... 2. (why is this necessary? sounds like a MultiFinder bug to me!) 3. Reserve one application event to applications, and guarantee that posting it will return it to the posting application. I like to dream. :-) -- ===================================================================== Ed Anson, Calcomp Display Products Division, Hudson NH 03051 (603) 885-8712, anson@elrond.CalComp.COM
fjo@ttrdf.UUCP (Frank Owen ) (10/13/88)
in article <2453@spray.CalComp.COM>, anson@spray.CalComp.COM (Ed Anson) says: > > In article <10050022@eecs.nwu.edu> bob@eecs.nwu.edu (Bob Hablutzel) writes: >>> What is the proper way to patch the GetNextEvent() trap for >>> compatibility with MultiFinder?. I have created an INIT that >> [ bunch of stuff deleted ] >> >>The problem here is that you have written a "tail patch". This is a critter >>that does it's work _after_ the original ROM routine. These are verboten, since >>some of Apple's patches to the OS rely on the return address of the call. > > What I'm still trying to figure out is this: Why does Apple persist in > forbidding a very useful type of patch? I am the original poster of the GetNextEvent problem. I have since received info on this issue. The reason you can't do a tail-patch on GetNextEvent is because Multifinder uses GNE to do task switching. Your call to GetNextEvent does not necessarily return directly to you. When a task switch occurs, the call to GNE returns to some other application's call to GetNextEvent. Multifinder's version of GNE apparently needs to identify all the direct callers to GNE are, and with a tail patch the caller of Multifinder's GNE is always the patch. This must confuse Multifinder in some way. So I guess Apple is quite justified in forbidding this type of patch in this particuliar case. It let's them do Multifinder. Apple is not leaving us without a workaround however. There is this low-memory global called "jGNEfilter" which points to a filter routine that GNE will jump to prior to returning. When GNE jumps to this address, register A1 contains a pointer to the EventRecord. I have changed my INIT so that now it no longer patches GetNextEvent, but rather "inserts" code to be executed just before the jGNEfilter routine. The address of my code is inserted into the low-memory global, and when I'm done mangling the EventRecord, my routine jumps to the address that had been there prior to my patch. simple. And it works. I think tech-note #85 spells out all the rules for this. I don't have that particuliar note, but if anyone on the net does, I'd appreciatte it if you'd send me a copy. I'd like to abide by the rules if at all possible. bye. -- Frank Owen (fjo@ttrdf) 312-982-2182 AT&T Bell Laboratories 5555 Touhy Ave., Skokie, IL 60077 PATH: ...!att!ttrdf!fjo
bob@eecs.nwu.edu (Bob Hablutzel) (10/14/88)
> In article <10050025@eecs.nwu.edu> bob@eecs.nwu.edu (Bob Hablutzel) writes: > >>What I'm still trying to figure out is this: Why does Apple persist in > >>forbidding a very useful type of patch? > > > >The reason is that > [very lucid explanation not repeated here.] > > Thank you, Bob. Now I understand. But I still don't like it :-( You're welcome. > There are some traps (like GetNextEvent) which are usefully patched at > the end. There are lots of people (like me) who want to accomplish something > that can only be accomplished by tail patching this trap. So our application > works today, but may someday cause strange failures in other areas. Well, there actually is another way, if you don't mind getting your feet a little wet (assembler, or at least glue routines). There exists a low memory global variables jGNEFilter, which, if not nil, contains the address of a function to call before returning from _GetNextEvent. _GetNextEvent calls the routines with A1 (I think) pointing to the event record for the _GetNextEvent call. You can play with this record in any way you like. > As I understand it (now), the only traps which must not be tail patched are > those which: > 1. Are relatively small, and > 2. Are called from other (bigger) traps. This seems right to me, although one can never tell. We may be missing something. But, like I say, it seems right. > Is it thus possible for Apple to classify traps according to these criteria, > and to declare some traps as safe for tail patching? I would hope that > GetNextEvent could be declared safe. Anyone from Apple want to comment on > this issue? While it may be possible, I doubt Apple will do it. They have to leave their options open. > I guess it's unavoidable, but it's still annoying that subtle new rules keep > popping up, documented in obscure places: > 1. Avoid tail patches. > 2. Call GetNextEvent three or four times before opening a window. > 3. Don't use the application events for application events. Did I miss something? I thought the only application event retroactively nonexistant was APP4. (Personally, I don't know why Apple didn't take over network events for multifinder events, since network events don't exist anymore anyhow. Sigh). But, like you say, the documentation is sometimes obscure. :-) Bob Hablutzel BOB@NUACC.ACNS.NWU.EDU
anson@spray.CalComp.COM (Ed Anson) (10/14/88)
In article <749@ttrdf.UUCP> fjo@ttrdf.UUCP (Frank Owen ) writes: > > Apple is not leaving us without a workaround however. There is this >low-memory global called "jGNEfilter" which points to a filter routine >that GNE will jump to prior to returning. When GNE jumps to this address, >register A1 contains a pointer to the EventRecord. Yes, there is the GNE filter. Yes, TN #85 says how to use it. But NO, Apple also warns that modifying low-memory globals is dangerous. Even looking at them is officially discouraged, but permitted "if really necessary". Another alternative to a tail patch of GNE, is a (permitted) patch of SystemEvent, which is called by both GNE and WNE after other processing is completed. I have tried this, and it works well. I can find no reason for any future compatibility problems. Or is it dangerous to rely on the fact that this trap gets called under these circumstances, even though it is documented by Inside Macintosh? :-| -- ===================================================================== Ed Anson, Calcomp Display Products Division, Hudson NH 03051 (603) 885-8712, anson@elrond.CalComp.COM
ech@poseidon.ATT.COM (Edward C Horvath) (10/14/88)
In article <10050022@eecs.nwu.edu> bob@eecs.nwu.edu (Bob Hablutzel) writes: ! What is the proper way to patch the GetNextEvent() trap for ! compatibility with MultiFinder?... In article <2453@spray.CalComp.COM>, anson@spray.CalComp.COM (Ed Anson) says: ! The problem here is that you have written a "tail patch"... ! forbidding a very useful type of patch? From article <749@ttrdf.UUCP>, by fjo@ttrdf.UUCP (Frank Owen ): ! ...There is this ! low-memory global called "jGNEfilter" which points to a filter routine ! that GNE will jump to prior to returning. When GNE jumps to this address, ! register A1 contains a pointer to the EventRecord. ! I have changed my INIT so that now it no longer patches GetNextEvent, ! but rather "inserts" code to be executed just before the jGNEfilter ! routine. The address of my code is inserted into the low-memory ! global, and when I'm done mangling the EventRecord, my routine jumps to ! the address that had been there prior to my patch. simple. And it works. ! I think tech-note #85 spells out all the rules for this. I don't have ! that particuliar note, but if anyone on the net does, I'd appreciatte it ! if you'd send me a copy. I'd like to abide by the rules if at all possible. You've got it exactly right, Frank: the only detail is to make sure you set the Boolean result at 4(sp) to TRUE if you replace a null event with one you created (or to FALSE if you "eat" a non-null event that would otherwise be returned). I'll send a copy of TN 85 in the BTL mail; look for it around Christmas... =Ned Horvath=
brecher@well.UUCP (Steve Brecher) (10/15/88)
In article <2456@spray.CalComp.COM>, anson@spray.CalComp.COM (Ed Anson) writes, > As I understand it (now), the only traps which must not be tail patched are > those which: > > 1. Are relatively small, and > 2. Are called from other (bigger) traps. Add: 3. Are patched by Apple to fix bugs using "come from" tests. A "come from" test examines the stack to determine the location of the caller of the trap, e.g. if returnAddress = aParticularROMaddress then doSomethingToFixTheROMbug else jump to original trap code Apple uses this technique to avoid consuming large amounts of RAM for ROM bug fixes; in some cases, without "come from" tests, entire managers would have to be replaced in RAM. A tail patch wipes out the ROM bug fix patch because the return address will never satisfy the test, since by definition a tail patch executes the previous trap code with a JSR. The wish to > ...see the rules modified to something like: > 1. Avoid tail patches, except for the following traps... cannot be granted by Apple until such time as it discovers how to write bug-free ROMs, or how to legally protect its operating system code without resorting to delivering it in ROM.
tim@hoptoad.uucp (Tim Maroney) (10/17/88)
Is there a technical note which refers to this "tail patching" issue? I must admit that as a seasoned mac programmer I find the rationales given for the illegality of tail patching quite incomprehensible. Whether or not there is a tail patch would appear to have no effect on the return-address Apple hacks. Let's look at a case. Say that GetNamedResource checks the return address to see if it's being called from a ROM Font Manager routine, and that routine has a tail patch for some reason. When the "old" software for the Font Manager calls the Resource Manager, the return address is exactly what the Resource Manager "where-from" check expects. The tail patch has no relevance, since the "where-from" check is meant only to apply to the way the Resource Manager is called from that place in the ROM, and that place gets executed normally. A tail patch by definition first calls the old trap software. The problem with non-standard register saving is more serious, since some software does depend on undocumented register return values. However, such code is broken. If it is a serious problem, your tail patch can as easily return the same register values once the bug is discovered, but the real burden of compatibility is on the broken code, not your patch. Sorry if I'm missing something, but I just can't see how tail patching could disturb a "where-from" check, and I think third-party developers have to draw the compatibility line somewhere. Compatibility with broken software is nice but not mandatory. -- Tim Maroney, Consultant, Eclectic Software, sun!hoptoad!tim "As I was walking among the fires of Hell, delighted with the enjoyments of Genius; which to Angels look like torment and insanity. I collected some of their Proverbs..." - Blake, "The Marriage of Heaven and Hell"
lsr@Apple.COM (Larry Rosenstein) (10/17/88)
In article <5654@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes: > >Let's look at a case. Say that GetNamedResource checks the return address >to see if it's being called from a ROM Font Manager routine, and that routine >has a tail patch for some reason. When the "old" software for the Font The problem occurs when there is a tail-patch of GetNamedResource (for example, in an INIT). The system patches are installed at boot time, while the INIT patches are installed afterwards. So now the Font Manager calls GetNamedResource which calls the INIT code. The INIT code calls the original GetNamedResource via a JSR, which leaves the return address in the INIT code. This means that the system patch does not recognize the return address, and the "bug" in the Font Manager is not fixed. This assumes that the INIT patch code exits by doing an RTS and returning the result gotten by the JSR to the old GetNamedResource. Under this circumstance, the bug fix code would not be executed. If it exits by calling the old GetNamedResource again (with the original parameters), then everything should be fine. The internal JSR simply becomes another call to GetNamedResource. (I don't write system patches, however, so there may be something else I haven't thought of that makes this idea wrong.) Patching the ROM in a "safe" way requires some ingenuity. Often ones first idea of how to do it makes some incorrect assumption, or requires a tail patch. The trick is to look at the problem from a different point of view, in order to come up with a solution that works. Larry Rosenstein, Object Specialist Apple Computer, Inc. 20525 Mariani Ave, MS 46-B Cupertino, CA 95014 AppleLink:Rosenstein1 domain:lsr@Apple.COM UUCP:{sun,voder,nsc,decwrl}!apple!lsr
brecher@well.UUCP (Steve Brecher) (10/18/88)
In article <5654@hoptoad.uucp>, tim@hoptoad.uucp (Tim Maroney) writes: > Whether or not there is a tail patch would appear to have no effect on the > return-address Apple hacks. ... A tail patch by definition first calls the > old trap software. Example: Let us presume that (hypothetical) ROM routine RsrcMgrTrap is patched by Apple, and the patch has a "come from" check to see if it is being called by FontMgrTrap. The purpose of the RsrcMgrTrap patch is to fix a bug in FontMgrTrap. Hence Apple's patch for RsrcMgrTrap would look schematically like this: Apple_RsrcMgrTrap_Patch: if return_Address = some_ROM_address_In_FontMgrTrap then do_Something_To_Fix_The_FontMgrTrap_Bug; jump to Original_RsrcMgrTrap_Code Now I as third-party programmer provide an INIT that patches RsrcMgrTrap with a tail patch, i.e., My_RsrcMgrTrap_Patch: Jsr Previous_RsrcMgrTrap ; equivalent to Jsr Apple_RsrcMgrTrap_Patch Do_Some_Stuff FontMgrTrap calls RsrcMgrTrap via an A-line trap instruction which gets the trap address from the dispatch table. My_RsrcMgrTrap_Patch is executed. My patch calls Apple's patch, Apple_RsrcMgrTrap_Patch; that patch sees my return address, not FontMgrTrap's, on the stack, so the bug in FontMgrTrap is not fixed. Note that Apple's patches are installed first (before INITs execute). In the process of installing a patch, the installation code gets the old trap code address via GetTrapAddress, and then installs the new patch via SetTrapAddress. The trap dispatch table thus contains the address of the most recently installed patch. By adding a tail patch to what is in effect a linked list of patches, I invalidate any "come from" patches installed earlier in the list.
darin@Apple.COM (Darin Adler) (10/18/88)
In article <5654@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes: > Is there a technical note which refers to this "tail patching" issue? I must > admit that as a seasoned mac programmer I find the rationales given for the > illegality of tail patching quite incomprehensible. Whether or not there is > a tail patch would appear to have no effect on the return-address Apple hacks. > > Let's look at a case. Say that GetNamedResource checks the return address > to see if it's being called from a ROM Font Manager routine, and that routine > has a tail patch for some reason. When the "old" software for the Font > Manager calls the Resource Manager, the return address is exactly what the > Resource Manager "where-from" check expects. The tail patch has no relevance, > since the "where-from" check is meant only to apply to the way the Resource > Manager is called from that place in the ROM, and that place gets executed > normally. A tail patch by definition first calls the old trap software. Here's where the problem comes in. The tail patch "by definition" calls the old trap, but with *a different return address*. The return address is in the middle of the patch rather than in ROM. This is why it's permissible to do something first, then call the real trap. In that case the stack is the same as if the trap had been called directly, with the correct return address. -- Darin Adler AppleLink: Adler4 UUCP: {sun,voder,nsc,mtxinu,dual}!apple!darin CSNET: darin@Apple.com
fjo@ttrdf.UUCP (Frank Owen ) (10/18/88)
in article <5654@hoptoad.uucp>, tim@hoptoad.uucp (Tim Maroney) says: > > Let's look at a case. Say that GetNamedResource checks the return address > to see if it's being called from a ROM Font Manager routine, and that routine > has a tail patch for some reason. When the "old" software for the Font > Manager calls the Resource Manager, the return address is exactly what the > Resource Manager "where-from" check expects. Bad example. Change it so that you put a tail patch on the GetNamedResource trap. Now when it checks the return address to see if it's being called from ROM Font Manager (patched or not) it will discover that the return address is somewhere in your patch. NOT in the ROM Font Manager, even if the ROM Font Manager DID make the GetNamedResource call. Another case. Say that Multifinder's GetNextEvent needs to know who called it so that it can determine if an application's been getting alot of null-events in a row. Now you put a tail patch on GetNextEvent. Well, when Multifinder looks to see who had called it, it always sees your patch. It effectively thinks that ALL GetNextEvent calls are coming from the same application. -- Frank Owen (fjo@ttrdf) 312-982-2182 AT&T Bell Laboratories 5555 Touhy Ave., Skokie, IL 60077 PATH: ...!att!ttrdf!fjo
tim@hoptoad.uucp (Tim Maroney) (10/18/88)
Thanks to Larry Rosenstein for his speedy and clear answer. (And while I'm at it, kudos to Apple employees in general for their greatly improved net support of late! It used to be that we could count on getting an answer which was at best curt and often outright rude; now we're practically guaranteed of a quick, clear, polite answer!) It seems that what you're saying is that the only safe kind of patch is one that does its stuff, clears the stack back to the return address, and then does a JMP.L to the old trap. Ick. Most trap patching applications I've seen or speculated on just can't be done that way. Could we at least get a list of "where-from" traps to make things a little less awful? -- Tim Maroney, Consultant, Eclectic Software, sun!hoptoad!tim "The Diabolonian position is new to the London playgoer of today, but not to lovers of serious literature. From Prometheus to the Wagnerian Siegfried, some enemy of the gods, unterrified champion of those oppressed by them, has always towered among the heroes of the loftiest poetry." - Shaw, "On Diabolonian Ethics"
c60a-1cu@e260-1b.berkeley.edu (Drew Dean) (10/18/88)
Since the reason tail patches break are ROM patches, why doesn't Apple rewrite the ROMs (with patches from System file applied), and call it a free upgrade for EVERYONE...Now my SE will magically have 60-100Kb more RAM (I forget exactly how big the patches are, see a recent MacTutor article). Of course, if the ROMs are soldered in, this isn't feasible, but if they're socketed (like they were at one time), why doesn't Apple do something good for its users and programmers alike...Won't hit the bottom line that much.... Drew Dean c60a-1cu@web.berkeley.edu ...!ucbvax!web!c60a-1cu
rpd@Apple.COM (Rick Daley) (10/19/88)
In article <5677@hoptoad.uucp>, tim@hoptoad.uucp (Tim Maroney) writes: > It seems that what you're saying is that the only safe kind of patch is > one that does its stuff, clears the stack back to the return address, and > then does a JMP.L to the old trap. Ick. Most trap patching applications > I've seen or speculated on just can't be done that way. Could we at least > get a list of "where-from" traps to make things a little less awful? Sorry, but it's not possible to predict which traps may get come-from patched in future system releases. These patches are there to fix bugs, and there wouldn't be any bugs if we knew where they all were. There are only three ways I know of for Apple to fix bugs in ROMs that have already shipped: 1) We can use come-from patches that work, but make us forbid tail-patches. 2) We can use patches that replace the defective routine, but waste lots of memory. New system releases already use up alot of the memory on a mac plus. 3) We can send out new ROMs. Assuming that the bug fixes and new features would all fit in the mac plus ROMs, this still means someone has to install them. If you take your own mac plus apart, and touch the wrong thing, you will be very dead and unlikely to buy Apple products in the future. Basically, the choice is somewhat like voting for the president. None of the choices are any good, but some seem to be even worse than others. Come-from patches seem to be the least of the evils. Rick Daley rpd@apple.COM These opinions were actually conveyed to me by each and every Apple employee and stock holder.
dwb@Apple.COM (David W. Berry) (10/19/88)
In article <5677@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes: >I've seen or speculated on just can't be done that way. Could we at least >get a list of "where-from" traps to make things a little less awful? Unfortunately, the list is quite dynamic and changes with every release of the system. To publish a list would restrict Apple in making further changes. It's an unfortunate fact of life that documenting something tends to make it permanent. Witness the memory manager bucky bits... >-- >Tim Maroney, Consultant, Eclectic Software, sun!hoptoad!tim Opinions: MINE, ALL MINE! (greedy evil chuckle) David W. Berry apple!dwb@sun.com dwb@apple.com 973-5168@408.MaBell
jmpdude@Apple.COM (Mike Puckett) (10/20/88)
I'm sure by now that many people must have responded to your message, but in case they haven't, I thought I would direct you to read pp. 424-425 in the first edition of Scott Knaster's "How to Write Macintosh Software." On those pages he explains how a tail-patch *can* cause problems. Mike Puckett jmpdude@apple.comm
jmunkki@kampi.hut.fi (Juri Munkki) (10/21/88)
In article <18969@apple.Apple.COM> rpd@Apple.COM (Rick Daley) writes: >In article <5677@hoptoad.uucp>, tim@hoptoad.uucp (Tim Maroney) writes: >Basically, the choice is somewhat like voting for the president. None of >the choices are any good, but some seem to be even worse than others. >Come-from patches seem to be the least of the evils. Maybe you need a new candidate? How about writing the future ROMs so that those large traps actually call a few subroutines too? All you would need to do to patch the routine is to change the "main program" and rewrite the buggy subroutine. I know you can't do this with current ROMs, but I still would prefer real rewritten traps than those awful tail patches. No wonder the Mac has gotten so slow, if you do stuff like that. Small traps should not do any extra stuff, because they should execute as fast as possible. Traps like GetNextEvent do not have to be fast, because you can't really guarantee that they'll execute in a known time. Traps like that should be split into a large number of subroutines. How about new ROM versions for all machines: MacPlus: Remove some ROM resources and put some new stuff in. MacSE: Remove the design team pictures and fix the bugs. Add as much from the MultiFinder file as possible. Mac II: Can you increase the ROM size to 512K? Fix bugs, add QuickerGraf, Virtual Memory support. Anti-alias Chicago-12 in the cached 8-bit version. (I know you can't actually do this, but you should think about it.) _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._ | Juri Munkki jmunkki@hut.fi jmunkki@fingate.bitnet I Want Ne | | Helsinki University of Technology Computing Centre My Own XT | ~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~ P.S. I'm in San Fransisco on Thursday November 17th and I have a day off. Would anybody be interested to show me Silicon Valley? Since I've practically never been in the US, I don't think I'll want to explore too much on my own. Anyone from MacTutor or Apple? You write to me at: Ehrensvardintie 20B8 00150 Helsinki, Finland Or call: +358 0 627 869 (your daytime hours) I'll also be at COMDEX, so if there are any interesting events that I should attend, please do not hesitate to tell me about them. I'm a nice person and a good Macintosh programmer. (At least that's what I'm told) _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._ | Juri Munkki jmunkki@hut.fi jmunkki@fingate.bitnet I Want Ne | | Helsinki University of Technology Computing Centre My Own XT | ~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~
fjo@ttrdf.UUCP (Frank Owen ) (10/21/88)
in article <18936@apple.Apple.COM>, darin@Apple.COM (Darin Adler) says: > ... This is why it's permissible to do > something first, then call the real trap. In that case the stack is the same > as if the trap had been called directly, with the correct return address. Not if you CALL the trap it isn't! You must JUMP to the trap address upon exit to keep the stack intact. -- Frank Owen (fjo@ttrdf) 312-982-2182 AT&T Bell Laboratories 5555 Touhy Ave., Skokie, IL 60077 PATH: ...!att!ttrdf!fjo