blob: 5b1df63bea6a3a19c1d00b2e17bb3185cf4c8d11 [file] [edit]
# REQUIRES: webassembly
# WebAssembly globals live in an index space of their own and hold values rather
# than bytes in the module, so they have no address to be named or read by. Give
# them a synthetic address space in which the offset is the global index, and
# serve the initializer when there is no process to ask for the current value.
# RUN: yaml2obj %s -o %t.wasm
# RUN: %lldb %t.wasm \
# RUN: -o "target modules dump sections" \
# RUN: -o "target modules dump symtab" \
# RUN: -o "image lookup -s g_answer" \
# RUN: -o "target modules load --file %t.wasm --slide 0x0000000400000000" \
# RUN: -o "target modules dump sections" \
# RUN: -o "memory read -s 4 -c 1 -f x 0x8000000400000001" \
# RUN: -o "memory read -s 8 -c 1 -f x 0x8000000400000002" \
# RUN: -o "memory read -s 8 -c 1 -f x 0x8000000400000004" \
# RUN: -o "memory read -s 4 -c 1 -f x 0x8000000400000005" \
# RUN: -o "memory read -s 1 -c 1 -f x 0x8000000400000001" \
# RUN: -o exit 2>&1 | FileCheck %s
# The global section spans the whole index space, imported globals included, and
# has a range of its own so that an index is not also a code or data address.
# CHECK: Dumping sections
# CHECK: wasm-global {{.*}}[0x8000000000000000-0x8000000000000006)
# Each named global becomes a data symbol spanning the one index it occupies.
# CHECK: Dumping symbol table
# CHECK: Data 0x8000000000000001 0x0000000000000001 {{.*}}g_answer
# CHECK: Data 0x8000000000000002 0x0000000000000001 {{.*}}g_double
# CHECK: Data 0x8000000000000004 0x0000000000000001 {{.*}}g_wide
# A global resolves to its index within that space.
# CHECK: 1 symbols match 'g_answer'
# CHECK: (wasm-globals.yaml.tmp.wasm.global + 1)
# Loading the module keeps the globals in their own space, with the module id.
# CHECK: Dumping sections
# CHECK: wasm-global {{.*}}[0x8000000400000000-0x8000000400000006)
# With no process to ask, a global reads back as the value it is initialized
# with, in the byte order WebAssembly gives its memory.
# CHECK: 0x8000000400000001: 0x0000002a
# CHECK: 0x8000000400000002: 0x3ff8000000000000
# CHECK: 0x8000000400000004: 0x00000000deadbeef
# All ones is a value like any other, not the absence of one.
# CHECK: 0x8000000400000005: 0xffffffff
# A type narrower than the global holding it reads the low bytes, which is how a
# char or short global is read.
# CHECK: 0x8000000400000001: 0x2a
# An imported global is declared by another module, so this one has neither a
# value type to size it nor an initializer to read, and gets no symbol.
# RUN: %lldb %t.wasm -o "image lookup -s g_imported" -o exit 2>&1 \
# RUN: | FileCheck --check-prefix=NOSYMBOL %s
# NOSYMBOL-NOT: symbols match 'g_imported'
# A read a global cannot serve fails rather than returning something plausible:
# an imported global has no initializer, an initializer that is not a constant
# has no value here, and reading past a global would have to come from somewhere
# else, because the next index is not adjacent storage.
# RUN: %lldb %t.wasm -o "memory read -s 4 -c 1 -f x 0x8000000000000000" -o exit 2>&1 \
# RUN: | FileCheck --check-prefix=NOVALUE %s
# RUN: %lldb %t.wasm -o "memory read -s 4 -c 1 -f x 0x8000000000000003" -o exit 2>&1 \
# RUN: | FileCheck --check-prefix=NOVALUE %s
# RUN: %lldb %t.wasm -o "memory read -s 8 -c 1 -f x 0x8000000000000001" -o exit 2>&1 \
# RUN: | FileCheck --check-prefix=NOVALUE %s
# NOVALUE: error reading data from section global
--- !WASM
FileHeader:
Version: 0x1
Sections:
- Type: TYPE
Signatures:
- Index: 0
ParamTypes: []
ReturnTypes:
- I32
- Type: IMPORT
Imports:
# An imported global occupies index 0, so the module's own globals start at
# index 1. It has no initializer here to read back.
- Module: env
Field: g_imported
Kind: GLOBAL
GlobalType: I32
GlobalMutable: false
# A tag import is what a module built with C++ exceptions carries. Its
# descriptor has a shape of its own, which the import section has to know in
# order to find where the next import starts.
- Module: env
Field: __cpp_exception
Kind: TAG
SigIndex: 0
- Type: FUNCTION
FunctionTypes: [ 0 ]
- Type: MEMORY
Memories:
- Minimum: 0x1
- Type: GLOBAL
Globals:
- Index: 1
Type: I32
Mutable: false
InitExpr:
Opcode: I32_CONST
Value: 42
# The bits of 1.5, a wider constant than the one before it, so the globals
# after this one only parse if this one was read at its own width.
- Index: 2
Type: F64
Mutable: false
InitExpr:
Opcode: F64_CONST
Value: 0x3FF8000000000000
# Initialized from another global rather than from a constant, so its value
# is only known once the module has been instantiated.
- Index: 3
Type: I32
Mutable: false
InitExpr:
Opcode: GLOBAL_GET
Index: 0
- Index: 4
Type: I64
Mutable: true
InitExpr:
Opcode: I64_CONST
Value: 3735928559
- Index: 5
Type: I32
Mutable: false
InitExpr:
Opcode: I32_CONST
Value: -1
- Type: CODE
Functions:
- Index: 0
Locals: []
Body: 412A0F0B
- Type: CUSTOM
Name: name
FunctionNames:
- Index: 0
Name: get_42
GlobalNames:
- Index: 0
Name: g_imported
- Index: 1
Name: g_answer
- Index: 2
Name: g_double
- Index: 3
Name: g_derived
- Index: 4
Name: g_wide
- Index: 5
Name: g_all_ones
...