系统调用号的定义在 /usr/include/asm/unistd.h 文件中
在glibc中寻找封装系统调用的例程。以open为例。int handle = open("/tmp/test.txt",O_RDONLY);(利用source insight工具)
(1)search open,在project中,由于open定义在fcntl.h中,所以在结果集中寻找fcntl文件中的open。
有:
Fcntl.h (e:\linux\glibc-2.16.0\io):157
extern int open (const char *__file, int __oflag, ...) __nonnull ((1));
和这里匹配,进入文件中。
(2)jump to definition出现三个宏定义和一个函数实现。
其中有两个宏的参数不匹配,第三个宏Macro in Loadmsgact.c匹配。进入。
这里是宏定义:
#define open(name,flags) open_not_cancel_2(name,flags)
(3)继续jump to definition
出现两个宏定义。
1 open_not_cancel_2 - Macro in Not-cancel.h (e:\glibc\...\generic) at line 23 (2 lines)
2 open_not_cancel_2 - Macro in Not-cancel.h (e:\glibc\...\linux) at line 26 (2 lines)
查看一下,第一个是:
#define open_not_cancel_2(name,flags)
__libc_open(name,flags)
第二个是:
#define open_not_cancel_2(name,flags)
INLINE_SYSCALL(open,2,(const char *)(name),(flags))
我们要找的肯定是第二个,系统调用(syscall)。。。
(4)进入后,对INLINE_SYSCALL进行jump to definition
在结果集中可以看到,它是具体平台相关的,有space,powerPC,s390,x86_63等,我们进入i386的(\glibc-2.16.0\sysdeps\unix\sysv\linux\i386\Sysdep.h)。
这里宏被展开。
#define INLINE_SYSCALL(name, nr, args...) \
({ \
unsigned int resultvar = INTERNAL_SYSCALL (name, , nr, args); \
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (resultvar, ), 0)) \
{ \
__set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, )); \
resultvar = 0xffffffff; \
} \
(int) resultvar; })
(5)查看INTERNAL_SYSCALL (name, , nr, args)的定义。
依然是平台相关的,我们选择i386的。但是此时有在i386下有3个。我们依次查看。
#ifdef I386_USE_SYSENTER //第一个if选择的是使用sysenter指令还是int 0x80指令来进入核心态。
//使用sysenter指令
# ifdef SHARED
//第二个if是对应动态链接还是静态链接。在静态链接(编译时加上-static选项)情况下,采用"call *_dl_sysinfo"指令;在动态链接情况下,采用"call *%gs:0x10"指令。
# define INTERNAL_SYSCALL(name, err, nr, args...) \//使用sysenter指令,动态链接情况
({ \
register unsigned int resultvar; \
EXTRAVAR_##nr \
asm volatile ( \
LOADARGS_##nr \
"movl %1, %%eax\n\t" \ // 存放系统调用号
"call *%%gs:%P2\n\t" \ //切换到核心态。
RESTOREARGS_##nr \
: "=a" (resultvar) \
: "i" (__NR_##name), "i" (offsetof (tcbhead_t, sysinfo)) \
ASMFMT_##nr(args) : "memory", "cc"); \
(int) resultvar; })
# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
({ \
register unsigned int resultvar; \
EXTRAVAR_##nr \
asm volatile ( \
LOADARGS_##nr \
"call *%%gs:%P2\n\t" \
RESTOREARGS_##nr \
: "=a" (resultvar) \
: "0" (name), "i" (offsetof (tcbhead_t, sysinfo)) \
ASMFMT_##nr(args) : "memory", "cc"); \
(int) resultvar; })
# else
# define INTERNAL_SYSCALL(name, err, nr, args...) \//使用sysenter指令,静态链接情况
({ \
register unsigned int resultvar; \
EXTRAVAR_##nr \
asm volatile ( \
LOADARGS_##nr \
"movl %1, %%eax\n\t" \
"call *_dl_sysinfo\n\t" \
RESTOREARGS_##nr \
: "=a" (resultvar) \
: "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc"); \
(int) resultvar; })
# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
({ \
register unsigned int resultvar; \
EXTRAVAR_##nr \
asm volatile ( \
LOADARGS_##nr \
"call *_dl_sysinfo\n\t" \
RESTOREARGS_##nr \
: "=a" (resultvar) \
: "0" (name) ASMFMT_##nr(args) : "memory", "cc"); \
(int) resultvar; })
# endif
//使用int 0x80软中断指令进入核心态。
#else
# define INTERNAL_SYSCALL(name, err, nr, args...) \
({ \
register unsigned int resultvar; \
EXTRAVAR_##nr \
asm volatile ( \
LOADARGS_##nr \
"movl %1, %%eax\n\t" \存系统调用号
"int $0x80\n\t" \发出软中断请求
RESTOREARGS_##nr \
: "=a" (resultvar) \
: "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc"); \
(int) resultvar; })
# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
({ \
register unsigned int resultvar; \
EXTRAVAR_##nr \
asm volatile ( \
LOADARGS_##nr \
"int $0x80\n\t" \
RESTOREARGS_##nr \
: "=a" (resultvar) \
: "0" (name) ASMFMT_##nr(args) : "memory", "cc"); \
(int) resultvar; })
#endif