C/LLVM: 调用名称中包含非法字符的函数

C/LLVM: Call function with illegal characters in its name

我有以下 LLVM 代码:

define i64 @main() {
entry:
  call void @some.function()
  ret i64 0
}

declare void @some.function()

some.function 里面有一个 .,这意味着如果我在 C:

中做这样的事情
#include <stdio.h>
void some.function(void) {
    puts("this will not work");
}

坏事发生:

$ cc tmp.c -S
tmp.c:3:10: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘.’ token
 void some.function(void) {
          ^

如果我将 some.function 更改为 some_function,我将得到以下程序集:

    .file   "tmp.c"
    .text
    .section    .rodata
.LC0:
    .string "this will not work"
    .text
    .globl  some_function
    .type   some_function, @function
some_function:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    leaq    .LC0(%rip), %rdi
    call    puts@PLT
    nop
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   some_function, .-some_function
    .ident  "GCC: (Ubuntu 8.4.0-1ubuntu1~18.04) 8.4.0"
    .section    .note.GNU-stack,"",@progbits

我可以手动将 some_function 的所有实例更改为 some.function 并编译它:

$ cc tmp.s main.s  # main.s is the LLVM code
$ ./a.out
this will not work

我怎样才能从 C 本身做到这一点?我想做的是这样的:

void "some.function"(void) {}

//or

void __some_special_macro((some.function))(void) {}

有什么想法吗?

如果您使用的是 GCC 或 Clang,则有 a feature for specifying that the name in assembly is different from the name in C:

extern void foo(void) __asm__("some.function");

那么,当你调用函数foo时,编译器会生成callq some.function.

这样的汇编代码