Date: Sat, 23 Feb 2002 14:36:40 -0800 From: Terry Lambert <tlambert2@mindspring.com> To: dak <aurelien.nephtali@wanadoo.fr> Cc: freebsd-hackers@freebsd.org Subject: Re: Kernel Module Message-ID: <3C781978.4E43221A@mindspring.com> References: <20020223220605.GA1863@mars>
next in thread | previous in thread | raw e-mail | index | archive | help
dak wrote: > I want to make a module that re-writes a kernel function. > Anybody can point me to a doc/skeleton code please ? > I've already taken a look at examples provided with FreeBSD > but I've only seen code to make new syscalls (or devices). > > Thanks in advance (and sorry for the bad english :>) This is called thunking. If you need to do this, you should reconsider your application or define an interface boundary for what you want to replace. The easiest way is to define a global function pointer you can overwrite (or a local one, if the overwrite is in the same file), e.g.: static int default_foo(int i, char c) { return( i * c); } int (*foo)(int i, char c) = default_foo; static int new_foo(int i, char c) { return( i + c); } int replace_foo() { foo = new_foo; } Alternately, you can replace the function at the address with a "thunk". A thunk is a "call new_func; ret;". You take the address of the function and write your replacement there (you will need to come up with the instruction value yourself): replace_default_foo() { char *instr = "\x71\x77\x78\x78xxxxxxxx"; /* abs call*/ void *old; old = (char *)default_foo; memcpy( (void *)instr+4 (void *)new_foo, sizeof(void *)); memcpy( old, (void&)instr, 4 + sizeof(void *)); } Basically, you eat an additional call/ret overhead. It's better to replace a function pointer. Alternately, you could do a fixup. With a fixup, you have a fake function, and when it's called, it patches the caller to point to the new function. Since relative calls are shorter than absolute, you can't fixup everything (not enough space for the absolute call instruction operand), but you can thunk to everything by stomping the caller. For the fixup, you stomp the address of the function with a replacement fixup function, instead of the real replacement function. When it gets called, it walks back the stack to find the caller, stops the caller code, then finishes calling through the replacement function. Thus the expense of the extra work occurs the first time you call it, but subseqnet calls use the fixed-up code instead, and call the replacement function directly. For relative calls, you fixup to a thunk, so that you don't have fixup failure overhead each time, but you still have cal overhead. If what your doing needs this, then you probably should be fixing the interface so that you don't need to do this, as other people are likely to want to do what you are doing, too. -- Terry To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3C781978.4E43221A>