Skip to content

Commit

Permalink
[PostEmscripten] Fix calcSegmentOffsets for large offsets (WebAssembl…
Browse files Browse the repository at this point in the history
…y#6260)

Specifically offsets larger than 2^32 which were being interpreted
misinterpreted here as very large int64_t values.
  • Loading branch information
sbc100 authored and radekdoulik committed Jul 12, 2024
1 parent f1ead41 commit fea72ee
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 14 deletions.
7 changes: 3 additions & 4 deletions src/passes/PostEmscripten.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,11 @@ static void calcSegmentOffsets(Module& wasm,
return;
}
}
auto it = offsets.find(curr->segment);
if (it != offsets.end()) {
if (offsets.find(curr->segment) != offsets.end()) {
Fatal() << "Cannot get offset of passive segment initialized "
"multiple times";
}
offsets[curr->segment] = dest->value.getInteger();
offsets[curr->segment] = dest->value.getUnsigned();
}
} searcher(passiveOffsets);
searcher.walkModule(&wasm);
Expand Down Expand Up @@ -317,7 +316,7 @@ struct PostEmscripten : public Pass {
// The first operand is the function pointer index, which must be
// constant if we are to optimize it statically.
if (auto* index = curr->operands[0]->dynCast<Const>()) {
size_t indexValue = index->value.getInteger();
size_t indexValue = index->value.getUnsigned();
if (indexValue >= flatTable.names.size()) {
// UB can lead to indirect calls to invalid pointers.
return;
Expand Down
42 changes: 32 additions & 10 deletions test/lit/passes/post-emscripten.wast
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
;; RUN: wasm-opt %s --post-emscripten -S -o - | filecheck %s
;; RUN: wasm-opt %s --enable-bulk-memory --post-emscripten -S -o - | filecheck %s

;; Checks that the start/stop exports are removed and that the data they
;; refer to is either zero'd out, or the segment emptied.

;; Two of the segments used here are active, so their offsets are trivial
;; to dirive. One segment is passive and its offset is derived from the
;; memory.init instruction.

;; Explictly use a data address that is larger then INT_MAX to verify
;; that these offset are correctly interpreted as unsigned.

(module
;; CHECK: (type $0 (func))

;; CHECK: (global $em_asm_start i32 (i32.const 1000))
(global $em_asm_start i32 (i32.const 1000))
;; CHECK: (global $em_asm_stop i32 (i32.const 1011))
(global $em_asm_stop i32 (i32.const 1011))
;; CHECK: (global $em_js_start i32 (i32.const 2006))
(global $em_js_start i32 (i32.const 2006))
;; CHECK: (global $em_js_stop i32 (i32.const 2015))
(global $em_js_stop i32 (i32.const 2015))
;; CHECK: (global $em_js_start i32 (i32.const -1294967290))
(global $em_js_start i32 (i32.const 3000000006))
;; CHECK: (global $em_js_stop i32 (i32.const -1294967281))
(global $em_js_stop i32 (i32.const 3000000015))
;; CHECK: (global $em_lib_deps_start i32 (i32.const 3000))
(global $em_lib_deps_start i32 (i32.const 3000))
;; CHECK: (global $em_lib_deps_stop i32 (i32.const 3009))
Expand All @@ -21,13 +30,12 @@
(global $foo_start i32 (i32.const 4000))
;; CHECK: (global $foo_stop i32 (i32.const 4015))
(global $foo_stop i32 (i32.const 4015))
(memory 10 10)
;; CHECK: (memory $0 10 10)

;; CHECK: (memory $mem 10 10)
(memory $mem 10 10)
;; CHECK: (data $data1 (i32.const 1000) "")
(data $data1 (i32.const 1000) "hello world")
;; CHECK: (data $data2 (i32.const 2000) "hello \00\00\00\00\00\00\00\00\00 world")
(data $data2 (i32.const 2000) "hello DELETE ME world")
;; CHECK: (data $data2 "hello \00\00\00\00\00\00\00\00\00 world")
(data $data2 "hello DELETE ME world")
;; CHECK: (data $data3 (i32.const 3000) "")
(data $data3 (i32.const 3000) "some deps")
(export "__start_em_asm" (global $em_asm_start))
Expand All @@ -40,4 +48,18 @@
(export "__start_foo" (global $foo_start))
;; CHECK: (export "__stop_foo" (global $foo_stop))
(export "__stop_foo" (global $foo_stop))
;; CHECK: (func $meminit
;; CHECK-NEXT: (memory.init $data2
;; CHECK-NEXT: (i32.const -1294967296)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (i32.const 21)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $meminit
(memory.init $mem $data2
(i32.const 3000000000)
(i32.const 0)
(i32.const 21)
)
)
)

0 comments on commit fea72ee

Please sign in to comment.