函数指针始终为零,但在取消引用和调用时起作用

问题描述 投票:0回答:1

这是我拥有的最小代码示例(我尝试运行最小示例以确保它重现我所看到的问题):

void testfn(void) {
    printf("Hello, world!\n");
}

int main(int argc, char *argv[]) {
    printf("fp: %p\n", &testfn);
    return 0;
}

我得到的输出是

fp: 0x0000000000000000
,表明我尝试打印的函数指针是 0。我尝试在
__attribute__((noinline))
上使用 GCC
testfn()
属性,得到了相同的结果。

我正在为 RISC-V 系统进行编译并在 QEMU 中运行。我认为也许

printf()
实现有问题(尽管它对我来说看起来很好,其他指针打印得很好),所以我尝试将函数指针转换为无符号 64 位 int,然后循环多次迭代(我认识到这一点)技术上是 UB,但在实践中通常有效),但循环执行精确的 0 次迭代:

void __attribute__((noinline)) testfn(void) {
    printf("Hello, world!\n");
}

int main(int argc, char *argv[]) {
    void (*fn)(void) = &testfn;

    printf("Testing printf...\n");
    printf("fp addr: %p\n", &fn);
    fn();

    for (int i = 0; i < (unsigned long long) fn; ++i) {
        printf("Here!\n");
    }

    printf("fp: %p\n", fn);
    return 0;
}

这会产生以下输出:

Testing printf...
fp addr: 0x0000000000003FA8
Hello, world!
fp: 0x0000000000000000

这是用于编译的命令:

riscv64-unknown-elf-gcc -Wall -O0 -fno-omit-frame-pointer -ggdb -gdwarf-2 -MD -mcmodel=medany -ffreestanding -fno-common -nostdlib -mno-relax -I. -fno-stack-protector -fno-pie -no-pie -c -o user/rkttest.o user/rkttest.c

这是我用来运行 QEMU 的命令;

qemu-system-riscv64 -machine virt -bios none -kernel kernel/kernel -m 128M -smp 3 -nographic -global virtio-mmio.force-legacy=false -drive file=fs.img,if=none,format=raw,id=x0 -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0

在我看来,函数指针总是为零,除非我尝试将其作为函数调用。在我看来,这就像编译器错误或我的环境中发生的一些奇怪的事情,但我想我应该把它扔到 Stack Overflow 上。我是不是错过了什么?

c gcc embedded function-pointers riscv
1个回答
0
投票

看起来系统实际上是将代码段放置在地址 0x0 处,并且编译器将函数放置在代码段的开头。对于系统的一部分来说,这是一个非常糟糕的主意。地址 0x0 上不应该有任何东西,永远

以下代码:

static void __attribute__((noinline)) testfn(void) {
    printf("Hello, world!\n");
}

static void __attribute__((noinline)) testfn2(void) {
    printf("Hello, world!\n");
}

int main(int argc, char *argv[]) {
    printf("fp: %p\n", &testfn);
    printf("fp: %p\n", &testfn2);

    return 0;
}

产生以下输出:

fp: 0x000000000000001A
fp: 0x0000000000000000

天啊。 🤦u200d♂️

© www.soinside.com 2019 - 2024. All rights reserved.