xref: /llvm-project/lld/test/wasm/shared64.s (revision 22b7b84860d39da71964c9b329937f2ee1d875ba)
13a293cbfSWouter van Oortmerssen# RUN: llvm-mc -filetype=obj -triple=wasm64-unknown-unknown -o %t.o %s
2*22b7b848SSam Clegg# RUN: wasm-ld -mwasm64 --experimental-pic --unresolved-symbols=import-dynamic -shared -o %t.wasm %t.o
33a293cbfSWouter van Oortmerssen# RUN: obj2yaml %t.wasm | FileCheck %s
4feddf115SSam Clegg# RUN: llvm-objdump --disassemble-symbols=__wasm_call_ctors,__wasm_apply_data_relocs --no-show-raw-insn --no-leading-addr %t.wasm | FileCheck %s --check-prefixes DIS
53a293cbfSWouter van Oortmerssen
69647a6f7SWouter van Oortmerssen.functype func_external () -> ()
79647a6f7SWouter van Oortmerssen
89647a6f7SWouter van Oortmerssen# Linker-synthesized globals
99647a6f7SWouter van Oortmerssen.globaltype __stack_pointer, i64
109647a6f7SWouter van Oortmerssen.globaltype	__table_base, i64, immutable
119647a6f7SWouter van Oortmerssen.globaltype	__memory_base, i64, immutable
129647a6f7SWouter van Oortmerssen
133a293cbfSWouter van Oortmerssen.section .data.data,"",@
143a293cbfSWouter van Oortmerssendata:
153a293cbfSWouter van Oortmerssen  .p2align 2
163a293cbfSWouter van Oortmerssen  .int32 2
173a293cbfSWouter van Oortmerssen  .size data, 4
183a293cbfSWouter van Oortmerssen
193a293cbfSWouter van Oortmerssen.section .data.indirect_func_external,"",@
203a293cbfSWouter van Oortmerssenindirect_func_external:
214157b603SWouter van Oortmerssen  .int64 func_external
224157b603SWouter van Oortmerssen.size indirect_func_external, 8
233a293cbfSWouter van Oortmerssen
243a293cbfSWouter van Oortmerssen.section .data.indirect_func,"",@
253a293cbfSWouter van Oortmerssenindirect_func:
264157b603SWouter van Oortmerssen  .int64 foo
274157b603SWouter van Oortmerssen  .size indirect_func, 8
283a293cbfSWouter van Oortmerssen
293a293cbfSWouter van Oortmerssen# Test data relocations
303a293cbfSWouter van Oortmerssen
313a293cbfSWouter van Oortmerssen.section .data.data_addr,"",@
323a293cbfSWouter van Oortmerssendata_addr:
333a293cbfSWouter van Oortmerssen  .int32 data
343a293cbfSWouter van Oortmerssen  .size data_addr, 4
353a293cbfSWouter van Oortmerssen
363a293cbfSWouter van Oortmerssen# .. against external symbols
373a293cbfSWouter van Oortmerssen
383a293cbfSWouter van Oortmerssen.section .data.data_addr_external,"",@
393a293cbfSWouter van Oortmerssendata_addr_external:
409647a6f7SWouter van Oortmerssen  .int64 data_external
419647a6f7SWouter van Oortmerssen  .size data_addr_external, 8
423a293cbfSWouter van Oortmerssen
433a293cbfSWouter van Oortmerssen# .. including addends
443a293cbfSWouter van Oortmerssen
453a293cbfSWouter van Oortmerssen.section .data.extern_struct_internal_ptr,"",@
463a293cbfSWouter van Oortmerssenextern_struct_internal_ptr:
473a293cbfSWouter van Oortmerssen  .int32 extern_struct + 4
483a293cbfSWouter van Oortmerssen  .size extern_struct_internal_ptr, 4
493a293cbfSWouter van Oortmerssen
503a293cbfSWouter van Oortmerssen# Test use of __stack_pointer
513a293cbfSWouter van Oortmerssen
523a293cbfSWouter van Oortmerssen.section .text,"",@
533a293cbfSWouter van Oortmerssenfoo:
543a293cbfSWouter van Oortmerssen  # %ptr = alloca i32
55f01fdd17SFangrui Song  # %0 = load i32, ptr @data, align 4
56f01fdd17SFangrui Song  # %1 = load ptr, ptr @indirect_func, align 4
573a293cbfSWouter van Oortmerssen  # call i32 %1()
583a293cbfSWouter van Oortmerssen  # ret i32 %0
593a293cbfSWouter van Oortmerssen  .functype foo () -> (i32)
603a293cbfSWouter van Oortmerssen  .local    i64, i32
613a293cbfSWouter van Oortmerssen  global.get  __stack_pointer
623a293cbfSWouter van Oortmerssen  i64.const 16
633a293cbfSWouter van Oortmerssen  i64.sub
643a293cbfSWouter van Oortmerssen  local.tee 0
653a293cbfSWouter van Oortmerssen  global.set  __stack_pointer
663a293cbfSWouter van Oortmerssen  global.get  __memory_base
673a293cbfSWouter van Oortmerssen  i64.const data@MBREL
683a293cbfSWouter van Oortmerssen  i64.add
693a293cbfSWouter van Oortmerssen  i32.load  0
703a293cbfSWouter van Oortmerssen  local.set 1
713a293cbfSWouter van Oortmerssen  global.get  indirect_func@GOT
724157b603SWouter van Oortmerssen  i64.load  0
734157b603SWouter van Oortmerssen  i32.wrap_i64
743a293cbfSWouter van Oortmerssen  call_indirect  () -> (i32)
753a293cbfSWouter van Oortmerssen  drop
763a293cbfSWouter van Oortmerssen  local.get 0
773a293cbfSWouter van Oortmerssen  i64.const 16
783a293cbfSWouter van Oortmerssen  i64.add
793a293cbfSWouter van Oortmerssen  global.set  __stack_pointer
803a293cbfSWouter van Oortmerssen  local.get 1
813a293cbfSWouter van Oortmerssen  end_function
823a293cbfSWouter van Oortmerssen
833a293cbfSWouter van Oortmerssenget_func_address:
849647a6f7SWouter van Oortmerssen  .functype get_func_address () -> (i64)
853a293cbfSWouter van Oortmerssen  global.get func_external@GOT
863a293cbfSWouter van Oortmerssen  end_function
873a293cbfSWouter van Oortmerssen
883a293cbfSWouter van Oortmerssenget_data_address:
899647a6f7SWouter van Oortmerssen  .functype get_data_address () -> (i64)
903a293cbfSWouter van Oortmerssen  global.get  data_external@GOT
913a293cbfSWouter van Oortmerssen  end_function
923a293cbfSWouter van Oortmerssen
933a293cbfSWouter van Oortmerssenget_local_func_address:
943a293cbfSWouter van Oortmerssen  # Verify that a function which is otherwise not address taken *is* added to
953a293cbfSWouter van Oortmerssen  # the wasm table with referenced via R_WASM_TABLE_INDEX_REL_SLEB64
963a293cbfSWouter van Oortmerssen  .functype get_local_func_address () -> (i64)
973a293cbfSWouter van Oortmerssen  global.get  __table_base
983a293cbfSWouter van Oortmerssen  i64.const get_func_address@TBREL
993a293cbfSWouter van Oortmerssen  i64.add
1003a293cbfSWouter van Oortmerssen  end_function
1013a293cbfSWouter van Oortmerssen
1023a293cbfSWouter van Oortmerssen.globl foo
1033a293cbfSWouter van Oortmerssen.globl data
1043a293cbfSWouter van Oortmerssen.globl indirect_func
1053a293cbfSWouter van Oortmerssen.globl indirect_func_external
1063a293cbfSWouter van Oortmerssen.globl data_addr
1073a293cbfSWouter van Oortmerssen.globl data_addr_external
1083a293cbfSWouter van Oortmerssen.globl extern_struct_internal_ptr
1093a293cbfSWouter van Oortmerssen.globl get_data_address
1103a293cbfSWouter van Oortmerssen.globl get_func_address
1113a293cbfSWouter van Oortmerssen.globl get_local_func_address
1123a293cbfSWouter van Oortmerssen
1133a293cbfSWouter van Oortmerssen.hidden foo
1143a293cbfSWouter van Oortmerssen.hidden data
1153a293cbfSWouter van Oortmerssen.hidden get_data_address
1163a293cbfSWouter van Oortmerssen.hidden get_func_address
1173a293cbfSWouter van Oortmerssen
1183a293cbfSWouter van Oortmerssen# Without this linking will fail because we import __stack_pointer (a mutable
1193a293cbfSWouter van Oortmerssen# global).
1203a293cbfSWouter van Oortmerssen# TODO(sbc): We probably want a nicer way to specify target_features section
1213a293cbfSWouter van Oortmerssen# in assembly.
1223a293cbfSWouter van Oortmerssen.section .custom_section.target_features,"",@
1233a293cbfSWouter van Oortmerssen.int8 1
1243a293cbfSWouter van Oortmerssen.int8 43
1253a293cbfSWouter van Oortmerssen.int8 15
1263a293cbfSWouter van Oortmerssen.ascii "mutable-globals"
1273a293cbfSWouter van Oortmerssen
1283a293cbfSWouter van Oortmerssen# check for dylink section at start
1293a293cbfSWouter van Oortmerssen
1303a293cbfSWouter van Oortmerssen# CHECK:      Sections:
1313a293cbfSWouter van Oortmerssen# CHECK-NEXT:   - Type:            CUSTOM
132b78c85a4SSam Clegg# CHECK-NEXT:     Name:            dylink.0
1334157b603SWouter van Oortmerssen# CHECK-NEXT:     MemorySize:      36
1343a293cbfSWouter van Oortmerssen# CHECK-NEXT:     MemoryAlignment: 2
1353a293cbfSWouter van Oortmerssen# CHECK-NEXT:     TableSize:       2
1363a293cbfSWouter van Oortmerssen# CHECK-NEXT:     TableAlignment:  0
1373a293cbfSWouter van Oortmerssen# CHECK-NEXT:     Needed:          []
1383a293cbfSWouter van Oortmerssen# CHECK-NEXT:   - Type:            TYPE
1393a293cbfSWouter van Oortmerssen
1403a293cbfSWouter van Oortmerssen# check for import of __table_base and __memory_base globals
1413a293cbfSWouter van Oortmerssen
1423a293cbfSWouter van Oortmerssen# CHECK:        - Type:            IMPORT
1433a293cbfSWouter van Oortmerssen# CHECK-NEXT:     Imports:
1443a293cbfSWouter van Oortmerssen# CHECK-NEXT:       - Module:          env
1453a293cbfSWouter van Oortmerssen# CHECK-NEXT:         Field:           memory
1463a293cbfSWouter van Oortmerssen# CHECK-NEXT:         Kind:            MEMORY
1473a293cbfSWouter van Oortmerssen# CHECK-NEXT:         Memory:
1483a293cbfSWouter van Oortmerssen# CHECK-NEXT:           Flags:         [ IS_64 ]
1493a293cbfSWouter van Oortmerssen# CHECK-NEXT:           Minimum:       0x1
1503a293cbfSWouter van Oortmerssen# CHECK-NEXT:       - Module:          env
1513a293cbfSWouter van Oortmerssen# CHECK-NEXT:         Field:           __indirect_function_table
1523a293cbfSWouter van Oortmerssen# CHECK-NEXT:         Kind:            TABLE
1533a293cbfSWouter van Oortmerssen# CHECK-NEXT:         Table:
1543a293cbfSWouter van Oortmerssen# CHECK-NEXT:           Index:           0
1553a293cbfSWouter van Oortmerssen# CHECK-NEXT:           ElemType:        FUNCREF
1563a293cbfSWouter van Oortmerssen# CHECK-NEXT:           Limits:
15739d32b23SSam Clegg# CHECK-NEXT:             Flags:         [ IS_64 ]
1583a293cbfSWouter van Oortmerssen# CHECK-NEXT:             Minimum:         0x2
1593a293cbfSWouter van Oortmerssen# CHECK-NEXT:       - Module:          env
1603a293cbfSWouter van Oortmerssen# CHECK-NEXT:         Field:           __stack_pointer
1613a293cbfSWouter van Oortmerssen# CHECK-NEXT:         Kind:            GLOBAL
1623a293cbfSWouter van Oortmerssen# CHECK-NEXT:         GlobalType:      I64
1633a293cbfSWouter van Oortmerssen# CHECK-NEXT:         GlobalMutable:   true
1643a293cbfSWouter van Oortmerssen# CHECK-NEXT:       - Module:          env
1653a293cbfSWouter van Oortmerssen# CHECK-NEXT:         Field:           __memory_base
1663a293cbfSWouter van Oortmerssen# CHECK-NEXT:         Kind:            GLOBAL
1673a293cbfSWouter van Oortmerssen# CHECK-NEXT:         GlobalType:      I64
1683a293cbfSWouter van Oortmerssen# CHECK-NEXT:         GlobalMutable:   false
1693a293cbfSWouter van Oortmerssen# CHECK-NEXT:       - Module:          env
1703a293cbfSWouter van Oortmerssen# CHECK-NEXT:         Field:           __table_base
1713a293cbfSWouter van Oortmerssen# CHECK-NEXT:         Kind:            GLOBAL
1723a293cbfSWouter van Oortmerssen# CHECK-NEXT:         GlobalType:      I64
1733a293cbfSWouter van Oortmerssen# CHECK-NEXT:         GlobalMutable:   false
1743a293cbfSWouter van Oortmerssen# CHECK-NEXT:       - Module:          GOT.mem
1753a293cbfSWouter van Oortmerssen# CHECK-NEXT:         Field:           indirect_func
1763a293cbfSWouter van Oortmerssen# CHECK-NEXT:         Kind:            GLOBAL
1774157b603SWouter van Oortmerssen# CHECK-NEXT:         GlobalType:      I64
1783a293cbfSWouter van Oortmerssen# CHECK-NEXT:         GlobalMutable:   true
1793a293cbfSWouter van Oortmerssen# CHECK-NEXT:       - Module:          GOT.func
1803a293cbfSWouter van Oortmerssen# CHECK-NEXT:         Field:           func_external
1813a293cbfSWouter van Oortmerssen# CHECK-NEXT:         Kind:            GLOBAL
1824157b603SWouter van Oortmerssen# CHECK-NEXT:         GlobalType:      I64
1833a293cbfSWouter van Oortmerssen# CHECK-NEXT:         GlobalMutable:   true
1843a293cbfSWouter van Oortmerssen# CHECK-NEXT:       - Module:          GOT.mem
1853a293cbfSWouter van Oortmerssen# CHECK-NEXT:         Field:           data_external
1863a293cbfSWouter van Oortmerssen# CHECK-NEXT:         Kind:            GLOBAL
1874157b603SWouter van Oortmerssen# CHECK-NEXT:         GlobalType:      I64
1883a293cbfSWouter van Oortmerssen# CHECK-NEXT:         GlobalMutable:   true
1893a293cbfSWouter van Oortmerssen# CHECK-NEXT:       - Module:          GOT.mem
1903a293cbfSWouter van Oortmerssen# CHECK-NEXT:         Field:           extern_struct
1913a293cbfSWouter van Oortmerssen# CHECK-NEXT:         Kind:            GLOBAL
1924157b603SWouter van Oortmerssen# CHECK-NEXT:         GlobalType:      I64
1933a293cbfSWouter van Oortmerssen# CHECK-NEXT:         GlobalMutable:   true
1943a293cbfSWouter van Oortmerssen# CHECK-NEXT:   - Type:            FUNCTION
1953a293cbfSWouter van Oortmerssen
1963a293cbfSWouter van Oortmerssen# CHECK:        - Type:            EXPORT
1973a293cbfSWouter van Oortmerssen# CHECK-NEXT:     Exports:
1983a293cbfSWouter van Oortmerssen# CHECK-NEXT:       - Name:            __wasm_call_ctors
1993a293cbfSWouter van Oortmerssen# CHECK-NEXT:         Kind:            FUNCTION
200e4888be7SSam Clegg# CHECK-NEXT:         Index:           0
2013a293cbfSWouter van Oortmerssen
2023a293cbfSWouter van Oortmerssen# check for elem segment initialized with __table_base global as offset
2033a293cbfSWouter van Oortmerssen
2043a293cbfSWouter van Oortmerssen# CHECK:        - Type:            ELEM
2053a293cbfSWouter van Oortmerssen# CHECK-NEXT:     Segments:
2063a293cbfSWouter van Oortmerssen# CHECK-NEXT:       - Offset:
2073a293cbfSWouter van Oortmerssen# CHECK-NEXT:           Opcode:          GLOBAL_GET
20839d32b23SSam Clegg# CHECK-NEXT:           Index:           2
209e4888be7SSam Clegg# CHECK-NEXT:         Functions:       [ 3, 2 ]
2103a293cbfSWouter van Oortmerssen
2113a293cbfSWouter van Oortmerssen# check the generated code in __wasm_call_ctors and __wasm_apply_data_relocs functions
2123a293cbfSWouter van Oortmerssen
213feddf115SSam Clegg# DIS:      <__wasm_call_ctors>:
214feddf115SSam Clegg# DIS-EMPTY:
215feddf115SSam Clegg# DIS-NEXT:                 end
216feddf115SSam Clegg
217feddf115SSam Clegg# DIS:      <__wasm_apply_data_relocs>:
218feddf115SSam Clegg# DIS-EMPTY:
219feddf115SSam Clegg# DIS-NEXT:                 i64.const       4
22086c90f9bSSam Clegg# DIS-NEXT:                 global.get      1
221feddf115SSam Clegg# DIS-NEXT:                 i64.add
22239d32b23SSam Clegg# DIS-NEXT:                 global.get      4
223feddf115SSam Clegg# DIS-NEXT:                 i64.store       0:p2align=2
224feddf115SSam Clegg# DIS-NEXT:                 i64.const       12
22586c90f9bSSam Clegg# DIS-NEXT:                 global.get      1
226feddf115SSam Clegg# DIS-NEXT:                 i64.add
227feddf115SSam Clegg# DIS-NEXT:                 global.get      2
228feddf115SSam Clegg# DIS-NEXT:                 i64.const       1
229feddf115SSam Clegg# DIS-NEXT:                 i64.add
230feddf115SSam Clegg# DIS-NEXT:                 i64.store       0:p2align=2
231feddf115SSam Clegg# DIS-NEXT:                 i64.const       20
23286c90f9bSSam Clegg# DIS-NEXT:                 global.get      1
233feddf115SSam Clegg# DIS-NEXT:                 i64.add
234feddf115SSam Clegg# DIS-NEXT:                 global.get      1
235feddf115SSam Clegg# DIS-NEXT:                 i32.const       0
236feddf115SSam Clegg# DIS-NEXT:                 i32.add
237feddf115SSam Clegg# DIS-NEXT:                 i32.store       0
238feddf115SSam Clegg# DIS-NEXT:                 i64.const       24
23986c90f9bSSam Clegg# DIS-NEXT:                 global.get      1
240feddf115SSam Clegg# DIS-NEXT:                 i64.add
24139d32b23SSam Clegg# DIS-NEXT:                 global.get      5
242feddf115SSam Clegg# DIS-NEXT:                 i64.store       0:p2align=2
243feddf115SSam Clegg# DIS-NEXT:                 i64.const       32
24486c90f9bSSam Clegg# DIS-NEXT:                 global.get      1
245feddf115SSam Clegg# DIS-NEXT:                 i64.add
24639d32b23SSam Clegg# DIS-NEXT:                 global.get      6
247feddf115SSam Clegg# DIS-NEXT:                 i32.const       4
248feddf115SSam Clegg# DIS-NEXT:                 i32.add
249feddf115SSam Clegg# DIS-NEXT:                 i32.store       0
250feddf115SSam Clegg# DIS-NEXT:                 end
2513a293cbfSWouter van Oortmerssen
2523a293cbfSWouter van Oortmerssen# check the data segment initialized with __memory_base global as offset
2533a293cbfSWouter van Oortmerssen
2543a293cbfSWouter van Oortmerssen# CHECK:        - Type:            DATA
2553a293cbfSWouter van Oortmerssen# CHECK-NEXT:     Segments:
2563a293cbfSWouter van Oortmerssen# CHECK-NEXT:       - SectionOffset:   6
2573a293cbfSWouter van Oortmerssen# CHECK-NEXT:         InitFlags:       0
2583a293cbfSWouter van Oortmerssen# CHECK-NEXT:         Offset:
2593a293cbfSWouter van Oortmerssen# CHECK-NEXT:           Opcode:          GLOBAL_GET
2603a293cbfSWouter van Oortmerssen# CHECK-NEXT:           Index:           1
2614157b603SWouter van Oortmerssen# CHECK-NEXT:         Content:         '020000000000000000000000010000000000000000000000000000000000000000000000'
262