llvm-project/lld/test/ELF/gnu-ifunc-plt.s

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

112 lines
4.2 KiB
ArmAsm
Raw Normal View History

// REQUIRES: x86
/// For non-preemptable ifunc, place ifunc PLT entries to the .iplt section.
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/shared2-x86-64.s -o %t1.o
// RUN: ld.lld %t1.o --shared -soname=so -o %t.so
// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
// RUN: ld.lld --hash-style=sysv %t.so %t.o -o %tout
// RUN: llvm-objdump -d --no-show-raw-insn --print-imm-hex %tout | FileCheck %s --check-prefix=DISASM
// RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT
// RUN: llvm-readobj -r --dynamic-table %tout | FileCheck %s
/// Check that the PLTRELSZ tag does not include the IRELATIVE relocations
// CHECK: DynamicSection [
// CHECK: 0x0000000000000008 RELASZ 72 (bytes)
// CHECK: 0x0000000000000002 PLTRELSZ 48 (bytes)
/// Check that the IRELATIVE relocations are placed to the .rela.dyn section after
/// other regular relocations (e.g. GLOB_DAT).
// CHECK: Relocations [
[ELF] Move R_*_IRELATIVE from .rel[a].plt to .rel[a].dyn unless --pack-dyn-relocs=android[+relr] An R_*_IRELATIVE represents the address of a STT_GNU_IFUNC symbol (redirected at runtime) which is non-preemptable and is not associated with a canonical PLT (associated with a symbol with a section index of SHN_UNDEF but a non-zero st_value). .rel[a].plt [DT_JMPREL, DT_JMPREL+DT_JMPRELSZ) contains relocations that can be lazily resolved. R_*_IRELATIVE are always eagerly resolved, so conceptually they do not belong to .rela.plt. "iplt" is mostly a misnomer. glibc powerpc and powerpc64 do not resolve R_*_IRELATIVE if they are in .rela.plt. // a.o - synthesized PLT call stub has an R_*_IRELATIVE void ifunc(); int main() { ifunc(); } // b.o static void real() {} asm (".type ifunc, %gnu_indirect_function"); void *ifunc() { return ℜ } The lld-linked executable crashes. ld.bfd places R_*_IRELATIVE in .rela.dyn and the executable works. glibc i386, x86_64, and aarch64 have logic (glibc/sysdeps/*/dl-machine.h:elf_machine_lazy_rel) to eagerly resolve R_*_IRELATIVE in .rel[a].plt so the lld-linked executable works. Move R_*_IRELATIVE from .rel[a].plt to .rel[a].dyn to fix the crashes on glibc powerpc/powerpc64. This also helps simplifying ifunc implementation in FreeBSD rtld-elf powerpc64. If --pack-dyn-relocs=android[+relr] is specified, the Android packed dynamic relocation format is used for .rela.dyn. We cannot name in.relaIplt ".rela.dyn" because the output section will have mixed formats. This can be improved in the future. Reviewed By: pcc Differential Revision: https://reviews.llvm.org/D65651 llvm-svn: 367745
2019-08-03 10:26:52 +08:00
// CHECK-NEXT: Section (4) .rela.dyn {
// CHECK-NEXT: 0x202480 R_X86_64_GLOB_DAT bar3 0x0
// CHECK-NEXT: 0x2034B0 R_X86_64_IRELATIVE - 0x201318
// CHECK-NEXT: 0x2034B8 R_X86_64_IRELATIVE - 0x201319
[ELF] Move R_*_IRELATIVE from .rel[a].plt to .rel[a].dyn unless --pack-dyn-relocs=android[+relr] An R_*_IRELATIVE represents the address of a STT_GNU_IFUNC symbol (redirected at runtime) which is non-preemptable and is not associated with a canonical PLT (associated with a symbol with a section index of SHN_UNDEF but a non-zero st_value). .rel[a].plt [DT_JMPREL, DT_JMPREL+DT_JMPRELSZ) contains relocations that can be lazily resolved. R_*_IRELATIVE are always eagerly resolved, so conceptually they do not belong to .rela.plt. "iplt" is mostly a misnomer. glibc powerpc and powerpc64 do not resolve R_*_IRELATIVE if they are in .rela.plt. // a.o - synthesized PLT call stub has an R_*_IRELATIVE void ifunc(); int main() { ifunc(); } // b.o static void real() {} asm (".type ifunc, %gnu_indirect_function"); void *ifunc() { return ℜ } The lld-linked executable crashes. ld.bfd places R_*_IRELATIVE in .rela.dyn and the executable works. glibc i386, x86_64, and aarch64 have logic (glibc/sysdeps/*/dl-machine.h:elf_machine_lazy_rel) to eagerly resolve R_*_IRELATIVE in .rel[a].plt so the lld-linked executable works. Move R_*_IRELATIVE from .rel[a].plt to .rel[a].dyn to fix the crashes on glibc powerpc/powerpc64. This also helps simplifying ifunc implementation in FreeBSD rtld-elf powerpc64. If --pack-dyn-relocs=android[+relr] is specified, the Android packed dynamic relocation format is used for .rela.dyn. We cannot name in.relaIplt ".rela.dyn" because the output section will have mixed formats. This can be improved in the future. Reviewed By: pcc Differential Revision: https://reviews.llvm.org/D65651 llvm-svn: 367745
2019-08-03 10:26:52 +08:00
// CHECK-NEXT: }
// CHECK-NEXT: Section (5) .rela.plt {
// CHECK-NEXT: 0x2034A0 R_X86_64_JUMP_SLOT bar2 0x0
// CHECK-NEXT: 0x2034A8 R_X86_64_JUMP_SLOT zed2 0x0
[ELF] Move R_*_IRELATIVE from .rel[a].plt to .rel[a].dyn unless --pack-dyn-relocs=android[+relr] An R_*_IRELATIVE represents the address of a STT_GNU_IFUNC symbol (redirected at runtime) which is non-preemptable and is not associated with a canonical PLT (associated with a symbol with a section index of SHN_UNDEF but a non-zero st_value). .rel[a].plt [DT_JMPREL, DT_JMPREL+DT_JMPRELSZ) contains relocations that can be lazily resolved. R_*_IRELATIVE are always eagerly resolved, so conceptually they do not belong to .rela.plt. "iplt" is mostly a misnomer. glibc powerpc and powerpc64 do not resolve R_*_IRELATIVE if they are in .rela.plt. // a.o - synthesized PLT call stub has an R_*_IRELATIVE void ifunc(); int main() { ifunc(); } // b.o static void real() {} asm (".type ifunc, %gnu_indirect_function"); void *ifunc() { return ℜ } The lld-linked executable crashes. ld.bfd places R_*_IRELATIVE in .rela.dyn and the executable works. glibc i386, x86_64, and aarch64 have logic (glibc/sysdeps/*/dl-machine.h:elf_machine_lazy_rel) to eagerly resolve R_*_IRELATIVE in .rel[a].plt so the lld-linked executable works. Move R_*_IRELATIVE from .rel[a].plt to .rel[a].dyn to fix the crashes on glibc powerpc/powerpc64. This also helps simplifying ifunc implementation in FreeBSD rtld-elf powerpc64. If --pack-dyn-relocs=android[+relr] is specified, the Android packed dynamic relocation format is used for .rela.dyn. We cannot name in.relaIplt ".rela.dyn" because the output section will have mixed formats. This can be improved in the future. Reviewed By: pcc Differential Revision: https://reviews.llvm.org/D65651 llvm-svn: 367745
2019-08-03 10:26:52 +08:00
// CHECK-NEXT: }
/// Check that .got.plt entries point back to PLT header
// GOTPLT: Contents of section .got.plt:
// GOTPLT-NEXT: 203488 90232000 00000000 00000000 00000000
// GOTPLT-NEXT: 203498 00000000 00000000 56132000 00000000
// GOTPLT-NEXT: 2034a8 66132000 00000000 00000000 00000000
// GOTPLT-NEXT: 2034b8 00000000 00000000
/// Check that we have 2 PLT sections: one regular .plt section and one
/// .iplt section for ifunc entries.
// DISASM: Disassembly of section .text:
// DISASM-EMPTY:
// DISASM-NEXT: <foo>:
// DISASM-NEXT: 201318: retq
// DISASM: <bar>:
// DISASM-NEXT: 201319: retq
// DISASM: <_start>:
// DISASM-NEXT: 20131a: callq 0x201370
// DISASM-NEXT: 20131f: callq 0x201380
// DISASM-NEXT: callq {{.*}} <bar2@plt>
// DISASM-NEXT: callq {{.*}} <zed2@plt>
// DISASM-NEXT: jmpq *0x114c(%rip)
// DISASM-EMPTY:
// DISASM-NEXT: Disassembly of section .plt:
// DISASM-EMPTY:
// DISASM-NEXT: <.plt>:
// DISASM-NEXT: 201340: pushq 0x214a(%rip)
// DISASM-NEXT: 201346: jmpq *0x214c(%rip)
// DISASM-NEXT: 20134c: nopl (%rax)
// DISASM-EMPTY:
// DISASM-NEXT: <bar2@plt>:
// DISASM-NEXT: 201350: jmpq *0x214a(%rip)
// DISASM-NEXT: 201356: pushq $0x0
// DISASM-NEXT: 20135b: jmp 0x201340 <.plt>
// DISASM-EMPTY:
// DISASM-NEXT: <zed2@plt>:
// DISASM-NEXT: 201360: jmpq *0x2142(%rip)
// DISASM-NEXT: 201366: pushq $0x1
// DISASM-NEXT: 20136b: jmp 0x201340 <.plt>
// DISASM-EMPTY:
// DISASM-NEXT: Disassembly of section .iplt:
// DISASM-EMPTY:
// DISASM-NEXT: <.iplt>:
// DISASM-NEXT: 201370: jmpq *0x213a(%rip)
// DISASM-NEXT: 201376: pushq $0x0
// DISASM-NEXT: 20137b: jmp 0x201340 <.plt>
// DISASM-NEXT: 201380: jmpq *0x2132(%rip)
// DISASM-NEXT: 201386: pushq $0x1
// DISASM-NEXT: 20138b: jmp 0x201340 <.plt>
// Test that --shuffle-sections does not affect the order of relocations and that
// we still place IRELATIVE relocations last. Check both random seed (0) and an
// arbitrary seed that was known to break the order of relocations previously (3).
// RUN: ld.lld --shuffle-sections='*=3' %t.so %t.o -o %tout2
// RUN: llvm-readobj --relocations %tout2 | FileCheck %s --check-prefix=SHUFFLE
// RUN: ld.lld --shuffle-sections='*=0' %t.so %t.o -o %tout3
// RUN: llvm-readobj --relocations %tout3 | FileCheck %s --check-prefix=SHUFFLE
// SHUFFLE: Section {{.*}} .rela.dyn {
// SHUFFLE-NEXT: R_X86_64_GLOB_DAT
// SHUFFLE-NEXT: R_X86_64_IRELATIVE
// SHUFFLE-NEXT: R_X86_64_IRELATIVE
// SHUFFLE-NEXT: }
.text
.type foo STT_GNU_IFUNC
.globl foo
foo:
ret
.type bar STT_GNU_IFUNC
.globl bar
bar:
ret
.globl _start
_start:
call foo
call bar
call bar2
call zed2
jmp *bar3@GOTPCREL(%rip)