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
);
95 #ifdef __AROS_USE_FULLJMP
96 /* And clear the instruction cache (only if vectors actually contain instructions) */
99 * Simply clear the entire cache...
100 * CHECKME: Why? - sonic
104 /* ...or clear the vector address range specifically */
105 CacheClearE (__AROS_GETJUMPVEC(library
,funcOffset
),LIB_VECTSIZE
,CACRF_ClearI
|CACRF_ClearD
);
109 /* Arbitration is no longer needed */
112 /* Sum the library up again */
115 DSETFUNCTION("Old function: 0x%p", ret
);