mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-18 21:06:50 +00:00
[ELF] Allow absolute relocation referencing symbol index 0 in PIC mode
The value of an absolute relocation, like R_RISCV_HI20 or R_PPC64_LO16, with a symbol index of 0, the resulting value should be treated as absolute and permitted in both -pie and -shared links. This change also resolves an absolute relocation referencing an undefined symbol in statically-linked executables. PPC64 has unfortunate exceptions: * R_PPC64_TOCBASE uses symbol index 0 but it should be treated as referencing the linker-defined .TOC. * R_PPC64_PCREL_OPT (https://reviews.llvm.org/D84360) could no longer rely on `isAbsoluteValue` return false.
This commit is contained in:
parent
1d4801f22a
commit
ba2de8f22d
@ -178,7 +178,7 @@ static RelType getMipsPairType(RelType type, bool isLocal) {
|
||||
// True if non-preemptable symbol always has the same value regardless of where
|
||||
// the DSO is loaded.
|
||||
static bool isAbsolute(const Symbol &sym) {
|
||||
if (sym.isUndefWeak())
|
||||
if (sym.isUndefined())
|
||||
return true;
|
||||
if (const auto *dr = dyn_cast<Defined>(&sym))
|
||||
return dr->section == nullptr; // Absolute symbol.
|
||||
@ -1005,7 +1005,7 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
|
||||
|
||||
// For the target and the relocation, we want to know if they are
|
||||
// absolute or relative.
|
||||
bool absVal = isAbsoluteValue(sym);
|
||||
bool absVal = isAbsoluteValue(sym) && e != RE_PPC64_TOCBASE;
|
||||
bool relE = isRelExpr(e);
|
||||
if (absVal && !relE)
|
||||
return true;
|
||||
@ -1021,7 +1021,7 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
|
||||
// calls to such symbols (e.g. glibc/stdlib/exit.c:__run_exit_handlers).
|
||||
// Normally such a call will be guarded with a comparison, which will load a
|
||||
// zero from the GOT.
|
||||
if (sym.isUndefWeak())
|
||||
if (sym.isUndefined())
|
||||
return true;
|
||||
|
||||
// We set the final symbols values for linker script defined symbols later.
|
||||
@ -1066,7 +1066,8 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
|
||||
type == R_HEX_GD_PLT_B22_PCREL_X ||
|
||||
type == R_HEX_GD_PLT_B32_PCREL_X)))
|
||||
expr = fromPlt(expr);
|
||||
} else if (!isAbsoluteValue(sym)) {
|
||||
} else if (!isAbsoluteValue(sym) ||
|
||||
(type == R_PPC64_PCREL_OPT && ctx.arg.emachine == EM_PPC64)) {
|
||||
expr = ctx.target->adjustGotPcExpr(type, addend,
|
||||
sec->content().data() + offset);
|
||||
// If the target adjusted the expression to R_RELAX_GOT_PC, we may end up
|
||||
|
@ -12,6 +12,8 @@
|
||||
|
||||
# CHECK: lui a0, 0x200
|
||||
# CHECK-NEXT: addi a0, a0, 0x1
|
||||
# CHECK-NEXT: lui a0, 0x200
|
||||
# CHECK-NEXT: addi a0, a0, 0x1
|
||||
# CHECK-NEXT: lw a0, 0x1(a0)
|
||||
# CHECK-NEXT: sw a0, 0x1(a0)
|
||||
|
||||
@ -23,6 +25,11 @@ abs = 0x200001
|
||||
_start:
|
||||
lui a0, %hi(abs)
|
||||
addi a0, a0, %lo(abs)
|
||||
.reloc ., R_RISCV_HI20, abs
|
||||
lui a0, 0
|
||||
.reloc ., R_RISCV_LO12_I, abs
|
||||
addi a0, a0, 0
|
||||
|
||||
lw a0, %lo(abs)(a0)
|
||||
sw a0, %lo(abs)(a0)
|
||||
|
||||
|
@ -29,10 +29,12 @@
|
||||
# RUN: ld.lld a.o b.o -o out1 -z undefs
|
||||
# RUN: llvm-readelf -r -x .data out1 | FileCheck %s --check-prefix=STATIC1
|
||||
# RUN: ld.lld a.o b.o -o out1.pie -pie -z undefs
|
||||
# RUN: llvm-readelf -r -x .data out1.pie | FileCheck %s --check-prefix=STATIC2
|
||||
# RUN: llvm-readelf -r -x .data out1.pie | FileCheck %s --check-prefix=STATIC1
|
||||
|
||||
# STATIC1: no relocations
|
||||
# STATIC2: R_X86_64_RELATIVE
|
||||
# STATIC1: Hex dump of section '.data':
|
||||
# STATIC1-NEXT: {{.*}} 00000000 00000000 00000000 00000000 .
|
||||
# STATIC1-EMPTY:
|
||||
|
||||
# RUN: ld.lld a.o b.o c.o -pie -z undefs 2>&1 | count 0
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user