[llvm-dev] lld mishandling R_X86_64_PC32 relocations

Stephen Checkoway via llvm-dev llvm-dev at lists.llvm.org
Tue Jun 5 10:33:37 PDT 2018


Hi,

I've tracked down what I believe is a bug in lld's relocation processing for R_X86_64_PC32 REL relocations.

I'm producing the object file in a slightly unusual way: I'm using objcopy on a relocatable i386 ELF object file to convert it to x86_64 which transforms a R_386_PC32 into a R_X86_64_PC32.

Steps to reproduce:

1. Assemble the attached bug.asm using nasm and note the R_386_PC32 REL.

$ nasm -felf32 -o bug.o bug.asm
$ x86_64-elf-objdump -dr bug.o | grep -A1 -e '<_start>:'
00000000 <_start>:
   0:	e8 fc ff ff ff       	call   1 <_start+0x1>
$ x86_64-elf-readelf -r bug.o

Relocation section '.rel.text._start' at offset 0x260 contains 1 entry:
 Offset     Info    Type            Sym.Value  Sym. Name
00000001  00000302 R_386_PC32        00000000   .text.foo

2. Convert bug.o to a 64-bit ELF object file and note the R_X86_64_PC32 REL (not RELA!)

$ x86_64-elf-objcopy -I elf32-i386 -O elf64-x86-64 bug.o bug-64.o
$ x86_64-elf-objdump -M i386 -dr bug-64.o | grep -A1 -e '<_start>:'
0000000000000000 <_start>:
   0:	e8 fc ff ff ff       	call   1 <_start+0x1>
$ x86_64-elf-readelf -r bug-64.o

Relocation section '.rel.text._start' at offset 0x128 contains 1 entry:
  Offset          Info           Type           Sym. Value    Sym. Name
000000000001  000300000002 R_X86_64_PC32     0000000000000000 .text.foo

3. Link with a just-built ld.lld and note that the relocation has been misapplied. It's now calling foo+4 rather than foo.

$ ./llvm-build/bin/ld.lld -melf_x86_64 -o bug-lld bug-64.o
$ x86_64-elf-objdump -M i386 -d bug-64-lld | grep -A1 -e '<_start>:'
0000000000201000 <_start>:
  201000:	e8 0f 00 00 00       	call   201014 <foo+0x4>

If you link with GNU ld instead, the relocation is applied correctly.

$ x86_64-elf-ld -melf_x86_64 -o bug-64-ld bug-64.o
$ x86_64-elf-objdump -M i386 -d bug-64-ld | grep -A1 -e '<_start>:'
0000000000400080 <_start>:
  400080:	e8 0b 00 00 00       	call   400090 <foo>

Linking the 32-bit object file works correctly with both GNU ld and ld.lld.

$ ./llvm-build/bin/ld.lld -melf_i386 -o bug-lld bug.o
$ x86_64-elf-objdump -d bug-lld | grep -A1 -e '<_start>:'
00011000 <_start>:
   11000:	e8 0b 00 00 00       	call   11010 <foo>
$ x86_64-elf-ld -melf_i386 -o bug-ld bug.o
$ x86_64-elf-objdump -d bug-ld | grep -A1 -e '<_start>:'
08048060 <_start>:
 8048060:	e8 0b 00 00 00       	call   8048070 <foo>

I'm not at all familiar with the lld source, but this looks a lot like getImplicitAddend() needs to be implemented for the X86_64 class.

Alternatively (but much less useful for me) would be an error message that REL relocations are not supported on x86-64.

I've attached all of the files created above, in case anyone wants to examine them.

Thank you,

Steve

-- 
Stephen Checkoway

-------------- next part --------------
A non-text attachment was scrubbed...
Name: bug-64-ld
Type: application/octet-stream
Size: 848 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180605/127dc029/attachment-0005.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bug-64-lld
Type: application/octet-stream
Size: 8816 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180605/127dc029/attachment-0006.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bug-64.o
Type: application/octet-stream
Size: 816 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180605/127dc029/attachment-0002.o>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bug-ld
Type: application/octet-stream
Size: 604 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180605/127dc029/attachment-0007.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bug-lld
Type: application/octet-stream
Size: 8624 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180605/127dc029/attachment-0008.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bug.asm
Type: application/octet-stream
Size: 229 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180605/127dc029/attachment-0009.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bug.o
Type: application/octet-stream
Size: 624 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180605/127dc029/attachment-0003.o>
-------------- next part --------------



More information about the llvm-dev mailing list