2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
5 Desc: Patch a library or device function
9 #include <aros/debug.h>
10 #include <exec/execbase.h>
11 #include <proto/intuition.h>
12 #include <aros/libcall.h>
13 #include <proto/exec.h>
15 #include "exec_debug.h"
17 /*****************************************************************************
21 AROS_LH3(APTR
, SetFunction
,
24 AROS_LHA(struct Library
*, library
, A1
),
25 AROS_LHA(LONG
, funcOffset
, A0
),
26 AROS_LHA(APTR
, newFunction
, D0
),
29 struct ExecBase
*, SysBase
, 70, Exec
)
32 Replaces a certain jumptable entry with another one. This function only
33 Forbid()s taskswitching but doesn't Disable() interrupts. You have
34 to do your own arbitration for functions which are callable from
38 library - Pointer to library structure.
39 funcOffset - Offset of the jumpvector from the library base address in
40 bytes. It's the negative LVO (library vector offset)
41 multiplied with LIB_VECTSIZE.
42 newFunction - New jumptable entry (pointer to the new function).
45 Old jumptable entry (pointer to the old function).
48 While it's more or less safe to patch a library vector with
49 SetFunction() it's not possible to safely remove the patch later.
50 So don't use this function if it can be avoided.
53 Patch of the function Open() from dos.library:
54 You can find the LVO of 5 in clib/dos_protos.h.
55 SetFunction(DOSBase, -5 * LIB_VECTSIZE, NewOpen);
56 NewOpen must be prepared with AROS_UFH macros.
62 MakeLibrary(), MakeFunctions(), SumLibrary()
66 ******************************************************************************/
71 DSETFUNCTION("SetFunction(%s, %ld, 0x%p)", library
->lib_Node
.ln_Name
, funcOffset
, newFunction
);
73 /* Vector pre-processing for non-native machines: */
74 funcOffset
= (-funcOffset
) / LIB_VECTSIZE
;
77 Arbitrate for the jumptable. This isn't enough for interrupt callable
78 functions - but it need not be.
82 /* Mark the library as changed. */
83 library
->lib_Flags
|=LIBF_CHANGED
;
86 ret
= __AROS_GETVECADDR (library
, funcOffset
);
88 /* Don't forget to initialise the vector, or else there would be no actual
89 assembler jump instruction in the vector */
90 __AROS_INITVEC (library
, funcOffset
);
93 __AROS_SETVECADDR (library
, funcOffset
, newFunction
);
96 /* And clear the instruction cache. */
97 /* Simply clear the entire cache... */
100 /* ...or clear the vector address range specifically */
101 CacheClearE (__AROS_GETJUMPVEC(library
,funcOffset
),LIB_VECTSIZE
,CACRF_ClearI
|CACRF_ClearD
);
104 /* Arbitration is no longer needed */
107 /* Sum the library up again */
110 DSETFUNCTION("Old function: 0x%p", ret
);