home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Contains all necessary functions to patch libraries functions safely.
- ** Theses functions are largely inspired from ISpy.c which can be found in
- ** the Amiga Mail archive (available from Fred Fish collection).
- **
- ** Author: Gael Marziou
- ** Created: 14 July 1994 (Bastille Day ;-)
- **
- */
-
- #include "code.h"
- #include "Patch_Libs.h"
-
-
- struct JumpTable *
- GetJumpTable(UBYTE *name, struct LVOTable *LVOArray, UBYTE NumberOfFunctions)
- {
- struct JumpTable *jumptable;
- ULONG *addressptr;
- UWORD *jmpinstr;
- UBYTE *jtname;
- UCOUNT i, j;
-
- /* Not really necessary to forbid again, just to indicate that I don't
- * want another task to create the semaphore while I'm trying to do the
- * same. Here GetJumpTable() is only called from InstallWedge(), so it
- * will just bump the forbid count.
- */
- Forbid();
-
- if (!(jumptable = (struct JumpTable *) FindSemaphore(name)))
- {
- /* No jump table we have to allocate it */
-
- if (jumptable = AllocMem(sizeof(struct JumpTable) + ((NumberOfFunctions-1) * 6),
- MEMF_PUBLIC | MEMF_CLEAR))
- {
- if (jtname = AllocMem(strlen(name) + 1, MEMF_PUBLIC | MEMF_CLEAR))
- {
-
- for (i = 0, j = 0; i < NumberOfFunctions * 6; i += 6, j++)
- {
- jmpinstr = (UWORD *) ((UBYTE *) jumptable->jt_Function + i);
- *jmpinstr = 0x4EF9;
-
- addressptr = (ULONG *) ((UBYTE *) jumptable->jt_Function + i + 2);
- *addressptr = (ULONG) SetFunction(
- (struct Library *) (*((ULONG *) LVOArray[j].lt_LibBase)),
- LVOArray[j].lt_LVO,
- (VOID *) ((UBYTE *) jumptable->jt_Function + i));
- }
-
- jumptable->jt_Semaphore.ss_Link.ln_Pri = 0;
-
- strcpy(jtname, name);
- jumptable->jt_Semaphore.ss_Link.ln_Name = jtname;
- AddSemaphore((struct SignalSemaphore *) jumptable);
- }
- else
- {
- FreeMem(jumptable, sizeof(struct JumpTable) + ((NumberOfFunctions-1) * 6));
- jumptable = NULL;
- }
- }
- }
- /* Clear the cpu's cache so the execution cache is valid */
- CacheClearU();
-
- Permit();
-
- /* If succeeded, you now have a jumptable which entries point to the original
- * library functions. If another task SetFunction()'ed one or more of those
- * already, that task can never go away anymore.
- */
- return (jumptable);
- }
-
-
-
- BOOL
- InstallWedge(UBYTE *JTName, struct LVOTable *LVOArray, UBYTE NumberOfFunctions)
- {
- struct JumpTable *jumptable;
- ULONG *addressptr;
- UCOUNT i, j;
-
- Forbid();
-
- /* Get pointer to JumpTable. Create it if necessary */
- if (jumptable = GetJumpTable(JTName, LVOArray, NumberOfFunctions))
- {
- /* Try to get exclusive lock on semaphore, in case it already existed. */
- if (AttemptSemaphore((struct SignalSemaphore *) jumptable))
- {
- /* Make sure nobody else has function addresses in the jumptable */
- if (jumptable->jt_Owner == NULL)
- {
- jumptable->jt_Owner = FindTask(0);
- /* Don't want to disable any longer than necessary */
- Disable();
-
- for (i = 2, j = 0; i < NumberOfFunctions * 6; i += 6, j++)
- {
- /* Replace addresses in the jumptable with my own. */
- addressptr = (ULONG *) ((UBYTE *) jumptable->jt_Function + i);
- (*((ULONG *) LVOArray[j].lt_oldFunction)) = (ULONG) * addressptr;
- *addressptr = (ULONG) LVOArray[j].lt_newFunction;
- }
- Enable();
- }
- ReleaseSemaphore((struct SignalSemaphore *) jumptable);
- }
- }
- /* Clear the cpu's cache so the execution cache is valid */
- CacheClearU();
-
- Permit();
- return ((BOOL) jumptable);
- }
-
-
-
- BOOL
- RemoveWedge(UBYTE *JTName, struct LVOTable *LVOArray, UBYTE NumberOfFunctions)
- {
- struct JumpTable *jumptable;
- ULONG *addressptr;
- UCOUNT i, j;
-
- Forbid();
-
- if (jumptable = GetJumpTable(JTName, LVOArray, NumberOfFunctions))
- {
- /* Check if this task owns this jumptable */
- if (jumptable->jt_Owner == FindTask(0))
- {
-
- /* Get the semaphore exclusively.
- * Depending on what got SetFunction()'ed this could take some time.
- * Also note that shared locks are used to indicate the code is
- * being executed and that shared locks can jump ahead of queue'ed
- * exclusive locks, adding to the waittime.
- */
-
- ObtainSemaphore((struct SignalSemaphore *) jumptable);
-
- Disable();
-
- /* Restore old pointers in jumptable */
-
- for (i = 2, j = 0; i < NumberOfFunctions * 6; i += 6, j++)
- {
- addressptr = (ULONG *) ((UBYTE *) jumptable->jt_Function + i);
- *addressptr = (*((ULONG *) LVOArray[j].lt_oldFunction));
- }
-
- Enable();
- jumptable->jt_Owner = NULL;
- ReleaseSemaphore((struct SignalSemaphore *) jumptable);
- }
- }
- /* Clear the cpu's cache so the execution cache is valid */
- CacheClearU();
-
- Permit();
-
- return (TRUE);
- }
-
-