如何从系统调用号获取Linux系统调用名称?

8
我需要将Linux系统调用号转换成易懂的名称。在内核2.6.32中,我从/usr/include/asm/unistd_32.h文件中提取了_NR*宏中的名称,虽然这种方法有点hacky,但是它确实有效。现在我需要在内核3.2.0上使其工作,但是该文件已经不存在了。
最不hacky且最可移植的方法是什么,可以将Linux系统调用号映射到易于理解的名称上?例如,1 - >退出,6 - >关闭等。

我不知道有什么编程方法可以做到这一点,只能深入内核源代码进行挖掘。此文件包含系统调用号码 - Dabo
2个回答

4

文件<sys/syscall.h>定义了许多SYS_宏(在我的系统上通过bits/syscall.h间接定义)。例如:

#define SYS_eventfd __NR_eventfd
#define SYS_eventfd2 __NR_eventfd2
#define SYS_execve __NR_execve
#define SYS_exit __NR_exit
#define SYS_exit_group __NR_exit_group
#define SYS_faccessat __NR_faccessat

这是您要找的吗?我不确定这是否涉及您的问题,但您可以执行以下操作:

switch(code) {
#define syscode_case(x) case x: return #x;
    syscode_case(SYS_eventfd);
    syscode_case(SYS_eventf2);
}

你仍然需要知道哪些宏是可用的,但不需要知道实际值。
编辑:
我的来源是 man 2 syscall,它声明了:
#include <sys/syscall.h>`   /* For SYS_xxx definitions

@GrzegorzJakacki 这不是你要找的吗?宏名称是可移植的。 - André Puel
1
谢谢。我知道我可以通过以下方式获取SYS_...宏列表: echo "#include<sys/syscall.h>" | gcc -dN -E - | awk '($1=="#define" && $2~/^SYS_/){print $2}' 因此,我可以找到SYS_...宏的列表。问题是,按照SYS_...宏是否是将系统调用号映射到名称的最佳方法。我不清楚SYS_...和__NR_...宏之间的区别是什么?是否有可能某些系统调用不会被SYS_...宏覆盖?在系统调用内核陷阱之前,EAX寄存器中的数字是否与SYS_...定义的值相同? - Grzegorz Jakacki

1
  1. 您可以在内核源代码目录中执行grep -rA3 'SYSCALL_DEFINE.\?(<syscallname>,' *(将<syscallname>替换为实际的系统调用)。
  2. 您可以使用man syscalls开始查找。
  3. 请查看此处,并耐心等待(评论中报告链接已损坏)。
  4. 这个似乎有效

那个链接已经失效了,请检查是否有替代方案。 - Vesper

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接