System calls : difference between sys_exit(), SYS_exit and exit()

拈花ヽ惹草 提交于 2019-12-23 08:37:14

问题


What is the difference between SYS_exit, sys_exit() and exit()?

What I understand :

  • The linux kernel provides system calls, which are listed in man 2 syscalls.
  • There are wrapper functions of those syscalls provided by glibc which have mostly similar names as the syscalls.

My question : In man 2 syscalls, there is no mention of SYS_exit and sys_exit(), for example. What are they?

Note : The syscall exit here is only an example. My question really is : What are SYS_xxx and sys_xxx()?


回答1:


I'll use exit() as in your example although this applies to all system calls.

The functions of the form sys_exit() are the actual entry points to the kernel routine that implements the function you think of as exit(). These symbols are not even available to user-mode programmers. That is, unless you are hacking the kernel, you cannot link to these functions because their symbols are not available outside the kernel. If I wrote libmsw.a which had a file scope function like

static int msw_func() {}

defined in it, you would have no success trying to link to it because it is not exported in the libmsw symbol table; that is:

cc your_program.c libmsw.a

would yield an error like:

ld: cannot resolve symbol msw_func

because it isn't exported; the same applies for sys_exit() as contained in the kernel.

In order for a user program to get to kernel routines, the syscall(2) interface needs to be used to effect a switch from user-mode to kernel mode. When that mode-switch (somtimes called a trap) occurs a small integer is used to look up the proper kernel routine in a kernel table that maps integers to kernel functions. An entry in the table has the form

{SYS_exit, sys_exit},

Where SYS_exit is an preprocessor macro which is

#define SYS_exit (1)

and has been 1 since before you were born because there hasn't been reason to change it. It also happens to be the first entry in the table of system calls which makes look up a simple array index.

As you note in your question, the proper way for a regular user-mode program to access sys_exit is through the thin wrapper in glibc (or similar core library). The only reason you'd ever need to mess with SYS_exit or sys_exit is if you were writing kernel code.




回答2:


This is now addressed in man syscall itself,

Roughly speaking, the code belonging to the system call with number __NR_xxx defined in /usr/include/asm/unistd.h can be found in the Linux kernel source in the routine sys_xxx(). (The dispatch table for i386 can be found in /usr/src/linux/arch/i386/kernel/entry.S.) There are many exceptions, however, mostly because older system calls were superseded by newer ones, and this has been treated somewhat unsystematically. On platforms with proprietary operating-system emulation, such as parisc, sparc, sparc64, and alpha, there are many additional system calls; mips64 also contains a full set of 32-bit system calls.

At least now /usr/include/asm/unistd.h is a preprocessor hack that links to either,

  • /usr/include/asm/unistd_32.h
  • /usr/include/asm/unistd_x32.h
  • /usr/include/asm/unistd_64.h

The C function exit() is defined in stdlib.h. Think of this as a high level event driven interface that allows you to register a callback with atexit()

/* Call all functions registered with `atexit' and `on_exit',
   in the reverse of the order in which they were registered,
   perform stdio cleanup, and terminate program execution with STATUS.  */

extern void exit (int __status) __THROW __attribute__ ((__noreturn__));

So essentially the kernel provides an interface (C symbols) called __NR_xxx. Traditionally people want sys_exit() which is defined with a preprocessor macro SYS_exit. This macro creates the sys_exit() function. The exit() function is part of the standard C library stdlib.h and ported to other operating systems that lack the Linux Kernel ABI entirely (there may not be __NR_xxx functions) and potentially don't even have sys_* functions available either (you could write exit() to send the interrupt or use VDSO in Assembly).



来源:https://stackoverflow.com/questions/18994106/system-calls-difference-between-sys-exit-sys-exit-and-exit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!