[comp.sys.mac.programmer] Locking executable resources

jon@druco.ATT.COM (GotowJK) (05/02/89)

The segment loader locks CODE resources into memory before it jumps to 
them.  Why are other executable resources (particularly INIT & cdev) 
not automatically locked?  Sure, you can set the "locked" bit on the 
resource so it loads as a locked handle, but should that really be 
necessary?  Why not make it automatic?  

Here's why this concern arose:

I wrote a quick patch to _InitGraf that simply beeps and then calls the 
real ROM code.  Simple, right?  Except that it crashes on startup when 
other inits load afterwards.  This is because these inits show their 
icons, calling InitGraf in the process, and do not have the "locked" 
bit set on the INIT resources.  When my patch gets called, the INIT 
code gets moved (or purged) because I have a long beep sound installed, 
and the return address from the trap call is no longer valid.  Bingo - 
it executes an empty memory location after it hits the rts.  

The dilemma is that this occurs because _somebody else's_ INIT resource 
is not locked, and I can't control that.  This seems to be major 
problem - or am I missing something?  

I really would like to do much more that just beep in my patch code, 
obviously.  This simple example is good enough to illustrate the point, 
however.  Any comments will be much appreciated.


------------------------------------------------------------------------
Jon Gotow - Physical Designer                             AT&T Bell Labs
General Business Systems Group                         200 Laurel Avenue
ARPA:  jon@druco.att.com                            Middletown, NJ 07748
UUCP:  att!druco!jon

Disclaimer:  As always, the opinions stated here have nothing whatsoever
to do with my employer.

cep@apple.com (Christopher Pettus) (05/03/89)

In article <4170@druco.ATT.COM> jon@druco.ATT.COM (GotowJK) writes:
> The segment loader locks CODE resources into memory before it jumps to 
> them.  Why are other executable resources (particularly INIT & cdev) 
> not automatically locked?

I know this sounds like begging the question, but it's because the segment 
manager doesn't load resources of type 'CODE'.  INITs, cdevs, etc. are 
loaded with plain, old, everyday resource manager calls that do not know 
they are loading code.  Its the responsibility of the code doing the 
loading to lock the code being loaded, a responsibility (judging from the 
rest of the post) that some code takes lightly.

> The dilemma is that this occurs because _somebody else's_ INIT resource 
> is not locked, and I can't control that.  This seems to be major 
> problem - or am I missing something?

I'm surprised that INITs are locking themselves down in memory; taking the 
chance that any trap calls they make won't compact memory seems pretty 
dicey.  The only thing you can do to help is make sure that you're patch 
won't compact memory if the trap being patched doesn't.  This will help 
guard against people playing "close to the edge" with unlocked handles.

-- Christopher Pettus                   | "Brahma said: Well, after hearing
   Network Systems Development          | ten thousand explanations, a fool
   Apple Computer, Inc.                 | is no wiser.  But an intelligent
   cep@apple.com   {nsc, sun}!apple!cep | man needs only two thousand five
   AppleLink: PETTUS.C                  | hundred."  -- The Mahabharata

lsr@Apple.COM (Larry Rosenstein) (05/03/89)

In article <4170@druco.ATT.COM> jon@druco.ATT.COM (GotowJK) writes:
> The dilemma is that this occurs because _somebody else's_ INIT resource 
> is not locked, and I can't control that.  This seems to be major 
> problem - or am I missing something?  

An important rule in patching traps is that your patch code has to be at 
least as careful as the trap being patched with respect to allocating 
memory and saving registers.  If the trap you are patching does not 
allocate memory, then your patch can't either.  Your patch has to save at 
least the registers that the original patch saves.  (This is especially 
important when patching the Resource Manager, since it saves more than the 
usual set of registers.)

In your case, InitGraf doesn't allocate memory, but SysBeep does.  So 
technically, you are "in the wrong."  (On the other hand, those INIT 
should be locking themselves down.)

Larry Rosenstein, Apple Computer, Inc.
Object Specialist

Internet: lsr@Apple.com   UUCP: {nsc, sun}!apple!lsr
AppleLink: Rosenstein1

rpd@Apple.COM (Rick Daley) (05/03/89)

