AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 421750
Accepted
Evan Carroll
Evan Carroll
Asked: 2018-02-04 20:40:23 +0800 CST2018-02-04 20:40:23 +0800 CST 2018-02-04 20:40:23 +0800 CST

你在哪里可以找到 Linux 的系统调用表?

  • 772

我看到很多人在网上参考

arch/x86/entry/syscalls/syscall_64.tbl

对于系统调用表,它工作正常。但是很多人参考

/include/uapi/asm-generic/unistd.h

这通常在 headers 包中找到。syscall_64.tbl节目怎么来,

0 common  read      sys_read

正确的答案,并unistd.h显示,

#define __NR_io_setup 0
__SC_COMP(__NR_io_setup, sys_io_setup, compat_sys_io_setup)

然后它显示__NR_read为

#define __NR_read 63
__SYSCALL(__NR_read, sys_read)

为什么是 63,而不是 1?我如何理解 out of /include/uapi/asm-generic/unistd.h?/usr/include/asm/里面还有

/usr/include/asm/unistd_x32.h
#define __NR_read (__X32_SYSCALL_BIT + 0)
#define __NR_write (__X32_SYSCALL_BIT + 1)
#define __NR_open (__X32_SYSCALL_BIT + 2)
#define __NR_close (__X32_SYSCALL_BIT + 3)
#define __NR_stat (__X32_SYSCALL_BIT + 4)

/usr/include/asm/unistd_64.h
#define __NR_read 0
#define __NR_write 1
#define __NR_open 2
#define __NR_close 3
#define __NR_stat 4

/usr/include/asm/unistd_32.h
#define __NR_restart_syscall 0
#define __NR_exit 1           
#define __NR_fork 2           
#define __NR_read 3           
#define __NR_write 4          

unistd有人可以告诉我这些文件之间的区别。解释如何unistd.h工作?查找系统调用表的最佳方法是什么?

syscalls
  • 5 5 个回答
  • 57123 Views

