mirror of
https://github.com/rui314/mold.git
synced 2024-11-10 10:57:55 +03:00
[ELF] Do not create a PLT entry for IFUNC if -fno-plt
This commit is contained in:
parent
424f43772a
commit
1709ad5996
@ -434,7 +434,7 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
|
||||
}
|
||||
|
||||
if (sym.is_ifunc())
|
||||
sym.flags |= (NEEDS_GOT | NEEDS_PLT);
|
||||
sym.flags |= NEEDS_GOT;
|
||||
|
||||
switch (rel.r_type) {
|
||||
case R_ARM_ABS32:
|
||||
@ -447,7 +447,7 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
|
||||
case R_ARM_CALL:
|
||||
case R_ARM_JUMP24:
|
||||
case R_ARM_THM_JUMP24:
|
||||
if (sym.is_imported)
|
||||
if (sym.is_imported || sym.is_ifunc())
|
||||
sym.flags |= NEEDS_PLT;
|
||||
break;
|
||||
case R_ARM_GOT_PREL:
|
||||
|
@ -430,7 +430,7 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
|
||||
}
|
||||
|
||||
if (sym.is_ifunc())
|
||||
sym.flags |= (NEEDS_GOT | NEEDS_PLT);
|
||||
sym.flags |= NEEDS_GOT;
|
||||
|
||||
switch (rel.r_type) {
|
||||
case R_AARCH64_ABS64:
|
||||
@ -443,7 +443,7 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
|
||||
break;
|
||||
case R_AARCH64_CALL26:
|
||||
case R_AARCH64_JUMP26:
|
||||
if (sym.is_imported)
|
||||
if (sym.is_imported || sym.is_ifunc())
|
||||
sym.flags |= NEEDS_PLT;
|
||||
break;
|
||||
case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
|
||||
|
@ -441,7 +441,7 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
|
||||
}
|
||||
|
||||
if (sym.is_ifunc())
|
||||
sym.flags |= (NEEDS_GOT | NEEDS_PLT);
|
||||
sym.flags |= NEEDS_GOT;
|
||||
|
||||
switch (rel.r_type) {
|
||||
case R_386_8:
|
||||
@ -462,7 +462,7 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
|
||||
sym.flags |= NEEDS_GOT;
|
||||
break;
|
||||
case R_386_PLT32:
|
||||
if (sym.is_imported)
|
||||
if (sym.is_imported || sym.is_ifunc())
|
||||
sym.flags |= NEEDS_PLT;
|
||||
break;
|
||||
case R_386_TLS_GOTIE:
|
||||
|
@ -241,6 +241,18 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
|
||||
case R_PPC64_REL16_LO:
|
||||
*(ul16 *)loc = S + A - P;
|
||||
break;
|
||||
case R_PPC64_PLT16_HA:
|
||||
*(ul16 *)loc = ha(G + GOT - ctx.TOC->value);
|
||||
break;
|
||||
case R_PPC64_PLT16_HI:
|
||||
*(ul16 *)loc = hi(G + GOT - ctx.TOC->value);
|
||||
break;
|
||||
case R_PPC64_PLT16_LO:
|
||||
*(ul16 *)loc = lo(G + GOT - ctx.TOC->value);
|
||||
break;
|
||||
case R_PPC64_PLT16_LO_DS:
|
||||
*(ul16 *)loc |= (G + GOT - ctx.TOC->value) & 0xfffc;
|
||||
break;
|
||||
case R_PPC64_GOT_TPREL16_HA:
|
||||
*(ul16 *)loc = ha(sym.get_gottp_addr(ctx) - ctx.TOC->value);
|
||||
break;
|
||||
@ -267,6 +279,8 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
|
||||
case R_PPC64_GOT_TPREL16_LO_DS:
|
||||
*(ul16 *)loc |= (sym.get_gottp_addr(ctx) - ctx.TOC->value) & 0xfffc;
|
||||
break;
|
||||
case R_PPC64_PLTSEQ:
|
||||
case R_PPC64_PLTCALL:
|
||||
case R_PPC64_TLS:
|
||||
case R_PPC64_TLSGD:
|
||||
case R_PPC64_TLSLD:
|
||||
@ -360,7 +374,7 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
|
||||
}
|
||||
|
||||
if (sym.is_ifunc())
|
||||
sym.flags |= (NEEDS_GOT | NEEDS_PLT);
|
||||
sym.flags |= NEEDS_GOT;
|
||||
|
||||
switch (rel.r_type) {
|
||||
case R_PPC64_ADDR64:
|
||||
@ -370,9 +384,12 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
|
||||
sym.flags |= NEEDS_GOTTP;
|
||||
break;
|
||||
case R_PPC64_REL24:
|
||||
if (sym.is_imported)
|
||||
if (sym.is_imported || sym.is_ifunc())
|
||||
sym.flags |= NEEDS_PLT;
|
||||
break;
|
||||
case R_PPC64_PLT16_HA:
|
||||
sym.flags |= NEEDS_GOT;
|
||||
break;
|
||||
case R_PPC64_GOT_TLSGD16_HA:
|
||||
sym.flags |= NEEDS_TLSGD;
|
||||
break;
|
||||
@ -386,6 +403,11 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
|
||||
case R_PPC64_TOC16_DS:
|
||||
case R_PPC64_REL16_HA:
|
||||
case R_PPC64_REL16_LO:
|
||||
case R_PPC64_PLT16_HI:
|
||||
case R_PPC64_PLT16_LO:
|
||||
case R_PPC64_PLT16_LO_DS:
|
||||
case R_PPC64_PLTSEQ:
|
||||
case R_PPC64_PLTCALL:
|
||||
case R_PPC64_TPREL16_HA:
|
||||
case R_PPC64_TPREL16_LO:
|
||||
case R_PPC64_GOT_TPREL16_LO_DS:
|
||||
|
@ -703,7 +703,7 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
|
||||
}
|
||||
|
||||
if (sym.is_ifunc())
|
||||
sym.flags |= (NEEDS_GOT | NEEDS_PLT);
|
||||
sym.flags |= NEEDS_GOT;
|
||||
|
||||
switch (rel.r_type) {
|
||||
case R_RISCV_32:
|
||||
@ -722,7 +722,7 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
|
||||
break;
|
||||
case R_RISCV_CALL:
|
||||
case R_RISCV_CALL_PLT:
|
||||
if (sym.is_imported)
|
||||
if (sym.is_imported || sym.is_ifunc())
|
||||
sym.flags |= NEEDS_PLT;
|
||||
break;
|
||||
case R_RISCV_GOT_HI20:
|
||||
|
@ -483,7 +483,7 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
|
||||
}
|
||||
|
||||
if (sym.is_ifunc())
|
||||
sym.flags |= (NEEDS_GOT | NEEDS_PLT);
|
||||
sym.flags |= NEEDS_GOT;
|
||||
|
||||
switch (rel.r_type) {
|
||||
case R_SPARC_64:
|
||||
@ -519,13 +519,14 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
|
||||
break;
|
||||
case R_SPARC_PLT32:
|
||||
case R_SPARC_WPLT30:
|
||||
case R_SPARC_WDISP30:
|
||||
case R_SPARC_HIPLT22:
|
||||
case R_SPARC_LOPLT10:
|
||||
case R_SPARC_PCPLT32:
|
||||
case R_SPARC_PCPLT22:
|
||||
case R_SPARC_PCPLT10:
|
||||
case R_SPARC_PLT64:
|
||||
if (sym.is_imported)
|
||||
if (sym.is_imported || sym.is_ifunc())
|
||||
sym.flags |= NEEDS_PLT;
|
||||
break;
|
||||
case R_SPARC_GOT13:
|
||||
@ -548,7 +549,6 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
|
||||
case R_SPARC_WDISP16:
|
||||
case R_SPARC_WDISP19:
|
||||
case R_SPARC_WDISP22:
|
||||
case R_SPARC_WDISP30:
|
||||
case R_SPARC_PC_HH22:
|
||||
scan_pcrel_rel(ctx, sym, rel);
|
||||
break;
|
||||
|
@ -633,7 +633,7 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
|
||||
}
|
||||
|
||||
if (sym.is_ifunc())
|
||||
sym.flags |= (NEEDS_GOT | NEEDS_PLT);
|
||||
sym.flags |= NEEDS_GOT;
|
||||
|
||||
switch (rel.r_type) {
|
||||
case R_X86_64_8:
|
||||
@ -681,7 +681,7 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
|
||||
}
|
||||
case R_X86_64_PLT32:
|
||||
case R_X86_64_PLTOFF64:
|
||||
if (sym.is_imported)
|
||||
if (sym.is_imported || sym.is_ifunc())
|
||||
sym.flags |= NEEDS_PLT;
|
||||
break;
|
||||
case R_X86_64_TLSGD: {
|
||||
|
12
elf/elf.h
12
elf/elf.h
@ -1118,6 +1118,9 @@ static constexpr u32 R_PPC64_GLOB_DAT = 20;
|
||||
static constexpr u32 R_PPC64_JMP_SLOT = 21;
|
||||
static constexpr u32 R_PPC64_RELATIVE = 22;
|
||||
static constexpr u32 R_PPC64_REL32 = 26;
|
||||
static constexpr u32 R_PPC64_PLT16_LO = 29;
|
||||
static constexpr u32 R_PPC64_PLT16_HI = 30;
|
||||
static constexpr u32 R_PPC64_PLT16_HA = 31;
|
||||
static constexpr u32 R_PPC64_ADDR64 = 38;
|
||||
static constexpr u32 R_PPC64_ADDR16_HIGHER = 39;
|
||||
static constexpr u32 R_PPC64_ADDR16_HIGHERA = 40;
|
||||
@ -1133,6 +1136,7 @@ static constexpr u32 R_PPC64_ADDR16_DS = 56;
|
||||
static constexpr u32 R_PPC64_ADDR16_LO_DS = 57;
|
||||
static constexpr u32 R_PPC64_GOT16_DS = 58;
|
||||
static constexpr u32 R_PPC64_GOT16_LO_DS = 59;
|
||||
static constexpr u32 R_PPC64_PLT16_LO_DS = 60;
|
||||
static constexpr u32 R_PPC64_TOC16_DS = 63;
|
||||
static constexpr u32 R_PPC64_TOC16_LO_DS = 64;
|
||||
static constexpr u32 R_PPC64_TLS = 67;
|
||||
@ -1184,6 +1188,8 @@ static constexpr u32 R_PPC64_TPREL16_HIGHA = 113;
|
||||
static constexpr u32 R_PPC64_DTPREL16_HIGH = 114;
|
||||
static constexpr u32 R_PPC64_DTPREL16_HIGHA = 115;
|
||||
static constexpr u32 R_PPC64_REL24_NOTOC = 116;
|
||||
static constexpr u32 R_PPC64_PLTSEQ = 119;
|
||||
static constexpr u32 R_PPC64_PLTCALL = 120;
|
||||
static constexpr u32 R_PPC64_PCREL_OPT = 123;
|
||||
static constexpr u32 R_PPC64_PCREL34 = 132;
|
||||
static constexpr u32 R_PPC64_GOT_PCREL34 = 133;
|
||||
@ -1224,6 +1230,9 @@ inline std::string rel_to_string<PPC64V2>(u32 r_type) {
|
||||
case R_PPC64_JMP_SLOT: return "R_PPC64_JMP_SLOT";
|
||||
case R_PPC64_RELATIVE: return "R_PPC64_RELATIVE";
|
||||
case R_PPC64_REL32: return "R_PPC64_REL32";
|
||||
case R_PPC64_PLT16_LO: return "R_PPC64_PLT16_LO";
|
||||
case R_PPC64_PLT16_HI: return "R_PPC64_PLT16_HI";
|
||||
case R_PPC64_PLT16_HA: return "R_PPC64_PLT16_HA";
|
||||
case R_PPC64_ADDR64: return "R_PPC64_ADDR64";
|
||||
case R_PPC64_ADDR16_HIGHER: return "R_PPC64_ADDR16_HIGHER";
|
||||
case R_PPC64_ADDR16_HIGHERA: return "R_PPC64_ADDR16_HIGHERA";
|
||||
@ -1239,6 +1248,7 @@ inline std::string rel_to_string<PPC64V2>(u32 r_type) {
|
||||
case R_PPC64_ADDR16_LO_DS: return "R_PPC64_ADDR16_LO_DS";
|
||||
case R_PPC64_GOT16_DS: return "R_PPC64_GOT16_DS";
|
||||
case R_PPC64_GOT16_LO_DS: return "R_PPC64_GOT16_LO_DS";
|
||||
case R_PPC64_PLT16_LO_DS: return "R_PPC64_PLT16_LO_DS";
|
||||
case R_PPC64_TOC16_DS: return "R_PPC64_TOC16_DS";
|
||||
case R_PPC64_TOC16_LO_DS: return "R_PPC64_TOC16_LO_DS";
|
||||
case R_PPC64_TLS: return "R_PPC64_TLS";
|
||||
@ -1290,6 +1300,8 @@ inline std::string rel_to_string<PPC64V2>(u32 r_type) {
|
||||
case R_PPC64_DTPREL16_HIGH: return "R_PPC64_DTPREL16_HIGH";
|
||||
case R_PPC64_DTPREL16_HIGHA: return "R_PPC64_DTPREL16_HIGHA";
|
||||
case R_PPC64_REL24_NOTOC: return "R_PPC64_REL24_NOTOC";
|
||||
case R_PPC64_PLTSEQ: return "R_PPC64_PLTSEQ";
|
||||
case R_PPC64_PLTCALL: return "R_PPC64_PLTCALL";
|
||||
case R_PPC64_PCREL_OPT: return "R_PPC64_PCREL_OPT";
|
||||
case R_PPC64_PCREL34: return "R_PPC64_PCREL34";
|
||||
case R_PPC64_GOT_PCREL34: return "R_PPC64_GOT_PCREL34";
|
||||
|
44
test/elf/ifunc-noplt.sh
Executable file
44
test/elf/ifunc-noplt.sh
Executable file
@ -0,0 +1,44 @@
|
||||
#!/bin/bash
|
||||
export LC_ALL=C
|
||||
set -e
|
||||
CC="${TEST_CC:-cc}"
|
||||
CXX="${TEST_CXX:-c++}"
|
||||
GCC="${TEST_GCC:-gcc}"
|
||||
GXX="${TEST_GXX:-g++}"
|
||||
MACHINE="${MACHINE:-$(uname -m)}"
|
||||
testname=$(basename "$0" .sh)
|
||||
echo -n "Testing $testname ... "
|
||||
t=out/test/elf/$MACHINE/$testname
|
||||
mkdir -p $t
|
||||
|
||||
# IFUNC is not supported on RISC-V yet
|
||||
[ $MACHINE = riscv64 -o $MACHINE = riscv32 ] && { echo skipped; exit; }
|
||||
|
||||
# Skip if libc is musl because musl does not support GNU FUNC
|
||||
ldd --help 2>&1 | grep -q musl && { echo skipped; exit; }
|
||||
|
||||
cat <<EOF | $CC -fPIC -o $t/a.o -c -xc - -fno-plt
|
||||
#include <stdio.h>
|
||||
|
||||
__attribute__((ifunc("resolve_foo")))
|
||||
void foo(void);
|
||||
|
||||
void hello(void) {
|
||||
printf("Hello world\n");
|
||||
}
|
||||
|
||||
typedef void Fn();
|
||||
|
||||
Fn *resolve_foo(void) {
|
||||
return hello;
|
||||
}
|
||||
|
||||
int main() {
|
||||
foo();
|
||||
}
|
||||
EOF
|
||||
|
||||
$CC -B. -o $t/exe $t/a.o
|
||||
$QEMU $t/exe | grep -q 'Hello world'
|
||||
|
||||
echo OK
|
Loading…
Reference in New Issue
Block a user