In article <4170@druco.ATT.COM> jon@druco.ATT.COM (GotowJK) writes:
> > The dilemma is that this occurs because _somebody else's_ INIT resource 
> > is not locked, and I can't control that.  This seems to be major 
> > problem - or am I missing something?  

lsr@Apple.com (Larry Rosenstein) writes:
> An important rule in patching traps is that your patch code has to be at 
> least as careful as the trap being patched with respect to allocating 
> memory and saving registers.
> ...
> In your case, InitGraf doesn't allocate memory, but SysBeep does.  So 
> technically, you are "in the wrong."  (On the other hand, those INIT 
> should be locking themselves down.)

Actually, InitGraf is now on the list of routines that may compact
memory.  This is documented in Inside Mac V, as the change was part
of Color QuickDraw.  It's possible that the INITs that are crashing
are old, and didn't expect that InitGraf would cause compaction.
But, it's more likely that the authors just didn't realize that INITs
aren't locked when they get run.  The system is pretty inconsistent about
locking executable resources when they are getting run.  So, folks should
keep this in mind when writing executable resources.  As for the original
problem, jon@druco.ATT.COM is just out of luck.  He's not doing anything
wrong, but he can't patch InitGraf with something that causes memory
allocation without risking breaking these INITs.
					Rick Daley
					rpd@apple.com

oster@dewey.soe.berkeley.edu (David Phillip Oster) (05/03/89)

In article <4170@druco.ATT.COM> jon@druco.ATT.COM (GotowJK) writes:
_>This is because these inits show their 
_>icons, calling InitGraf in the process, and do not have the "locked" 
_>bit set on the INIT resources.  When my patch gets called, the INIT 
_>code gets moved (or purged) because I have a long beep sound installed, 
_>and the return address from the trap call is no longer valid.  Bingo - 
_>it executes an empty memory location after it hits the rts.  
_>The dilemma is that this occurs because _somebody else's_ INIT resource 
_>is not locked, and I can't control that.  This seems to be major 
_>problem - or am I missing something?  

It is simply incorrect to call system calls without locking your init. The
guys who try it are wrong. Write to the authors and complain.

YOu could always turn off the smashed stack checker, allocate memory above
BufPtr, configure it as a heap zone, make it the current zone, and run out
of it. That way, unlocked resources in the application heap wouldn't get
smashed.

doner@hub.ucsb.edu (John Doner) (05/04/89)

In article <4170@druco.ATT.COM> jon@druco.ATT.COM (GotowJK) writes:
>The segment loader locks CODE resources into memory before it jumps to 
>them.  Why are other executable resources (particularly INIT & cdev) 
>not automatically locked?  Sure, you can set the "locked" bit on the 
>resource so it loads as a locked handle, but should that really be 
>necessary?  Why not make it automatic?  
>
I disassembled INIT 31, and sure enough, it JSR's to INIT resources
immediately after reading them in and without locking them.  Looks
like a bug to me.  I would think that *any* executed block should
be locked before being jumped to.

John Doner
doner@hub.ucsb.edu

stearns@Apple.COM (Bryan Stearns) (05/04/89)

From article <1591@hub.ucsb.edu>, by doner@hub.ucsb.edu (John Doner):
> I disassembled INIT 31, and sure enough, it JSR's to INIT resources
> immediately after reading them in and without locking them.  Looks
> like a bug to me.  I would think that *any* executed block should
> be locked before being jumped to.

Sorry, my fault. Back in the good old days, we thought it was neat to
save a little code here & there: I figgered we'd just require that the 
INIT resource have its resLocked bit set, and good old Resource Manager 
would lock it for us. 

I'm told by the folks who now deal with such things that they'll add the
HLock in the next version.

 ...........................................................................
Bryan Stearns                                            Apple Computer, Inc.
Macintosh Finder Group                     10500 North DeAnza Blvd, M/S 27-AJ
stearns@apple.com                                         Cupertino, CA 95014
{nsc,dual,sun,ucbvax!mtxinu}!apple!stearns "Laugh while you can, monkey boy!"

jkjl@munnari.oz (John Lim) (05/08/89)

