我对下面的宏预处理器定义感到困惑:
#define HOOK_SYSCALL(NAME) original_##NAME = get_sys_call_table_addr()[__NR_##NAME];
名为get_sys_call_table_addr()的函数的代码如下:
ssize_t *sys_call_table = (ssize_t *)NULL;
void** get_sys_call_table_addr(void)
{
void *swi_addr=(long *)0xffff0008;
unsigned long offset=0;
unsigned long *vector_swi_addr=0;
offset=((*(long *)swi_addr)&0xfff)+8;
vector_swi_addr=*(unsigned long *)(swi_addr+offset);
while(vector_swi_addr++)
{
if(((*(unsigned long *)vector_swi_addr)& 0xfffff000)==0xe28f8000)
{
offset=((*(unsigned long *)vector_swi_addr)& 0xfff)+8;
sys_call_table=(void *)vector_swi_addr+offset;
break;
}
}
return (void **) sys_call_table;
}
我想问一下这个具体的界限:
get_sys_call_table_addr()[__ NR _ ## NAME];
将内联函数作为数组调用?就像我们对正常类型的数组所做的那样,例如阵列[3];
谢谢!
答案 0 :(得分:3)
##
用于连接预处理程序令牌。假设NAME
为exit
。那么get_sys_call_table_addr()[__NR_##NAME]
将是
get_sys_call_table_addr()[__NR_exit]
。这意味着调用get_sys_call_table_addr()
并且评估结果将是指针。
请注意arr[x]
是*(arr + x)
。假设__NR_exit
是一个值为1
的常量。然后,函数返回的结果指针移动1
,然后解除引用。现在,这将分配给变量original_exit
。
答案 1 :(得分:1)
令牌##用于将两个令牌连接成一个。例如,在上面的示例中,__ NR _ ## NAME变为__NR_NAME。
函数get_sys_call_table_addr()返回一个表sys_call_table,它是一个双指针。该表应用作数组变量,并指向[__NR_NAME]指向的地址。
换句话说,get_sys_call_table_addr()[__ NR _ ## NAME]变为sys_call_table [__ NR_NAME];