Skip to content

Commit 66c63b8

Browse files
committed
MAISTRA-2648: WASM fix for s390x
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
1 parent 8849b2c commit 66c63b8

File tree

9 files changed

+37
-16
lines changed

9 files changed

+37
-16
lines changed

include/proxy-wasm/exports.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,13 @@ template <typename Pairs> size_t pairsSize(const Pairs &result) {
4444

4545
template <typename Pairs> void marshalPairs(const Pairs &result, char *buffer) {
4646
char *b = buffer;
47-
*reinterpret_cast<uint32_t *>(b) = result.size();
47+
bool reverse = "null" != contextOrEffectiveContext()->wasmVm()->runtime();
48+
*reinterpret_cast<uint32_t *>(b) = reverse ? htowasm(result.size()) : result.size();
4849
b += sizeof(uint32_t);
4950
for (auto &p : result) {
50-
*reinterpret_cast<uint32_t *>(b) = p.first.size();
51+
*reinterpret_cast<uint32_t *>(b) = reverse ? htowasm(p.first.size()) : p.first.size();
5152
b += sizeof(uint32_t);
52-
*reinterpret_cast<uint32_t *>(b) = p.second.size();
53+
*reinterpret_cast<uint32_t *>(b) = reverse ? htowasm(p.second.size()) : p.second.size();
5354
b += sizeof(uint32_t);
5455
}
5556
for (auto &p : result) {

include/proxy-wasm/word.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ namespace proxy_wasm {
2121

2222
#include "proxy_wasm_common.h"
2323

24+
// Use byteswap functions only when compiling for big-endian platforms.
25+
#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
26+
__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
27+
#define htowasm(x) __builtin_bswap32(x)
28+
#define wasmtoh(x) __builtin_bswap32(x)
29+
#else
30+
#define htowasm(x) (x)
31+
#define wasmtoh(x) (x)
32+
#endif
33+
2434
// Represents a Wasm-native word-sized datum. On 32-bit VMs, the high bits are always zero.
2535
// The Wasm/VM API treats all bits as significant.
2636
struct Word {

src/exports.cc

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,22 @@ Pairs toPairs(std::string_view buffer) {
4646
if (buffer.size() < sizeof(uint32_t)) {
4747
return {};
4848
}
49-
auto size = *reinterpret_cast<const uint32_t *>(b);
49+
bool reverse = "null" != contextOrEffectiveContext()->wasmVm()->runtime();
50+
auto size = reverse ? wasmtoh(*reinterpret_cast<const uint32_t *>(b))
51+
: *reinterpret_cast<const uint32_t *>(b);
5052
b += sizeof(uint32_t);
5153
if (sizeof(uint32_t) + size * 2 * sizeof(uint32_t) > buffer.size()) {
5254
return {};
5355
}
5456
result.resize(size);
5557
for (uint32_t i = 0; i < size; i++) {
56-
result[i].first = std::string_view(nullptr, *reinterpret_cast<const uint32_t *>(b));
58+
result[i].first =
59+
std::string_view(nullptr, reverse ? wasmtoh(*reinterpret_cast<const uint32_t *>(b))
60+
: *reinterpret_cast<const uint32_t *>(b));
5761
b += sizeof(uint32_t);
58-
result[i].second = std::string_view(nullptr, *reinterpret_cast<const uint32_t *>(b));
62+
result[i].second =
63+
std::string_view(nullptr, reverse ? wasmtoh(*reinterpret_cast<const uint32_t *>(b))
64+
: *reinterpret_cast<const uint32_t *>(b));
5965
b += sizeof(uint32_t);
6066
}
6167
for (auto &p : result) {
@@ -652,6 +658,7 @@ Word grpc_send(Word token, Word message_ptr, Word message_size, Word end_stream)
652658
// logs.
653659
Word writevImpl(Word fd, Word iovs, Word iovs_len, Word *nwritten_ptr) {
654660
auto context = contextOrEffectiveContext();
661+
bool reverse = "null" != context->wasmVm()->runtime();
655662

656663
// Read syscall args.
657664
uint64_t log_level;
@@ -675,7 +682,9 @@ Word writevImpl(Word fd, Word iovs, Word iovs_len, Word *nwritten_ptr) {
675682
}
676683
const uint32_t *iovec = reinterpret_cast<const uint32_t *>(memslice.value().data());
677684
if (iovec[1] /* buf_len */) {
678-
memslice = context->wasmVm()->getMemory(iovec[0] /* buf */, iovec[1] /* buf_len */);
685+
auto iovec0 = reverse ? wasmtoh(iovec[0]) : iovec[0];
686+
auto iovec1 = reverse ? wasmtoh(iovec[1]) : iovec[1];
687+
memslice = context->wasmVm()->getMemory(iovec0 /* buf */, iovec1 /* buf_len */);
679688
if (!memslice) {
680689
return 21; // __WASI_EFAULT
681690
}

src/signature_util.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ bool SignatureUtil::verifySignature(std::string_view bytecode, std::string &mess
8383

8484
uint32_t alg_id;
8585
std::memcpy(&alg_id, payload.data(), sizeof(uint32_t));
86+
alg_id = wasmtoh(alg_id);
8687

8788
if (alg_id != 2) {
8889
message = "Signature has a wrong alg_id (want: 2, is: " + std::to_string(alg_id) + ")";

src/v8/v8.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ bool V8::getWord(uint64_t pointer, Word *word) {
432432
}
433433
uint32_t word32;
434434
::memcpy(&word32, memory_->data() + pointer, size);
435-
word->u64_ = word32;
435+
word->u64_ = wasmtoh(word32);
436436
return true;
437437
}
438438

@@ -441,7 +441,7 @@ bool V8::setWord(uint64_t pointer, Word word) {
441441
if (pointer + size > memory_->data_size()) {
442442
return false;
443443
}
444-
uint32_t word32 = word.u32();
444+
uint32_t word32 = htowasm(word.u32());
445445
::memcpy(memory_->data() + pointer, &word32, size);
446446
return true;
447447
}

src/wamr/wamr.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ bool Wamr::getWord(uint64_t pointer, Word *word) {
339339

340340
uint32_t word32;
341341
::memcpy(&word32, wasm_memory_data(memory_.get()) + pointer, size);
342-
word->u64_ = word32;
342+
word->u64_ = wasmtoh(word32);
343343
return true;
344344
}
345345

@@ -348,7 +348,7 @@ bool Wamr::setWord(uint64_t pointer, Word word) {
348348
if (pointer + size > wasm_memory_data_size(memory_.get())) {
349349
return false;
350350
}
351-
uint32_t word32 = word.u32();
351+
uint32_t word32 = htowasm(word.u32());
352352
::memcpy(wasm_memory_data(memory_.get()) + pointer, &word32, size);
353353
return true;
354354
}

src/wasmtime/wasmtime.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ bool Wasmtime::getWord(uint64_t pointer, Word *word) {
354354

355355
uint32_t word32;
356356
::memcpy(&word32, wasm_memory_data(memory_.get()) + pointer, size);
357-
word->u64_ = word32;
357+
word->u64_ = wasmtoh(word32);
358358
return true;
359359
}
360360

@@ -363,7 +363,7 @@ bool Wasmtime::setWord(uint64_t pointer, Word word) {
363363
if (pointer + size > wasm_memory_data_size(memory_.get())) {
364364
return false;
365365
}
366-
uint32_t word32 = word.u32();
366+
uint32_t word32 = htowasm(word.u32());
367367
::memcpy(wasm_memory_data(memory_.get()) + pointer, &word32, size);
368368
return true;
369369
}

src/wavm/wavm.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,12 +344,12 @@ bool Wavm::getWord(uint64_t pointer, Word *data) {
344344
auto p = reinterpret_cast<char *>(memory_base_ + pointer);
345345
uint32_t data32;
346346
memcpy(&data32, p, sizeof(uint32_t));
347-
data->u64_ = data32;
347+
data->u64_ = wasmtoh(data32);
348348
return true;
349349
}
350350

351351
bool Wavm::setWord(uint64_t pointer, Word data) {
352-
uint32_t data32 = data.u32();
352+
uint32_t data32 = htowasm(data.u32());
353353
return setMemory(pointer, sizeof(uint32_t), &data32);
354354
}
355355

test/runtime_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ TEST_P(TestVM, Memory) {
5656
ASSERT_TRUE(vm_->getWord(0x2000, &word));
5757
ASSERT_EQ(100, word.u64_);
5858

59-
int32_t data[2] = {-1, 200};
59+
uint32_t data[2] = {htowasm(static_cast<uint32_t>(-1)), htowasm(200)};
6060
ASSERT_TRUE(vm_->setMemory(0x200, sizeof(int32_t) * 2, static_cast<void *>(data)));
6161
ASSERT_TRUE(vm_->getWord(0x200, &word));
6262
ASSERT_EQ(-1, static_cast<int32_t>(word.u64_));

0 commit comments

Comments
 (0)