In article <1591@hub.ucsb.edu> doner@hub.UUCP (John Doner) writes:
>like a bug to me.  I would think that *any* executed block should
                                       ^^^^^^
                                       Not strictly true.
>be locked before being jumped to.
>
>John Doner
>doner@hub.ucsb.edu

You do not have to lock any executable resource if you are
not calling code that will move handles in the *same* system heap.

I.e.
	INIT that is unlocked is launched into appl heap.
	Allocates block in system heap and BlockMoves patches
	into block.
	SetTrapAddress to block in system heap.
	RTS to INIT 31.

Note that the above code should work provided you do not call
any Traps that move mem (read IM 3,4,5 appendices !). All inits
should never install patches that move mem on traps that arent 
supposed to move mem.

I have seen several articles in MacTutor that are fairly
laughable concerning VBL tasks. The idiots use GetCursor()
and GetIcon() in the VBL tasks which move memory during interrupts 
(a no-no).

	John Lim

jmunkki@kampi.hut.fi (Juri Munkki) (05/09/89)

In article <1476@murtoa.cs.mu.oz.au> jkjl@munmurra.UUCP (John Lim) writes:
>You do not have to lock any executable resource if you are
>not calling code that will move handles in the *same* system heap.
						^^^^^^^
						Not strictly true. :-)

How do you know that allocating a block from the system heap will not
cause changes in the application heap? You think it doesn't happen,
but how can you be sure? I'm pretty sure you are correct in assuming
this, but since Apple doesn't say anything about the affected zones,
it might change in the future! Never assume anything.

>I have seen several articles in MacTutor that are fairly
>laughable concerning VBL tasks. The idiots use GetCursor()
>and GetIcon() in the VBL tasks which move memory during interrupts 

It was relatively easy to predict what would happen to MacTutor
after a few years. It was a very good magazine for the first two
or three years, but after that the technical quality of most of
the articles has declined. However: I don't think that calling
the authours "idiots" will help the magazine. Simply point out
the bugs and leave out the insults. Insulting people is a very
good way of making enemies.

The reason for what has happened to MacTutor does not lie in the
people who are making it. I think it was caused by the way the
Macintosh programmer community has evolved. Good books are finally
available and electronical communication satisfies the needs of
the most advanced programmers.

As to the question of locking or not locking: It doesn't take any
extra code to lock down your INITs. Why not do it?

_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
|     Juri Munkki jmunkki@hut.fi  jmunkki@fingate.bitnet        I Want   Ne   |
|     Helsinki University of Technology Computing Centre        My Own   XT   |
^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^

jkjl@munnari.oz (John Lim) (05/10/89)

In article <21859@santra.UUCP> jmunkki@kampi.hut.fi (Juri Munkki) writes:
-In article <1476@murtoa.cs.mu.oz.au> jkjl@munmurra.UUCP (John Lim) writes:
->You do not have to lock any executable resource if you are
->not calling code that will move handles in the *same* system heap.
-						^^^^^^^
-						Not strictly true. :-)
-
-How do you know that allocating a block from the system heap will not
-cause changes in the application heap? You think it doesn't happen,
-but how can you be sure? I'm pretty sure you are correct in assuming
-this, but since Apple doesn't say anything about the affected zones,
-it might change in the future! Never assume anything.
-

I agree it might change in the future, but the point i'm making
is that you dont have to lock code resources down today. Of course
defensive programming means you should lock down such resources even
if you're confident nothing will change in the future.

->I have seen several articles in MacTutor that are fairly
->laughable concerning VBL tasks. The idiots use GetCursor()
->and GetIcon() in the VBL tasks which move memory during interrupts 
-
-It was relatively easy to predict what would happen to MacTutor
-after a few years. It was a very good magazine for the first two
-or three years, but after that the technical quality of most of
-the articles has declined. However: I don't think that calling
-the authours "idiots" will help the magazine. Simply point out
-the bugs and leave out the insults. Insulting people is a very
-good way of making enemies.
-

Point taken. Apologies to everyone insulted by my previous remarks.

-
-As to the question of locking or not locking: It doesn't take any
-extra code to lock down your INITs. Why not do it?
-

I do lock my INITs. But if you dont call any memory moving traps,
i dont think you should have to lock code resourcse.

	john