I know in swift it is possible to interop with c using the @_silgen_name attr on a function in a swift module. Is there a way to do this with a symbol defined in an assembly file? I would like to make syscalls using Swift. This is why I'm asking.
- A compiled object file has no idea whether it was compiled from C, or assembled from assembly language.Crowman– Crowman2016-09-09 22:33:24 +00:00Commented Sep 9, 2016 at 22:33
- @PaulGriffiths how does the compiler know where the symbol thats in the asm file is when its compiling the swift module?jack sexton– jack sexton2016-09-09 22:41:01 +00:00Commented Sep 9, 2016 at 22:41
- In exactly the same way that it knows where the symbol is with a C source file - it looks it up in the symbol table of the object file.Crowman– Crowman2016-09-09 22:43:33 +00:00Commented Sep 9, 2016 at 22:43
- @PaulGriffiths but I haven't told the compiler to link it. is there a special flag I need to pass in or something?jack sexton– jack sexton2016-09-09 22:54:15 +00:00Commented Sep 9, 2016 at 22:54
- This question may be helpful.Crowman– Crowman2016-09-09 22:57:00 +00:00Commented Sep 9, 2016 at 22:57
1 Answer
You can use Objective-C to create a bridging-header (usually named something like MyProject-Bridging-Header.h) that contains the function prototype. Bridging-headers allow Swift to access Objective-C (and by extension, C or assembly). They are well documented.
You can also use Swift's @_silgen_name attribute to achieve the same effect. However, this is not properly supported.
For example, given your assembly code:
.globl _add // ensure that the symbol can be found ... _add: // int add(int a, int b) movl %esi, %eax addl %edi, %eax ret You would put the prototype in a bridging-header (this is the recommended way to do it):
int add(int a, int b); Alternatively, you can do something like this at the top-level of your Swift module (however, this is unofficial, and is not future-proof):
@_silgen_name("add") func add(a: Int32, b: Int32) -> Int32 Either way, you can then invoke the function in Swift like any other function:
let a = add(1, 2); 8 Comments
swiftc -import-objc-header add.h app.swift add.o -o app where add.h contain the header, add.o is compiled assembly code.clang -S -mllvm --x86-asm-syntax=intel add.sg++ -c main.s. Can you try llvm-g++ -c main.s?