windowsassemblygccclangllvm

"junk at end of line" when assembling .s file compiled from C++ file using Clang and LLVM, but works with C file


I am learning how to use the LLVM toolchain. I have a .cpp file, and I'm trying to compile it to an LLVM bitcode file, compile the LLVM bytecode file into an assembly file, and then assemble the assembly file into a program.

Here is the .cpp file,

#include <iostream>

int main() {
    std::cout << "Hello, world!\n";
}

And here is what I am typing into the command line (taken from LLVM docs),

# Compile the C file into an LLVM bitcode file
clang -O3 -emit-llvm hello.cpp -c -o hello.bc

# Compile the program to native assembly using the LLC code generator
llc hello.bc -o hello.s

# Assemble the native assembly language file into a program
gcc hello.s -o hello.native

However, on the last step to assemble the native assembly language file into a program, I encounter this error:

hello.s: Assembler messages:
hello.s:72: Error: junk at end of line, first unrecognized character is `,'

Here is part of the hello.s file,

.L.str:                                 # @.str
    .asciz  "Hello world!\n"

    .section    .ctors,"dw"
    .p2align    3
    .quad   _GLOBAL__sub_I_hello.cpp
    .section    .rdata$.refptr._ZSt4cout,"dr",discard,.refptr._ZSt4cout
    .p2align    3
    .globl  .refptr._ZSt4cout

Line 72 corresponds to this line,

.section    .rdata$.refptr._ZSt4cout,"dr",discard,.refptr._ZSt4cout

If I follow the same steps above but with a .c file, the last step works and is able to produce a hello.native file.

I am wondering why do the above steps not work with a .cpp file, and what I have to do differently for .cpp files?


Solution

  • For cpp its a very small change. I use clang-17 here and some flags are needed to make this work - see that I explicitly used the cpp counterparts - clang++ and g++

    $ clang++-17 -c hello.cpp -fPIE -emit-llvm -o hello.bc
    $ llc-17 --relocation-model=pic hello.bc -o hello.s
    $ g++ hello.s -o hello.native
    $ ./hello.native
    Hello, world!
    

    The compiler versions are

    $ g++ --version
    g++ (Ubuntu 13.2.0-4ubuntu3) 13.2.0
    Copyright (C) 2023 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    $ clang++-17 --version
    Ubuntu clang version 17.0.2 (1~exp1ubuntu2.1)
    Target: x86_64-pc-linux-gnu
    Thread model: posix
    InstalledDir: /usr/bin