[comp.sys.amiga] BCPL vs. 2.0

bartonr@eecs.cs.pdx.edu (Robert L Barton) (05/28/90)

 bartonr@eecs.cs.pdx.edu (Robert L Barton) writes:
RLB> You don't need 2.0 to do this.  SetPatch 1.34, for example,
RLB> changes the Execute() vector to make use of a resident Run command.

 deven@rpi.edu (Deven T. Corzine) replies:
DTC> Which does not mean that the SetFunction() call works on it.  It means
DTC> SetPatch knows the bizarre jump format and patches that.

  No, SetFunction() works just fine on Execute().  SetFunction simply replaces
the first two bytes with a JMP instruction and the last four with an address.
Of course the return value won't be meaningful, so if you patch an entry with

  oldFunc = SetFunction(DOSBase, offset, newFunc)

and then try to undo that by following it later with

  newFunc = SetFunction(DOSBase, offset, oldFunc)

you would have a problem, since oldFunc would not be an absolute address, as it
would be with a non-DOS function.  But for one-time patching, such as in the
startup-sequence, it does the trick.  Also SetFunction does not change the entry
in the Global Vector, so any internal calls to Execute() would still go to the
original place, but I don't think there are any of these in dos.library.

---------------
Robert L Barton
Memorial Coliseum
Portland OR

deven@rpi.edu (Deven T. Corzine) (05/31/90)

bartonr@eecs.cs.pdx.edu (Robert L Barton) writes:
Robert> You don't need 2.0 to do this.  SetPatch 1.34, for example,
Robert> changes the Execute() vector to make use of a resident Run
Robert> command.

deven@rpi.edu (Deven T. Corzine) replies:
Deven> Which does not mean that the SetFunction() call works on it.
Deven> It means SetPatch knows the bizarre jump format and patches
Deven> that.

On 28 May 90 11:11:25 GMT, bartonr@eecs.cs.pdx.edu (Robert L Barton) said:
Robert>   No, SetFunction() works just fine on Execute().  SetFunction
Robert> simply replaces the first two bytes with a JMP instruction and
Robert> the last four with an address.  Of course the return value
Robert> won't be meaningful, so if you patch an entry with

Robert>   oldFunc = SetFunction(DOSBase, offset, newFunc)

Robert> and then try to undo that by following it later with

Robert>   newFunc = SetFunction(DOSBase, offset, oldFunc)

Robert> you would have a problem, since oldFunc would not be an
Robert> absolute address, as it would be with a non-DOS function.  But
Robert> for one-time patching, such as in the startup-sequence, it
Robert> does the trick.  Also SetFunction does not change the entry in
Robert> the Global Vector, so any internal calls to Execute() would
Robert> still go to the original place, but I don't think there are
Robert> any of these in dos.library.

Okay, you're right in that SetFunction() does indeed force the first
two bytes to be a JMP instruction.  But the return value is still
meaningless.  Not only can you not use it to restore the original
vector, you can't use it to call the original function.  Probably the
most common use of SetFunction() is to slightly change the way a
function works, not completely replace it.  That usually involves
calling the original function you're replacing, even if you never
intend to restore the original vector.

This will NOT work on dos.library since the "address" returned is
actually the branch instruction to the BCPL global vector.  Sure, the
Execute() patch could know the value to load into D0 and then jump to
the global vector, but that's still special-casing the patch because
the vector format is known to be bizarre.

If the "patch" is a complete replacement function, then using
SetFunction() will work, but that isn't the normal case...

Deven
-- 
Deven T. Corzine        Internet:  deven@rpi.edu, shadow@pawl.rpi.edu
Snail:  2214 12th St. Apt. 2, Troy, NY 12180   Phone:  (518) 271-0750
Bitnet:  deven@rpitsmts, userfxb6@rpitsmts     UUCP:  uunet!rpi!deven
Simple things should be simple and complex things should be possible.