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

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

143 lines
3.8 KiB
ArmAsm
Raw Normal View History

// REQUIRES: aarch64
// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o
// RUN: ld.lld -static %t.o -o %tout
// RUN: llvm-objdump -d --no-show-raw-insn %tout | FileCheck %s --check-prefix=DISASM
// RUN: llvm-readobj -r --symbols --sections %tout | FileCheck %s
// CHECK: Sections [
// CHECK: Section {
// CHECK: Index: 1
[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: Name: .rela.dyn
// CHECK-NEXT: Type: SHT_RELA
// CHECK-NEXT: Flags [
// CHECK-NEXT: SHF_ALLOC
// CHECK-NEXT: ]
// CHECK-NEXT: Address: [[RELA:.*]]
// CHECK-NEXT: Offset: 0x158
// CHECK-NEXT: Size: 48
// CHECK-NEXT: Link: 0
// CHECK-NEXT: Info: 4
// CHECK-NEXT: AddressAlignment: 8
// CHECK-NEXT: EntrySize: 24
// CHECK-NEXT: }
// 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 ({{.*}}) .rela.dyn {
// CHECK-NEXT: 0x2201C0 R_AARCH64_IRELATIVE
// CHECK-NEXT: 0x2201C8 R_AARCH64_IRELATIVE
// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK: Symbols [
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name:
// CHECK-NEXT: Value: 0x0
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
// CHECK-NEXT: Other: 0
// CHECK-NEXT: Section: Undefined
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: $x.0
// CHECK-NEXT: Value: 0x210188
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
// CHECK-NEXT: Other: 0
// CHECK-NEXT: Section: .text
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: __rela_iplt_end
// CHECK-NEXT: Value: 0x200188
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
// CHECK-NEXT: Other [
// CHECK-NEXT: STV_HIDDEN
// CHECK-NEXT: ]
[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: .rela.dyn
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: __rela_iplt_start
// CHECK-NEXT: Value: 0x200158
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
// CHECK-NEXT: Other [
// CHECK-NEXT: STV_HIDDEN
// CHECK-NEXT: ]
[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: .rela.dyn
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: _start
// CHECK-NEXT: Value: 0x210190
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global
// CHECK-NEXT: Type: None
// CHECK-NEXT: Other: 0
// CHECK-NEXT: Section: .text
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: bar
// CHECK-NEXT: Value: 0x21018C
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global
// CHECK-NEXT: Type: GNU_IFunc
// CHECK-NEXT: Other: 0
// CHECK-NEXT: Section: .text
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: foo
// CHECK-NEXT: Value: 0x210188
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global
// CHECK-NEXT: Type: GNU_IFunc
// CHECK-NEXT: Other: 0
// CHECK-NEXT: Section: .text
// CHECK-NEXT: }
// CHECK-NEXT: ]
// 344 = 0x158
// 392 = 0x188
// DISASM: Disassembly of section .text:
// DISASM-EMPTY:
// DISASM-NEXT: <foo>:
// DISASM-NEXT: 210188: ret
// DISASM: <bar>:
// DISASM-NEXT: 21018c: ret
// DISASM: <_start>:
// DISASM-NEXT: 210190: bl #16
// DISASM-NEXT: 210194: bl #28
// DISASM-NEXT: 210198: add x2, x2, #344
// DISASM-NEXT: 21019c: add x2, x2, #392
// DISASM-EMPTY:
// DISASM-NEXT: Disassembly of section .iplt:
// DISASM-EMPTY:
// DISASM-NEXT: <.iplt>:
// DISASM-NEXT: 2101a0: adrp x16, #65536
// DISASM-NEXT: 2101a4: ldr x17, [x16, #448]
// DISASM-NEXT: 2101a8: add x16, x16, #448
// DISASM-NEXT: 2101ac: br x17
// DISASM-NEXT: 2101b0: adrp x16, #65536
// DISASM-NEXT: 2101b4: ldr x17, [x16, #456]
// DISASM-NEXT: 2101b8: add x16, x16, #456
// DISASM-NEXT: 2101bc: br x17
.text
.type foo STT_GNU_IFUNC
.globl foo
foo:
ret
.type bar STT_GNU_IFUNC
.globl bar
bar:
ret
.globl _start
_start:
bl foo
bl bar
add x2, x2, :lo12:__rela_iplt_start
add x2, x2, :lo12:__rela_iplt_end