5 个回答

  • Voted
  1. Best Answer
    Stephen Kitt
    2018-02-09T10:37:32+08:002018-02-09T10:37:32+08:00

    当我研究这种事情时,我发现直接询问编译器很有用(有关详细信息,请参阅在终端中打印标准 C/GCC 预定义宏):

    printf SYS_read | gcc -include sys/syscall.h -E -
    

    这表明(在 Debian 上)涉及的标头是/usr/include/x86_64-linux-gnu/sys/syscall.h、/usr/include/x86_64-linux-gnu/asm/unistd.h、/usr/include/x86_64-linux-gnu/asm/unistd_64.h和/usr/include/x86_64-linux-gnu/bits/syscall.h,并打印 的系统调用号read,在 x86-64 上为 0。

    如果您安装了适当的系统头文件(在交叉编译器环境中),则可以找到其他体系结构的系统调用号。对于 32 位 x86,这很容易:

    printf SYS_read | gcc -include sys/syscall.h -m32 -E -
    

    其中涉及/usr/include/asm/unistd_32.h其他头文件,并打印数字 3。

    所以从用户空间的角度来看,32 位 x86 系统调用在 中定义asm/unistd_32.h,64 位 x86 系统调用在asm/unistd_64.h. asm/unistd_x32.h用于x32 ABI。

    uapi/asm-generic/unistd.h列出了默认系统调用,它们用于没有特定于体系结构的系统调用表的体系结构。

    在内核中,引用略有不同,并且是特定于体系结构的(同样,对于不使用通用系统调用表的体系结构)。这就是诸如此类的文件arch/x86/entry/syscalls/syscall_64.tbl的来源(它们最终会生成在用户空间中使用的头文件unistd_64.h等)。您将在有关该主题的两篇 LWN 文章中找到有关系统调用的更多详细信息,系统调用剖析第 1 部分和系统调用剖析第 2 部分。

    • 25
  2. Ciro Santilli OurBigBook.com
    2019-02-07T02:55:06+08:002019-02-07T02:55:06+08:00

    不同的拱门在不同的文件中定义了不同的系统调用号

    每个架构的系统调用号都不同,例如:

    • x86_64: arch/x86/entry/syscalls/syscall_64.tbl: 读取为 0

    • x86: arch/x86/entry/syscalls/syscall_32.tbl: 读取为 3

    • arm64: include/uapi/asm-generic/unistd.h: 读取为 63,另见:https ://reverseengineering.stackexchange.com/questions/16917/arm64-syscalls-table/18834#18834

    • arm: arch/arm/tools/syscall.tbl, 读取为 3

    include/uapi/asm-generic/unistd.h与arch/*定义

    我认为这include/uapi/asm-generic/unistd.h是统一所有拱门的系统调用编号的新尝试。

    但由于系统调用编号无法更改以不破坏系统调用 API,因此在统一努力之前的旧架构(包括 x86、x86_64 和 arm)保留了在arch/. arm64 较新,unistd.h但获得了新的 API。

    这个相关问题要求自动获取完整的系统调用列表,包括参数:https ://stackoverflow.com/questions/6604007/how-can-i-get-a-list-of-linux-system-calls-and -number-of-args-they-take-automati

    strace源代码

    我信任该工具,并且他们将数据整理在 下linux/,例如:

    • x86_64:https ://github.com/strace/strace/blob/v4.26/linux/x86_64/syscallent.h
    • aarch64:https ://github.com/strace/strace/blob/27739ebccc96c0f70cd2aeb37fd7b0ecfef21724/linux/aarch64/syscallent.h

    请注意,aarch64 是我之前提到#include的拱不可知论者。64/syscallent.h

    这些表包含参数的数量,但不包含实际的参数类型,我想知道strace它们在哪里编码。

    glibc源代码

    • x86_64:https ://github.com/bminor/glibc/blob/glibc-2.35/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h#L231
    • 17
  3. Marcin Juszkiewicz
    2018-11-06T01:42:39+08:002018-11-06T01:42:39+08:00

    我有一个页面列出了每个 Linux 支持的体系结构的所有系统调用:

    https://marcin.juszkiewicz.com.pl/download/tables/syscalls.html

    • 10
  4. prateeknischal
    2020-04-13T11:42:49+08:002020-04-13T11:42:49+08:00

    为了补充所有出色的答案,有一个实用程序ausyscall可用于列出特定体系结构的所有系统调用及其整数映射。

    例如:

    $ ausyscall --dump
    Using x86_64 syscall table:
    0   read
    1   write
    2   open
    3   close
    4   stat
    ...
    
    • 5
  5. Fox
    2018-02-05T15:53:27+08:002018-02-05T15:53:27+08:00

    此答案不会涉及 的asm-generic版本unistd.h,因为没有任何内容包含它。1

    如中所述syscalls(2):

    粗略地说,在Linux内核源码中的routine ()中/usr/include/asm/unistd.h可以找到属于编号为__NR_xxx的系统调用的代码。sys_xxx

    也就是说,正确的系统调用号将在/usr/include/asm/unistd.h. 现在,在典型的 x86 系统上,这将仅包含asm/unistd_*.h取决于目标的文件之一。

    适用于 64 位程序的系统调用号位于 中asm/unistd_64.h,适用于 32 位程序的系统调用号位于asm/unistd_32.h(或几乎等效的_x32.h变体)中。两者是不同的,因为 32 位和 64 位架构实际上是完全不同的操作系统。由于各种原因,它们共享相同的系统调用集,但顺序不同。

    其中大多数也具有 C 语言包装器,因此您很少需要syscall(2)直接使用。


    1因为我不知道它是干什么用的。

    • 3

相关问题

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    ssh 无法协商:“找不到匹配的密码”,正在拒绝 cbc

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    如何卸载内核模块“nvidia-drm”?

    • 13 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add 返回:“连接代理时出错:没有这样的文件或目录” 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve