davids@ucscf.UCSC.EDU (Dave Schreiber) (03/18/91)
I've been trying to patch AllocMem() as an experiment, and haven't been
able to get it to work. I manage to patch it correctly with SetFunction(),
but when I try to print a carriage return using printf, the machine crashes
with a 8000 0006 error (CHK instruction). Here's the code:
#include <exec/types.h>
#include <exec/exec.h>
#include <clib/exec_protos.h>
struct ExecBase *ExecBase;
APTR __regargs (*oldAllocMem)();
APTR __regargs newAllocMem(ULONG size,ULONG types);
#define NEG_AM_OFFSET 0xff3a
main()
{
APTR temp;
ExecBase=(struct ExecBase *)OpenLibrary("exec.library",0L);
Forbid(); /*Stop multitasking*/
/*Patch AllocMem()*/
oldAllocMem=SetFunction(ExecBase,NEG_AM_OFFSET,newAllocMem);
temp=(APTR)AllocMem(1000,0L); /*Goes to my routine & allocates*/
/*the memory without a problem*/
printf("%x ",temp); /*Crashes here if there's a \n in that line*/
/*Otherwise, it just continues on fine*/
/*Undo patch*/
printf("%x\n",SetFunction(ExecBase,NEG_AM_OFFSET,oldAllocMem));
Permit();
if(temp!=0L)
FreeMem(temp,1000); /*Again, doesn't crash*/
CloseLibrary(ExecBase); /*Exits without a hitch*/
}
APTR __regargs newAllocMem(ULONG size,ULONG types)
{
return(oldAllocMem(size,types));
}
If I change newAllocMem() so that it just returns NULL, the call to
AllocMem() in main() returns NULL; i.e. I know that calls to AllocMem() are
being routed to my module. newAllocMem() as it is above also works without
a hitch. But when I printf() an '\n' (or when I Permit() without undoing the
patch), it crashes. Any suggestions? BTW, I'm using a 3000 under 2.02
(under 1.3 it crashes as well, but it gives a 8000 0003 error).
Thanks in advance.
--
Dave Schreiber E-mail: davids@ucscf.ucsc.edu
"It was fun learning about logic, but I don't see where or when I will ever
use it again." Disclaimer:bairds@eecs.cs.pdx.edu (Shawn L. Baird) (03/18/91)
davids@ucscf.UCSC.EDU (Dave Schreiber) writes: >I've been trying to patch AllocMem() as an experiment, and haven't been >able to get it to work. I manage to patch it correctly with SetFunction(), >but when I try to print a carriage return using printf, the machine crashes >with a 8000 0006 error (CHK instruction). Here's the code: [ stuff deleted ] > Forbid(); /*Stop multitasking*/ > /*Patch AllocMem()*/ > oldAllocMem=SetFunction(ExecBase,NEG_AM_OFFSET,newAllocMem); > temp=(APTR)AllocMem(1000,0L); /*Goes to my routine & allocates*/ > /*the memory without a problem*/ > printf("%x ",temp); /*Crashes here if there's a \n in that line*/ > /*Otherwise, it just continues on fine*/ > /*Undo patch*/ > printf("%x\n",SetFunction(ExecBase,NEG_AM_OFFSET,oldAllocMem)); > Permit(); [ more stuff deleted ] Here's my $0.02. Since you've stopped multi-tasking the console device, which is another task, cannot run. Thus the crash. Since stdout doesn't flush until it gets a newline... Try this instead: Forbid(); /*Stop multitasking*/ /*Patch AllocMem()*/ oldAllocMem=SetFunction(ExecBase,NEG_AM_OFFSET,newAllocMem); Permit(); temp=(APTR)AllocMem(1000,0L); /*Goes to my routine & allocates*/ /*the memory without a problem*/ printf("%x\n",temp); /*Crashes here if there's a \n in that line*/ /*Otherwise, it just continues on fine*/ Forbid(); /*Undo patch*/ tmpfunc=SetFunction(ExecBase,NEG_AM_OFFSET,oldAllocMem)); Permit(); printf("%x\n",tmpfunc); /* print out the address of the old routine */ /* if tmpfunc != newAllocMem then somebody else probably also did a SetFunction() while we were running I guess */ | Shawn L. Baird | Or via US Snail: | | bairds@eecs.ee.pdx.edu | 17650 SE Cason Rd. | | ...uunet!tektronix!psueea!eecs!bairds | Gladstone, OR 97027 |
bairds@eecs.cs.pdx.edu (Shawn L. Baird) (03/18/91)
Kludge fix mode: It crashes if you Permit() after the SetFunction()? Hmmm... Not sure why that would be the case. Try something fun like doing a SetFunction() and then exiting, freeing up the memory that newAllocMem() was at. That ought to create a few special effects. ;) | Shawn L. Baird | Or via US Snail: | | bairds@eecs.ee.pdx.edu | 17650 SE Cason Rd. | | ...uunet!tektronix!psueea!eecs!bairds | Gladstone, OR 97027 |
rosenber@ra.abo.fi (Robin Rosenberg INF) (03/19/91)
In article <13531@darkstar.ucsc.edu> davids@ucscf.UCSC.EDU (Dave Schreiber) writes: >I've been trying to patch AllocMem() as an experiment, and haven't been >able to get it to work. I manage to patch it correctly with SetFunction(), >but when I try to print a carriage return using printf, the machine crashes >with a 8000 0006 error (CHK instruction). Here's the code: 1. Stack checking off 2. Make sure your global as accessible, either compile for absoulute addressing or declare your patch function using __saveds to get A4 right. 3. AllocMem has THREE parameters: size(d0),types(d1) and execbase(a6). Declared them properly when writing the patch. Something like. Declare the pointer to the old function the same way. void * (* __asm __saveds oldallocmem)( register __d0 ULONG size, register __d1 ULONG types, register __a6 struct ExecBase *SysBase); void *__asm __saveds myallocmem( register __d0 ULONG size, register __d1 ULONG types, register __a6 struct ExecBase *SysBase) { return (*oldallocmem)(size,types,SysBase); } ----- Robin
forgeas@swinjm.UUCP (Jean-Michel Forgeas) (03/19/91)
In article <13531@darkstar.ucsc.edu>, Dave Schreiber writes: > APTR __regargs newAllocMem(ULONG size,ULONG types); > [...] > oldAllocMem=SetFunction(ExecBase,NEG_AM_OFFSET,newAllocMem); > [...] > APTR __regargs newAllocMem(ULONG size,ULONG types) > { > return(oldAllocMem(size,types)); > } Just an idea: when it sees __regargs, the compiler assigns registers to parameters, and in your case should use D0/D1. But did you verify it with a small disassembly of newAllocMem() ? > temp=(APTR)AllocMem(1000,0L); /*Goes to my routine & allocates*/ > /*the memory without a problem*/ How are you sure that 'temp' is something valid ? > If I change newAllocMem() so that it just returns NULL, the call to > AllocMem() in main() returns NULL; i.e. I know that calls to AllocMem() are > being routed to my module. newAllocMem() as it is above also works without > a hitch. But when I printf() an '\n' (or when I Permit() without undoing the > patch), it crashes. Any suggestions? BTW, I'm using a 3000 under 2.02 > (under 1.3 it crashes as well, but it gives a 8000 0003 error). Seems that it crashes every time newAllocMem() calls oldAllocMem(). 1 - Either you call oldAllocMem with bad values into registers, don't forget that the a6 register must stay with ExecBase value. 2 - Either you don't call oldAllocMem() at all but jump into the 5th dimension. Best regards, Jean-Michel -- \___/ Jean-Michel Forgeas \-/ cbmvax!cbmehq!cbmfra!swinjm!forgeas | The Software Winery -^- And, where is the universe ?