forked from envoyproxy/envoy
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MAISTRA-2648: WASM fix for s390x (envoyproxy#139)
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>
- Loading branch information
Showing
2 changed files
with
189 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <typename Pairs> size_t pairsSize(const Pairs &result) { | ||
|
||
template <typename Pairs> void marshalPairs(const Pairs &result, char *buffer) { | ||
char *b = buffer; | ||
- *reinterpret_cast<uint32_t *>(b) = result.size(); | ||
+ *reinterpret_cast<uint32_t *>(b) = htowasm(result.size()); | ||
b += sizeof(uint32_t); | ||
for (auto &p : result) { | ||
- *reinterpret_cast<uint32_t *>(b) = p.first.size(); | ||
+ *reinterpret_cast<uint32_t *>(b) = htowasm(p.first.size()); | ||
b += sizeof(uint32_t); | ||
- *reinterpret_cast<uint32_t *>(b) = p.second.size(); | ||
+ *reinterpret_cast<uint32_t *>(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<const uint32_t *>(b); | ||
+ auto size = wasmtoh(*reinterpret_cast<const uint32_t *>(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<const uint32_t *>(b)); | ||
+ result[i].first = std::string_view(nullptr, wasmtoh(*reinterpret_cast<const uint32_t *>(b))); | ||
b += sizeof(uint32_t); | ||
- result[i].second = std::string_view(nullptr, *reinterpret_cast<const uint32_t *>(b)); | ||
+ result[i].second = std::string_view(nullptr, wasmtoh(*reinterpret_cast<const uint32_t *>(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<const uint32_t *>(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<char *>(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<uint32_t>(-1)), htowasm(200)}; | ||
ASSERT_TRUE(vm_->setMemory(0x200, sizeof(int32_t) * 2, static_cast<void *>(data))); | ||
ASSERT_TRUE(vm_->getWord(0x200, &word)); | ||
ASSERT_EQ(-1, static_cast<int32_t>(word.u64_)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters