Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / ExecutionEngine / RuntimeDyld / X86 / ELF_STT_GNU_IFUNC.s
blobadcd27613ea968359233a22fa5eb25b845a46b97
1 # REQUIRES: x86_64-linux
2 # RUN: rm -rf %t && mkdir -p %t
3 # RUN: split-file %s %t
4 # RUN: llvm-mc -triple=x86_64-unknown-linux-gnu -filetype=obj -o %t/test_runner.o %t/test_runner.s
5 # RUN: llvm-mc -triple=x86_64-unknown-linux-gnu -filetype=obj -o %t/func_defs.o %t/func_defs.s
6 # RUN: llvm-rtdyld -triple=x86_64-unknown-linux-gnu -verify -check=%s %t/test_runner.o %t/func_defs.o
7 # RUN: llvm-rtdyld -triple=x86_64-unknown-linux-gnu -execute %t/test_runner.o %t/func_defs.o
9 #--- test_runner.s
11 # The _main function of this file contains calls to the two external functions
12 # "indirect_func" and "normal_func" that are not yet defined. They are called via
13 # the PLT to simulate how a compiler would emit a call to an external function.
14 # Eventually, indirect_func will resolve to a STT_GNU_IFUNC and normal_func to a
15 # regular function. We include calls to both types of functions in this test to
16 # test that both types of functions are executed correctly when their types are
17 # not known initially.
18 # It also contains a call to a locally defined indirect function. As RuntimeDyld
19 # treats local functions a bit differently than external functions, we also test
20 # that.
21 # Verify that the functions return the excpeted value. If the external indirect
22 # function call fails, this returns the error code 1. If the external normal
23 # function call fails, it's the error code 2. If the call to the locally
24 # defined indirect function fails, return the error code 3.
26 local_real_func:
27 mov $0x56, %eax
28 ret
30 local_indirect_func_resolver:
31 lea local_real_func(%rip), %rax
32 ret
34 .type local_indirect_func, @gnu_indirect_function
35 .set local_indirect_func, local_indirect_func_resolver
37 .global _main
38 _main:
39 call indirect_func@plt
40 cmp $0x12, %eax
41 je 1f
42 mov $1, %eax
43 ret
46 call normal_func@plt
47 cmp $0x34, %eax
48 je 1f
49 mov $2, %eax
50 ret
53 call local_indirect_func@plt
54 cmp $0x56, %eax
55 je 1f
56 mov $3, %eax
57 ret
60 xor %eax, %eax
61 ret
63 # Test that the indirect functions have the same addresses in both calls.
64 # rtdyld-check: decode_operand(test_indirect_func_address_1, 4) + next_pc(test_indirect_func_address_1) = decode_operand(test_indirect_func_address_2, 4) + next_pc(test_indirect_func_address_2)
65 test_indirect_func_address_1:
66 lea indirect_func(%rip), %rax
68 test_indirect_func_address_2:
69 lea indirect_func(%rip), %rax
71 # rtdyld-check: decode_operand(test_local_indirect_func_address_1, 4) + next_pc(test_indirect_func_address_1) = decode_operand(test_local_indirect_func_address_2, 4) + next_pc(test_indirect_func_address_2)
72 test_local_indirect_func_address_1:
73 lea local_indirect_func(%rip), %rax
75 test_local_indirect_func_address_2:
76 lea local_indirect_func(%rip), %rax
78 #--- func_defs.s
80 # This file contains the external functions that are called above. The type of
81 # the indirect function is set to @gnu_indirect_function and its value is set
82 # to the value of ifunc_resolver. This is what gcc emits when using
83 # __attribute__((ifunc("ifunc_resolver"))) in C. The resolver function just
84 # returns the address of the real function "real_func".
85 # To test that everyting works correctly, the indirect function returns 0x12
86 # and the direct function returns 0x23. This is verified in the _main function
87 # above.
89 real_func:
90 mov $0x12, %eax
91 ret
93 ifunc_resolver:
94 lea real_func(%rip), %rax
95 ret
97 .global indirect_func
98 .type indirect_func, @gnu_indirect_function
99 .set indirect_func, ifunc_resolver
101 .global normal_func
102 normal_func:
103 mov $0x34, %eax
106 # Test that the address of the indirect function is equal even when it is
107 # defined in another object file.
108 # rtdyld-check: decode_operand(test_indirect_func_address_1, 4) + next_pc(test_indirect_func_address_1) = decode_operand(test_indirect_func_address_3, 4) + next_pc(test_indirect_func_address_3)
109 test_indirect_func_address_3:
110 lea indirect_func(%rip), %rax