262 lines · plain
1# RUN: llvm-mc -filetype=obj -triple=wasm64-unknown-unknown -o %t.o %s2# RUN: wasm-ld -mwasm64 --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, i6410.globaltype __table_base, i64, immutable11.globaltype __memory_base, i64, immutable12 13.section .data.data,"",@14data:15 .p2align 216 .int32 217 .size data, 418 19.section .data.indirect_func_external,"",@20indirect_func_external:21 .int64 func_external22.size indirect_func_external, 823 24.section .data.indirect_func,"",@25indirect_func:26 .int64 foo27 .size indirect_func, 828 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 .int64 data_external41 .size data_addr_external, 842 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 i64, i3261 global.get __stack_pointer62 i64.const 1663 i64.sub64 local.tee 065 global.set __stack_pointer66 global.get __memory_base67 i64.const data@MBREL68 i64.add69 i32.load 070 local.set 171 global.get indirect_func@GOT72 i64.load 073 i32.wrap_i6474 call_indirect () -> (i32)75 drop76 local.get 077 i64.const 1678 i64.add79 global.set __stack_pointer80 local.get 181 end_function82 83get_func_address:84 .functype get_func_address () -> (i64)85 global.get func_external@GOT86 end_function87 88get_data_address:89 .functype get_data_address () -> (i64)90 global.get data_external@GOT91 end_function92 93get_local_func_address:94 # Verify that a function which is otherwise not address taken *is* added to95 # the wasm table with referenced via R_WASM_TABLE_INDEX_REL_SLEB6496 .functype get_local_func_address () -> (i64)97 global.get __table_base98 i64.const get_func_address@TBREL99 i64.add100 end_function101 102.globl foo103.globl data104.globl indirect_func105.globl indirect_func_external106.globl data_addr107.globl data_addr_external108.globl extern_struct_internal_ptr109.globl get_data_address110.globl get_func_address111.globl get_local_func_address112 113.hidden foo114.hidden data115.hidden get_data_address116.hidden get_func_address117 118# Without this linking will fail because we import __stack_pointer (a mutable119# global).120# TODO(sbc): We probably want a nicer way to specify target_features section121# in assembly.122.section .custom_section.target_features,"",@123.int8 1124.int8 43125.int8 15126.ascii "mutable-globals"127 128# check for dylink section at start129 130# CHECK: Sections:131# CHECK-NEXT: - Type: CUSTOM132# CHECK-NEXT: Name: dylink.0133# CHECK-NEXT: MemorySize: 36134# CHECK-NEXT: MemoryAlignment: 2135# CHECK-NEXT: TableSize: 2136# CHECK-NEXT: TableAlignment: 0137# CHECK-NEXT: Needed: []138# CHECK-NEXT: - Type: TYPE139 140# check for import of __table_base and __memory_base globals141 142# CHECK: - Type: IMPORT143# CHECK-NEXT: Imports:144# CHECK-NEXT: - Module: env145# CHECK-NEXT: Field: memory146# CHECK-NEXT: Kind: MEMORY147# CHECK-NEXT: Memory:148# CHECK-NEXT: Flags: [ IS_64 ]149# CHECK-NEXT: Minimum: 0x1150# CHECK-NEXT: - Module: env151# CHECK-NEXT: Field: __indirect_function_table152# CHECK-NEXT: Kind: TABLE153# CHECK-NEXT: Table:154# CHECK-NEXT: Index: 0155# CHECK-NEXT: ElemType: FUNCREF156# CHECK-NEXT: Limits:157# CHECK-NEXT: Flags: [ IS_64 ]158# CHECK-NEXT: Minimum: 0x2159# CHECK-NEXT: - Module: env160# CHECK-NEXT: Field: __stack_pointer161# CHECK-NEXT: Kind: GLOBAL162# CHECK-NEXT: GlobalType: I64163# CHECK-NEXT: GlobalMutable: true164# CHECK-NEXT: - Module: env165# CHECK-NEXT: Field: __memory_base166# CHECK-NEXT: Kind: GLOBAL167# CHECK-NEXT: GlobalType: I64168# CHECK-NEXT: GlobalMutable: false169# CHECK-NEXT: - Module: env170# CHECK-NEXT: Field: __table_base171# CHECK-NEXT: Kind: GLOBAL172# CHECK-NEXT: GlobalType: I64173# CHECK-NEXT: GlobalMutable: false174# CHECK-NEXT: - Module: GOT.mem175# CHECK-NEXT: Field: indirect_func176# CHECK-NEXT: Kind: GLOBAL177# CHECK-NEXT: GlobalType: I64178# CHECK-NEXT: GlobalMutable: true179# CHECK-NEXT: - Module: GOT.func180# CHECK-NEXT: Field: func_external181# CHECK-NEXT: Kind: GLOBAL182# CHECK-NEXT: GlobalType: I64183# CHECK-NEXT: GlobalMutable: true184# CHECK-NEXT: - Module: GOT.mem185# CHECK-NEXT: Field: data_external186# CHECK-NEXT: Kind: GLOBAL187# CHECK-NEXT: GlobalType: I64188# CHECK-NEXT: GlobalMutable: true189# CHECK-NEXT: - Module: GOT.mem190# CHECK-NEXT: Field: extern_struct191# CHECK-NEXT: Kind: GLOBAL192# CHECK-NEXT: GlobalType: I64193# CHECK-NEXT: GlobalMutable: true194# CHECK-NEXT: - Type: FUNCTION195 196# CHECK: - Type: EXPORT197# CHECK-NEXT: Exports:198# CHECK-NEXT: - Name: __wasm_call_ctors199# CHECK-NEXT: Kind: FUNCTION200# CHECK-NEXT: Index: 0201 202# check for elem segment initialized with __table_base global as offset203 204# CHECK: - Type: ELEM205# CHECK-NEXT: Segments:206# CHECK-NEXT: - Offset:207# CHECK-NEXT: Opcode: GLOBAL_GET208# CHECK-NEXT: Index: 2209# CHECK-NEXT: Functions: [ 3, 2 ]210 211# check the generated code in __wasm_call_ctors and __wasm_apply_data_relocs functions212 213# DIS: <__wasm_call_ctors>:214# DIS-EMPTY:215# DIS-NEXT: end216 217# DIS: <__wasm_apply_data_relocs>:218# DIS-EMPTY:219# DIS-NEXT: i64.const 4220# DIS-NEXT: global.get 1221# DIS-NEXT: i64.add222# DIS-NEXT: global.get 4223# DIS-NEXT: i64.store 0:p2align=2224# DIS-NEXT: i64.const 12225# DIS-NEXT: global.get 1226# DIS-NEXT: i64.add227# DIS-NEXT: global.get 2228# DIS-NEXT: i64.const 1229# DIS-NEXT: i64.add230# DIS-NEXT: i64.store 0:p2align=2231# DIS-NEXT: i64.const 20232# DIS-NEXT: global.get 1233# DIS-NEXT: i64.add234# DIS-NEXT: global.get 1235# DIS-NEXT: i32.const 0236# DIS-NEXT: i32.add237# DIS-NEXT: i32.store 0238# DIS-NEXT: i64.const 24239# DIS-NEXT: global.get 1240# DIS-NEXT: i64.add241# DIS-NEXT: global.get 5242# DIS-NEXT: i64.store 0:p2align=2243# DIS-NEXT: i64.const 32244# DIS-NEXT: global.get 1245# DIS-NEXT: i64.add246# DIS-NEXT: global.get 6247# DIS-NEXT: i32.const 4248# DIS-NEXT: i32.add249# DIS-NEXT: i32.store 0250# DIS-NEXT: end251 252# check the data segment initialized with __memory_base global as offset253 254# CHECK: - Type: DATA255# CHECK-NEXT: Segments:256# CHECK-NEXT: - SectionOffset: 6257# CHECK-NEXT: InitFlags: 0258# CHECK-NEXT: Offset:259# CHECK-NEXT: Opcode: GLOBAL_GET260# CHECK-NEXT: Index: 1261# CHECK-NEXT: Content: '020000000000000000000000010000000000000000000000000000000000000000000000'262