How can I find where a function is implemented?

I've read a great book on BSD rootkits, and one of the examples that I found interesting suggested that I find where exit() is implemented, and use the implementation details to write a process-hiding system call. In the sources for libc, exit() is implemented as a wrapper around _exit(), which isn't very helpful.

How can I find where exit, or any other syscall, for that matter, is implemented?
 
Awesome, thanks. In the future, what should I use? As of now, I use

Code:
grep -r "exit" *

But the problem with this is that this shows every single instance of the string "exit" in /usr/src/. I have to sift through it to try to find the declaration itself.


IDEA: Maybe if I build my kernel with -g, objdump might print a source code location along with the object's name? Maybe? Would building with -g be a good idea?
 
IDEA: Maybe if I build my kernel with -g, objdump might print a source code location along with the object's name? Maybe? Would building with -g be a good idea?
I don't think so, have never tried it though.

What exactly are you searching for? Syscalls' code?

If so, this might help
 
I'm just curiously browsing through the code to see anything I find interesting. Mainly what structures do, syscalls, internal routines, etc. It's just such a pain to have to identify where everything happens.
 
As with most systems the functions in libc are basically just wrappers around the syscalls. There's a table in /usr/src/kern/syscall.master that defines which number is used for which syscall. Work your way from there.
 
What about structures? Where are most structures and their handling functions defined?

I'm beginning to see that there is no general purpose solution to this...
 
I suggest you run ctags(1) on a subset of of the source tree.

something along the lines of
Code:
find . -name "*.[ch]" -print | xargs ctags -a

This will do a shallow parse of the source code and create lines identifying where functions are defined.

By grepping this file you can see where a particular pice of code is defined without having to wade through all the places it is merely used.

You may also use vi or emacs with a tags file to view or edit the file containing the definition. e.g. vi -t foo to fire up vi on the file containing the function foo and place the cursor on the first line of the function definition.

It was really designed for small numbers of files at a time so it might be very slow and unwieldy to use it on a tags file from the whole source tree so you might want to only include a subset. But as a means of exploring the code base you might find it very informative.
 
A nice thing in vim is this:
Place your cursor on a variable or function name and hit
Code:
[I
, then vim will take you to its definition.
 
lme@ said:
A nice thing in vim is this:
Place your cursor on a variable or function name and hit
Code:
[I
, then vim will take you to its definition.

Does that require cscope?
 
brd@ said:
Does that require cscope?

No, it searches the current file and the #include files to find the variable / function definition.
 
To use grep to find a function definition in a specific directory, don't do this:

Code:
grep 'function' *

Instead, do this:

Code:
grep '^function' *

This way you will get only one line - with the actual definition.
 
remember glibc is fully abstracted to calling the host system kernel's syscalls for actually doing this stuff. So since it abstracts exit() to _exit() its a good bet its calling the syscall exit implemented in the kernel.

Thing is i'd love to play more and see how you specify these syscalls to porting glibc and see how its able to call these functions does the kernel have a shared library it can link against or something?
 
No idea about glibc (which is GNU libc and is not used in FreeBSD); but for libc, library routines that invoke system calls are generated automatically from sys/kern/syscalls.master. So, in order to add a new syscall, you need to do this:

1. Add a new syscall definition to sys/kern/syscalls.master

2. Do 'make sysent', which will generate various header and source files.

3. Add implementation of the syscall handler to the kernel.

4. Add syscall prototype to some header for userland to compile with.

5. Add the syscall to lib/libc/sys/Symbol.map, so that applications can link with it.

6. Rebuild the kernel and the world.
 
Back
Top