llc tool followed by g++ : Abnormal behavior while compiling assembly to object file


I am executing following steps to convert assembly to object code.

llc -march=x86-64 -filetype=asm input.ll -o input.s

g++ -g -c -o input.s --input.o


ll → llc → .s -->g++ -->obj

original source was something like this


printf(" **** %s ****",str);

input.s turn out to be

movq .str@GOTPCREL(%rip),%rdi

movq .str.1@GOTPCREL(%rip),%rsi

xorl %eax,%eax

movq %rdi,%r14

callq printf@PLT

While at Runtime

mov 0x0(%rip),%rdi

mov 0x0(%rip),%rsi

xor %eax,%eax

mov %rdi,%r14

callq printf@PLT

Not really sure what happened here?

I was expecting at runtime offset for str and str.1 to be different.

I could really use some help to determine if this is bug?

Hi Mahesh,

movq .str@GOTPCREL(%rip),%rdi
movq .str.1@GOTPCREL(%rip),%rsi

That's quite strange. You wouldn't normally expect to access a
constant string via the GOT. It looks like LLVM has decided to put the
symbols in an odd section, so it'd be a good idea to make sure your
entire triple matches GCC (e.g. -mtriple=x86_64-linux-gnu or
x86_64-apple-macosx or whatever).

mov 0x0(%rip),%rdi
mov 0x0(%rip),%rsi

Is this really at runtime, or are you inspecting the .o file? If it's
the .o file this is pretty normal. GCC will have recorded a bunch of
relocations in a different place, telling the linker how to fix these
accesses up so they really do end up pointing to different strings.
"objdump -rd" would print them alongside the disassembly.

If it's at runtime, you still want to look at the object file to find
out whether it's GCC or your linker that's made the mistake (or LLVM,
of course; maybe it's not just me that was surprised by the llc
output, but GCC couldn't cope either).




Runtime Output i pasted was from gdb asm layout, which appears exactly same as what you mentioned,with objdump -rd

I have done
readelf -x .rodata objfile

neither of strings str or str1 appear in output, so that does confirm strings are not in data section.

My triple however looks something like this X86_64-unknown-linux-gnu. which is okay,i guess?

I have created objfile from llc directly (so no g++), same behavior.

could it be issue with llvm ir ?

IR declarations are

$.str = comdat any
$.str.1 = comdat any
@.str = linkonce_odr unnamed_addr addrspace(2) constant [7 x i8] c"OhNo!\0A\00", comdat, align 64
@.str.1 = linkonce_odr unnamed_addr constant [21 x i8] c"**** extent ****\0A\00", comdat, align 1