diff --git a/.envrc b/.envrc index 1dfcd40..3550a30 100644 --- a/.envrc +++ b/.envrc @@ -1 +1 @@ -use flake .#matar-clang +use flake diff --git a/src/memory.cc b/src/memory.cc index 3733ace..bcf2a30 100644 --- a/src/memory.cc +++ b/src/memory.cc @@ -1,8 +1,8 @@ #include "memory.hh" #include "header.hh" #include "util/bits.hh" +#include "util/crypto.hh" #include "util/log.hh" -#include "util/utils.hh" #include #include diff --git a/src/util/bits.hh b/src/util/bits.hh index d9e2236..3be421f 100644 --- a/src/util/bits.hh +++ b/src/util/bits.hh @@ -14,19 +14,19 @@ get_bit(Int num, size_t n) { template inline void set_bit(Int& num, size_t n) { - num |= (1 << n); + num |= (static_cast(1) << n); } template inline void rst_bit(Int& num, size_t n) { - num &= ~(1 << n); + num &= ~(static_cast(1) << n); } template inline void chg_bit(Int& num, size_t n, bool x) { - num = (num & ~(1 << n)) | (x << n); + num = (num & ~(static_cast(1) << n)) | (static_cast(x) << n); } /// read range of bits from start to end inclusive @@ -36,5 +36,5 @@ bit_range(Int num, size_t start, size_t end) { // NOTE: we do not require -1 if it is a signed integral Int left = std::numeric_limits::digits - (std::is_unsigned::value) - end; - return num << left >> (left + start); + return static_cast(num << left) >> (left + start); } diff --git a/src/util/utils.hh b/src/util/crypto.hh similarity index 94% rename from src/util/utils.hh rename to src/util/crypto.hh index f0c4a11..8bab0d5 100644 --- a/src/util/utils.hh +++ b/src/util/crypto.hh @@ -2,7 +2,8 @@ #include #include -#include +#include +#include #include // Why I wrote this myself? I do not know @@ -14,8 +15,8 @@ using std::rotr; template std::string sha256(std::array& data) { + std::stringstream ss; // Assuming 1 byte = 8 bits - std::string string; size_t k = 512 - (N * 8 + 65) % 512; size_t L = N + (65 + k) / 8; size_t i = 0, j = 0; @@ -108,12 +109,12 @@ sha256(std::array& data) { h[j] += h0[j]; } + ss << std::hex << std::setfill('0'); + for (j = 0; j < 8; j++) for (i = 0; i < 4; i++) - fmt::format_to(std::back_inserter(string), - "{:02x}", - ((h[j] >> (24 - i * 8)) & 0xFF)); + ss << std::setw(2) << ((h[j] >> (24 - i * 8)) & 0xFF); - return string; + return ss.str(); } } diff --git a/src/util/log.hh b/src/util/log.hh index 1b003c5..b895e9f 100644 --- a/src/util/log.hh +++ b/src/util/log.hh @@ -6,12 +6,12 @@ namespace logging { namespace ansi { -static constexpr std::string_view RED = "\033[31m"; -static constexpr std::string_view YELLOW = "\033[33m"; -static constexpr std::string_view MAGENTA = "\033[35m"; -static constexpr std::string_view WHITE = "\033[37m"; -static constexpr std::string_view BOLD = "\033[1m"; -static constexpr std::string_view RESET = "\033[0m"; +static constexpr auto RED = "\033[31m"; +static constexpr auto YELLOW = "\033[33m"; +static constexpr auto MAGENTA = "\033[35m"; +static constexpr auto WHITE = "\033[37m"; +static constexpr auto BOLD = "\033[1m"; +static constexpr auto RESET = "\033[0m"; } using fmt::print; @@ -20,8 +20,9 @@ class Logger { using LogLevel = matar::LogLevel; public: - Logger(LogLevel level = LogLevel::Debug) - : level(0) { + Logger(LogLevel level = LogLevel::Debug, FILE* stream = stderr) + : level(0) + , stream(stream) { set_level(level); } @@ -69,14 +70,14 @@ class Logger { void set_level(LogLevel level) { this->level = (static_cast(level) << 1) - 1; } - void set_stream(std::ostream& stream) { this->stream = stream; } + void set_stream(FILE* stream) { this->stream = stream; } private: uint8_t level; - std::reference_wrapper stream = std::clog; + FILE* stream; }; } extern logging::Logger glogger; -#define debug(x) logger.debug("{} = {}", #x, x); +#define debug(x) glogger.debug("{} = {}", #x, x); diff --git a/tests/bus.cc b/tests/bus.cc index b288103..9bef370 100644 --- a/tests/bus.cc +++ b/tests/bus.cc @@ -1,7 +1,7 @@ #include "bus.hh" #include -#define TAG "bus" +static constexpr auto TAG = "[bus]"; using namespace matar; @@ -41,5 +41,3 @@ TEST_CASE_METHOD(BusFixture, "Word", TAG) { CHECK(bus.read_halfword(100724276) == 0x491D); CHECK(bus.read_byte(100724276) == 0x1D); } - -#undef TAG diff --git a/tests/cpu/arm/exec.cc b/tests/cpu/arm/exec.cc index 1cf76d7..c968f7d 100644 --- a/tests/cpu/arm/exec.cc +++ b/tests/cpu/arm/exec.cc @@ -32,7 +32,7 @@ class CpuFixture { }; }; -#define TAG "arm execution" +static constexpr auto TAG = "[arm][execution]"; using namespace arm; @@ -1051,5 +1051,3 @@ TEST_CASE_METHOD(CpuFixture, "Data Processing", TAG) { CHECK(cpu.spsr.raw() == cpu.cpsr.raw()); } } - -#undef TAG diff --git a/tests/cpu/arm/instruction.cc b/tests/cpu/arm/instruction.cc index 010f63e..8581b20 100644 --- a/tests/cpu/arm/instruction.cc +++ b/tests/cpu/arm/instruction.cc @@ -1,7 +1,7 @@ #include "cpu/arm/instruction.hh" #include -#define TAG "disassembler" +static constexpr auto TAG = "[arm][disassembly]"; using namespace matar; using namespace arm; @@ -467,5 +467,3 @@ TEST_CASE("Software Interrupt", TAG) { CHECK(instruction.condition == Condition::EQ); CHECK(instruction.disassemble() == "SWIEQ"); } - -#undef TAG diff --git a/tests/meson.build b/tests/meson.build index 81007e9..75ab8f7 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -10,6 +10,7 @@ tests_sources = files( ) subdir('cpu') +subdir('util') catch2 = dependency('catch2', version: '>=3.4.0', static: true) catch2_tests = executable( diff --git a/tests/util/bits.cc b/tests/util/bits.cc new file mode 100644 index 0000000..d292939 --- /dev/null +++ b/tests/util/bits.cc @@ -0,0 +1,106 @@ +#include "util/bits.hh" +#include + +static constexpr auto TAG = "[util][bits]"; + +TEST_CASE("8 bits", TAG) { + uint8_t num = 45; + + CHECK(get_bit(num, 0)); + CHECK(!get_bit(num, 1)); + CHECK(get_bit(num, 5)); + CHECK(!get_bit(num, 6)); + CHECK(!get_bit(num, 7)); + + set_bit(num, 6); + CHECK(get_bit(num, 6)); + + rst_bit(num, 6); + CHECK(!get_bit(num, 6)); + + chg_bit(num, 5, false); + CHECK(!get_bit(num, 5)); + + chg_bit(num, 5, true); + CHECK(get_bit(num, 5)); + + // 0b0110 + CHECK(bit_range(num, 1, 4) == 6); +} + +TEST_CASE("16 bits", TAG) { + uint16_t num = 34587; + + CHECK(get_bit(num, 0)); + CHECK(get_bit(num, 1)); + CHECK(!get_bit(num, 5)); + CHECK(!get_bit(num, 14)); + CHECK(get_bit(num, 15)); + + set_bit(num, 14); + CHECK(get_bit(num, 14)); + + rst_bit(num, 14); + CHECK(!get_bit(num, 14)); + + chg_bit(num, 5, true); + CHECK(get_bit(num, 5)); + + // num = 45 + chg_bit(num, 5, false); + CHECK(!get_bit(num, 5)); + + // 0b1000110 + CHECK(bit_range(num, 2, 8) == 70); +} + +TEST_CASE("32 bits", TAG) { + uint32_t num = 3194142523; + + CHECK(get_bit(num, 0)); + CHECK(get_bit(num, 1)); + CHECK(get_bit(num, 12)); + CHECK(get_bit(num, 29)); + CHECK(!get_bit(num, 30)); + CHECK(get_bit(num, 31)); + + set_bit(num, 30); + CHECK(get_bit(num, 30)); + + rst_bit(num, 30); + CHECK(!get_bit(num, 30)); + + chg_bit(num, 12, false); + CHECK(!get_bit(num, 12)); + + chg_bit(num, 12, true); + CHECK(get_bit(num, 12)); + + // 0b10011000101011111100111 + CHECK(bit_range(num, 3, 25) == 5003239); +} + +TEST_CASE("64 bits", TAG) { + uint64_t num = 58943208889991935; + + CHECK(get_bit(num, 0)); + CHECK(get_bit(num, 1)); + CHECK(!get_bit(num, 10)); + CHECK(get_bit(num, 55)); + CHECK(!get_bit(num, 60)); + + set_bit(num, 63); + CHECK(get_bit(num, 63)); + + rst_bit(num, 63); + CHECK(!get_bit(num, 63)); + + chg_bit(num, 10, true); + CHECK(get_bit(num, 10)); + + chg_bit(num, 10, false); + CHECK(!get_bit(num, 10)); + + // 0b011010001 + CHECK(bit_range(num, 39, 47) == 209); +} diff --git a/tests/util/crypto.cc b/tests/util/crypto.cc new file mode 100644 index 0000000..54eac3c --- /dev/null +++ b/tests/util/crypto.cc @@ -0,0 +1,21 @@ +#include "util/crypto.hh" +#include + +static constexpr auto TAG = "[util][crypto]"; + +TEST_CASE("sha256 matar", TAG) { + std::array data = { 'm', 'a', 't', 'a', 'r' }; + + CHECK(crypto::sha256(data) == + "3b02a908fd5743c0e868675bb6ae77d2a62b3b5f7637413238e2a1e0e94b6a53"); +} + +TEST_CASE("sha256 forgis", TAG) { + std::array data = { 'i', ' ', 'p', 'u', 't', ' ', 't', 'h', + 'e', ' ', 'n', 'e', 'w', ' ', 'f', 'o', + 'r', 'g', 'i', 's', ' ', 'o', 'n', ' ', + 't', 'h', 'e', ' ', 'j', 'e', 'e', 'p' }; + + CHECK(crypto::sha256(data) == + "cfddca2ce2673f355518cbe2df2a8522693c54723a469e8b36a4f68b90d2b759"); +} diff --git a/tests/util/meson.build b/tests/util/meson.build new file mode 100644 index 0000000..8db8f1f --- /dev/null +++ b/tests/util/meson.build @@ -0,0 +1,4 @@ +tests_sources += files( + 'bits.cc', + 'crypto.cc' +) \ No newline at end of file