#c #llvm
#c #llvm
Вопрос:
У меня есть следующий код LLVM:
define i64 @main() {
entry:
call void @some.function()
ret i64 0
}
declare void @some.function()
some.function
.
в нем есть a, что означает, что если я сделаю что-то подобное на 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
to 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) {}
Есть мысли?
Ответ №1:
Если вы используете GCC или Clang, есть возможность указать, что имя в сборке отличается от имени в C:
extern void foo(void) __asm__("some.function");
Затем, когда вы вызываете функцию foo
, компилятор сгенерирует ассемблерный код, такой как callq some.function
.