如何在 NASM 中调用全局 C 函数指针而不出现警告?

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

鉴于

main.c

#include <stdio.h>

void (*fn_ptr)(void);

void foo(void);

void bar(void) {
    printf("bar\n");
}

int main(void) {
    fn_ptr = bar;
    foo();
}

foo.s

extern fn_ptr

global foo
foo:
    mov rax, fn_ptr
    call [rax]
    ret

我们可以像这样运行和编译它:

clear &&
nasm foo.s -f elf64 -O0 &&
clang main.c foo.o -z noexecstack &&
./a.out

成功打印

bar
,但也打印警告:

/usr/bin/ld: foo.o: warning: relocation against `fn_ptr' in read-only section `.text'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
bar

我在NASM中找不到任何调用全局函数指针的在线示例,将其更改为

mov rax, fn_ptr wrt ..plt
call [fn_ptr wrt ..plt]
会打印此错误:

foo.s:7: error: ELF format cannot produce non-PC-relative PLT references

(对于任何想知道

-z noexecstack
消除了什么警告的人):

/usr/bin/ld: warning: foo.o: missing .note.GNU-stack section implies executable stack
/usr/bin/ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker
c assembly nasm
1个回答
0
投票

来自评论;我现在可以输入答案了。

以下组装说明不起作用:

    mov rax, fn_ptr wrt ..plt
    call fn_ptr wrt ..plt
    call [fn_ptr wrt ..plt]

但这些确实:

    lea rax, [rel fn_ptr wrt ..plt]
    call [rel fn_ptr wrt ..plt]

确实存在ELF格式错误。我很惊讶它无法处理

mov rax, fn_ptr wrt ..plt
call [fn_ptr wrt ..plt]
肯定无法工作。没有
call qword
这样的指令,只有
call rel dword
call [rel dword]

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