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