【问题标题】:Why is Linux syscall return type "long"?为什么 Linux 系统调用返回类型为“long”?
【发布时间】:2014-01-23 06:44:49
【问题描述】:

我正在阅读 Linux Kernel Development,第 3 版,以了解内核实现和设计。第 5 章是关于系统调用的。作者展示了一个使用SYSCALL_DEFINE0 宏定义的系统调用声明示例,在该特定示例中扩展为:

asmlinkage long sys_getpid(void)

他进一步说:

[...] 为了兼容 32 位和 64 位系统,定义为在用户空间返回 int 的系统调用在内核中返回 long。

他没有比这更深入,我无法完全理解为什么会这样。为什么long 的使用与 32 位和 64 位系统相关?为什么我们不能返回一个普通的int

【问题讨论】:

    标签: c linux linux-kernel system-calls


    【解决方案1】:

    因为在许多 64 bits 机器(例如 x86-64)上,通用 GCC 编译器 sizeof(int)==4sizeof(void*)==8 && sizeof(long)==8;这称为 I32LP64(或只是 LP64)data model

    例如,在 Linux/x86-64 系统上编译并运行以下程序:

    #include<stdio.h>
    #include<stdint.h>
    int main ()
    {
      printf ("sizeof(int)=%d\n", (int) sizeof (int));
      printf ("sizeof(intptr_t)=%d\n", (int) sizeof (intptr_t));
      printf ("sizeof(short)=%d\n", (int) sizeof (short));
      printf ("sizeof(long)=%d\n", (int) sizeof (long));
      printf ("sizeof(long long)=%d\n", (int) sizeof (long long));
      printf ("sizeof(void*)=%d\n", (int) sizeof (void *));
      return 0;
    }
    

    在使用gcc -Wall s.c -o s 在我的系统上编译并在我的Debian/Sid/x86-64(i3770k 处理器,GCC 4.8.2)上运行./s 之后:

    sizeof(int)=4
    sizeof(intptr_t)=8
    sizeof(short)=2
    sizeof(long)=8
    sizeof(long long)=8
    sizeof(void*)=8
    

    使用gcc -m32 -Wall s.c -o s32在32位模式下编译并运行./s32后:

    sizeof(int)=4
    sizeof(intptr_t)=4
    sizeof(short)=2
    sizeof(long)=4
    sizeof(long long)=8
    sizeof(void*)=4
    

    如果使用 gcc -mx32 -O3 -Wall s.c -o sx32 编译 x32,我将得到相同的输出!

    顺便说一句,也许更好的问题是为什么不使用intptr_t .... 我不知道(可能是习惯问题;when Linus 首先开始编写他的内核,C99 标准定义@ 987654343@ 和 intptr_t- 还不存在)。

    阅读有关ABIs 的更多信息,特别是仔细阅读X86-64 ABI(另请参阅x32 ABI...)和x86 calling conventions 上的维基页面。

    【讨论】:

    • 所以这意味着返回指针的系统调用会将其返回为long?
    • @AndreyT,我的 x86-64 上的 gcc 4.8.1 为 sizeof(long) 返回 8。
    • 我正在使用 gcc 4.6.3 运行 x86-64,它也为 sizeof(long) 返回 8。
    • 好的,这一定是我的困惑。确实是 8。
    • 好的,听起来很合理。 en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models 还说 Linux 和大多数 Unix 系统使用 LP64 数据模型——这就是原因。我想知道为什么不使用intptr_t
    猜你喜欢
    • 1970-01-01
    • 2012-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-22
    • 1970-01-01
    • 2016-06-08
    相关资源
    最近更新 更多