From def52e1e643aa3cd0f1c3c5309a02e6c78720b7e Mon Sep 17 00:00:00 2001 From: Otto van der Schaaf Date: Mon, 11 Apr 2022 13:42:35 +0200 Subject: [PATCH] Revert "Revert "MAISTRA-2648: WASM fix for s390x (#139)" (#149)" This reverts commit d5e17b5936f4bf166a775d549037a2b248a874de. Signed-off-by: Otto van der Schaaf --- .../proxy-wasm-cpp-host-s390x-support.patch | 185 ++++++++++++++++++ bazel/repositories.bzl | 4 + 2 files changed, 189 insertions(+) create mode 100644 bazel/external/proxy-wasm-cpp-host-s390x-support.patch diff --git a/bazel/external/proxy-wasm-cpp-host-s390x-support.patch b/bazel/external/proxy-wasm-cpp-host-s390x-support.patch new file mode 100644 index 0000000000..7f1e1447af --- /dev/null +++ b/bazel/external/proxy-wasm-cpp-host-s390x-support.patch @@ -0,0 +1,185 @@ +diff --git a/include/proxy-wasm/exports.h b/include/proxy-wasm/exports.h +index ded6419..c2a4f37 100644 +--- a/include/proxy-wasm/exports.h ++++ b/include/proxy-wasm/exports.h +@@ -44,12 +44,12 @@ template size_t pairsSize(const Pairs &result) { + + template void marshalPairs(const Pairs &result, char *buffer) { + char *b = buffer; +- *reinterpret_cast(b) = result.size(); ++ *reinterpret_cast(b) = htowasm(result.size()); + b += sizeof(uint32_t); + for (auto &p : result) { +- *reinterpret_cast(b) = p.first.size(); ++ *reinterpret_cast(b) = htowasm(p.first.size()); + b += sizeof(uint32_t); +- *reinterpret_cast(b) = p.second.size(); ++ *reinterpret_cast(b) = htowasm(p.second.size()); + b += sizeof(uint32_t); + } + for (auto &p : result) { +diff --git a/include/proxy-wasm/word.h b/include/proxy-wasm/word.h +index e96fdfb..559471e 100644 +--- a/include/proxy-wasm/word.h ++++ b/include/proxy-wasm/word.h +@@ -21,6 +21,16 @@ namespace proxy_wasm { + + #include "proxy_wasm_common.h" + ++// Use byteswap functions only when compiling for big-endian platforms. ++#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ ++ __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ++#define htowasm(x) __builtin_bswap32(x) ++#define wasmtoh(x) __builtin_bswap32(x) ++#else ++#define htowasm(x) (x) ++#define wasmtoh(x) (x) ++#endif ++ + // Represents a Wasm-native word-sized datum. On 32-bit VMs, the high bits are always zero. + // The Wasm/VM API treats all bits as significant. + struct Word { +diff --git a/src/exports.cc b/src/exports.cc +index 0922b2d..32dbb0d 100644 +--- a/src/exports.cc ++++ b/src/exports.cc +@@ -46,16 +46,16 @@ Pairs toPairs(std::string_view buffer) { + if (buffer.size() < sizeof(uint32_t)) { + return {}; + } +- auto size = *reinterpret_cast(b); ++ auto size = wasmtoh(*reinterpret_cast(b)); + b += sizeof(uint32_t); + if (sizeof(uint32_t) + size * 2 * sizeof(uint32_t) > buffer.size()) { + return {}; + } + result.resize(size); + for (uint32_t i = 0; i < size; i++) { +- result[i].first = std::string_view(nullptr, *reinterpret_cast(b)); ++ result[i].first = std::string_view(nullptr, wasmtoh(*reinterpret_cast(b))); + b += sizeof(uint32_t); +- result[i].second = std::string_view(nullptr, *reinterpret_cast(b)); ++ result[i].second = std::string_view(nullptr, wasmtoh(*reinterpret_cast(b))); + b += sizeof(uint32_t); + } + for (auto &p : result) { +@@ -675,7 +675,8 @@ Word writevImpl(Word fd, Word iovs, Word iovs_len, Word *nwritten_ptr) { + } + const uint32_t *iovec = reinterpret_cast(memslice.value().data()); + if (iovec[1] /* buf_len */) { +- memslice = context->wasmVm()->getMemory(iovec[0] /* buf */, iovec[1] /* buf_len */); ++ memslice = context->wasmVm()->getMemory(wasmtoh(iovec[0]) /* buf */, ++ wasmtoh(iovec[1]) /* buf_len */); + if (!memslice) { + return 21; // __WASI_EFAULT + } +diff --git a/src/signature_util.cc b/src/signature_util.cc +index d4585fe..7442a88 100644 +--- a/src/signature_util.cc ++++ b/src/signature_util.cc +@@ -83,6 +83,7 @@ bool SignatureUtil::verifySignature(std::string_view bytecode, std::string &mess + + uint32_t alg_id; + std::memcpy(&alg_id, payload.data(), sizeof(uint32_t)); ++ alg_id = wasmtoh(alg_id); + + if (alg_id != 2) { + message = "Signature has a wrong alg_id (want: 2, is: " + std::to_string(alg_id) + ")"; +diff --git a/src/v8/v8.cc b/src/v8/v8.cc +index dd33f5b..ea658a9 100644 +--- a/src/v8/v8.cc ++++ b/src/v8/v8.cc +@@ -432,7 +432,7 @@ bool V8::getWord(uint64_t pointer, Word *word) { + } + uint32_t word32; + ::memcpy(&word32, memory_->data() + pointer, size); +- word->u64_ = word32; ++ word->u64_ = wasmtoh(word32); + return true; + } + +@@ -441,7 +441,7 @@ bool V8::setWord(uint64_t pointer, Word word) { + if (pointer + size > memory_->data_size()) { + return false; + } +- uint32_t word32 = word.u32(); ++ uint32_t word32 = htowasm(word.u32()); + ::memcpy(memory_->data() + pointer, &word32, size); + return true; + } +diff --git a/src/wamr/wamr.cc b/src/wamr/wamr.cc +index addc703..87c6031 100644 +--- a/src/wamr/wamr.cc ++++ b/src/wamr/wamr.cc +@@ -339,7 +339,7 @@ bool Wamr::getWord(uint64_t pointer, Word *word) { + + uint32_t word32; + ::memcpy(&word32, wasm_memory_data(memory_.get()) + pointer, size); +- word->u64_ = word32; ++ word->u64_ = wasmtoh(word32); + return true; + } + +@@ -348,7 +348,7 @@ bool Wamr::setWord(uint64_t pointer, Word word) { + if (pointer + size > wasm_memory_data_size(memory_.get())) { + return false; + } +- uint32_t word32 = word.u32(); ++ uint32_t word32 = htowasm(word.u32()); + ::memcpy(wasm_memory_data(memory_.get()) + pointer, &word32, size); + return true; + } +diff --git a/src/wasmtime/wasmtime.cc b/src/wasmtime/wasmtime.cc +index 37146ec..85e90d1 100644 +--- a/src/wasmtime/wasmtime.cc ++++ b/src/wasmtime/wasmtime.cc +@@ -354,7 +354,7 @@ bool Wasmtime::getWord(uint64_t pointer, Word *word) { + + uint32_t word32; + ::memcpy(&word32, wasm_memory_data(memory_.get()) + pointer, size); +- word->u64_ = word32; ++ word->u64_ = wasmtoh(word32); + return true; + } + +@@ -363,7 +363,7 @@ bool Wasmtime::setWord(uint64_t pointer, Word word) { + if (pointer + size > wasm_memory_data_size(memory_.get())) { + return false; + } +- uint32_t word32 = word.u32(); ++ uint32_t word32 = htowasm(word.u32()); + ::memcpy(wasm_memory_data(memory_.get()) + pointer, &word32, size); + return true; + } +diff --git a/src/wavm/wavm.cc b/src/wavm/wavm.cc +index 1b0d738..38b0518 100644 +--- a/src/wavm/wavm.cc ++++ b/src/wavm/wavm.cc +@@ -344,12 +344,12 @@ bool Wavm::getWord(uint64_t pointer, Word *data) { + auto p = reinterpret_cast(memory_base_ + pointer); + uint32_t data32; + memcpy(&data32, p, sizeof(uint32_t)); +- data->u64_ = data32; ++ data->u64_ = wasmtoh(data32); + return true; + } + + bool Wavm::setWord(uint64_t pointer, Word data) { +- uint32_t data32 = data.u32(); ++ uint32_t data32 = htowasm(data.u32()); + return setMemory(pointer, sizeof(uint32_t), &data32); + } + +diff --git a/test/runtime_test.cc b/test/runtime_test.cc +index 7bfd392..f6a8722 100644 +--- a/test/runtime_test.cc ++++ b/test/runtime_test.cc +@@ -56,7 +56,7 @@ TEST_P(TestVM, Memory) { + ASSERT_TRUE(vm_->getWord(0x2000, &word)); + ASSERT_EQ(100, word.u64_); + +- int32_t data[2] = {-1, 200}; ++ uint32_t data[2] = {htowasm(static_cast(-1)), htowasm(200)}; + ASSERT_TRUE(vm_->setMemory(0x200, sizeof(int32_t) * 2, static_cast(data))); + ASSERT_TRUE(vm_->getWord(0x200, &word)); + ASSERT_EQ(-1, static_cast(word.u64_)); \ No newline at end of file diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl index afce17b768..4882381b04 100644 --- a/bazel/repositories.bzl +++ b/bazel/repositories.bzl @@ -956,6 +956,10 @@ def _proxy_wasm_cpp_host(): name = "proxy_wasm_cpp_host", # patches = ["@envoy//bazel/external:0001-proxy-wasm-cpp-host-with-openssl-support.patch"], # patch_args = ["-p1"], + # The patch fixes WASM on s390x https://issues.redhat.com/browse/MAISTRA-2648 + # The permanent fix is https://github.com/proxy-wasm/proxy-wasm-cpp-host/pull/198 + patches = ["@envoy//bazel/external:proxy-wasm-cpp-host-s390x-support.patch"], + patch_args = ["-p1"], ) def _com_github_google_jwt_verify():