grub2: bring back build of aros-side grub2 tools
[AROS.git] / rom / exec / setfunction.c
blob32b8c01b0c5fdd04074bde208f2b26e0cfa38461
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Patch a library or device function
6 Lang: english
7 */
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 /*****************************************************************************
19 NAME */
21 AROS_LH3(APTR, SetFunction,
23 /* SYNOPSIS */
24 AROS_LHA(struct Library *, library, A1),
25 AROS_LHA(LONG, funcOffset, A0),
26 AROS_LHA(APTR, newFunction, D0),
28 /* LOCATION */
29 struct ExecBase *, SysBase, 70, Exec)
31 /* FUNCTION
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
35 interrupts.
37 INPUTS
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).
44 RESULT
45 Old jumptable entry (pointer to the old function).
47 NOTES
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.
52 EXAMPLE
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.
58 BUGS
59 None.
61 SEE ALSO
62 MakeLibrary(), MakeFunctions(), SumLibrary()
64 INTERNALS
66 ******************************************************************************/
68 AROS_LIBFUNC_INIT
69 APTR ret;
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.
80 Forbid();
82 /* Mark the library as changed. */
83 library->lib_Flags|=LIBF_CHANGED;
85 /* Get old vector. */
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);
92 /* Write new one. */
93 __AROS_SETVECADDR (library, funcOffset, newFunction);
95 #ifdef __AROS_USE_FULLJMP
96 /* And clear the instruction cache (only if vectors actually contain instructions) */
97 #if 1
99 * Simply clear the entire cache...
100 * CHECKME: Why? - sonic
102 CacheClearU();
103 #else
104 /* ...or clear the vector address range specifically */
105 CacheClearE (__AROS_GETJUMPVEC(library,funcOffset),LIB_VECTSIZE,CACRF_ClearI|CACRF_ClearD);
106 #endif
107 #endif
109 /* Arbitration is no longer needed */
110 Permit();
112 /* Sum the library up again */
113 SumLibrary(library);
115 DSETFUNCTION("Old function: 0x%p", ret);
117 /* All done. */
118 return ret;
119 AROS_LIBFUNC_EXIT
120 } /* SetFunction */