mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-27 00:50:45 +00:00
Fix for Big-Endian machines (#6245)
This commit is contained in:
@@ -1003,6 +1003,60 @@ struct Wasm_test : public beast::unit_test::suite
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testSwapBytes()
|
||||
{
|
||||
testcase("Wasm swap bytes");
|
||||
|
||||
uint64_t const SWAP_DATAU64 = 0x123456789abcdeffull;
|
||||
uint64_t const REVERSE_SWAP_DATAU64 = 0xffdebc9a78563412ull;
|
||||
int64_t const SWAP_DATAI64 = 0x123456789abcdeffll;
|
||||
int64_t const REVERSE_SWAP_DATAI64 = 0xffdebc9a78563412ll;
|
||||
|
||||
uint32_t const SWAP_DATAU32 = 0x12789aff;
|
||||
uint32_t const REVERSE_SWAP_DATAU32 = 0xff9a7812;
|
||||
int32_t const SWAP_DATAI32 = 0x12789aff;
|
||||
int32_t const REVERSE_SWAP_DATAI32 = 0xff9a7812;
|
||||
|
||||
uint16_t const SWAP_DATAU16 = 0x12ff;
|
||||
uint16_t const REVERSE_SWAP_DATAU16 = 0xff12;
|
||||
int16_t const SWAP_DATAI16 = 0x12ff;
|
||||
int16_t const REVERSE_SWAP_DATAI16 = 0xff12;
|
||||
|
||||
uint64_t b1 = SWAP_DATAU64;
|
||||
int64_t b2 = SWAP_DATAI64;
|
||||
b1 = adjustWasmEndianessHlp(b1);
|
||||
b2 = adjustWasmEndianessHlp(b2);
|
||||
BEAST_EXPECT(b1 == REVERSE_SWAP_DATAU64);
|
||||
BEAST_EXPECT(b2 == REVERSE_SWAP_DATAI64);
|
||||
b1 = adjustWasmEndianessHlp(b1);
|
||||
b2 = adjustWasmEndianessHlp(b2);
|
||||
BEAST_EXPECT(b1 == SWAP_DATAU64);
|
||||
BEAST_EXPECT(b2 == SWAP_DATAI64);
|
||||
|
||||
uint32_t b3 = SWAP_DATAU32;
|
||||
int32_t b4 = SWAP_DATAI32;
|
||||
b3 = adjustWasmEndianessHlp(b3);
|
||||
b4 = adjustWasmEndianessHlp(b4);
|
||||
BEAST_EXPECT(b3 == REVERSE_SWAP_DATAU32);
|
||||
BEAST_EXPECT(b4 == REVERSE_SWAP_DATAI32);
|
||||
b3 = adjustWasmEndianessHlp(b3);
|
||||
b4 = adjustWasmEndianessHlp(b4);
|
||||
BEAST_EXPECT(b3 == SWAP_DATAU32);
|
||||
BEAST_EXPECT(b4 == SWAP_DATAI32);
|
||||
|
||||
uint16_t b5 = SWAP_DATAU16;
|
||||
int16_t b6 = SWAP_DATAI16;
|
||||
b5 = adjustWasmEndianessHlp(b5);
|
||||
b6 = adjustWasmEndianessHlp(b6);
|
||||
BEAST_EXPECT(b5 == REVERSE_SWAP_DATAU16);
|
||||
BEAST_EXPECT(b6 == REVERSE_SWAP_DATAI16);
|
||||
b5 = adjustWasmEndianessHlp(b5);
|
||||
b6 = adjustWasmEndianessHlp(b6);
|
||||
BEAST_EXPECT(b5 == SWAP_DATAU16);
|
||||
BEAST_EXPECT(b6 == SWAP_DATAI16);
|
||||
}
|
||||
|
||||
void
|
||||
run() override
|
||||
{
|
||||
@@ -1035,6 +1089,7 @@ struct Wasm_test : public beast::unit_test::suite
|
||||
testBadAlloc();
|
||||
testBadAlign();
|
||||
testReturnType();
|
||||
testSwapBytes();
|
||||
|
||||
// perfTest();
|
||||
}
|
||||
|
||||
@@ -261,4 +261,35 @@ wasmParams(Types&&... args)
|
||||
return v;
|
||||
}
|
||||
|
||||
template <typename T, size_t size = sizeof(T)>
|
||||
inline constexpr T
|
||||
adjustWasmEndianessHlp(T x)
|
||||
{
|
||||
static_assert(std::is_integral<T>::value, "Only integral types");
|
||||
if constexpr (size > 1)
|
||||
{
|
||||
using U = std::make_unsigned<T>::type;
|
||||
U u = static_cast<U>(x);
|
||||
U const low = (u & 0xFF) << ((size - 1) << 3);
|
||||
u = adjustWasmEndianessHlp<U, size - 1>(u >> 8);
|
||||
return static_cast<T>(low | u);
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
template <typename T, size_t size = sizeof(T)>
|
||||
inline constexpr T
|
||||
adjustWasmEndianess(T x)
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
static_assert(std::is_integral<T>::value, "Only integral types");
|
||||
if constexpr (std::endian::native == std::endian::big)
|
||||
{
|
||||
return adjustWasmEndianessHlp(x);
|
||||
}
|
||||
return x;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -9,6 +9,19 @@ typedef std::variant<STBase const*, uint256 const*> FieldValue;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T>
|
||||
Bytes
|
||||
getIntBytes(STBase const* obj)
|
||||
{
|
||||
static_assert(std::is_integral<T>::value, "Only integral types");
|
||||
|
||||
auto const& num(static_cast<STInteger<T> const*>(obj));
|
||||
T const data = adjustWasmEndianess(num->value());
|
||||
auto const* b = reinterpret_cast<uint8_t const*>(&data);
|
||||
auto const* e = reinterpret_cast<uint8_t const*>(&data + 1);
|
||||
return Bytes{b, e};
|
||||
}
|
||||
|
||||
static Expected<Bytes, HostFunctionError>
|
||||
getAnyFieldData(STBase const* obj)
|
||||
{
|
||||
@@ -58,20 +71,25 @@ getAnyFieldData(STBase const* obj)
|
||||
}
|
||||
break;
|
||||
case STI_UINT16: {
|
||||
auto const& num(static_cast<STInteger<std::uint16_t> const*>(obj));
|
||||
std::uint16_t const data = num->value();
|
||||
auto const* b = reinterpret_cast<uint8_t const*>(&data);
|
||||
auto const* e = reinterpret_cast<uint8_t const*>(&data + 1);
|
||||
return Bytes{b, e};
|
||||
return getIntBytes<std::uint16_t>(obj);
|
||||
}
|
||||
break;
|
||||
case STI_UINT32: {
|
||||
auto const* num(static_cast<STInteger<std::uint32_t> const*>(obj));
|
||||
std::uint32_t const data = num->value();
|
||||
auto const* b = reinterpret_cast<uint8_t const*>(&data);
|
||||
auto const* e = reinterpret_cast<uint8_t const*>(&data + 1);
|
||||
return Bytes{b, e};
|
||||
return getIntBytes<std::uint32_t>(obj);
|
||||
}
|
||||
// LCOV_EXCL_START
|
||||
case STI_UINT64: {
|
||||
return getIntBytes<std::uint64_t>(obj);
|
||||
}
|
||||
break;
|
||||
case STI_INT32: {
|
||||
return getIntBytes<std::int32_t>(obj);
|
||||
}
|
||||
break;
|
||||
case STI_INT64: {
|
||||
return getIntBytes<std::int64_t>(obj);
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
break;
|
||||
case STI_UINT256: {
|
||||
auto const* uint256Obj(static_cast<STUInt256 const*>(obj));
|
||||
@@ -135,7 +153,7 @@ locateField(STObject const& obj, Slice const& locator)
|
||||
auto const& knownSFields = SField::getKnownCodeToField();
|
||||
|
||||
{
|
||||
int32_t const sfieldCode = locPtr[0];
|
||||
int32_t const sfieldCode = adjustWasmEndianess(locPtr[0]);
|
||||
auto const it = knownSFields.find(sfieldCode);
|
||||
if (it == knownSFields.end())
|
||||
return Unexpected(HostFunctionError::INVALID_FIELD);
|
||||
@@ -148,7 +166,7 @@ locateField(STObject const& obj, Slice const& locator)
|
||||
|
||||
for (int i = 1; i < locSize; ++i)
|
||||
{
|
||||
int32_t const sfieldCode = locPtr[i];
|
||||
int32_t const sfieldCode = adjustWasmEndianess(locPtr[i]);
|
||||
|
||||
if (STI_ARRAY == field->getSType())
|
||||
{
|
||||
|
||||
@@ -77,6 +77,7 @@ getDataUInt64(IW const* runtime, wasm_val_vec_t const* params, int32_t& i)
|
||||
memcpy(&x, r->data(), sizeof(uint64_t));
|
||||
else
|
||||
x = *reinterpret_cast<uint64_t const*>(r->data());
|
||||
x = adjustWasmEndianess(x);
|
||||
|
||||
return x;
|
||||
}
|
||||
@@ -290,7 +291,7 @@ returnResult(
|
||||
}
|
||||
else if constexpr (std::is_same_v<t, std::uint32_t>)
|
||||
{
|
||||
auto const resultValue = res.value();
|
||||
auto const resultValue = adjustWasmEndianess(res.value());
|
||||
return hfResult(
|
||||
results,
|
||||
setData(
|
||||
|
||||
Reference in New Issue
Block a user