From 93cab1ee41f7c27cc50903a003667410604ec7df Mon Sep 17 00:00:00 2001 From: iris Date: Mon, 11 May 2026 23:44:19 +0200 Subject: [PATCH] we load the ELF correctly it seems! --- .clang-format | 4 +- .gitignore | 3 +- CMakeLists.txt | 6 +- core/mem.cpp | 34 +++++++++++ core/mem.hpp | 16 +++++ external/ircolib/file.hpp | 10 +-- external/ircolib/floats.hpp | 104 ++++++++++++++++---------------- external/ircolib/log.hpp | 10 +++ external/ircolib/mem_access.hpp | 54 ++++++++++------- external/ircolib/types.hpp | 7 ++- main.cpp | 33 +++++++--- 11 files changed, 188 insertions(+), 93 deletions(-) create mode 100644 core/mem.cpp create mode 100644 core/mem.hpp create mode 100644 external/ircolib/log.hpp diff --git a/.clang-format b/.clang-format index 9f0277e..bc2a8f9 100644 --- a/.clang-format +++ b/.clang-format @@ -28,7 +28,9 @@ BreakConstructorInitializers: AfterColon BreakConstructorInitializersBeforeComma: false ColumnLimit: 120 ConstructorInitializerAllOnOneLineOrOnePerLine: false -ContinuationIndentWidth: 4 +IndentAccessModifiers: false +AccessModifierOffset: 0 +ContinuationIndentWidth: 0 IncludeCategories: - Regex: '^<.*' Priority: 1 diff --git a/.gitignore b/.gitignore index 21d5065..b90ea87 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ tests/ -build/ \ No newline at end of file +build/ +.vscode/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index ca31ec5..ac78bcb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,7 @@ option(BUILD_SHARED_LIBS OFF) include_directories(external/ELFIO) include_directories(external/capstone/include) +include_directories(external/cflags/include) include_directories(external) if(WIN32) @@ -18,5 +19,6 @@ set(CAPSTONE_ARCHITECTURE_DEFAULT OFF) set(CAPSTONE_PPC_SUPPORT ON) add_subdirectory(external/capstone) -add_executable(weee main.cpp) -target_link_libraries(weee PUBLIC capstone) \ No newline at end of file +add_executable(weee main.cpp core/mem.cpp) +target_link_libraries(weee PUBLIC capstone) +target_include_directories(weee PUBLIC core) \ No newline at end of file diff --git a/core/mem.cpp b/core/mem.cpp new file mode 100644 index 0000000..0480236 --- /dev/null +++ b/core/mem.cpp @@ -0,0 +1,34 @@ +#include +#include +#include + +namespace weee::core { +mem::mem() { + mem1.resize(24_mib); + std::fill(mem1.begin(), mem1.end(), 0); +} + +void mem::copy(const std::vector &src, const ircolib::u32 offset) { + if (offset + src.size() >= mem1.size()) + ircolib::panic("mem::copy outside mem1 range (src @ 0x{:08} for size 0x{:08X})", offset, src.size()); + + std::println("Copying {} bytes to mem1[{}]", src.size(), offset); + std::copy(src.begin(), src.end(), mem1.begin() + offset); +} + +void mem::copy(const ircolib::u8 *src, const ircolib::u32 size, const ircolib::u32 offset) { + if (offset + size >= mem1.size()) + ircolib::panic("mem::copy outside mem1 range (src @ 0x{:08} for size 0x{:08X})", offset, size); + + std::println("Copying {} bytes to mem1[{}]", size, offset); + memcpy(&mem1[offset], src, size); +} + +void mem::set(const ircolib::u8 val, const ircolib::u32 size, const ircolib::u32 offset) { + if (offset + size >= mem1.size()) + ircolib::panic("mem::set outside mem1 range (@ 0x{:08} for size 0x{:08X})", offset, size); + + std::println("Setting {} bytes to {} from mem1[{}]", size, val, offset); + memset(&mem1[offset], val, size); +} +} // namespace weee::core diff --git a/core/mem.hpp b/core/mem.hpp new file mode 100644 index 0000000..f1920e1 --- /dev/null +++ b/core/mem.hpp @@ -0,0 +1,16 @@ +#pragma once +#include +#include + +namespace weee::core { +struct mem { + mem(); + + void copy(const std::vector &src, const ircolib::u32 offset); + void copy(const ircolib::u8 *src, const ircolib::u32 size, const ircolib::u32 offset); + void set(const ircolib::u8 val, const ircolib::u32 size, const ircolib::u32 offset); + + private: + std::vector mem1; +}; +} // namespace weee::core diff --git a/external/ircolib/file.hpp b/external/ircolib/file.hpp index c4b3c67..ebfb463 100644 --- a/external/ircolib/file.hpp +++ b/external/ircolib/file.hpp @@ -7,29 +7,29 @@ namespace fs = std::filesystem; namespace ircolib { -static inline std::vector ReadFileBinary(const std::string &path) { +static inline std::vector read_file_binary(const std::string &path) { std::ifstream file(path, std::ios::binary); return {std::istreambuf_iterator{file}, {}}; } -static inline void WriteFileBinary(const std::vector &data, const std::string &path) { +static inline void write_file_binary(const std::vector &data, const std::string &path) { std::ofstream file(path, std::ios::binary); std::copy(data.begin(), data.end(), std::ostreambuf_iterator{file}); } -static inline void WriteFileBinary(const u8 *data, const size_t size, const std::string &path) { +static inline void write_file_binary(const u8 *data, const size_t size, const std::string &path) { FILE *out = fopen(path.c_str(), "wb"); fwrite(data, size, 1, out); fclose(out); } template -static inline void WriteFileBinary(const std::array &data, const std::string &path) { +static inline void write_file_binary(const std::array &data, const std::string &path) { std::ofstream file(path, std::ios::binary); std::copy(data.begin(), data.end(), std::ostreambuf_iterator{file}); } -static inline size_t NextPow2(size_t num) { +static inline size_t next_pow2(size_t num) { // Taken from "Bit Twiddling Hacks" by Sean Anderson: // https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 --num; diff --git a/external/ircolib/floats.hpp b/external/ircolib/floats.hpp index 913f1de..24868bc 100644 --- a/external/ircolib/floats.hpp +++ b/external/ircolib/floats.hpp @@ -1,106 +1,106 @@ #pragma once #include -#include +#include namespace ircolib { -static inline auto roundCeil(float f) { +static inline auto round_ceil(float f) { #ifdef SIMD_SUPPORT - __m128 t = _mm_set_ss(f); - t = _mm_round_ss(t, t, _MM_FROUND_TO_POS_INF); - return _mm_cvtss_f32(t); + __m128 t = _mm_set_ss(f); + t = _mm_round_ss(t, t, _MM_FROUND_TO_POS_INF); + return _mm_cvtss_f32(t); #else - return ceilf(f); + return ceilf(f); #endif } -static inline auto roundCeil(double f) { +static inline auto round_ceil(double f) { #ifdef SIMD_SUPPORT - __m128d t = _mm_set_sd(f); - t = _mm_round_sd(t, t, _MM_FROUND_TO_POS_INF); - return _mm_cvtsd_f64(t); + __m128d t = _mm_set_sd(f); + t = _mm_round_sd(t, t, _MM_FROUND_TO_POS_INF); + return _mm_cvtsd_f64(t); #else - return ceil(f); + return ceil(f); #endif } -static inline auto roundNearest(float f) { +static inline auto round_nearest(float f) { #ifdef SIMD_SUPPORT - __m128 t = _mm_set_ss(f); - t = _mm_round_ss(t, t, _MM_FROUND_TO_NEAREST_INT); - return _mm_cvtss_f32(t); + __m128 t = _mm_set_ss(f); + t = _mm_round_ss(t, t, _MM_FROUND_TO_NEAREST_INT); + return _mm_cvtss_f32(t); #else - return roundf(f); + return roundf(f); #endif } -static inline auto roundNearest(double f) { +static inline auto round_nearest(double f) { #ifdef SIMD_SUPPORT - __m128d t = _mm_set_sd(f); - t = _mm_round_sd(t, t, _MM_FROUND_TO_NEAREST_INT); - return _mm_cvtsd_f64(t); + __m128d t = _mm_set_sd(f); + t = _mm_round_sd(t, t, _MM_FROUND_TO_NEAREST_INT); + return _mm_cvtsd_f64(t); #else - return round(f); + return round(f); #endif } -static inline auto roundCurrent(float f) { +static inline auto round_current(float f) { #ifdef SIMD_SUPPORT - auto t = _mm_set_ss(f); - t = _mm_round_ss(t, t, _MM_FROUND_CUR_DIRECTION); - return _mm_cvtss_f32(t); + auto t = _mm_set_ss(f); + t = _mm_round_ss(t, t, _MM_FROUND_CUR_DIRECTION); + return _mm_cvtss_f32(t); #else - return rint(f); + return rint(f); #endif } -static inline auto roundCurrent(double f) { +static inline auto round_current(double f) { #ifdef SIMD_SUPPORT - auto t = _mm_set_sd(f); - t = _mm_round_sd(t, t, _MM_FROUND_CUR_DIRECTION); - return _mm_cvtsd_f64(t); + auto t = _mm_set_sd(f); + t = _mm_round_sd(t, t, _MM_FROUND_CUR_DIRECTION); + return _mm_cvtsd_f64(t); #else - return rint(f); + return rint(f); #endif } -static inline auto roundFloor(float f) { +static inline auto round_floor(float f) { #ifdef SIMD_SUPPORT - __m128 t = _mm_set_ss(f); - t = _mm_round_ss(t, t, _MM_FROUND_TO_NEG_INF); - return _mm_cvtss_f32(t); + __m128 t = _mm_set_ss(f); + t = _mm_round_ss(t, t, _MM_FROUND_TO_NEG_INF); + return _mm_cvtss_f32(t); #else - return floor(f); + return floor(f); #endif } -static inline auto roundFloor(double f) { +static inline auto round_floor(double f) { #ifdef SIMD_SUPPORT - __m128d t = _mm_set_sd(f); - t = _mm_round_sd(t, t, _MM_FROUND_TO_NEG_INF); - return _mm_cvtsd_f64(t); + __m128d t = _mm_set_sd(f); + t = _mm_round_sd(t, t, _MM_FROUND_TO_NEG_INF); + return _mm_cvtsd_f64(t); #else - return floor(f); + return floor(f); #endif } -static inline auto roundTrunc(float f) { +static inline auto round_trunc(float f) { #ifdef SIMD_SUPPORT - __m128 t = _mm_set_ss(f); - t = _mm_round_ss(t, t, _MM_FROUND_TO_ZERO); - return _mm_cvtss_f32(t); + __m128 t = _mm_set_ss(f); + t = _mm_round_ss(t, t, _MM_FROUND_TO_ZERO); + return _mm_cvtss_f32(t); #else - return trunc(f); + return trunc(f); #endif } -static inline auto roundTrunc(double f) { +static inline auto round_trunc(double f) { #ifdef SIMD_SUPPORT - __m128d t = _mm_set_sd(f); - t = _mm_round_sd(t, t, _MM_FROUND_TO_ZERO); - return _mm_cvtsd_f64(t); + __m128d t = _mm_set_sd(f); + t = _mm_round_sd(t, t, _MM_FROUND_TO_ZERO); + return _mm_cvtsd_f64(t); #else - return trunc(f); + return trunc(f); #endif } -} // namespace Util +} // namespace ircolib diff --git a/external/ircolib/log.hpp b/external/ircolib/log.hpp new file mode 100644 index 0000000..8c3b3cd --- /dev/null +++ b/external/ircolib/log.hpp @@ -0,0 +1,10 @@ +#pragma once +#include + +namespace ircolib { +template +void panic(std::format_string fmt, Args &&...args) { + std::println(fmt, std::forward(args)...); + exit(1); +} +} // namespace ircolib diff --git a/external/ircolib/mem_access.hpp b/external/ircolib/mem_access.hpp index 3434bc4..c4e0822 100644 --- a/external/ircolib/mem_access.hpp +++ b/external/ircolib/mem_access.hpp @@ -8,7 +8,7 @@ #include namespace ircolib { -static inline std::vector IntegralToBuffer(const std::integral auto &val) { +static inline std::vector integral_to_buffer(const std::integral auto &val) { std::vector ret{}; ret.resize(sizeof(val)); @@ -17,27 +17,35 @@ static inline std::vector IntegralToBuffer(const std::integral auto &val) { return ret; } -static inline constexpr bool IsInsideRange(const std::integral auto &addr, const std::integral auto &start, - const std::integral auto &end) { +static inline auto integral_to_slice(const std::integral auto &val) -> std::array { + std::array ret{}; + + memcpy(ret.data(), &val, sizeof(val)); + + return ret; +} + +static inline constexpr bool is_inside_range(const std::integral auto &addr, const std::integral auto &start, + const std::integral auto &end) { return addr >= start && addr <= end; } template -static constexpr inline T ReadAccess(const u8 *data, const u32 index); +static constexpr inline T read_access(const u8 *data, const u32 index); template -static constexpr inline T ReadAccess(const std::vector &data, const u32 index); +static constexpr inline T read_access(const std::vector &data, const u32 index); template -static constexpr inline T ReadAccess(const std::array &data, const u32 index); +static constexpr inline T read_access(const std::array &data, const u32 index); template -static constexpr inline void WriteAccess(u8 *data, const u32 index, const T val); +static constexpr inline void write_access(u8 *data, const u32 index, const T val); template -static constexpr inline void WriteAccess(std::vector &data, const u32 index, const T val); +static constexpr inline void write_access(std::vector &data, const u32 index, const T val); template -static constexpr inline void WriteAccess(std::array &data, const u32 index, const T val); +static constexpr inline void write_access(std::array &data, const u32 index, const T val); template <> -constexpr inline u64 ReadAccess(const u8 *data, const u32 index) { +constexpr inline u64 read_access(const u8 *data, const u32 index) { u32 hi = *reinterpret_cast(&data[index + 0]); u32 lo = *reinterpret_cast(&data[index + 4]); const auto &result = static_cast(hi) << 32 | static_cast(lo); @@ -45,36 +53,36 @@ constexpr inline u64 ReadAccess(const u8 *data, const u32 index) { } template -static constexpr inline T ReadAccess(const u8 *data, const u32 index) { +static constexpr inline T read_access(const u8 *data, const u32 index) { return *reinterpret_cast(&data[index]); } template <> -constexpr inline u64 ReadAccess(const std::vector &data, const u32 index) { +constexpr inline u64 read_access(const std::vector &data, const u32 index) { u32 hi = *reinterpret_cast(&data[index + 0]); u32 lo = *reinterpret_cast(&data[index + 4]); return (static_cast(hi) << 32) | static_cast(lo); } template -static constexpr inline T ReadAccess(const std::vector &data, const u32 index) { +static constexpr inline T read_access(const std::vector &data, const u32 index) { return *reinterpret_cast(&data[index]); } template -constexpr inline u64 ReadAccess(const std::array &data, const u32 index) { +constexpr inline u64 read_access(const std::array &data, const u32 index) { u32 hi = *reinterpret_cast(&data[index + 0]); u32 lo = *reinterpret_cast(&data[index + 4]); return static_cast(hi) << 32 | static_cast(lo); } template -static constexpr inline T ReadAccess(const std::array &data, const u32 index) { +static constexpr inline T read_access(const std::array &data, const u32 index) { return *reinterpret_cast(&data[index]); } template -constexpr inline void WriteAccess(std::array &data, const u32 index, const u64 val) { +constexpr inline void write_access(std::array &data, const u32 index, const u64 val) { const u32 hi = val >> 32; const u32 lo = val; @@ -83,12 +91,12 @@ constexpr inline void WriteAccess(std::array &data, const u32 index, c } template -static constexpr inline void WriteAccess(std::array &data, const u32 index, const T val) { +static constexpr inline void write_access(std::array &data, const u32 index, const T val) { *reinterpret_cast(&data[index]) = val; } template <> -constexpr inline void WriteAccess(std::vector &data, const u32 index, const u64 val) { +constexpr inline void write_access(std::vector &data, const u32 index, const u64 val) { const u32 hi = val >> 32; const u32 lo = val; @@ -97,12 +105,12 @@ constexpr inline void WriteAccess(std::vector &data, const u32 index, const } template -static constexpr inline void WriteAccess(std::vector &data, const u32 index, const T val) { +static constexpr inline void write_access(std::vector &data, const u32 index, const T val) { *reinterpret_cast(&data[index]) = val; } template <> -constexpr inline void WriteAccess(u8 *data, const u32 index, const u64 val) { +constexpr inline void write_access(u8 *data, const u32 index, const u64 val) { const u32 hi = val >> 32; const u32 lo = val; @@ -111,12 +119,12 @@ constexpr inline void WriteAccess(u8 *data, const u32 index, const u64 val) { } template -static constexpr inline void WriteAccess(u8 *data, const u32 index, const T val) { +static constexpr inline void write_access(u8 *data, const u32 index, const T val) { *reinterpret_cast(&data[index]) = val; } template -static constexpr inline void SwapBuffer(std::vector &data) { +static constexpr inline void swap_buffer(std::vector &data) { for (size_t i = 0; i < data.size(); i += sizeof(T)) { const T original = *reinterpret_cast(&data[i]); *reinterpret_cast(&data[i]) = std::byteswap(original); @@ -124,7 +132,7 @@ static constexpr inline void SwapBuffer(std::vector &data) { } template -static constexpr inline void SwapBuffer(std::array &data) { +static constexpr inline void swap_buffer(std::array &data) { for (size_t i = 0; i < data.size(); i += sizeof(T)) { const T original = *reinterpret_cast(&data[i]); *reinterpret_cast(&data[i]) = std::byteswap(original); diff --git a/external/ircolib/types.hpp b/external/ircolib/types.hpp index 9752f90..b96d7de 100644 --- a/external/ircolib/types.hpp +++ b/external/ircolib/types.hpp @@ -10,4 +10,9 @@ using s8 = int8_t; using s16 = int16_t; using s32 = int32_t; using s64 = int64_t; -} \ No newline at end of file + +} // namespace ircolib + +constexpr ircolib::u32 operator""_kib(const unsigned long long v) { return v * 1024; } +constexpr ircolib::u32 operator""_mib(const unsigned long long v) { return v * 1024 * 1024; } +constexpr ircolib::u32 operator""_gib(const unsigned long long v) { return v * 1024 * 1024 * 1024; } diff --git a/main.cpp b/main.cpp index fd0243f..12907d1 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,19 @@ #include #include +#include #include +#include "mem.hpp" int main(int argc, char **argv) { ELFIO::elfio reader; - if (!reader.load("tests/application/application.elf")) - return 1; + + weee::core::mem mem; + + cflags::cflags flags; + flags.add_string_callback('\0', "elf", [&](const std::string &v) { reader.load(v); }, "ELF binary to load"); + + if (!flags.parse(argc, argv)) + return -1; size_t sanity_bss_check_count = 0; @@ -17,12 +25,6 @@ int main(int argc, char **argv) { if (segment->get_memory_size() == 0) continue; - if (segment->get_file_size() == 0) { - sanity_bss_check_count++; - if (sanity_bss_check_count > 1) - std::println("weee does not support multiple .bss segments"); - } - const bool exc = segment->get_flags() & ELFIO::PF_X; const bool rd = segment->get_flags() & ELFIO::PF_R; const bool wr = segment->get_flags() & ELFIO::PF_W; @@ -30,6 +32,21 @@ int main(int argc, char **argv) { std::println("Segment {} {}{}{} @ 0x{:08X} -> 0x{:08X}", segment->get_index(), rd ? 'R' : '_', wr ? 'W' : '_', exc ? 'X' : '_', segment->get_virtual_address(), segment->get_virtual_address() + segment->get_memory_size() - 1); + + if (segment->get_file_size() == 0) { + sanity_bss_check_count++; + if (sanity_bss_check_count > 1) { + std::println("weee does not support multiple .bss segments"); + return -2; + } + + // .bss we zero out + mem.set(0, segment->get_memory_size(), segment->get_virtual_address() & 0x0FFFFFFF); + continue; + } + + mem.copy((const ircolib::u8 *)segment->get_data(), segment->get_file_size(), + segment->get_virtual_address() & 0x0FFFFFFF); } return 0;