summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/tools/wasm-split.cpp34
-rw-r--r--test/lit/wasm-split/instrument-funcs.wast2
-rw-r--r--test/lit/wasm-split/mismatched-hashes.wast23
3 files changed, 48 insertions, 11 deletions
diff --git a/src/tools/wasm-split.cpp b/src/tools/wasm-split.cpp
index a363b825b..32a726791 100644
--- a/src/tools/wasm-split.cpp
+++ b/src/tools/wasm-split.cpp
@@ -359,7 +359,7 @@ void Instrumenter::instrumentFuncs() {
});
}
-// wasm-split profile format::
+// wasm-split profile format:
//
// The wasm-split profile is a binary format designed to be simple to produce
// and consume. It is comprised of:
@@ -443,14 +443,23 @@ void Instrumenter::addProfileExport() {
// TODO: export the memory if it is not already exported.
}
+uint64_t hashFile(const std::string& filename) {
+ auto contents(read_file<std::vector<char>>(filename, Flags::Binary));
+ size_t digest = 0;
+ // Don't use `hash` or `rehash` - they aren't deterministic between executions
+ for (char c : contents) {
+ hash_combine(digest, c);
+ }
+ return uint64_t(digest);
+}
+
void instrumentModule(Module& wasm, const WasmSplitOptions& options) {
// Check that the profile export name is not already taken
if (wasm.getExportOrNull(options.profileExport) != nullptr) {
Fatal() << "error: Export " << options.profileExport << " already exists.";
}
- // TODO: calculate module hash.
- uint64_t moduleHash = 0;
+ uint64_t moduleHash = hashFile(options.input);
PassRunner runner(&wasm, options.passOptions);
Instrumenter(options.profileExport, moduleHash).run(&runner, &wasm);
@@ -471,16 +480,21 @@ std::set<Name> readProfile(Module& wasm, const WasmSplitOptions& options) {
Fatal() << "Unexpected end of profile data";
}
uint32_t i32 = 0;
- i32 |= uint32_t(profileData[i++]);
- i32 |= uint32_t(profileData[i++]) << 8;
- i32 |= uint32_t(profileData[i++]) << 16;
- i32 |= uint32_t(profileData[i++]) << 24;
+ i32 |= uint32_t(uint8_t(profileData[i++]));
+ i32 |= uint32_t(uint8_t(profileData[i++])) << 8;
+ i32 |= uint32_t(uint8_t(profileData[i++])) << 16;
+ i32 |= uint32_t(uint8_t(profileData[i++])) << 24;
return i32;
};
- // TODO: Read and compare the 8-byte module hash. Just skip it for now.
- readi32();
- readi32();
+ // Read and compare the 8-byte module hash.
+ uint64_t expected = readi32();
+ expected |= uint64_t(readi32()) << 32;
+ if (expected != hashFile(options.input)) {
+ Fatal() << "error: checksum in profile does not match module checksum. "
+ << "The split module must be the original module that was "
+ << "instrumented to generate the profile.";
+ }
std::set<Name> keptFuncs;
ModuleUtils::iterDefinedFunctions(wasm, [&](Function* func) {
diff --git a/test/lit/wasm-split/instrument-funcs.wast b/test/lit/wasm-split/instrument-funcs.wast
index bdd222d82..4b729aed2 100644
--- a/test/lit/wasm-split/instrument-funcs.wast
+++ b/test/lit/wasm-split/instrument-funcs.wast
@@ -59,7 +59,7 @@
;; CHECK-NEXT: (block
;; CHECK-NEXT: (i64.store align=1
;; CHECK-NEXT: (local.get $addr)
-;; CHECK-NEXT: (i64.const 0)
+;; CHECK-NEXT: (i64.const {{.*}})
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.store offset=8 align=1
;; CHECK-NEXT: (local.get $addr)
diff --git a/test/lit/wasm-split/mismatched-hashes.wast b/test/lit/wasm-split/mismatched-hashes.wast
new file mode 100644
index 000000000..561135bbe
--- /dev/null
+++ b/test/lit/wasm-split/mismatched-hashes.wast
@@ -0,0 +1,23 @@
+;; Check that using different inputs for the instrumentation and splitting steps
+;; results in an error.
+
+;; Instrument the module
+;; RUN: wasm-split --instrument %s -o %t.instrumented.wasm
+
+;; Generate a profile
+;; RUN: node %S/call_exports.mjs %t.instrumented.wasm %t.prof
+
+;; Attempt to split the instrumented module
+;; RUN: not wasm-split %t.instrumented.wasm --profile=%t.prof -o1 %t.1.wasm -o2 %t.2.wasm \
+;; RUN: 2>&1 | filecheck %s
+
+;; CHECK: error: checksum in profile does not match module checksum.
+;; CHECK-SAME: The split module must be the original module that was instrumented
+;; CHECK-SAME: to generate the profile.
+
+;; Check that the matcing module succeeds
+;; RUN: wasm-split %s --profile=%t.prof -o1 %t.1.wasm -o2 %t.2.wasm
+
+(module
+ (export "memory" (memory 0 0))
+)