259 lines · plain
1# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s2# RUN: wasm-ld --experimental-pic --unresolved-symbols=import-dynamic -shared -o %t.wasm %t.o3# RUN: obj2yaml %t.wasm | FileCheck %s4# 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 DIS5 6.functype func_external () -> ()7 8# Linker-synthesized globals9.globaltype __stack_pointer, i3210.globaltype __table_base, i32, immutable11.globaltype __memory_base, i32, immutable12 13.section .data.data,"",@14data:15 .p2align 216 .int32 217 .size data, 418 19.section .data.indirect_func_external,"",@20indirect_func_external:21 .int32 func_external22.size indirect_func_external, 423 24.section .data.indirect_func,"",@25indirect_func:26 .int32 foo27 .size indirect_func, 428 29# Test data relocations30 31.section .data.data_addr,"",@32data_addr:33 .int32 data34 .size data_addr, 435 36# .. against external symbols37 38.section .data.data_addr_external,"",@39data_addr_external:40 .int32 data_external41 .size data_addr_external, 442 43# .. including addends44 45.section .data.extern_struct_internal_ptr,"",@46extern_struct_internal_ptr:47 .int32 extern_struct + 448 .size extern_struct_internal_ptr, 449 50# Test use of __stack_pointer51 52.section .text,"",@53foo:54 # %ptr = alloca i3255 # %0 = load i32, ptr @data, align 456 # %1 = load ptr, ptr @indirect_func, align 457 # call i32 %1()58 # ret i32 %059 .functype foo () -> (i32)60 .local i32, i3261 global.get __stack_pointer62 i32.const 1663 i32.sub64 local.tee 065 global.set __stack_pointer66 global.get __memory_base67 i32.const data@MBREL68 i32.add69 i32.load 070 local.set 171 global.get indirect_func@GOT72 i32.load 073 call_indirect () -> (i32)74 drop75 local.get 076 i32.const 1677 i32.add78 global.set __stack_pointer79 local.get 180 end_function81 82get_func_address:83 .functype get_func_address () -> (i32)84 global.get func_external@GOT85 end_function86 87get_data_address:88 .functype get_data_address () -> (i32)89 global.get data_external@GOT90 end_function91 92get_local_func_address:93 # Verify that a function which is otherwise not address taken *is* added to94 # the wasm table with referenced via R_WASM_TABLE_INDEX_REL_SLEB95 .functype get_local_func_address () -> (i32)96 global.get __table_base97 i32.const get_func_address@TBREL98 i32.add99 end_function100 101.globl foo102.globl data103.globl indirect_func104.globl indirect_func_external105.globl data_addr106.globl data_addr_external107.globl extern_struct_internal_ptr108.globl get_data_address109.globl get_func_address110.globl get_local_func_address111 112.hidden foo113.hidden data114.hidden get_data_address115.hidden get_func_address116 117# Without this linking will fail because we import __stack_pointer (a mutable118# global).119# TODO(sbc): We probably want a nicer way to specify target_features section120# in assembly.121.section .custom_section.target_features,"",@122.int8 1123.int8 43124.int8 15125.ascii "mutable-globals"126 127# check for dylink section at start128 129# CHECK: Sections:130# CHECK-NEXT: - Type: CUSTOM131# CHECK-NEXT: Name: dylink.0132# CHECK-NEXT: MemorySize: 24133# CHECK-NEXT: MemoryAlignment: 2134# CHECK-NEXT: TableSize: 2135# CHECK-NEXT: TableAlignment: 0136# CHECK-NEXT: Needed: []137# CHECK-NEXT: - Type: TYPE138 139# check for import of __table_base and __memory_base globals140 141# CHECK: - Type: IMPORT142# CHECK-NEXT: Imports:143# CHECK-NEXT: - Module: env144# CHECK-NEXT: Field: memory145# CHECK-NEXT: Kind: MEMORY146# CHECK-NEXT: Memory:147# CHECK-NEXT: Minimum: 0x1148# CHECK-NEXT: - Module: env149# CHECK-NEXT: Field: __indirect_function_table150# CHECK-NEXT: Kind: TABLE151# CHECK-NEXT: Table:152# CHECK-NEXT: Index: 0153# CHECK-NEXT: ElemType: FUNCREF154# CHECK-NEXT: Limits:155# CHECK-NEXT: Minimum: 0x2156# CHECK-NEXT: - Module: env157# CHECK-NEXT: Field: __stack_pointer158# CHECK-NEXT: Kind: GLOBAL159# CHECK-NEXT: GlobalType: I32160# CHECK-NEXT: GlobalMutable: true161# CHECK-NEXT: - Module: env162# CHECK-NEXT: Field: __memory_base163# CHECK-NEXT: Kind: GLOBAL164# CHECK-NEXT: GlobalType: I32165# CHECK-NEXT: GlobalMutable: false166# CHECK-NEXT: - Module: env167# CHECK-NEXT: Field: __table_base168# CHECK-NEXT: Kind: GLOBAL169# CHECK-NEXT: GlobalType: I32170# CHECK-NEXT: GlobalMutable: false171# CHECK-NEXT: - Module: GOT.mem172# CHECK-NEXT: Field: indirect_func173# CHECK-NEXT: Kind: GLOBAL174# CHECK-NEXT: GlobalType: I32175# CHECK-NEXT: GlobalMutable: true176# CHECK-NEXT: - Module: GOT.func177# CHECK-NEXT: Field: func_external178# CHECK-NEXT: Kind: GLOBAL179# CHECK-NEXT: GlobalType: I32180# CHECK-NEXT: GlobalMutable: true181# CHECK-NEXT: - Module: GOT.mem182# CHECK-NEXT: Field: data_external183# CHECK-NEXT: Kind: GLOBAL184# CHECK-NEXT: GlobalType: I32185# CHECK-NEXT: GlobalMutable: true186# CHECK-NEXT: - Module: GOT.mem187# CHECK-NEXT: Field: extern_struct188# CHECK-NEXT: Kind: GLOBAL189# CHECK-NEXT: GlobalType: I32190# CHECK-NEXT: GlobalMutable: true191# CHECK-NEXT: - Type: FUNCTION192 193# CHECK: - Type: EXPORT194# CHECK-NEXT: Exports:195# CHECK-NEXT: - Name: __wasm_call_ctors196# CHECK-NEXT: Kind: FUNCTION197# CHECK-NEXT: Index: 0198 199# check for elem segment initialized with __table_base global as offset200 201# CHECK: - Type: ELEM202# CHECK-NEXT: Segments:203# CHECK-NEXT: - Offset:204# CHECK-NEXT: Opcode: GLOBAL_GET205# CHECK-NEXT: Index: 2206# CHECK-NEXT: Functions: [ 3, 2 ]207 208# check the generated code in __wasm_call_ctors and __wasm_apply_data_relocs functions209 210# DIS: <__wasm_call_ctors>:211# DIS-EMPTY:212# DIS-NEXT: end213 214# DIS: <__wasm_apply_data_relocs>:215# DIS-EMPTY:216# DIS-NEXT: i32.const 4217# DIS-NEXT: global.get 1218# DIS-NEXT: i32.add219# DIS-NEXT: global.get 4220# DIS-NEXT: i32.store 0221# DIS-NEXT: i32.const 8222# DIS-NEXT: global.get 1223# DIS-NEXT: i32.add224# DIS-NEXT: global.get 2225# DIS-NEXT: i32.const 1226# DIS-NEXT: i32.add227# DIS-NEXT: i32.store 0228# DIS-NEXT: i32.const 12229# DIS-NEXT: global.get 1230# DIS-NEXT: i32.add231# DIS-NEXT: global.get 1232# DIS-NEXT: i32.const 0233# DIS-NEXT: i32.add234# DIS-NEXT: i32.store 0235# DIS-NEXT: i32.const 16236# DIS-NEXT: global.get 1237# DIS-NEXT: i32.add238# DIS-NEXT: global.get 5239# DIS-NEXT: i32.store 0240# DIS-NEXT: i32.const 20241# DIS-NEXT: global.get 1242# DIS-NEXT: i32.add243# DIS-NEXT: global.get 6244# DIS-NEXT: i32.const 4245# DIS-NEXT: i32.add246# DIS-NEXT: i32.store 0247# DIS-NEXT: end248 249# check the data segment initialized with __memory_base global as offset250 251# CHECK: - Type: DATA252# CHECK-NEXT: Segments:253# CHECK-NEXT: - SectionOffset: 6254# CHECK-NEXT: InitFlags: 0255# CHECK-NEXT: Offset:256# CHECK-NEXT: Opcode: GLOBAL_GET257# CHECK-NEXT: Index: 1258# CHECK-NEXT: Content: '020000000000000001000000000000000000000000000000'259