diff options
-rwxr-xr-x | scripts/test/generate_lld_tests.py | 3 | ||||
-rw-r--r-- | scripts/test/lld.py | 64 | ||||
-rw-r--r-- | test/lld/basic_safe_stack.s | 38 | ||||
-rw-r--r-- | test/lld/basic_safe_stack.wat | 41 | ||||
-rw-r--r-- | test/lld/basic_safe_stack.wat.out | 116 |
5 files changed, 230 insertions, 32 deletions
diff --git a/scripts/test/generate_lld_tests.py b/scripts/test/generate_lld_tests.py index 25a72f885..8338ffbd9 100755 --- a/scripts/test/generate_lld_tests.py +++ b/scripts/test/generate_lld_tests.py @@ -34,7 +34,7 @@ def generate_wat_files(llvm_bin, emscripten_root): print('\n[ building wat files from C sources... ]\n') lld_path = os.path.join(shared.options.binaryen_test, 'lld') - for src_file, ext in files_with_extensions(lld_path, ['.c', '.cpp']): + for src_file, ext in files_with_extensions(lld_path, ['.c', '.cpp', '.s']): print('..', src_file) obj_file = src_file.replace(ext, '.o') @@ -69,6 +69,7 @@ def generate_wat_files(llvm_bin, emscripten_root): '--export', '__wasm_call_ctors', '--export', '__data_end', '--global-base=568', + '--no-gc-sections', ] # We had a regression where this test only worked if debug names # were included. diff --git a/scripts/test/lld.py b/scripts/test/lld.py index 19528ebc6..1407ea4b7 100644 --- a/scripts/test/lld.py +++ b/scripts/test/lld.py @@ -30,41 +30,43 @@ def args_for_finalize(filename): return ret +def run_test(input_path): + print('..', input_path) + is_passive = '.passive.' in input_path + mem_file = input_path + '.mem' + extension_arg_map = { + '.out': [], + } + if not is_passive: + extension_arg_map.update({ + '.mem.out': ['--separate-data-segments', mem_file], + }) + for ext, args in extension_arg_map.items(): + expected_file = input_path + ext + if ext != '.out' and not os.path.exists(expected_file): + continue + + cmd = shared.WASM_EMSCRIPTEN_FINALIZE + [input_path, '-S'] + args + cmd += args_for_finalize(os.path.basename(input_path)) + actual = support.run_command(cmd) + + if not os.path.exists(expected_file): + print(actual) + shared.fail_with_error('output ' + expected_file + + ' does not exist') + shared.fail_if_not_identical_to_file(actual, expected_file) + if ext == '.mem.out': + with open(mem_file) as mf: + mem = mf.read() + shared.fail_if_not_identical_to_file(mem, input_path + '.mem.mem') + os.remove(mem_file) + + def test_wasm_emscripten_finalize(): print('\n[ checking wasm-emscripten-finalize testcases... ]\n') for input_path in shared.get_tests(shared.get_test_dir('lld'), ['.wat', '.wasm']): - print('..', input_path) - is_passive = '.passive.' in input_path - mem_file = input_path + '.mem' - extension_arg_map = { - '.out': [], - } - if not is_passive: - extension_arg_map.update({ - '.mem.out': ['--separate-data-segments', mem_file], - }) - for ext, ext_args in extension_arg_map.items(): - expected_file = input_path + ext - if ext != '.out' and not os.path.exists(expected_file): - continue - - cmd = shared.WASM_EMSCRIPTEN_FINALIZE + [input_path, '-S'] + \ - ext_args - cmd += args_for_finalize(os.path.basename(input_path)) - actual = support.run_command(cmd) - - if not os.path.exists(expected_file): - print(actual) - shared.fail_with_error('output ' + expected_file + - ' does not exist') - shared.fail_if_not_identical_to_file(actual, expected_file) - if ext == '.mem.out': - with open(mem_file) as mf: - mem = mf.read() - shared.fail_if_not_identical_to_file(mem, input_path + - '.mem.mem') - os.remove(mem_file) + run_test(input_path) def update_lld_tests(): diff --git a/test/lld/basic_safe_stack.s b/test/lld/basic_safe_stack.s new file mode 100644 index 000000000..74614e798 --- /dev/null +++ b/test/lld/basic_safe_stack.s @@ -0,0 +1,38 @@ +# Test that wasm-binaryen-finalize --check-stack-overflow correctly +# inserts stack chekc handlers. + +.globl stackRestore +.globl stackAlloc + +.globaltype __stack_pointer, i32 + +stackRestore: + .functype stackRestore(i32) -> () + local.get 0 + global.set __stack_pointer + end_function + +stackAlloc: + .functype stackAlloc(i32) -> (i32) + .local i32, i32 + global.get __stack_pointer + # Get arg 0 -> number of bytes to allocate + local.get 0 + # Stack grows down. Subtract arg0 from __stack_pointer + i32.sub + # Align result by anding with ~15 + i32.const 0xfffffff0 + i32.and + local.tee 1 + global.set __stack_pointer + local.get 1 + end_function + +.globl main +main: + .functype main () -> () + end_function + +.export_name stackAlloc, stackAlloc +.export_name stackSave, stackSave +.export_name stackRestore, stackRestore diff --git a/test/lld/basic_safe_stack.wat b/test/lld/basic_safe_stack.wat new file mode 100644 index 000000000..27f172913 --- /dev/null +++ b/test/lld/basic_safe_stack.wat @@ -0,0 +1,41 @@ +(module + (type $none_=>_none (func)) + (type $i32_=>_none (func (param i32))) + (type $i32_=>_i32 (func (param i32) (result i32))) + (memory $0 2) + (table $0 1 1 funcref) + (global $global$0 (mut i32) (i32.const 66112)) + (global $global$1 i32 (i32.const 568)) + (export "memory" (memory $0)) + (export "__wasm_call_ctors" (func $__wasm_call_ctors)) + (export "stackRestore" (func $stackRestore)) + (export "stackAlloc" (func $stackAlloc)) + (export "main" (func $main)) + (export "__data_end" (global $global$1)) + (func $__wasm_call_ctors + ) + (func $stackRestore (param $0 i32) + (global.set $global$0 + (local.get $0) + ) + ) + (func $stackAlloc (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (global.set $global$0 + (local.tee $1 + (i32.and + (i32.sub + (global.get $global$0) + (local.get $0) + ) + (i32.const -16) + ) + ) + ) + (local.get $1) + ) + (func $main + ) +) + diff --git a/test/lld/basic_safe_stack.wat.out b/test/lld/basic_safe_stack.wat.out new file mode 100644 index 000000000..037d729df --- /dev/null +++ b/test/lld/basic_safe_stack.wat.out @@ -0,0 +1,116 @@ +(module + (type $none_=>_none (func)) + (type $i32_=>_none (func (param i32))) + (type $i32_=>_i32 (func (param i32) (result i32))) + (type $none_=>_i32 (func (result i32))) + (import "env" "__handle_stack_overflow" (func $__handle_stack_overflow)) + (memory $0 2) + (table $0 1 1 funcref) + (global $global$0 (mut i32) (i32.const 66112)) + (global $global$1 i32 (i32.const 568)) + (global $__stack_limit (mut i32) (i32.const 0)) + (export "memory" (memory $0)) + (export "__wasm_call_ctors" (func $__wasm_call_ctors)) + (export "stackRestore" (func $stackRestore)) + (export "stackAlloc" (func $stackAlloc)) + (export "main" (func $main)) + (export "__data_end" (global $global$1)) + (export "__set_stack_limit" (func $__set_stack_limit)) + (export "stackSave" (func $stackSave)) + (export "__growWasmMemory" (func $__growWasmMemory)) + (func $__wasm_call_ctors + (nop) + ) + (func $stackRestore (param $0 i32) + (local $1 i32) + (if + (i32.lt_u + (local.tee $1 + (local.get $0) + ) + (global.get $__stack_limit) + ) + (call $__handle_stack_overflow) + ) + (global.set $global$0 + (local.get $1) + ) + ) + (func $stackAlloc (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (block + (if + (i32.lt_u + (local.tee $3 + (local.tee $1 + (i32.and + (i32.sub + (global.get $global$0) + (local.get $0) + ) + (i32.const -16) + ) + ) + ) + (global.get $__stack_limit) + ) + (call $__handle_stack_overflow) + ) + (global.set $global$0 + (local.get $3) + ) + ) + (local.get $1) + ) + (func $main + (nop) + ) + (func $__set_stack_limit (param $0 i32) + (global.set $__stack_limit + (local.get $0) + ) + ) + (func $stackSave (result i32) + (global.get $global$0) + ) + (func $__growWasmMemory (param $newSize i32) (result i32) + (memory.grow + (local.get $newSize) + ) + ) +) +(; +--BEGIN METADATA -- +{ + "staticBump": 0, + "tableSize": 1, + "initializers": [ + "__wasm_call_ctors" + ], + "declares": [ + "__handle_stack_overflow" + ], + "externs": [ + ], + "exports": [ + "__wasm_call_ctors", + "stackRestore", + "stackAlloc", + "main", + "__set_stack_limit", + "stackSave", + "__growWasmMemory" + ], + "namedGlobals": { + "__data_end" : "568" + }, + "invokeFuncs": [ + ], + "features": [ + ], + "mainReadsParams": 1 +} +-- END METADATA -- +;) |