[LLVMbugs] [Bug 8656] New: MC miscompiles CALL to absolute address on X86-32 ELF

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Sat Nov 20 14:18:08 PST 2010


http://llvm.org/bugs/show_bug.cgi?id=8656

           Summary: MC miscompiles CALL to absolute address on X86-32 ELF
           Product: tools
           Version: trunk
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: llc
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: pdox at google.com
                CC: llvmbugs at cs.uiuc.edu


----REPRODUCING THE PROBLEM----

Download test.c and run:

llvm-gcc -emit-llvm -S test.c -o test.ll
llc -march=x86 -mcpu=pentium4 -mtriple="i686-none-linux-gnu"  -filetype=asm
test.ll -o test.s
llvm-mc -assemble -filetype=obj -arch=i686 -triple=i686-none-linux-gnu test.s
-o test.o

You will get an assertion or segmentation fault.

Alternatively, use direct object emission:

llc -march=x86 -mcpu=pentium4 -mtriple="i686-none-linux-gnu"  -filetype=obj
test.ll -o test.o

The command will succeed, but if you examine test.o (e.g. with objdump) you
will find that the generated call is incorrect.

----EXPLANATION----

In C code, we can generate a call to an absolute address. For example:

    // Call function at 0x1000
    ((void(*)())0x1000)();

This is useful for low-level system programming.  The above compiles to
bitcode:

    call void (...)* inttoptr (i64 4096 to void (...)*)() nounwind

Running llc for X86-32 ELF with assembly output emits:

    calll 4096

Note that the IA-32 instruction set does not actually have a form of the call
instruction that can call an absolute address. When using ELF, however, the
above operation can be emitted as a 32-bit PC-relative call with a relocation
which computes the value 4096 - PC.

For example, with binutils gas, "calll 4096" is correctly assembled to:

      13:    e8 fc 0f 00 00              call   1014 <main+0x1014>

With relocation:

    00000014 R_386_PC32        *ABS*


However, with llvm-mc, "calll 4096" generates an assertion or segmentation
fault in ELFObjectWriter::IsFixupFullyResolved. This function does not expect a
PC-relative Fixup that has no symbols. It tries to dereference getSymA() which
is NULL.

Something different but also wrong happens when you use direct object emission
(llc -filetype=obj).

In this case, the assembling happens successfully, but the resulting object
file contains: 

  13:    e8 00 10 00 00           call   1018 <main+0x1018>

With no relocation, which means it will actually call PC+4096, instead of
absolute address 4096.

-- 
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.



More information about the llvm-bugs mailing list