diff --git a/src/backend/common/WorkerJob.h b/src/backend/common/WorkerJob.h index 8ff3ccdc9..7057c3571 100644 --- a/src/backend/common/WorkerJob.h +++ b/src/backend/common/WorkerJob.h @@ -30,6 +30,7 @@ #include "base/net/stratum/Job.h" +#include "base/tools/Alignment.h" #include "crypto/common/Nonce.h" @@ -77,7 +78,7 @@ public: } else { for (size_t i = 0; i < N; ++i) { - *nonce(i) += roundSize; + writeUnaligned(nonce(i), readUnaligned(nonce(i)) + roundSize); } } @@ -136,11 +137,11 @@ inline bool xmrig::WorkerJob<1>::nextRound(uint32_t rounds, uint32_t roundSize) return false; } if (nonceSize() == sizeof(uint64_t)) { - m_jobs[index()].nonce()[1] = n[1]; + writeUnaligned(m_jobs[index()].nonce() + 1, readUnaligned(n + 1)); } } else { - *n += roundSize; + writeUnaligned(n, readUnaligned(n) + roundSize); } return true; diff --git a/src/backend/cpu/CpuWorker.cpp b/src/backend/cpu/CpuWorker.cpp index c5037a0e1..86201e506 100644 --- a/src/backend/cpu/CpuWorker.cpp +++ b/src/backend/cpu/CpuWorker.cpp @@ -23,6 +23,7 @@ #include "backend/cpu/Cpu.h" #include "backend/cpu/CpuWorker.h" +#include "base/tools/Alignment.h" #include "base/tools/Chrono.h" #include "core/config/Config.h" #include "core/Miner.h" @@ -271,7 +272,7 @@ void xmrig::CpuWorker::start() uint32_t current_job_nonces[N]; for (size_t i = 0; i < N; ++i) { - current_job_nonces[i] = *m_job.nonce(i); + current_job_nonces[i] = readUnaligned(m_job.nonce(i)); } # ifdef XMRIG_FEATURE_BENCHMARK diff --git a/src/backend/cuda/CudaWorker.cpp b/src/backend/cuda/CudaWorker.cpp index 725d59c95..5c51b9a6c 100644 --- a/src/backend/cuda/CudaWorker.cpp +++ b/src/backend/cuda/CudaWorker.cpp @@ -22,6 +22,7 @@ #include "backend/cuda/runners/CudaCnRunner.h" #include "backend/cuda/wrappers/CudaDevice.h" #include "base/io/log/Log.h" +#include "base/tools/Alignment.h" #include "base/tools/Chrono.h" #include "core/Miner.h" #include "crypto/common/Nonce.h" @@ -152,7 +153,7 @@ void xmrig::CudaWorker::start() uint32_t foundNonce[16] = { 0 }; uint32_t foundCount = 0; - if (!m_runner->run(*m_job.nonce(), &foundCount, foundNonce)) { + if (!m_runner->run(readUnaligned(m_job.nonce()), &foundCount, foundNonce)) { return; } diff --git a/src/backend/opencl/OclWorker.cpp b/src/backend/opencl/OclWorker.cpp index d2563d8ff..d9977a403 100644 --- a/src/backend/opencl/OclWorker.cpp +++ b/src/backend/opencl/OclWorker.cpp @@ -23,6 +23,7 @@ #include "backend/opencl/runners/tools/OclSharedData.h" #include "backend/opencl/runners/tools/OclSharedState.h" #include "base/io/log/Log.h" +#include "base/tools/Alignment.h" #include "base/tools/Chrono.h" #include "core/Miner.h" #include "crypto/common/Nonce.h" @@ -179,7 +180,7 @@ void xmrig::OclWorker::start() const uint64_t t = Chrono::steadyMSecs(); try { - m_runner->run(*m_job.nonce(), results); + m_runner->run(readUnaligned(m_job.nonce()), results); } catch (std::exception &ex) { printError(id(), ex.what()); diff --git a/src/base/base.cmake b/src/base/base.cmake index db26e2e98..0f4f87255 100644 --- a/src/base/base.cmake +++ b/src/base/base.cmake @@ -68,6 +68,7 @@ set(HEADERS_BASE src/base/net/tools/MemPool.h src/base/net/tools/NetBuffer.h src/base/net/tools/Storage.h + src/base/tools/Alignment.h src/base/tools/Arguments.h src/base/tools/Baton.h src/base/tools/bswap_64.h diff --git a/src/base/net/stratum/Job.cpp b/src/base/net/stratum/Job.cpp index 17122eaab..8465ec0bc 100644 --- a/src/base/net/stratum/Job.cpp +++ b/src/base/net/stratum/Job.cpp @@ -30,6 +30,7 @@ #include "base/net/stratum/Job.h" +#include "base/tools/Alignment.h" #include "base/tools/Buffer.h" #include "base/tools/Cvt.h" #include "base/tools/cryptonote/BlockTemplate.h" @@ -73,7 +74,7 @@ bool xmrig::Job::setBlob(const char *blob) return false; } - if (*nonce() != 0 && !m_nicehash) { + if (readUnaligned(nonce()) != 0 && !m_nicehash) { m_nicehash = true; } diff --git a/src/base/tools/Alignment.h b/src/base/tools/Alignment.h new file mode 100644 index 000000000..00316af9d --- /dev/null +++ b/src/base/tools/Alignment.h @@ -0,0 +1,53 @@ +/* XMRig + * Copyright (c) 2018-2022 SChernykh + * Copyright (c) 2016-2022 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_ALIGNMENT_H +#define XMRIG_ALIGNMENT_H + + +#include +#include + + +namespace xmrig { + + +template +inline T readUnaligned(const T* ptr) +{ + static_assert(std::is_integral::value, "Integer type required"); + + T result; + memcpy(&result, ptr, sizeof(T)); + return result; +} + + +template +inline void writeUnaligned(T* ptr, T data) +{ + static_assert(std::is_integral::value, "Integer type required"); + + memcpy(ptr, &data, sizeof(T)); +} + + +} /* namespace xmrig */ + + +#endif /* XMRIG_ALIGNMENT_H */ diff --git a/src/crypto/common/Nonce.cpp b/src/crypto/common/Nonce.cpp index e2e51c2c2..feb487866 100644 --- a/src/crypto/common/Nonce.cpp +++ b/src/crypto/common/Nonce.cpp @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +#include "base/tools/Alignment.h" #include "crypto/common/Nonce.h" @@ -53,10 +54,10 @@ bool xmrig::Nonce::next(uint8_t index, uint32_t *nonce, uint32_t reserveCount, u continue; } - *nonce = (nonce[0] & ~mask) | counter; + writeUnaligned(nonce, static_cast((readUnaligned(nonce) & ~mask) | counter)); if (mask > 0xFFFFFFFFULL) { - nonce[1] = (nonce[1] & (~mask >> 32)) | (counter >> 32); + writeUnaligned(nonce + 1, static_cast((readUnaligned(nonce + 1) & (~mask >> 32)) | (counter >> 32))); } return true; diff --git a/src/net/JobResult.h b/src/net/JobResult.h index 614baf14a..c7dbf6c53 100644 --- a/src/net/JobResult.h +++ b/src/net/JobResult.h @@ -45,12 +45,12 @@ public: inline JobResult(const Job &job, uint64_t nonce, const uint8_t *result, const uint8_t* header_hash = nullptr, const uint8_t *mix_hash = nullptr, const uint8_t* miner_signature = nullptr) : algorithm(job.algorithm()), + index(job.index()), clientId(job.clientId()), jobId(job.id()), backend(job.backend()), nonce(nonce), - diff(job.diff()), - index(job.index()) + diff(job.diff()) { memcpy(m_result, result, sizeof(m_result)); @@ -70,12 +70,12 @@ public: inline JobResult(const Job &job) : algorithm(job.algorithm()), + index(job.index()), clientId(job.clientId()), jobId(job.id()), backend(job.backend()), nonce(0), - diff(0), - index(job.index()) + diff(0) { } @@ -88,12 +88,12 @@ public: inline const uint8_t *minerSignature() const { return m_hasMinerSignature ? m_minerSignature : nullptr; } const Algorithm algorithm; + const uint8_t index; const String clientId; const String jobId; const uint32_t backend; const uint64_t nonce; const uint64_t diff; - const uint8_t index; private: uint8_t m_result[32] = { 0 };