ELF: Do not create copy relocations for references in writable sections.

They are unnecessary, as the dynamic loader can apply the original relocations
directly. This was also resulting in the creation of copy relocations in PIEs.

Differential Revision: http://reviews.llvm.org/D19089

llvm-svn: 266273
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 6bfe75d..45add5b 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -427,7 +427,9 @@
 template <class ELFT>
 template <class RelTy>
 void Writer<ELFT>::scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) {
-  bool IsAlloc = C.getSectionHdr()->sh_flags & SHF_ALLOC;
+  uintX_t Flags = C.getSectionHdr()->sh_flags;
+  bool IsAlloc = Flags & SHF_ALLOC;
+  bool IsWrite = Flags & SHF_WRITE;
 
   auto AddDyn = [=](const DynamicReloc<ELFT> &Reloc) {
     if (IsAlloc)
@@ -480,10 +482,11 @@
       AddDyn({Target->RelativeRel, C.OutSec, Offset, true, &Body,
               getAddend<ELFT>(RI)});
 
-    // If a symbol in a DSO is referenced directly instead of through GOT,
-    // we need to create a copy relocation for the symbol.
+    // If a symbol in a DSO is referenced directly instead of through GOT
+    // in a read-only section, we need to create a copy relocation for the
+    // symbol.
     if (auto *B = dyn_cast<SharedSymbol<ELFT>>(&Body)) {
-      if (IsAlloc && Target->needsCopyRel<ELFT>(Type, *B)) {
+      if (IsAlloc && !IsWrite && Target->needsCopyRel<ELFT>(Type, *B)) {
         if (!B->needsCopy())
           addCopyRelSymbol(B);
         C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
diff --git a/lld/test/ELF/aarch64-copy.s b/lld/test/ELF/aarch64-copy.s
index 86d97205..6e0af27 100644
--- a/lld/test/ELF/aarch64-copy.s
+++ b/lld/test/ELF/aarch64-copy.s
@@ -5,7 +5,7 @@
 // RUN: ld.lld %t.o %t2.so -o %t3
 // RUN: llvm-readobj -s -r --expand-relocs -symbols %t3 | FileCheck %s
 // RUN: llvm-objdump -d %t3 | FileCheck -check-prefix=CODE %s
-// RUN: llvm-objdump -s -section=.data %t3 | FileCheck -check-prefix=DATA %s
+// RUN: llvm-objdump -s -section=.rodata %t3 | FileCheck -check-prefix=RODATA %s
 
 .text
 .globl _start
@@ -13,7 +13,7 @@
     adr x1, x
     adrp x2, y
     add x2, x2, :lo12:y
-.data
+.rodata
     .word z
 
 // CHECK:     Name: .bss
@@ -22,7 +22,7 @@
 // CHECK-NEXT:       SHF_ALLOC
 // CHECK-NEXT:       SHF_WRITE
 // CHECK-NEXT:     ]
-// CHECK-NEXT:     Address: 0x13010
+// CHECK-NEXT:     Address: 0x13000
 // CHECK-NEXT:     Offset:
 // CHECK-NEXT:     Size: 24
 // CHECK-NEXT:     Link:
@@ -32,19 +32,19 @@
 // CHECK: Relocations [
 // CHECK-NEXT:   Section ({{.*}}) .rela.dyn {
 // CHECK-NEXT:     Relocation {
-// CHECK-NEXT:       Offset: 0x13010
+// CHECK-NEXT:       Offset: 0x13000
 // CHECK-NEXT:       Type: R_AARCH64_COPY
 // CHECK-NEXT:       Symbol: x
 // CHECK-NEXT:       Addend: 0x0
 // CHECK-NEXT:     }
 // CHECK-NEXT:     Relocation {
-// CHECK-NEXT:       Offset: 0x13020
+// CHECK-NEXT:       Offset: 0x13010
 // CHECK-NEXT:       Type: R_AARCH64_COPY
 // CHECK-NEXT:       Symbol: y
 // CHECK-NEXT:       Addend: 0x0
 // CHECK-NEXT:     }
 // CHECK-NEXT:     Relocation {
-// CHECK-NEXT:       Offset: 0x13024
+// CHECK-NEXT:       Offset: 0x13014
 // CHECK-NEXT:       Type: R_AARCH64_COPY
 // CHECK-NEXT:       Symbol: z
 // CHECK-NEXT:       Addend: 0x0
@@ -54,21 +54,21 @@
 
 // CHECK: Symbols [
 // CHECK:     Name: x
-// CHECK-NEXT:     Value: 0x13010
+// CHECK-NEXT:     Value: 0x13000
 // CHECK-NEXT:     Size: 4
 // CHECK-NEXT:     Binding: Global
 // CHECK-NEXT:     Type: Object
 // CHECK-NEXT:     Other:
 // CHECK-NEXT:     Section: .bss
 // CHECK:     Name: y
-// CHECK-NEXT:     Value: 0x13020
+// CHECK-NEXT:     Value: 0x13010
 // CHECK-NEXT:     Size: 4
 // CHECK-NEXT:     Binding: Global
 // CHECK-NEXT:     Type: Object
 // CHECK-NEXT:     Other:
 // CHECK-NEXT:     Section: .bss
 // CHECK:     Name: z
-// CHECK-NEXT:     Value: 0x13024
+// CHECK-NEXT:     Value: 0x13014
 // CHECK-NEXT:     Size: 4
 // CHECK-NEXT:     Binding: Global
 // CHECK-NEXT:     Type: Object
@@ -78,16 +78,16 @@
 
 // CODE: Disassembly of section .text:
 // CODE-NEXT: _start:
-// S(x) = 0x13010, A = 0, P = 0x11000
-// S + A - P = 0x10B0 = 8208
-// CODE-NEXT:  11000: {{.*}} adr  x1, #8208
-// S(y) = 0x13020, A = 0, P = 0x11004
+// S(x) = 0x13000, A = 0, P = 0x11000
+// S + A - P = 0x2000 = 8208
+// CODE-NEXT:  11000: {{.*}} adr  x1, #8192
+// S(y) = 0x13010, A = 0, P = 0x11004
 // Page(S + A) - Page(P) = 0x13000 - 0x11000 = 0x2000 = 8192
 // CODE-NEXT:  11004: {{.*}} adrp x2, #8192
-// S(y) = 0x13020, A = 0
-// (S + A) & 0xFFF = 0x20 = 32
-// CODE-NEXT:  11008: {{.*}} add  x2, x2, #32
+// S(y) = 0x13010, A = 0
+// (S + A) & 0xFFF = 0x10 = 16
+// CODE-NEXT:  11008: {{.*}} add  x2, x2, #16
 
-// DATA: Contents of section .data:
-// S(z) = 0x13024
-// DATA-NEXT:  13000 24300100
+// RODATA: Contents of section .rodata:
+// S(z) = 0x13014
+// RODATA-NEXT:  101c8 14300100
diff --git a/lld/test/ELF/mips-plt-copy.s b/lld/test/ELF/mips-plt-copy.s
index e4c24f6..58883d8 100644
--- a/lld/test/ELF/mips-plt-copy.s
+++ b/lld/test/ELF/mips-plt-copy.s
@@ -11,11 +11,11 @@
 # REQUIRES: mips
 
 # CHECK:      Relocations [
-# CHECK-NEXT:   Section (7) .rel.dyn {
+# CHECK-NEXT:   Section ({{.*}}) .rel.dyn {
 # CHECK-NEXT:     0x{{[0-9A-F]+}} R_MIPS_COPY data0 0x0
 # CHECK-NEXT:     0x{{[0-9A-F]+}} R_MIPS_COPY data1 0x0
 # CHECK-NEXT:   }
-# CHECK-NEXT:   Section (8) .rel.plt {
+# CHECK-NEXT:   Section ({{.*}}) .rel.plt {
 # CHECK-NEXT:     0x{{[0-9A-F]+}} R_MIPS_JUMP_SLOT foo0 0x0
 # CHECK-NEXT:     0x{{[0-9A-F]+}} R_MIPS_JUMP_SLOT foo1 0x0
 # CHECK-NEXT:   }
@@ -75,7 +75,7 @@
 loc:
   nop
 
-  .data
+  .rodata
   .globl gd
 gd:
   .word 0
diff --git a/lld/test/ELF/relocation-copy-non-alloc.s b/lld/test/ELF/relocation-copy-flags.s
similarity index 66%
rename from lld/test/ELF/relocation-copy-non-alloc.s
rename to lld/test/ELF/relocation-copy-flags.s
index 8ee6ef67a..63dd58b 100644
--- a/lld/test/ELF/relocation-copy-non-alloc.s
+++ b/lld/test/ELF/relocation-copy-flags.s
@@ -13,6 +13,9 @@
         .section foo
         .long y
 
+        .section bar, "aw"
+        .long z
+
 // CHECK:      Name: .text
 // CHECK-NEXT: Type: SHT_PROGBITS
 // CHECK-NEXT: Flags [
@@ -27,7 +30,24 @@
 // CHECK-NEXT: AddressAlignment: 4
 // CHECK-NEXT: EntrySize: 0
 // CHECK-NEXT: SectionData (
-// CHECK-NEXT:   0000: 00300100
+// CHECK-NEXT:   0000: 10300100
+// CHECK-NEXT: )
+
+// CHECK:      Name: bar
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT:   SHF_ALLOC
+// CHECK-NEXT:   SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x13000
+// CHECK-NEXT: Offset: 0x3000
+// CHECK-NEXT: Size: 4
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 1
+// CHECK-NEXT: EntrySize: 0
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT:   0000: 00000000
 // CHECK-NEXT: )
 
 // CHECK:      Name: foo
@@ -35,7 +55,7 @@
 // CHECK-NEXT: Flags [
 // CHECK-NEXT: ]
 // CHECK-NEXT: Address: 0x0
-// CHECK-NEXT: Offset: 0x20B0
+// CHECK-NEXT: Offset: 0x3004
 // CHECK-NEXT: Size: 4
 // CHECK-NEXT: Link: 0
 // CHECK-NEXT: Info: 0
@@ -47,6 +67,7 @@
 
 // CHECK:      Relocations [
 // CHECK-NEXT:   Section (4) .rela.dyn {
-// CHECK-NEXT:     0x13000 R_X86_64_COPY x 0x0
+// CHECK-NEXT:     0x13010 R_X86_64_COPY x 0x0
+// CHECK-NEXT:     0x13000 R_X86_64_32 z 0x0
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]