[lld] r343422 - [COFF] In MinGW mode, ignore relocations against a discarded section

Martin Storsjo via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 30 11:31:03 PDT 2018


Author: mstorsjo
Date: Sun Sep 30 11:31:03 2018
New Revision: 343422

URL: http://llvm.org/viewvc/llvm-project?rev=343422&view=rev
Log:
[COFF] In MinGW mode, ignore relocations against a discarded section

When GCC produces a jump table as part of a comdat function, the
jump table itself is produced as plain non-comdat rdata section. When
linked with ld.bfd, all of those rdata sections are kept, with
relocations unchanged in the sections that refer to discarded comdat
sections.

This has been observed with at least GCC 5.x and 7.x.

Differential Revision: https://reviews.llvm.org/D52600

Added:
    lld/trunk/test/COFF/Inputs/comdat-jumptable2.s
    lld/trunk/test/COFF/comdat-jumptable.s
Modified:
    lld/trunk/COFF/Chunks.cpp

Modified: lld/trunk/COFF/Chunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.cpp?rev=343422&r1=343421&r2=343422&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.cpp (original)
+++ lld/trunk/COFF/Chunks.cpp Sun Sep 30 11:31:03 2018
@@ -351,7 +351,12 @@ void SectionChunk::writeTo(uint8_t *Buf)
           check(File->getCOFFObj()->getSymbol(Rel.SymbolTableIndex));
       StringRef Name;
       File->getCOFFObj()->getSymbolName(Sym, Name);
-      error("relocation against symbol in discarded section: " + Name);
+
+      // MinGW mode object files (built by GCC) can have leftover sections
+      // with relocations against discarded comdat sections. Such sections
+      // are left as is, with relocations untouched.
+      if (!Config->MinGW)
+        error("relocation against symbol in discarded section: " + Name);
       continue;
     }
     // Get the output section of the symbol for this relocation.  The output

Added: lld/trunk/test/COFF/Inputs/comdat-jumptable2.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/Inputs/comdat-jumptable2.s?rev=343422&view=auto
==============================================================================
--- lld/trunk/test/COFF/Inputs/comdat-jumptable2.s (added)
+++ lld/trunk/test/COFF/Inputs/comdat-jumptable2.s Sun Sep 30 11:31:03 2018
@@ -0,0 +1,35 @@
+        .section .text at comdatfunc, "x"
+        .linkonce discard
+        .globl comdatfunc
+comdatfunc:
+        leaq .Ljumptable(%rip), %rax
+        movslq (%rax, %rcx, 4), %rcx
+        addq %rcx, %rax
+        jmp *%rax
+
+        .section .rdata, "dr"
+        .long 0xcccccccc
+.Ljumptable:
+        .long .Ltail1-.Ljumptable
+        .long .Ltail2-.Ljumptable
+        .long .Ltail3-.Ljumptable
+        .long 0xdddddddd
+
+        .section .text at comdatfunc, "x"
+# If assembled with binutils, the following line can be kept in:
+#       .linkonce discard
+.Ltail1:
+        movl $1, %eax
+        ret
+.Ltail2:
+        movl $2, %eax
+        ret
+.Ltail3:
+        movl $3, %eax
+        ret
+
+        .text
+        .globl otherfunc
+otherfunc:
+        call comdatfunc
+        ret

Added: lld/trunk/test/COFF/comdat-jumptable.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/comdat-jumptable.s?rev=343422&view=auto
==============================================================================
--- lld/trunk/test/COFF/comdat-jumptable.s (added)
+++ lld/trunk/test/COFF/comdat-jumptable.s Sun Sep 30 11:31:03 2018
@@ -0,0 +1,70 @@
+# REQUIRES: x86
+# RUN: llvm-mc -triple=x86_64-windows-gnu %s -filetype=obj -o %t1.obj
+# RUN: llvm-mc -triple=x86_64-windows-gnu %S/Inputs/comdat-jumptable2.s -filetype=obj -o %t2.obj
+
+# RUN: llvm-objdump -s %t1.obj | FileCheck --check-prefix=OBJ1 %s
+# RUN: llvm-objdump -s %t2.obj | FileCheck --check-prefix=OBJ2 %s
+
+# RUN: lld-link -lldmingw -entry:main %t1.obj %t2.obj -out:%t.exe
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=EXE %s
+
+# Test linking cases where comdat functions have an associated jump table
+# in a non-comdat rdata (which GCC produces for functions with jump tables).
+# In these cases, ld.bfd keeps all rdata sections, but the relocations that
+# refer to discarded comdat sections just are emitted as they were originally.
+
+# In real scenarios, the jump table .rdata section should be identical across
+# all object files; here it is different to illustrate more clearly what
+# the linker actually does.
+
+# OBJ1: Contents of section .rdata:
+# OBJ1:  0000 aaaaaaaa 14000000 1e000000 28000000
+# OBJ1:  0010 bbbbbbbb
+
+# OBJ2: Contents of section .rdata:
+# OBJ2:  0000 cccccccc 14000000 1e000000 28000000
+# OBJ2:  0010 dddddddd
+
+# EXE: Contents of section .rdata:
+# EXE:  140002000 aaaaaaaa 0c100000 12100000 18100000
+# EXE:  140002010 bbbbbbbb cccccccc 14000000 1e000000
+# EXE:  140002020 28000000 dddddddd
+
+
+        .section .text at comdatfunc, "x"
+        .linkonce discard
+        .globl comdatfunc
+comdatfunc:
+        leaq .Ljumptable(%rip), %rax
+        movslq (%rax, %rcx, 4), %rcx
+        addq %rcx, %rax
+        jmp *%rax
+
+        .section .rdata, "dr"
+        .long 0xaaaaaaaa
+.Ljumptable:
+        .long .Ltail1-.Ljumptable
+        .long .Ltail2-.Ljumptable
+        .long .Ltail3-.Ljumptable
+        .long 0xbbbbbbbb
+
+        .section .text at comdatfunc, "x"
+# If assembled with binutils, the following line can be kept in:
+#       .linkonce discard
+.Ltail1:
+        movl $1, %eax
+        ret
+.Ltail2:
+        movl $2, %eax
+        ret
+.Ltail3:
+        movl $3, %eax
+        ret
+
+
+        .text
+        .globl main
+main:
+        call comdatfunc
+        call otherfunc
+        ret




More information about the llvm-commits mailing list