[lld] 9267cae - [ELF] Don't error on R_PPC64_REL24/R_PPC64_REL24_NOTOC referencing __tls_get_addr for missing R_PPC64_TLSGD/R_PPC64_TLSLD

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 23 10:38:14 PDT 2020


Author: Fangrui Song
Date: 2020-10-23T10:38:07-07:00
New Revision: 9267caebfa9209e4ae69517043d008d1b83307aa

URL: https://github.com/llvm/llvm-project/commit/9267caebfa9209e4ae69517043d008d1b83307aa
DIFF: https://github.com/llvm/llvm-project/commit/9267caebfa9209e4ae69517043d008d1b83307aa.diff

LOG: [ELF] Don't error on R_PPC64_REL24/R_PPC64_REL24_NOTOC referencing __tls_get_addr for missing R_PPC64_TLSGD/R_PPC64_TLSLD

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

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 499b1b6f0a66..3a9771523713 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -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.

diff  --git a/lld/test/ELF/ppc64-tls-missing-gdld.s b/lld/test/ELF/ppc64-tls-missing-gdld.s
index e9a0a4f3cf3d..fcc1a2c21a25 100644
--- a/lld/test/ELF/ppc64-tls-missing-gdld.s
+++ b/lld/test/ELF/ppc64-tls-missing-gdld.s
@@ -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 at got@tlsgd at ha


        


More information about the llvm-commits mailing list