现在的位置: 首页 > 综合 > 正文

在glibc中寻找封装系统调用的例程。以open为例

2013年10月17日 ⁄ 综合 ⁄ 共 3505字 ⁄ 字号 评论关闭

系统调用号的定义在 /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


抱歉!评论已关闭.