1# Test that linking without shared memory causes __tls_base to be 2# internalized. 3 4# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s 5 6.globaltype __tls_base, i32 7 8.globl get_tls1 9get_tls1: 10 .functype get_tls1 () -> (i32) 11 global.get __tls_base 12 i32.const tls1@TLSREL 13 i32.add 14 end_function 15 16.globl get_tls1_got 17get_tls1_got: 18 .functype get_tls1_got () -> (i32) 19 global.get tls1@GOT@TLS 20 end_function 21 22.section .data.no_tls,"",@ 23.globl no_tls 24.p2align 2 25no_tls: 26 .int32 42 27 .size no_tls, 4 28 29.section .tdata.tls1,"T",@ 30.globl tls1 31.p2align 2 32tls1: 33 .int32 43 34 .size tls1, 2 35 36.section .custom_section.target_features,"",@ 37 .int8 2 38 .int8 43 39 .int8 7 40 .ascii "atomics" 41 .int8 43 42 .int8 11 43 .ascii "bulk-memory" 44 45# RUN: wasm-ld --no-gc-sections --no-entry -o %t.wasm %t.o 46# RUN: obj2yaml %t.wasm | FileCheck %s 47# RUN: llvm-objdump --disassemble-symbols=get_tls1 --no-show-raw-insn --no-leading-addr %t.wasm | FileCheck %s --check-prefixes DIS 48 49# RUN: wasm-ld --experimental-pic -shared -o %t.so %t.o 50# RUN: obj2yaml %t.so | FileCheck %s --check-prefixes=SHARED,PIC 51 52# RUN: wasm-ld --experimental-pic --no-gc-sections --no-entry -pie -o %t-pie.wasm %t.o 53# RUN: obj2yaml %t-pie.wasm | FileCheck %s --check-prefixes=PIE,PIC 54 55# RUN: wasm-ld --experimental-pic --features=atomics,bulk-memory,extended-const --no-gc-sections --no-entry -pie -o %t-extended-const.wasm %t.o 56# RUN: obj2yaml %t-extended-const.wasm | FileCheck %s --check-prefixes=EXT-CONST 57 58# CHECK: - Type: GLOBAL 59# __stack_pointer 60# CHECK-NEXT: Globals: 61# CHECK-NEXT: - Index: 0 62# CHECK-NEXT: Type: I32 63# CHECK-NEXT: Mutable: true 64# CHECK-NEXT: InitExpr: 65# CHECK-NEXT: Opcode: I32_CONST 66# CHECK-NEXT: Value: 66576 67# __tls_base 68# CHECK-NEXT: - Index: 1 69# CHECK-NEXT: Type: I32 70# CHECK-NEXT: Mutable: false 71# CHECK-NEXT: InitExpr: 72# CHECK-NEXT: Opcode: I32_CONST 73# CHECK-NEXT: Value: 1024 74# GOT.data.internal.tls1 75# CHECK-NEXT: - Index: 2 76# CHECK-NEXT: Type: I32 77# CHECK-NEXT: Mutable: false 78# CHECK-NEXT: InitExpr: 79# CHECK-NEXT: Opcode: I32_CONST 80# CHECK-NEXT: Value: 1024 81# CHECK-NEXT: - Type: EXPORT 82 83# CHECK: - Type: DATA 84# .data 85# CHECK-NEXT: Segments: 86# CHECK-NEXT: - SectionOffset: 7 87# CHECK-NEXT: InitFlags: 0 88# CHECK-NEXT: Offset: 89# CHECK-NEXT: Opcode: I32_CONST 90# CHECK-NEXT: Value: 1024 91# CHECK-NEXT: Content: 2B000000 92# .tdata 93# CHECK-NEXT: - SectionOffset: 17 94# CHECK-NEXT: InitFlags: 0 95# CHECK-NEXT: Offset: 96# CHECK-NEXT: Opcode: I32_CONST 97# CHECK-NEXT: Value: 1028 98# CHECK-NEXT: Content: 2A000000 99# CHECK-NEXT: - Type: CUSTOM 100 101# The constant value here which we add to `__tls_base` should not be absolute 102# but relative to `__tls_base`, in this case zero rather than 1024. 103# DIS: <get_tls1>: 104# DIS-EMPTY: 105# DIS-NEXT: global.get 1 106# DIS-NEXT: i32.const 0 107# DIS-NEXT: i32.add 108# DIS-NEXT: end 109 110# In PIC mode we expect TLS data and non-TLS data to be merged into 111# a single segment which is initialized via the __memory_base import 112 113# SHARED: - Type: IMPORT 114# SHARED-NEXT: Imports: 115# SHARED-NEXT: - Module: env 116# SHARED-NEXT: Field: memory 117# SHARED-NEXT: Kind: MEMORY 118# SHARED-NEXT: Memory: 119# SHARED-NEXT: Minimum: 0x1 120# SHARED-NEXT: - Module: env 121# SHARED-NEXT: Field: __memory_base 122# SHARED-NEXT: Kind: GLOBAL 123# SHARED-NEXT: GlobalType: I32 124 125# In SHARED mode we export the address of all data symbols. 126# SHARED: - Type: EXPORT 127# SHARED-NEXT: Exports: 128# SHARED: - Name: tls1 129# SHARED-NEXT: Kind: GLOBAL 130# SHARED: - Name: no_tls 131# SHARED-NEXT: Kind: GLOBAL 132 133# In PIE mode we don't export data address by default. 134# PIE: - Type: EXPORT 135# PIE-NEXT: Exports: 136# PIE-NEXT: - Name: memory 137# PIE-NEXT: Kind: MEMORY 138# PIE-NEXT: Index: 0 139# PIE-NEXT: - Type: 140 141# .tdata and .data are combined into single segment in PIC mode. 142# PIC: - Type: DATA 143# PIC-NEXT: Segments: 144# PIC-NEXT: - SectionOffset: 6 145# PIC-NEXT: InitFlags: 0 146# PIC-NEXT: Offset: 147# PIC-NEXT: Opcode: GLOBAL_GET 148# PIC-NEXT: Index: {{\d*}} 149# PIC-NEXT: Content: 2B0000002A000000 150# PIC-NEXT: - Type: CUSTOM 151 152# Unless we have extended-const, in which case the merging is not needed. 153# The first segment is placed directly at `__memory_base` and the second 154# one is offset from `__memory_base` using `i32.add` and a constant. 155 156# EXT-CONST: - Type: DATA 157# EXT-CONST-NEXT: Segments: 158# EXT-CONST-NEXT: - SectionOffset: 6 159# EXT-CONST-NEXT: InitFlags: 0 160# EXT-CONST-NEXT: Offset: 161# EXT-CONST-NEXT: Opcode: GLOBAL_GET 162# EXT-CONST-NEXT: Index: 1 163# EXT-CONST-NEXT: Content: 2B000000 164# EXT-CONST-NEXT: - SectionOffset: 18 165# EXT-CONST-NEXT: InitFlags: 0 166# EXT-CONST-NEXT: Offset: 167# EXT-CONST-NEXT: Extended: true 168# This instruction sequence decodes to: 169# (global.get[0x23] 0x1 i32.const[0x41] 0x04 i32.add[0x6A] end[0x0b]) 170# EXT-CONST-NEXT: Body: 230141046A0B 171# EXT-CONST-NEXT: Content: 2A000000 172