MIPS asm backend emitting weird symbols into object file?

I'm cross-compiling for MIPS. The test-case is as simple as it can be:

void foo() {}

$clang -target mips64-octeon-linux -c -B
path/to/cross/compiled/mips/assembler a.c

And then I look at the object file:

$ nm a.o
0000000000000020 t $tmp0
0000000000000000 T foo

I would like to know what "$tmp0" is. Furthermore, if I pass -g to
clang, I see a whole bunch of such symbols. Some of them appear to be
MIPS specific DWARF extensions. But the ones I'm not able to figure
out are the $tmp* symbols:

# nm a.o
0000000000000000 N $.debug_info_begin0
0000000000000000 N $debug_cmdline
0000000000000020 t $debug_end0
0000000000000000 N $debug_range
0000000000000000 t $func_begin0
0000000000000020 t $func_end0
0000000000000000 N $info_string
0000000000000000 N $info_string0
00000000000000a7 N $info_string1
00000000000000ab N $info_string2
00000000000000cf N $info_string3
0000000000000000 N $line_table_start0
0000000000000004 N $pubNames_begin0
000000000000001a N $pubNames_end0
0000000000000000 N $section_abbrev
0000000000000000 N $section_debug_loc
0000000000000000 N $section_info
0000000000000000 N $section_line
0000000000000004 t $tmp0
0000000000000008 t $tmp1
000000000000000c t $tmp2
0000000000000020 t $tmp3
0000000000000020 t $tmp4
0000000000000000 T foo

These symbols are not from the IR. They seem to be inserted by the
MIPS asm back-end.

I wouldn't be worried if these are MIPS specific temporary structures
to hold debug/dwarf info and such, but the reason I started to look
into this is that some of the symbols are appearing in the debugger
backtrace (I'm using gdb 7.9) of a mips binary.

Any suggestions on where to start looking or what they might be?

Thanks,
Sandeep

Hi,

Could you attach the assembly output produced by adding -save-temps to your command?

I encountered a similar issue over the weekend so I think I might know what the problem is. The current pc symbol '.' is implemented by dropping a private label (currently named $tmp*) and referencing that. Private labels aren't supposed to appear in the object output for the N32/N64. They currently appear because the private label naming convention is ABI dependant and LLVM doesn't know this yet. It turns out that on O32, private labels begin with '$' but on N32/N64 they begin with '.L'. I'll have a patch for this shortly.

I've uploaded a patch at http://reviews.llvm.org/D9821. It's not completely correct since it's using the target triple instead of the ABI but it resolves the immediate problems.

Thanks Daniel for the explanation & the quick workaround. I've tested
the patch and it works fine.

The following testcases may need to be updated though:

    LLVM :: CodeGen/Mips/analyzebranch.ll
    LLVM :: CodeGen/Mips/atomic.ll
    LLVM :: CodeGen/Mips/blez_bgez.ll
    LLVM :: CodeGen/Mips/blockaddr.ll
    LLVM :: CodeGen/Mips/fpbr.ll
    LLVM :: CodeGen/Mips/llvm-ir/ashr.ll
    LLVM :: CodeGen/Mips/llvm-ir/indirectbr.ll
    LLVM :: CodeGen/Mips/llvm-ir/lshr.ll
    LLVM :: CodeGen/Mips/llvm-ir/select.ll
    LLVM :: CodeGen/Mips/llvm-ir/shl.ll
    LLVM :: CodeGen/Mips/longbranch.ll
    LLVM :: CodeGen/Mips/octeon.ll
    LLVM :: MC/Mips/cpsetup.s
    LLVM :: MC/Mips/mips3/valid.s
    LLVM :: MC/Mips/mips4/valid.s
    LLVM :: MC/Mips/mips5/valid.s
    LLVM :: MC/Mips/mips64/valid.s
    LLVM :: MC/Mips/mips64r2/valid.s
    LLVM :: MC/Mips/mips64r3/valid.s
    LLVM :: MC/Mips/mips64r5/valid.s

Could you please subscribe me to the "full/correct" fix, whenever that
comes around?

Thanks,
Sandeep