Path: utzoo!attcan!uunet!crdgw1!rpi!netserv2!deven From: deven@rpi.edu (Deven T. Corzine) Newsgroups: comp.sys.amiga.tech Subject: Re: SetFunction()ing Dos.library Message-ID: Date: 8 Feb 90 08:46:50 GMT References: <783@kunivv1.sci.kun.nl> <1472@jimi.cs.unlv.edu> <1990Feb5.222754.2239@actrix.co.nz> Organization: Rensselaer Polytechnic Institute, Troy, NY Lines: 112 In-Reply-To: jbickers@actrix.co.nz's message of 5 Feb 90 22:27:54 GMT In article <1472@jimi.cs.unlv.edu> maniac@hubert.cs.unlv.edu (Eric J. Schwertfeger) writes: maniac> Is it possible to setfunction dos.library? I have been told maniac> that the normal setfunction call willnot, but is it possible maniac> to do a work-around? In response to the original article, the problem was with programs opening * as stderr in the startup-sequence. Let me just suggest to begin with that you simply use runback to start such programs instead; then they will try to open null:* instead of con:*. If it's really important for you to get stdout and nullify (no pun intended) stderr, then I guess you can go ahead and deal with SetFunction and dos.library... (Read on...) On 5 Feb 90 22:27:54 GMT, jbickers@actrix.co.nz (John Bickers) said: jbickers> Yes, the normal SetFunction() expects a library entry (6 jbickers> bytes in the library table) to be: jbickers> jmp 32-bit address jbickers> So when you SetFunction a library vector it returns the jbickers> top four bytes of the 6 as the function point it's supposed jbickers> to return, and plugs in the 4-byte pointer you provide. It jbickers> also seems to re-write the jmp instruction code. jbickers> This works fine for most libraries, but the DOS library jbickers> doesn't have that type of entry. Instead of a jmp to a jbickers> 32-bit address it has: jbickers> moveq nn,d0 ; nn is some value DOS understands jbickers> bra.w DOS routine jbickers> The DOS routine is usually the same for all the jbickers> different "vectors", and it must somehow work out from the jbickers> value in d0 which DOS function you are calling (go BCPL! :). I always found it quite annoying that AmigaDOS breaks this simple rule for Exec libraries... argh. jbickers> So to emulate SetFunction(), you have to write your own jbickers> code that will replace the moveq,bra sequence with a 32-bit jbickers> jump to your intercept code, and your intercept code must, jbickers> at the end, move nn into d0 and then jmp to the destination jbickers> of the original branch instruction. jbickers> You can determine the value of nn and the destination of jbickers> the original branch instruction by taking a debugger to the jbickers> DOSBase vector. For example, a do-nothing program in Lattice jbickers> C was enough for CodeProbe to pick up DOSBase from. It's an awful kludge, but I suppose you could write your own SetFunction() which understands both the proper form of the jump vector, and the form which dos.library uses. I wouldn't suggest hardcoding the address of the DOS routine as discovered from a debugger; it might not be consistent across machines, though it will probably work for a single machine. (I do hope dos.library isn't quite so stupid as to have the vector table in ROM!) Patch SetFunction (with SetFunction!) to check for a vector entry consisting of a moveq nn,d0 followed by a bra.w , and if it is of that form, AllocMem space for a stub routine consisting of the moveq nn,d0 followed by a jmp , and change the original vector to point to the stub. The SetFunction patch would have to be able to recognize the moveq and bra.w opcodes, and also be able to calculate the absolute address of the from the address of the original vector and the offset given in the instruction. After creating the stub routine and replacing the original vector, this patch should then call the original SetFunction. If the vector is already a jmp instruction, the patch should only call the original SetFunction. If the vector is neither jmp or moveq/bra, it should probably barf. (assuming there's a defined way for SetFunction to fail and give an error return (-1?) otherwise, I guess it just has to call the original SetFunction and let things go to hell.) Optionally, also patch UnSetFunction to recognize the stub routine (when it's the target of the to-be-restored vector address) and have it reconstruct the original moveq/bra sequence in the vector table, or perhaps have the SetFunction patch save the sequence in the allocated block for simplicity. Patching UnSetFunction also would be good for symmetry, but probably insignificant, as the allocated block would be 16 bytes of memory per SetFunction'd dos.library call, and such dos patches would probably be left in, and not backed out. If they are backed out, then there is a memory loss, but an insignificant one... it would only create only one stub routine for any given call which was SetFunction'd, and at worst, you'd lose 16*n bytes of memory, where n is the number of dos.library calls there are. (what, maybe 50 functions, max? (probably less) 50 functions would be 800 bytes lost to stub routines. Not critical.) Still, it would be bad form to patch SetFunction but not UnSetFunction, so both should be done. I told you it was a kludge. [I wonder if I should go ahead and write it, though... it's a kludge, but could be a useful one.] Deven -- Deven T. Corzine Internet: deven@rpi.edu, shadow@pawl.rpi.edu Snail: 2151 12th St. Apt. 4, Troy, NY 12180 Phone: (518) 274-0327 Bitnet: deven@rpitsmts, userfxb6@rpitsmts UUCP: uunet!rpi!deven Simple things should be simple and complex things should be possible.