oster@dewey.soe.berkeley.edu (David Phillip Oster) (01/23/89)
In article <6347@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes: _>However, this doesn't address the fact that you may need a different A5 _>from the one in CurrentA5, which was David's point. This may happen in _>interrupt driven code that is not switched by MultiFinder. VBL tasks _>only run when their application has the processor, but not so things _>like socket listeners or custom interrupt handlers. I still don't know _>any way around this except for stashing a copy of your A5 in _>code-relative space, which is explicitly forbidden (with good reason) _>by Tech Note #2. Be careful here. What is forbidden is modifying your code resources. There is no problem creating a block of exectuable code at run time, that was created with a nice constant built -in: MOVE.L #Correct A5,-(sp) JSR socketListener. RTS you create this by saying: typedef struct JumpBufA5{ short moveInstruction; long a5Val; short jsrInstruction; long destination short rtsInstrutcion; }JumpBufA5, *JumpBufA5Ptr; listenerDispatcher = (JumpBufA5Ptr) NewPtr(sizeof(JmpBufA5)); listenerDispatcher.moveInstruction = MOVEOPCODE; listenerDispatcher.a5Val = (long) CurrentA5; listenerDispatcher.jmpInstruction = JSROPCODE; listenerDispatcher.destination = (long) socketListerner; listenerDispatcher.rtsInsuction = RTSOPCODE; and declare socket listener as: /* */ pascal void socketListener(correctA5)Ptr correctA5;{ Ptr oldA5; oldA5 = SetA5(coeectA5); ... SetA5(oldA5); } You might think the above might lead you into trouble on a 68020 because of the instruction cache. But, the instruction cache should never be holding any address that NewPtr() is going to return, so the 68020 should never get confused. After all, the system reads code in from disk, and if that isn't modifying memory that is about to be executed, I don't know what is! You might think you could optimise the dispatcher's JSR, RTS to a JMP instruction. Don't try it: you'll screw up the compiler's popping of the arguments in socketListener. The advantage of this trick is it lets you program the MMU to generate an interrupt if anyone tries to write on one of your code segments. --- David Phillip Oster --"When we replace the mouse with a pen, Arpa: oster@dewey.soe.berkeley.edu --3 button mouse fans will need saxophone Uucp: {uwvax,decvax}!ucbvax!oster%dewey.soe.berkeley.edu --lessons." - Gasee
tim@hoptoad.uucp (Tim Maroney) (01/24/89)
In article <27674@ucbvax.BERKELEY.EDU> oster@dewey.soe.berkeley.edu.UUCP (David Phillip Oster) writes: >Be careful here. What is forbidden is modifying your code resources. There >is no problem creating a block of exectuable code at run time, that was >created with a nice constant built -in: That's not neccessarily true. A memory manager typically has three kinds of access checks, read, write, and execute. In the hypothetical protected mode OS, it's quite possible that the heap will be turned off for execute mode access. This protects against the old "jumping into data space" bug, just as protecting against writing on executable code prevents against the obverse "writing into code space" problem. Still, you're probably right, since Apple hasn't explicitly warned against putting code into the heap. >You might think the above might lead you into trouble on a 68020 because >of the instruction cache. But, the instruction cache should never be >holding any address that NewPtr() is going to return, so the 68020 should >never get confused. After all, the system reads code in from disk, and if >that isn't modifying memory that is about to be executed, I don't know >what is! True. I think the reason for this is that instructions aren't cached until after they have been executed once. Since this code never changes except before it's executed the first time, there shouldn't be a problem. I believe this is the same reason the OS reads code from disk without difficulty. >You might think you could optimise the dispatcher's JSR, RTS to a JMP >instruction. Don't try it: you'll screw up the compiler's popping of >the arguments in socketListener. Well, except that you can't write a socket listener in anything but assembler because everything is stored in registers. I experimented with a save/restore registers approach and writing a listener in C, but pushing and popping the registers was too slow given the time constraints of a listener. If Apple had put all the information into a data structure intead of into registers, there wouldn't be a problem. But since ReadPacket requires the registers to be set up correctly.... -- Tim Maroney, Consultant, Eclectic Software, sun!hoptoad!tim "The time is gone, the song is over. Thought I'd something more to say." - Roger Waters, Time