理解 VSYSCALL_ADDR 和函数指针

Understand VSYSCALL_ADDR and function pointer

我遇到了以下代码。我在这里有两个问题。 1. 在哪里可以找到这个__NR_vgetcpu?我可以通过 callign VSYSCALL_ADDR 获得哪些其他值? 2. "my_getpuc =( int(*)) .....)"这一行是做什么的?

int (*my_getcpu)(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache);
char *addr3 = (char *)VSYSCALL_ADDR(__NR_vgetcpu);
printf("vgetcpu addr is %p \n", addr3);
my_getcpu = (int (*)(unsigned *, unsigned *, struct getcpu_cache *))addr3;
my_getcpu(&cpu, &node, &cache);

您可以使用 grepackag

轻松找到这些

第一个问题,grep了一下,发现在文件中有arch/x86/include/asm/vsyscall.h

enum vsyscall_num {
    __NR_vgettimeofday,
    __NR_vtime,
    __NR_vgetcpu,
};

#define VSYSCALL_START (-10UL << 20)
#define VSYSCALL_SIZE 1024
#define VSYSCALL_END (-2UL << 20)
#define VSYSCALL_MAPPED_PAGES 1
#define VSYSCALL_ADDR(vsyscall_nr) (VSYSCALL_START+VSYSCALL_SIZE*(vsyscall_nr))

所以 __NR_vgetcpu2 VSYSCALL_ADDR(__NR_vgetcpu)(-10UL << 20) + 1024 * 2 等于 0xff600800

对于第二个问题,行 my_getcpu =( int(*)) .....)0xff600800 转换为函数指针(具有 3 个参数和 returns int)并将其分配给 my_getcpu 所以my_getcpu 可以像下一行中的函数一样对待。