在 C 中调用系统调用函数的问题
Problems calling syscall function in C
为了家庭作业,我必须修改 linux 内核。
我在虚拟机上工作,我给内核加了一个系统调用,我称之为get_unique_id
。这是 get_unique_id.c
的代码:
#include <linux/linkage.h>
#include <asm/uaccess.h>
asmlinkage long sys_get_unique_id(int * uuid)
{
// static because we want its state to persist between calls
static int uid = 0;
++uid;
// assign new uid value to user-provided mem location
// returns non-zero if success or -EFAULT otherwise
int ret = put_user(uid, uuid);
return ret;
}
我也将这一行添加到 syscalls.h
:
asmlinkage long sys_get_unique_id(int * uuid);
这一行到 syscall_32.tbl :
383 i386 get_unique_id sys_get_unique_id
最后这一行 syscall_64.tbl
:
548 common get_unique_id sys_get_unique_id
重新编译和加载内核后,我写了一个小的 C 程序来测试我的系统调用,这里是 C 测试文件的代码:
// get_unique_id_test.c
#include <stdio.h>
#include <limits.h>
#include "syscalls_test.h"
int main(void)
{
// initialize the ints we want
int id1;
int id2;
// check the id's are unique and that no error occured
for (int i = INT_MIN; i < INT_MAX - 1; i += 2) {
long ret1 = get_unique_id(&id1);
long ret2 = get_unique_id(&id2);
if (ret1 != 0)
printf("ERROR: get_unique_id returned: %ld\n", ret1);
if (ret2 != 0)
printf("ERROR: get_unique_id returned: %ld\n", ret2);
if (id2 != id1 + 1)
printf("ERROR: successive id's did not increment properly: id1 = %d, id2 = %d\n", id1, id2);
}
return 0;
}
及其头文件:
// syscalls_test.h
#include <errno.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#define __NR_get_unique_id 383
inline long get_unique_id(int * uuid)
{
return syscall(__NR_get_unique_id, uuid) ? errno : 0;
}
不幸的是,在尝试使用以下命令编译 C 测试文件时:gcc -std=c99 get_unique_id_test.c -o get_unique_id_test
,出现以下错误:
In file included from get_unique_id_test.c:4:0:
syscalls_test.h: In function ‘get_unique_id’:
syscalls_test.h:10:5: warning: implicit declaration of function ‘syscall’ [-Wimplicit-function-declaration]
return syscall(__NR_get_unique_id, uuid) ? errno : 0;
^
syscalls_test.h: In function ‘get_unique_id’:
syscalls_test.h:10:5: warning: implicit declaration of function ‘syscall’ [-Wimplicit-function-declaration]
return syscall(__NR_get_unique_id, uuid) ? errno : 0;
^
/tmp/cc1euZ3r.o: In function `main':
get_unique_id_test.c:(.text+0x22): undefined reference to `get_unique_id'
get_unique_id_test.c:(.text+0x34): undefined reference to `get_unique_id'
collect2: error: ld returned 1 exit status
gcc 似乎找不到在 syscalls_test.h
中声明的函数 get_unique_id(int * uuid)
和我认为应该在 [=25= 中声明的 syscall
函数], 对吗?
我不明白为什么会这样。有人有想法吗?
编辑: 我的问题是使用 a3f 的解决方案解决的(见下文)PLUS 将 #include "syscalls_test.h"
移动到最顶部正如他在评论中所说的那样。非常感谢。
#define _GNU_SOURCE
在包括 unistd.h
或任何其他 header 之前因为 syscall(2)
不是 POSIX.
- 使用
static inline
而不是普通的 inline
。 Plain inline
提供内联定义,但编译器可以随意忽略它并使用您未提供的外部定义。
尝试以下方法:
#include <unistd.h>
为了家庭作业,我必须修改 linux 内核。
我在虚拟机上工作,我给内核加了一个系统调用,我称之为get_unique_id
。这是 get_unique_id.c
的代码:
#include <linux/linkage.h>
#include <asm/uaccess.h>
asmlinkage long sys_get_unique_id(int * uuid)
{
// static because we want its state to persist between calls
static int uid = 0;
++uid;
// assign new uid value to user-provided mem location
// returns non-zero if success or -EFAULT otherwise
int ret = put_user(uid, uuid);
return ret;
}
我也将这一行添加到 syscalls.h
:
asmlinkage long sys_get_unique_id(int * uuid);
这一行到 syscall_32.tbl :
383 i386 get_unique_id sys_get_unique_id
最后这一行 syscall_64.tbl
:
548 common get_unique_id sys_get_unique_id
重新编译和加载内核后,我写了一个小的 C 程序来测试我的系统调用,这里是 C 测试文件的代码:
// get_unique_id_test.c
#include <stdio.h>
#include <limits.h>
#include "syscalls_test.h"
int main(void)
{
// initialize the ints we want
int id1;
int id2;
// check the id's are unique and that no error occured
for (int i = INT_MIN; i < INT_MAX - 1; i += 2) {
long ret1 = get_unique_id(&id1);
long ret2 = get_unique_id(&id2);
if (ret1 != 0)
printf("ERROR: get_unique_id returned: %ld\n", ret1);
if (ret2 != 0)
printf("ERROR: get_unique_id returned: %ld\n", ret2);
if (id2 != id1 + 1)
printf("ERROR: successive id's did not increment properly: id1 = %d, id2 = %d\n", id1, id2);
}
return 0;
}
及其头文件:
// syscalls_test.h
#include <errno.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#define __NR_get_unique_id 383
inline long get_unique_id(int * uuid)
{
return syscall(__NR_get_unique_id, uuid) ? errno : 0;
}
不幸的是,在尝试使用以下命令编译 C 测试文件时:gcc -std=c99 get_unique_id_test.c -o get_unique_id_test
,出现以下错误:
In file included from get_unique_id_test.c:4:0:
syscalls_test.h: In function ‘get_unique_id’:
syscalls_test.h:10:5: warning: implicit declaration of function ‘syscall’ [-Wimplicit-function-declaration]
return syscall(__NR_get_unique_id, uuid) ? errno : 0;
^
syscalls_test.h: In function ‘get_unique_id’:
syscalls_test.h:10:5: warning: implicit declaration of function ‘syscall’ [-Wimplicit-function-declaration]
return syscall(__NR_get_unique_id, uuid) ? errno : 0;
^
/tmp/cc1euZ3r.o: In function `main':
get_unique_id_test.c:(.text+0x22): undefined reference to `get_unique_id'
get_unique_id_test.c:(.text+0x34): undefined reference to `get_unique_id'
collect2: error: ld returned 1 exit status
gcc 似乎找不到在 syscalls_test.h
中声明的函数 get_unique_id(int * uuid)
和我认为应该在 [=25= 中声明的 syscall
函数], 对吗?
我不明白为什么会这样。有人有想法吗?
编辑: 我的问题是使用 a3f 的解决方案解决的(见下文)PLUS 将 #include "syscalls_test.h"
移动到最顶部正如他在评论中所说的那样。非常感谢。
#define _GNU_SOURCE
在包括unistd.h
或任何其他 header 之前因为syscall(2)
不是 POSIX.- 使用
static inline
而不是普通的inline
。 Plaininline
提供内联定义,但编译器可以随意忽略它并使用您未提供的外部定义。
尝试以下方法:
#include <unistd.h>