Stephen Checkoway via llvm-dev
2018-Jun-05 17:33 UTC
[llvm-dev] lld mishandling R_X86_64_PC32 relocations
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 --------------
Peter Collingbourne via llvm-dev
2018-Jun-05 19:34 UTC
[llvm-dev] lld mishandling R_X86_64_PC32 relocations
Hi Stephen, I think the bug is in objcopy, as it is creating a file that does not comply with the x86-64 psABI, which requires all relocations to be RELA: https://github.com/hjl-tools/x86-psABI/blob/hjl/master/object-files.tex#L429 I also tried passing your bug-64.o to ld.gold, and it rejects it with an internal error. $ ld.gold -r -o bug-64-2.o bug-64.o ld.gold: internal error in scan_relocatable_relocs, at ../../gold/x86_64.cc:5118 $ ld.gold -o bug-64-2.o bug-64.o ld.gold: error: bug-64.o: unsupported REL reloc section ld.gold: internal error in relocate_section, at ../../gold/x86_64.cc:5051 Probably what needs to happen is that we need to start rejecting files which use the wrong relocation type and a bug needs to be filed against objcopy. Peter On Tue, Jun 5, 2018 at 10:33 AM, Stephen Checkoway via llvm-dev < llvm-dev at lists.llvm.org> wrote:> 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 > > > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > >-- -- Peter -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180605/bc3e4260/attachment.html>
Stephen Checkoway via llvm-dev
2018-Jun-05 20:50 UTC
[llvm-dev] lld mishandling R_X86_64_PC32 relocations
Hi Peter, I hadn't noticed that line about RELA in the ABI document, thanks! I agree that this is a bug in objcopy. I'll file a bug against objcopy. It seems that lld already supports relocations that don't comply with the standard (namely R_X86_64_16 and R_X86_64_8 <https://github.com/hjl-tools/x86-psABI/blob/hjl/master/object-files.tex#L554>), but I guess that's different than supporting an entirely different format. Thanks for looking into this. Steve> On Jun 5, 2018, at 14:34, Peter Collingbourne via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > Hi Stephen, > > I think the bug is in objcopy, as it is creating a file that does not comply with the x86-64 psABI, which requires all relocations to be RELA: > https://github.com/hjl-tools/x86-psABI/blob/hjl/master/object-files.tex#L429 > I also tried passing your bug-64.o to ld.gold, and it rejects it with an internal error. > > $ ld.gold -r -o bug-64-2.o bug-64.o > ld.gold: internal error in scan_relocatable_relocs, at ../../gold/x86_64.cc:5118 > $ ld.gold -o bug-64-2.o bug-64.o > ld.gold: error: bug-64.o: unsupported REL reloc section > ld.gold: internal error in relocate_section, at ../../gold/x86_64.cc:5051 > > Probably what needs to happen is that we need to start rejecting files which use the wrong relocation type and a bug needs to be filed against objcopy. > > Peter > > On Tue, Jun 5, 2018 at 10:33 AM, Stephen Checkoway via llvm-dev <llvm-dev at lists.llvm.org> wrote: > 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 > > > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > > > > > -- > -- > Peter > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-- Stephen Checkoway
Seemingly Similar Threads
- xen debugger (kdb/xdb/hdb) patch for c/s 25467
- [RFC][LLVM] New Constant type for representing function PLT entries
- [LLVMdev] Assertion fails resolving R_X86_64_PC32 relocation
- [LLVMdev] Assertion fails resolving R_X86_64_PC32 relocation
- [LLVMdev] python: Symbol `__gxx_personality_v0' causes overflow in R_X86_64_PC32 relocation