8

I am currently using llc to convert a .ll file to a .s using the commandline. Then I want to take this file and then use nasm to create an executable from it. While the first step seems to work fine, I can't get the second step to work.


the original file is called code.ll and contains the following code:

define i32 @main() {
    ret i32 0
}

now I use the cmd to build the .s file by typing:

llc code.ll

this works fine and creates a code.s file containing the following code:

    .def     @feat.00;
    .scl    3;
    .type   0;
    .endef
    .globl  @feat.00
@feat.00 = 1
    .def     _main;
    .scl    2;
    .type   32;
    .endef
    .text
    .globl  _main
    .align  16, 0x90
_main:                                  # @main
# BB#0:
    xorl    %eax, %eax
    ret

Now I want to create an executable using this code, about which the llc doc tells me this:

The assembly language output can then be passed through a native assembler and linker to generate a native executable.

So I use nasm (which should do what I want as far as I understand) by typing:

nasm code.s

which produces the following list of errors:

code.s:1: error: attempt to define a local label before any non-local labels
code.s:1: error: parser: instruction expected
code.s:2: error: attempt to define a local label before any non-local labels
code.s:2: error: parser: instruction expected
code.s:3: error: attempt to define a local label before any non-local labels
code.s:3: error: parser: instruction expected
code.s:4: error: attempt to define a local label before any non-local labels
code.s:5: error: attempt to define a local label before any non-local labels
code.s:5: error: parser: instruction expected
code.s:6: error: parser: instruction expected
code.s:7: error: parser: instruction expected
code.s:8: error: parser: instruction expected
code.s:9: error: parser: instruction expected
code.s:12: error: parser: instruction expected
code.s:13: error: parser: instruction expected
code.s:14: error: parser: instruction expected
BB#0::1: error: parser: instruction expected
BB#0::2: error: parser: instruction expected
BB#0::3: error: parser: instruction expected
BB#0::4: error: parser: instruction expected
BB#0::5: error: parser: instruction expected
BB#0::8: error: parser: instruction expected
BB#0::9: error: parser: instruction expected
BB#0::10: error: parser: instruction expected

As my experience concerning LLVM or assembler is close to zero I were unable to solve this myself.

In case I have left out something important just tell me and I will edit my answer as fast as possible.

lncr
  • 826
  • 8
  • 16
  • The generated code is in AT&T syntax and NASM won't understand it. You'd have to use GNU assembler (`as`) to assemble that `.s` file or any assembler capable of understanding AT&T syntax. – Michael Petch Aug 31 '17 at 17:07
  • @Michael Petch Ok, while I can't test it atm it definitely sounds like this is is what I needed. Would you mind to write a answer so I can accept it. In case you don't have the time for it I will just write a self answer in a few days, which would pretty much just reiterate your answer with a short explaination of what AT&T syntax is and what syntax is is used by NASM. Thanks – lncr Aug 31 '17 at 17:16
  • Please be my guest and self answer when you think you have resolved it. – Michael Petch Aug 31 '17 at 17:16
  • 4
    LLVM has it's own assembler you should be able to use or better yet `llc` can generate an object file directly without having to invoke a "native assembler" at all.You'd just need to use a native linker on the object file to create a native executable. – Ross Ridge Aug 31 '17 at 18:09
  • @MichaelPetch - To produce intel assembly syntax use `llc -x86-asm-syntax=intel filename.ll` ***but*** it is still not 100% `nasm` compatible. I just use `clang` at that point to compile/link to executable. – Frank C. Sep 01 '17 at 10:40

1 Answers1

4

Thanks to the comments of @Michael Petch and @Ross Ridge I finally understood why this does not work and found a working alternative.


The cause of the problem

There are different kinds of assembler language, which vary in syntax and are not directly compatible. As nasm is expecting another assembly language than llc is producing, it obviously does not work, which explains the long list of errors.

How to do it instead

Considering that llc has AT&T assembler as output, which was created for the GNU toolchain, the most obvious step would be to use GCC to create the executable after building the code.s file with llc.

To install GCC I downloaded MinGW, installed it and called

mingw-get install gcc

now I can access GCC which can be used to create code.exe by calling

gcc code.s -o code.exe

gcc [filename] -o [name of the created executable]


As this solution is probably more complicated than it needs to be I would be glad to see some alternatives/ improvements.

Community
  • 1
  • 1
lncr
  • 826
  • 8
  • 16
  • 2
    If you have `llvm` don't you already have `clang`? That would save you adding YATC (yet another tool chain). – Frank C. Sep 01 '17 at 15:11
  • Frank is right. `clang` already has an assembler built-in, or can use `as` from binutils. You don't need gcc to build `.s` files if you already have `clang`. – Peter Cordes Sep 02 '17 at 00:30
  • @Frank C. As far as I know, I do not have clang/I would need to download it. But as long as my way of doing I this way works I do not want to spend a rather large amount of time learning how to do it another way, even if my way is more complicated – lncr Sep 02 '17 at 15:45