[ELF] Don't error on R_PPC64_REL24/R_PPC64_REL24_NOTOC referencing __tls_get_addr...
authorFangrui Song <i@maskray.me>
Fri, 23 Oct 2020 17:37:24 +0000 (10:37 -0700)
committerFangrui Song <i@maskray.me>
Fri, 23 Oct 2020 17:38:07 +0000 (10:38 -0700)
This partially reverts D85994.

In glibc, elf/dl-sym.c calls the raw `__tls_get_addr` by specifying the
tls_index parameter. Such a call does not have a pairing R_PPC64_TLSGD/R_PPC64_TLSLD.
This is legitimate. Since we cannot distinguish the benign case from cases due
to toolchain issues, we have to be permissive.

Acked by Stefan Pintilie

lld/ELF/Relocations.cpp
lld/test/ELF/ppc64-tls-missing-gdld.s

index 499b1b6..3a97715 100644 (file)
@@ -1319,28 +1319,6 @@ static void scanReloc(InputSectionBase &sec, OffsetGetter &getOffset, RelTy *&i,
   int64_t addend = computeAddend<ELFT>(rel, end, sec, expr, sym.isLocal());
 
   if (config->emachine == EM_PPC64) {
-    // For a call to __tls_get_addr, the instruction needs to be relocated by
-    // two relocations, R_PPC64_TLSGD/R_PPC64_TLSLD and R_PPC64_REL24[_NOTOC].
-    // R_PPC64_TLSGD/R_PPC64_TLSLD should precede R_PPC64_REL24[_NOTOC].
-    if ((type == R_PPC64_REL24 || type == R_PPC64_REL24_NOTOC) &&
-        sym.getName() == "__tls_get_addr") {
-      bool err = i - start < 2;
-      if (!err) {
-        // Subtract 2 to get the previous iterator because we have already done
-        // ++i above. This is now safe because we know that i-1 is not the
-        // start.
-        const RelTy &prevRel = *(i - 2);
-        RelType prevType = prevRel.getType(config->isMips64EL);
-        err = prevRel.r_offset != rel.r_offset ||
-              (prevType != R_PPC64_TLSGD && prevType != R_PPC64_TLSLD);
-      }
-
-      if (err)
-        errorOrWarn("call to __tls_get_addr is missing a "
-                    "R_PPC64_TLSGD/R_PPC64_TLSLD relocation" +
-                    getLocation(sec, sym, offset));
-    }
-
     // We can separate the small code model relocations into 2 categories:
     // 1) Those that access the compiler generated .toc sections.
     // 2) Those that access the linker allocated got entries.
index e9a0a4f..fcc1a2c 100644 (file)
@@ -1,28 +1,12 @@
 # REQUIRES: ppc
 # RUN: llvm-mc --triple=powerpc64le %s --filetype=obj -o %t1.o
 # RUN: llvm-mc --triple=powerpc64 %s --filetype=obj -o %t2.o
-# RUN: not ld.lld --shared %t1.o -o /dev/null 2>&1 | FileCheck %s
-# RUN: not ld.lld --shared %t2.o -o /dev/null 2>&1 | FileCheck %s
+# RUN: ld.lld --shared --fatal-warnings %t1.o -o /dev/null
+# RUN: ld.lld --shared --fatal-warnings %t2.o -o /dev/null
 
-# CHECK:      ld.lld: error: call to __tls_get_addr is missing a R_PPC64_TLSGD/R_PPC64_TLSLD relocation
-# CHECK-NEXT:   defined in {{.*}}.o
-# CHECK-NEXT:   referenced by {{.*}}.o:(.text+0x8)
-
-# CHECK:      ld.lld: error: call to __tls_get_addr is missing a R_PPC64_TLSGD/R_PPC64_TLSLD relocation
-# CHECK-NEXT:   defined in {{.*}}.o
-# CHECK-NEXT:   referenced by {{.*}}.o:(.text+0x18)
-
-# CHECK:      ld.lld: error: call to __tls_get_addr is missing a R_PPC64_TLSGD/R_PPC64_TLSLD relocation
-# CHECK-NEXT:   defined in {{.*}}.o
-# CHECK-NEXT:   referenced by {{.*}}.o:(.text+0x28)
-
-# CHECK:      ld.lld: error: call to __tls_get_addr is missing a R_PPC64_TLSGD/R_PPC64_TLSLD relocation
-# CHECK-NEXT:   defined in {{.*}}.o
-# CHECK-NEXT:   referenced by {{.*}}.o:(.text+0x38)
-
-# CHECK:      ld.lld: error: call to __tls_get_addr is missing a R_PPC64_TLSGD/R_PPC64_TLSLD relocation
-# CHECK-NEXT:   defined in {{.*}}.o
-# CHECK-NEXT:   referenced by {{.*}}.o:(.text+0x40)
+## User code can call __tls_get_addr by specifying the tls_index parameter.
+## We need to allow R_PPC64_REL24/R_PPC64_REL24_NOTOC referencing __tls_get_addr
+## without a pairing R_PPC64_TLSGD/R_PPC64_TLSLD.
 
 GeneralDynamic:
   addis 3, 2, x@got@tlsgd@ha