Arm64 - 绝对分支生成异常

问题描述

使用 BLR 在 64arm 中使用其绝对地址 (0x80904) 跳转到 C 函数失败:

LDR x3,=0x80904 
SUB x0,x3,x19
BL print_x0 // Prints something to uart,i.e,x0 == x19

BLR x19  // Fails!

地址很好:BLR x3 有效。

x19 值在 print_x0 之后不会改变。我测试过了。

为什么分支会产生这个异常?

谢谢!

解决方法

首先感谢大家的帮助!我让它工作。也就是说,我真的不明白问题出在哪里。

下面的函数创建了一个结构,其中包含我调用的函数的地址(参见 fn)。这个地址后来在我尝试 BLR x19 之前被加载到 x19。

struct task_struct * copy_process(unsigned long fn)
{
    struct task_struct *p;
    p = (struct task_struct *)get_free_page();

    char buff[] = "0000000000000000";
    parse_int((unsigned long)fn,buff,16);
    uart_send_string("fn: ");
    uart_send_string(buff);
    uart_send_string("\n");

    // Configure the task struct
    p->cpu_context.x19 = fn;
    return p;
}

注释掉 parse_int((unsigned long)fn,16); 就足够了,一切都按预期工作。

这里是 parse_int 的样子:

void parse_int(u64 number,char* str,int base) {
    if(base > 36)
        return;

    int length = 0;
    while (str[length] != '\0') {
        str[length] = '0';
        length++;
    }

    char remainder;
    while(number >= 0 && length >= 0) {
        length--;
        remainder = (number % base);
        if(remainder > 9) {
            remainder -= 10;
            str[length] = 'A' + remainder;    
        } else {
            str[length] = '0' + remainder;
        }
        number /= base;
    }
}

我想在这次调用中内存以某种方式被破坏了,但我不知道是怎么回事。

如果您知道原因,请随意回答原始问题,我会将其标记为好问题。我也会删除我的这个答案,因为这对遇到同样问题的人可能没有帮助。

谢谢