Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for big-endian platforms. #198

Merged
merged 2 commits into from
Feb 6, 2022

Conversation

knm3000
Copy link
Contributor

@knm3000 knm3000 commented Nov 8, 2021

Wasm binary always has Little-endian byte ordering. V8 is hardcoded to reverse the bytes with every wasm load/store operation done on Big-endian machines. But in case of envoy proxy the wasm binary file is linked with envoy C code compiled on a native BE machine. In this case a BE value is being written to LE enforced memory, and the crash happens when running wasm on BE machine. To fix this, everything needs to be written to memory in LE order when linking with any other libraries outside the wasm binary itself.
Resolves #197

@knm3000 knm3000 changed the title Fix for the crash on big endian machine. (#197) Fix for the crash on big endian machine Nov 8, 2021
Copy link
Member

@PiotrSikora PiotrSikora left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the report and this fix!

But is it complete? Do we need to do anything for getWord and/or other runtimes?

Also, are you able to pass all tests in this repo and Wasm tests in Envoy with this fix? Sorry, normally I'd verify this myself, but I don't have access to any big-endian machine.

src/v8/v8.cc Outdated
@@ -441,7 +441,11 @@ bool V8::setWord(uint64_t pointer, Word word) {
if (pointer + size > memory_->data_size()) {
return false;
}
#if BYTE_ORDER == LITTLE_ENDIAN
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where are those defines coming from? I'm not sure if this is the most portable way to detect endianess. I'd prefer using __BYTE_ORDER__ and friends, since that's supported by both GCC and Clang:

#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
  uint32_t word32 = __builtin_bswap32(word.u32());
#else
  uint32_t word32 = word.u32();
#endif

Note the different order to fallback to little-endian in case of missing defines.

@knm3000
Copy link
Contributor Author

knm3000 commented Nov 19, 2021

Thanks for the review, I've changed the code to use __BYTE_ORDER__
I believe V8 is the only runtime, that supports s390x (other wasm runtimes do not).
As for getWord, I don't think we need more reversals: one reversal is done in setWord, and the other reversal is done by V8 itself when V8 runs on BE.
I tried to run tests from this repo, however, it is not possible to compile them on s390x with bazel:

ERROR: Analysis of target '//test:exports_test' failed; build aborted: no matching toolchains found for types @rules_rust//rust:toolchain

Bazel 'rules_rust' is not supported on s390x: https://github.com/bazelbuild/rules_rust/releases
I may try to manually (without bazel) compile wasm rust tests from envoy repo, and when possible manually run some of them using -c envoy.yaml option (similar to this repo test https://github.com/maistra/header-append-filter).
As for c++ wasm tests, emscripten is not supported on s390x (the workaround is to compile *.wasm on x86 machine and transfer it to s390x).

@PiotrSikora
Copy link
Member

Bazel 'rules_rust' is not supported on s390x: https://github.com/bazelbuild/rules_rust/releases I may try to manually (without bazel) compile wasm rust tests from envoy repo, and when possible manually run some of them using -c envoy.yaml option (similar to this repo test https://github.com/maistra/header-append-filter). As for c++ wasm tests, emscripten is not supported on s390x (the workaround is to compile *.wasm on x86 machine and transfer it to s390x).

rules_rust supports s390x-unknown-linux-gnu target, but it's not included in the DEFAULT_TOOLCHAIN_TRIPLES, so you need to provide it manually in the WORKSPACE file... maybe using rust_repository_set?

Copy link
Member

@PiotrSikora PiotrSikora left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I'll wait with merging it for a bit to see if you can figure out how to run Rust tests.

@knm3000
Copy link
Contributor Author

knm3000 commented Nov 25, 2021

Could run the tests on s390x with the following local code changes:

  1. Added rust_repository_set to WORKSPACE:
load("@rules_rust//rust:repositories.bzl", "rust_repository_set")
rust_repository_set(
    name = "rust_linux_s390x",
    exec_triple = "s390x-unknown-linux-gnu",
    extra_target_triples = ["wasm32-unknown-unknown", "wasm32-wasi"],
    version = "1.56.0",
)
  1. boringssl is not supported on s390x:
In file included from src/signature_util.cc:20:
In file included from external/boringssl/src/include/openssl/curve25519.h:18:
external/boringssl/src/include/openssl/base.h:122:2: error: "Unknown target CPU"
#error "Unknown target CPU"
 ^
1 error generated.

So I had to use this fork https://github.com/maistra/proxy-wasm-cpp-host to compile the tests (boringssl is replaced with openssl).

  1. rust-lld linker is not available for s390x, therefore it is not included into bazel s390 rust toolchain.
INFO: From Compiling Rust cdylib _wasm_clock_wasm (1 files):
error: linker `rust-lld` not found

Replaced rust-lld with lld (added rustc_flags = ["-C", "linker=/usr/bin/lld"], to each wasm_rust_binary in https://github.com/proxy-wasm/proxy-wasm-cpp-host/blob/master/test/test_data/BUILD)

tests on s390x:

# bazel test //test/...
INFO: Analyzed 9 targets (79 packages loaded, 2127 targets configured).
INFO: Found 1 target and 8 test targets...
INFO: Elapsed time: 36.022s, Critical Path: 4.59s
INFO: 173 processes: 68 internal, 105 processwrapper-sandbox.
INFO: Build completed successfully, 173 total actions
//test:bytecode_util_test                                                PASSED in 0.2s
//test:exports_test                                                      PASSED in 0.1s
//test:null_vm_test                                                      PASSED in 0.2s
//test:runtime_test                                                      PASSED in 0.2s
//test:shared_data                                                       PASSED in 0.1s
//test:shared_queue                                                      PASSED in 0.1s
//test:vm_id_handle                                                      PASSED in 0.1s
//test:wasm_test                                                         PASSED in 0.1s

@PiotrSikora
Copy link
Member

Hi @knm3000, thanks for getting those tests to work! However, you response reminded me that we don't actually run tests against V8 in Proxy-Wasm C++ Host repo (we always relied on testing all the way in Envoy), which obviously isn't great.

It took me way too much time, but I finally managed to get V8 working in #204, and if you checkout/cherry-pick that PR, then you should be able to run tests against V8 using:

bazel test --runtime=v8 //test/...

Note: Bazel support in V8 is still under active development, and I've extended list of source files to include those needed by s390x and added some defines, but it was never tested on a s390x system, so I'm not sure if it works.

@knm3000
Copy link
Contributor Author

knm3000 commented Jan 7, 2022

Hi @PiotrSikora, I have built the tests with v8 on s390x using your latest changes, the following extra changes are required for the build: #214
After that I see that some tests fail on s390x when running with bazel test --define runtime=v8 //test/...
//test:exports_test FAILED and //test:runtime_test FAILED.
I'll continue working on this (PR 214 is to fix the build problem only).

@PiotrSikora
Copy link
Member

//test:exports_test fails with and without your patch, so something is still broken:

[==========] Running 3 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 3 tests from Runtimes/TestVM
[ RUN      ] Runtimes/TestVM.Environment/0
test/exports_test.cc:70: Failure
Expected: (std::string::npos) != (msg.find("KEY1: VALUE1\n")), actual: 18446744073709551615 vs 18446744073709551615
test/exports_test.cc:71: Failure
Expected: (std::string::npos) != (msg.find("KEY2: VALUE2\n")), actual: 18446744073709551615 vs 18446744073709551615
[  FAILED  ] Runtimes/TestVM.Environment/0, where GetParam() = "v8" (1237 ms)
[ RUN      ] Runtimes/TestVM.WithoutEnvironment/0
[       OK ] Runtimes/TestVM.WithoutEnvironment/0 (227 ms)
[ RUN      ] Runtimes/TestVM.Clock/0
ERROR from integration: Function: run failed: Uncaught RuntimeError: unreachable
test/exports_test.cc:113: Failure
Expected: (std::string::npos) != (msg.find("monotonic: ")), actual: 18446744073709551615 vs 18446744073709551615
test/exports_test.cc:114: Failure
Expected: (std::string::npos) != (msg.find("realtime: ")), actual: 18446744073709551615 vs 18446744073709551615
[  FAILED  ] Runtimes/TestVM.Clock/0, where GetParam() = "v8" (241 ms)
[----------] 3 tests from Runtimes/TestVM (1707 ms total)

However, //test:runtime_test fails only with this patch, and passes without it (at least for me, on s390x under QEMU):

[==========] Running 7 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 7 tests from Runtimes/TestVM
[ RUN      ] Runtimes/TestVM.Basic/0
[       OK ] Runtimes/TestVM.Basic/0 (7 ms)
[ RUN      ] Runtimes/TestVM.Memory/0
test/runtime_test.cc:57: Failure
Expected equality of these values:
  100
  word.u64_
    Which is: 1677721600
[  FAILED  ] Runtimes/TestVM.Memory/0, where GetParam() = "v8" (3166 ms)
[ RUN      ] Runtimes/TestVM.Clone/0
test/runtime_test.cc:86: Failure
Expected equality of these values:
  100
  word.u64_
    Which is: 1677721600
[  FAILED  ] Runtimes/TestVM.Clone/0, where GetParam() = "v8" (1993 ms)
[ RUN      ] Runtimes/TestVM.StraceLogLevel/0
TRACE from integration: [host->vm] run()
TRACE from integration: [vm->host] env.callback()
TRACE from integration: [vm<-host] env.callback return: void
TRACE from integration: [host<-vm] run return: void
[       OK ] Runtimes/TestVM.StraceLogLevel/0 (1381 ms)
[ RUN      ] Runtimes/TestVM.Callback/0
[       OK ] Runtimes/TestVM.Callback/0 (1313 ms)
[ RUN      ] Runtimes/TestVM.Trap/0
ERROR from integration: Function: trigger failed: Uncaught RuntimeError: unreachable
[       OK ] Runtimes/TestVM.Trap/0 (1241 ms)
[ RUN      ] Runtimes/TestVM.Trap2/0
ERROR from integration: Function: trigger2 failed: Uncaught RuntimeError: unreachable
[       OK ] Runtimes/TestVM.Trap2/0 (1370 ms)
[----------] 7 tests from Runtimes/TestVM (10475 ms total)

[----------] Global test environment tear-down
[==========] 7 tests from 1 test suite ran. (10481 ms total)

@knm3000
Copy link
Contributor Author

knm3000 commented Jan 10, 2022

On the real s390x hardware the test results are the same.
There is 1 difference between "without patch" and "with patch" use cases for //test:exports_test

without patch: Uncaught RuntimeError: memory access out of bounds

Running main() from gmock_main.cc
[==========] Running 3 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 3 tests from Runtimes/TestVM
[ RUN      ] Runtimes/TestVM.Environment/0
ERROR from integration: Function: run failed: Uncaught RuntimeError: memory access out of bounds
test/exports_test.cc:70: Failure
Expected: (std::string::npos) != (msg.find("KEY1: VALUE1\n")), actual: 18446744073709551615 vs 18446744073709551615
test/exports_test.cc:71: Failure
Expected: (std::string::npos) != (msg.find("KEY2: VALUE2\n")), actual: 18446744073709551615 vs 18446744073709551615
[  FAILED  ] Runtimes/TestVM.Environment/0, where GetParam() = "v8" (297 ms)
[ RUN      ] Runtimes/TestVM.WithoutEnvironment/0
[       OK ] Runtimes/TestVM.WithoutEnvironment/0 (153 ms)
[ RUN      ] Runtimes/TestVM.Clock/0
ERROR from integration: Function: run failed: Uncaught RuntimeError: unreachable
test/exports_test.cc:113: Failure
Expected: (std::string::npos) != (msg.find("monotonic: ")), actual: 18446744073709551615 vs 18446744073709551615
test/exports_test.cc:114: Failure
Expected: (std::string::npos) != (msg.find("realtime: ")), actual: 18446744073709551615 vs 18446744073709551615
[  FAILED  ] Runtimes/TestVM.Clock/0, where GetParam() = "v8" (153 ms)
[----------] 3 tests from Runtimes/TestVM (603 ms total)

with patch: Uncaught RuntimeError: unreachable

Running main() from gmock_main.cc
[==========] Running 3 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 3 tests from Runtimes/TestVM
[ RUN      ] Runtimes/TestVM.Environment/0
ERROR from integration: Function: run failed: Uncaught RuntimeError: unreachable
test/exports_test.cc:70: Failure
Expected: (std::string::npos) != (msg.find("KEY1: VALUE1\n")), actual: 18446744073709551615 vs 18446744073709551615
test/exports_test.cc:71: Failure
Expected: (std::string::npos) != (msg.find("KEY2: VALUE2\n")), actual: 18446744073709551615 vs 18446744073709551615
[  FAILED  ] Runtimes/TestVM.Environment/0, where GetParam() = "v8" (290 ms)
[ RUN      ] Runtimes/TestVM.WithoutEnvironment/0
[       OK ] Runtimes/TestVM.WithoutEnvironment/0 (193 ms)
[ RUN      ] Runtimes/TestVM.Clock/0
ERROR from integration: Function: run failed: Uncaught RuntimeError: unreachable
test/exports_test.cc:113: Failure
Expected: (std::string::npos) != (msg.find("monotonic: ")), actual: 18446744073709551615 vs 18446744073709551615
test/exports_test.cc:114: Failure
Expected: (std::string::npos) != (msg.find("realtime: ")), actual: 18446744073709551615 vs 18446744073709551615
[  FAILED  ] Runtimes/TestVM.Clock/0, where GetParam() = "v8" (267 ms)
[----------] 3 tests from Runtimes/TestVM (750 ms total)

Anyway, it is not good, and I need to fix this.

@PiotrSikora
Copy link
Member

@knm3000 not much help with the bug itself, but with #216, #219, #220 and #221, you should be able to build Proxy-Wasm C++ Host on Linux/s390x without any patches. Thanks for the pointers in this PR!

Copy link
Member

@PiotrSikora PiotrSikora left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unapproving until this can pass the tests.

@knm3000
Copy link
Contributor Author

knm3000 commented Jan 24, 2022

Hi @PiotrSikora , I've updated the PR, now the tests are passed on s390x, can you please review? Thanks.

[root@41602232c1ef proxy-wasm-cpp-host]# bazel-4.2.2 test --define runtime=v8 //test/...
INFO: Analyzed 9 targets (0 packages loaded, 0 targets configured).
INFO: Found 1 target and 8 test targets...
INFO: Elapsed time: 0.919s, Critical Path: 0.00s
INFO: 1 process: 1 internal.
INFO: Build completed successfully, 1 total action
//test:bytecode_util_test                                       (cached) PASSED in 0.0s
//test:exports_test                                             (cached) PASSED in 0.7s
//test:null_vm_test                                             (cached) PASSED in 0.0s
//test:runtime_test                                             (cached) PASSED in 0.7s
//test:shared_data                                              (cached) PASSED in 0.0s
//test:shared_queue                                             (cached) PASSED in 0.0s
//test:vm_id_handle                                             (cached) PASSED in 0.0s
//test:wasm_test                                                (cached) PASSED in 0.3s

Executed 0 out of 8 tests: 8 tests pass.
INFO: Build completed successfully, 1 total action

Copy link
Member

@PiotrSikora PiotrSikora left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this!

I'm looking at those changes, and they all (sans the one case with getMemory) do the same swap in various (but not all) calls to setWord. I imagine that the remaining instances were omitted because of a poor test coverage in this repository, and not because they aren't needed.

Do you think we could do the swap in Word constructor in include/proxy-wasm/word.h? That should solve this at the core.

@knm3000
Copy link
Contributor Author

knm3000 commented Jan 28, 2022

I tried swapping in Word constructor (and in setMemory method from v8.cc), it doesn't work.
We don't need to swap everything, most calls to Word constructor or to setWord() work fine on BE machines without swapping. We need to swap only in functions, that are outside of wasm binary (and are compiled on a native s390x machine). E.g. extern "C" functions from https://github.com/proxy-wasm/proxy-wasm-rust-sdk/blob/master/src/hostcalls.rs
These functions are defined in https://github.com/proxy-wasm/proxy-wasm-cpp-host/blob/master/src/exports.cc and they also make calls to copyToPointerSize() from https://github.com/proxy-wasm/proxy-wasm-cpp-host/blob/master/include/proxy-wasm/wasm.h

This time I put some more calls to __builtin_bswap32 into exports.cc (I found more errors when running a different example https://github.com/proxy-wasm/proxy-wasm-rust-sdk/blob/master/examples/http_headers.rs, and when compiling http_headers.wasm binary for s390x target, I also had to change from_le_bytes to from_be_bytes in https://github.com/proxy-wasm/proxy-wasm-rust-sdk/blob/master/src/hostcalls.rs to make it work).

Anyway, we need to swap only in exports.cc (and not in any other places).

The tests still work with the latest update to PR code:

[root@41602232c1ef proxy-wasm-cpp-host]# bazel-4.2.2 test --define runtime=v8 //test/...
INFO: Analyzed 9 targets (0 packages loaded, 0 targets configured).
INFO: Found 1 target and 8 test targets...
INFO: Elapsed time: 0.372s, Critical Path: 0.00s
INFO: 1 process: 1 internal.
INFO: Build completed successfully, 1 total action
//test:bytecode_util_test                                       (cached) PASSED in 0.0s
//test:exports_test                                             (cached) PASSED in 0.5s
//test:null_vm_test                                             (cached) PASSED in 0.0s
//test:runtime_test                                             (cached) PASSED in 0.7s
//test:shared_data                                              (cached) PASSED in 0.0s
//test:shared_queue                                             (cached) PASSED in 0.0s
//test:vm_id_handle                                             (cached) PASSED in 0.0s
//test:wasm_test                                                (cached) PASSED in 0.3s

Executed 0 out of 8 tests: 8 tests pass.
INFO: Build completed successfully, 1 total action

@PiotrSikora
Copy link
Member

Thanks for iterating on this, @knm3000!

I tried swapping in Word constructor (and in setMemory method from v8.cc), it doesn't work. We don't need to swap everything, most calls to Word constructor or to setWord() work fine on BE machines without swapping. We need to swap only in functions, that are outside of wasm binary (and are compiled on a native s390x machine). E.g. extern "C" functions from https://github.com/proxy-wasm/proxy-wasm-rust-sdk/blob/master/src/hostcalls.rs These functions are defined in https://github.com/proxy-wasm/proxy-wasm-cpp-host/blob/master/src/exports.cc and they also make calls to copyToPointerSize() from https://github.com/proxy-wasm/proxy-wasm-cpp-host/blob/master/include/proxy-wasm/wasm.h
This time I put some more calls to __builtin_bswap32 into exports.cc (I found more errors when running a different example https://github.com/proxy-wasm/proxy-wasm-rust-sdk/blob/master/examples/http_headers.rs, and when compiling http_headers.wasm binary for s390x target,

I've looked at those changes, and you've wrapped all calls to setWord() with the #ifdef. This should be done once inside the setWord() function, instead of in all the callsites. Sorry, I should have suggested it instead of the Word constructor.

Once you do that, I suspect that some tests will start failing, since you're swapping only when setting memory, but not when getting it, and a similar change should be done in getWord().

Also, since exactly the same swap is now done in multiple places, could you add a new function and use it instead of adding #ifdef blocks everywhere? e.g. wordHostToWasm in include/proxy-wasm/word.h:

uint32_t wordHostToWasm(Word w) {
#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) &&                                    \
    __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
   return __builtin_bswap32(w.u32());
#else
   return w.u32();
#endif
}

(untested, but something like that should work)

I also had to change from_le_bytes to from_be_bytes in https://github.com/proxy-wasm/proxy-wasm-rust-sdk/blob/master/src/hostcalls.rs to make it work).

This is wrong. Wasm is little-endian, so everything in its memory space should be little-endian.

Instead of the changes in hostcalls.rs, you should correct the endianess of the string lengths written in those loops in toParis and marshalPairs functions.

Anyway, we need to swap only in exports.cc (and not in any other places).

The tests still work with the latest update to PR code:

One reason that those tests are passing, is that you've patched callsites to setWord() in src/ but not in test/, so they are not doing the same work, and you're getting unmodified memory back, instead of swapped twice.

Also, if you change action: build to action: test in .github/workflows/cpp.yml for Wasmtime on Linux/s390x, then we we'll execute tests on the CI as well (using Wasmtime, not V8, since the latter would take forever to build under QEMU).

@PiotrSikora
Copy link
Member

uint32_t wordHostToWasm(Word w) {
#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) &&                                    \
    __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
   return __builtin_bswap32(w.u32());
#else
   return w.u32();
#endif
}

(untested, but something like that should work)

Actually, ignore that. You can simply use htole32() when writing Wasm memory, and le32toh() when reading Wasm memory. Those functions should be available in <endian.h>.

Signed-off-by: Konstantin Maksimov <konstantin.maksimov@ibm.com>
@knm3000
Copy link
Contributor Author

knm3000 commented Feb 3, 2022

Hi @PiotrSikora, please review the latest commit:

@knm3000
Copy link
Contributor Author

knm3000 commented Feb 3, 2022

Build on macos failed, it looks like htole32 (and other similar functions) are not defined on macos. Should I define them like this #ifdef __APPLE__ zeromq/zmqpp#164 (comment) ? Or is it better to use #if defined(__BYTE_ORDER__) .... __builtin_bswap32(x) instead?

@PiotrSikora
Copy link
Member

Build on macos failed, it looks like htole32 (and other similar functions) are not defined on macos. Should I define them like this #ifdef __APPLE__ zeromq/zmqpp#164 (comment) ? Or is it better to use #if defined(__BYTE_ORDER__) .... __builtin_bswap32(x) instead?

macOS is always little-endian, so this should be even easier:

#ifdef __APPLE__
#define htole32(x) (x)
#define le32toh(x) (x)
#endif

Maybe add it to include/proxy-wasm/word.h?

@PiotrSikora
Copy link
Member

That doc might be out-of-date, because they test on Linux/s390x on their CI, and if you make the same changes to setWord() and getWord() in src/wasmtime/wasmtime.cc as you did in src/v8/v8.cc, then all tests pass with Wasmtime.

It might be a good idea to proactively make them in src/wamr/wamr.cc and src/wavm/wavm.cc.

Use htole32() and le32toh() instead of __builtin_bswap32()
Moved byte reversals into `setWord()`
Defined htole32() and le32toh() for macos
Reverse in setWord() for wasmtime, wamr and wavm

Signed-off-by: Konstantin Maksimov <konstantin.maksimov@ibm.com>
@knm3000
Copy link
Contributor Author

knm3000 commented Feb 4, 2022

Made the same changes to wasmtime, wamr and wavm. When running with wasmtime 1 test (Clock from exports_test.cc) fails:

[root@41602232c1ef proxy-wasm-cpp-host]# bazel-5.0.0 test --test_output=all --define runtime=wasmtime //test:exports_test
INFO: Build option --define has changed, discarding analysis cache.
INFO: Analyzed target //test:exports_test (0 packages loaded, 5598 targets configured).
INFO: Found 1 test target...
FAIL: //test:exports_test (see /root/.cache/bazel/_bazel_root/5e52136a6a90864c271222189d591428/execroot/proxy_wasm_cpp_host/bazel-out/s390x-fastbuild/testlogs/test/exports_test/test.log)
INFO: From Testing //test:exports_test:
==================== Test output for //test:exports_test:
Running main() from gmock_main.cc
[==========] Running 3 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 3 tests from Runtimes/TestVM
[ RUN      ] Runtimes/TestVM.Environment/0
[       OK ] Runtimes/TestVM.Environment/0 (4147 ms)
[ RUN      ] Runtimes/TestVM.WithoutEnvironment/0
[       OK ] Runtimes/TestVM.WithoutEnvironment/0 (4138 ms)
[ RUN      ] Runtimes/TestVM.Clock/0
================================================================================
Target //test:exports_test up-to-date:
  bazel-bin/test/exports_test
INFO: Elapsed time: 17.357s, Critical Path: 16.98s
INFO: 7 processes: 2 internal, 5 processwrapper-sandbox.
INFO: Build completed, 1 test FAILED, 7 total actions
//test:exports_test                                                      FAILED in 12.6s

It fails during the call to run(current_context_) without any error messages, some problems with Instant::now() and SystemTime::now() calls in https://github.com/proxy-wasm/proxy-wasm-cpp-host/blob/master/test/test_data/clock.rs
I'm not sure how to fix this, maybe it is a bug in wasmtime for s390x.
Other tests work fine with wasmtime on s390x.

@PiotrSikora
Copy link
Member

Made the same changes to wasmtime, wamr and wavm.

Thanks!

When running with wasmtime 1 test (Clock from exports_test.cc) fails:

[root@41602232c1ef proxy-wasm-cpp-host]# bazel-5.0.0 test --test_output=all --define runtime=wasmtime //test:exports_test
INFO: Build option --define has changed, discarding analysis cache.
INFO: Analyzed target //test:exports_test (0 packages loaded, 5598 targets configured).
INFO: Found 1 test target...
FAIL: //test:exports_test (see /root/.cache/bazel/_bazel_root/5e52136a6a90864c271222189d591428/execroot/proxy_wasm_cpp_host/bazel-out/s390x-fastbuild/testlogs/test/exports_test/test.log)
INFO: From Testing //test:exports_test:
==================== Test output for //test:exports_test:
Running main() from gmock_main.cc
[==========] Running 3 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 3 tests from Runtimes/TestVM
[ RUN      ] Runtimes/TestVM.Environment/0
[       OK ] Runtimes/TestVM.Environment/0 (4147 ms)
[ RUN      ] Runtimes/TestVM.WithoutEnvironment/0
[       OK ] Runtimes/TestVM.WithoutEnvironment/0 (4138 ms)
[ RUN      ] Runtimes/TestVM.Clock/0
================================================================================
Target //test:exports_test up-to-date:
  bazel-bin/test/exports_test
INFO: Elapsed time: 17.357s, Critical Path: 16.98s
INFO: 7 processes: 2 internal, 5 processwrapper-sandbox.
INFO: Build completed, 1 test FAILED, 7 total actions
//test:exports_test                                                      FAILED in 12.6s

It fails during the call to run(current_context_) without any error messages, some problems with Instant::now() and SystemTime::now() calls in https://github.com/proxy-wasm/proxy-wasm-cpp-host/blob/master/test/test_data/clock.rs I'm not sure how to fix this, maybe it is a bug in wasmtime for s390x. Other tests work fine with wasmtime on s390x.

That's interesting. This was failing for me prior to your changes, but it works fine now under Docker/QEMU:

$ docker run --rm -t --platform linux/s390x piotrsikora/build-tools:bazel-5.0.0-clang-13-gcc-11 /bin/bash -c "git clone https://github.com/knm3000/proxy-wasm-cpp-host -b big-endian && cd proxy-wasm-cpp-host/ && bazel test --define runtime=wasmtime //test/..."
[...]
INFO: Elapsed time: 1413.911s, Critical Path: 900.59s
INFO: 411 processes: 190 internal, 221 processwrapper-sandbox.
INFO: Build completed successfully, 411 total actions
//test:bytecode_util_test                                                PASSED in 1.2s
//test:exports_test                                                      PASSED in 107.8s
//test:null_vm_test                                                      PASSED in 0.9s
//test:runtime_test                                                      PASSED in 57.3s
//test:shared_data                                                       PASSED in 0.9s
//test:shared_queue                                                      PASSED in 1.2s
//test:vm_id_handle                                                      PASSED in 0.9s
//test:wasm_test                                                         PASSED in 31.8s

Executed 8 out of 8 tests: 8 tests pass.
INFO: Build completed successfully, 411 total actions

Granted, it's QEMU and not the real hardware, but still... Anyway, I can play around with it in a separate PR.

Copy link
Member

@PiotrSikora PiotrSikora left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for iterating on this, and figuring out how to build it in the first place. Great work!

Note: I believe that there are still some hostcalls where we don't do the correct byteswap, but we don't have a good test coverage, so I won't hold back this PR because of it.

@PiotrSikora PiotrSikora changed the title Fix for the crash on big endian machine Add support for big-endian platforms. Feb 6, 2022
@PiotrSikora PiotrSikora merged commit b402508 into proxy-wasm:master Feb 6, 2022
@knm3000 knm3000 deleted the big-endian branch February 7, 2022 11:07
knm3000 added a commit to knm3000/proxy that referenced this pull request Feb 10, 2022
knm3000 added a commit to knm3000/envoy-1 that referenced this pull request Feb 21, 2022
Fixes https://issues.redhat.com/browse/MAISTRA-2648
The permanent fix is not a part of maistra/envoy yet:
proxy-wasm/proxy-wasm-cpp-host#198

Signed-off-by: Konstantin Maksimov <konstantin.maksimov@ibm.com>
knm3000 added a commit to knm3000/envoy-1 that referenced this pull request Feb 22, 2022
Fixes https://issues.redhat.com/browse/MAISTRA-2648
The permanent fix is not a part of maistra/envoy yet:
proxy-wasm/proxy-wasm-cpp-host#198

Signed-off-by: Konstantin Maksimov <konstantin.maksimov@ibm.com>
knm3000 added a commit to knm3000/envoy-1 that referenced this pull request Mar 10, 2022
Fixes https://issues.redhat.com/browse/MAISTRA-2648
The permanent fix is not a part of maistra/envoy yet:
proxy-wasm/proxy-wasm-cpp-host#198

Signed-off-by: Konstantin Maksimov <konstantin.maksimov@ibm.com>
maistra-bot pushed a commit to maistra/envoy that referenced this pull request Mar 17, 2022
Fixes https://issues.redhat.com/browse/MAISTRA-2648
The permanent fix is not a part of maistra/envoy yet:
proxy-wasm/proxy-wasm-cpp-host#198

Signed-off-by: Konstantin Maksimov <konstantin.maksimov@ibm.com>
maistra-bot pushed a commit to maistra/envoy that referenced this pull request Mar 17, 2022
Fixes https://issues.redhat.com/browse/MAISTRA-2648
The permanent fix is not a part of maistra/envoy yet:
proxy-wasm/proxy-wasm-cpp-host#198

Signed-off-by: Konstantin Maksimov <konstantin.maksimov@ibm.com>
knm3000 added a commit to knm3000/envoy-1 that referenced this pull request Jun 21, 2022
Fixes WASM on s390x https://issues.redhat.com/browse/MAISTRA-2648
The permanent fixes are:
proxy-wasm/proxy-wasm-cpp-host#198
proxy-wasm/proxy-wasm-cpp-host#282

Signed-off-by: Konstantin Maksimov konstantin.maksimov@ibm.com
knm3000 added a commit to knm3000/proxy-wasm-cpp-host-1 that referenced this pull request Jun 23, 2022
knm3000 added a commit to knm3000/proxy-wasm-cpp-host-1 that referenced this pull request Jun 24, 2022
knm3000 added a commit to knm3000/proxy-wasm-cpp-host-1 that referenced this pull request Jun 24, 2022
oschaaf pushed a commit to oschaaf/proxy-wasm-cpp-host that referenced this pull request Aug 4, 2022
Fixes WASM on s390x https://issues.redhat.com/browse/MAISTRA-2648
Corresponding proxy-wasm/proxy-wasm-cpp-host PRs:
proxy-wasm#198
proxy-wasm#282
dcillera pushed a commit to dcillera/envoy that referenced this pull request Feb 19, 2024
Fixes https://issues.redhat.com/browse/MAISTRA-2648
The permanent fix is not a part of maistra/envoy yet:
proxy-wasm/proxy-wasm-cpp-host#198

Signed-off-by: Konstantin Maksimov <konstantin.maksimov@ibm.com>
dcillera pushed a commit to dcillera/envoy that referenced this pull request Feb 19, 2024
Fixes https://issues.redhat.com/browse/MAISTRA-2648
The permanent fix is not a part of maistra/envoy yet:
proxy-wasm/proxy-wasm-cpp-host#198

Signed-off-by: Konstantin Maksimov <konstantin.maksimov@ibm.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

WASM extension crashes on Big-endian machine
2 participants