forked from OSchip/llvm-project
[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
This commit is contained in:
parent
2b8fb5185e
commit
9267caebfa
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue