This commit is contained in:
2026-05-11 18:07:14 +02:00
parent f563827898
commit 2b0176790e
4 changed files with 75 additions and 79 deletions
+1
View File
@@ -8,6 +8,7 @@ option(BUILD_SHARED_LIBS OFF)
include_directories(external/ELFIO)
include_directories(external/capstone/include)
include_directories(external)
if(WIN32)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
+20 -20
View File
@@ -1,5 +1,5 @@
#pragma once
#include <types.hpp>
#include <ircolib/types.hpp>
#include <fstream>
#include <vector>
#include <filesystem>
@@ -8,36 +8,36 @@ namespace fs = std::filesystem;
namespace ircolib {
static inline std::vector<u8> ReadFileBinary(const std::string &path) {
std::ifstream file(path, std::ios::binary);
return {std::istreambuf_iterator{file}, {}};
std::ifstream file(path, std::ios::binary);
return {std::istreambuf_iterator{file}, {}};
}
static inline void WriteFileBinary(const std::vector<u8> &data, const std::string &path) {
std::ofstream file(path, std::ios::binary);
std::copy(data.begin(), data.end(), std::ostreambuf_iterator{file});
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) {
FILE *out = fopen(path.c_str(), "wb");
fwrite(data, size, 1, out);
fclose(out);
FILE *out = fopen(path.c_str(), "wb");
fwrite(data, size, 1, out);
fclose(out);
}
template <size_t Size>
static inline void WriteFileBinary(const std::array<u8, Size> &data, const std::string &path) {
std::ofstream file(path, std::ios::binary);
std::copy(data.begin(), data.end(), std::ostreambuf_iterator{file});
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) {
// Taken from "Bit Twiddling Hacks" by Sean Anderson:
// https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
--num;
num |= num >> 1;
num |= num >> 2;
num |= num >> 4;
num |= num >> 8;
num |= num >> 16;
return num + 1;
// Taken from "Bit Twiddling Hacks" by Sean Anderson:
// https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
--num;
num |= num >> 1;
num |= num >> 2;
num |= num >> 4;
num |= num >> 8;
num |= num >> 16;
return num + 1;
}
} // namespace Util
} // namespace ircolib
+46 -49
View File
@@ -1,5 +1,5 @@
#pragma once
#include <types.hpp>
#include <ircolib/types.hpp>
#include <cstring>
#include <functional>
#include <bit>
@@ -9,18 +9,17 @@
namespace ircolib {
static inline std::vector<u8> IntegralToBuffer(const std::integral auto &val) {
std::vector<u8> ret{};
ret.resize(sizeof(val));
std::vector<u8> ret{};
ret.resize(sizeof(val));
memcpy(ret.data(), &val, sizeof(val));
memcpy(ret.data(), &val, sizeof(val));
return ret;
return ret;
}
static inline constexpr bool IsInsideRange(const std::integral auto& addr,
const std::integral auto& start,
const std::integral auto& end) {
return addr >= start && addr <= end;
static inline constexpr bool IsInsideRange(const std::integral auto &addr, const std::integral auto &start,
const std::integral auto &end) {
return addr >= start && addr <= end;
}
template <typename T>
@@ -39,97 +38,97 @@ static constexpr inline void WriteAccess(std::array<u8, Size> &data, const u32 i
template <>
constexpr inline u64 ReadAccess(const u8 *data, const u32 index) {
u32 hi = *reinterpret_cast<const u32 *>(&data[index + 0]);
u32 lo = *reinterpret_cast<const u32 *>(&data[index + 4]);
const auto& result = static_cast<u64>(hi) << 32 | static_cast<u64>(lo);
return result;
u32 hi = *reinterpret_cast<const u32 *>(&data[index + 0]);
u32 lo = *reinterpret_cast<const u32 *>(&data[index + 4]);
const auto &result = static_cast<u64>(hi) << 32 | static_cast<u64>(lo);
return result;
}
template <typename T>
static constexpr inline T ReadAccess(const u8 *data, const u32 index) {
return *reinterpret_cast<const T *>(&data[index]);
return *reinterpret_cast<const T *>(&data[index]);
}
template <>
constexpr inline u64 ReadAccess(const std::vector<u8> &data, const u32 index) {
u32 hi = *reinterpret_cast<const u32 *>(&data[index + 0]);
u32 lo = *reinterpret_cast<const u32 *>(&data[index + 4]);
return (static_cast<u64>(hi) << 32) | static_cast<u64>(lo);
u32 hi = *reinterpret_cast<const u32 *>(&data[index + 0]);
u32 lo = *reinterpret_cast<const u32 *>(&data[index + 4]);
return (static_cast<u64>(hi) << 32) | static_cast<u64>(lo);
}
template <typename T>
static constexpr inline T ReadAccess(const std::vector<u8> &data, const u32 index) {
return *reinterpret_cast<const T *>(&data[index]);
return *reinterpret_cast<const T *>(&data[index]);
}
template <size_t Size>
constexpr inline u64 ReadAccess(const std::array<u8, Size> &data, const u32 index) {
u32 hi = *reinterpret_cast<const u32 *>(&data[index + 0]);
u32 lo = *reinterpret_cast<const u32 *>(&data[index + 4]);
return static_cast<u64>(hi) << 32 | static_cast<u64>(lo);
u32 hi = *reinterpret_cast<const u32 *>(&data[index + 0]);
u32 lo = *reinterpret_cast<const u32 *>(&data[index + 4]);
return static_cast<u64>(hi) << 32 | static_cast<u64>(lo);
}
template <typename T, size_t Size>
static constexpr inline T ReadAccess(const std::array<u8, Size> &data, const u32 index) {
return *reinterpret_cast<const T *>(&data[index]);
return *reinterpret_cast<const T *>(&data[index]);
}
template <size_t Size>
constexpr inline void WriteAccess(std::array<u8, Size> &data, const u32 index, const u64 val) {
const u32 hi = val >> 32;
const u32 lo = val;
const u32 hi = val >> 32;
const u32 lo = val;
*reinterpret_cast<u32 *>(&data[index + 0]) = hi;
*reinterpret_cast<u32 *>(&data[index + 4]) = lo;
*reinterpret_cast<u32 *>(&data[index + 0]) = hi;
*reinterpret_cast<u32 *>(&data[index + 4]) = lo;
}
template <typename T, size_t Size>
static constexpr inline void WriteAccess(std::array<u8, Size> &data, const u32 index, const T val) {
*reinterpret_cast<T *>(&data[index]) = val;
*reinterpret_cast<T *>(&data[index]) = val;
}
template <>
constexpr inline void WriteAccess(std::vector<u8> &data, const u32 index, const u64 val) {
const u32 hi = val >> 32;
const u32 lo = val;
const u32 hi = val >> 32;
const u32 lo = val;
*reinterpret_cast<u32 *>(&data[index + 0]) = hi;
*reinterpret_cast<u32 *>(&data[index + 4]) = lo;
*reinterpret_cast<u32 *>(&data[index + 0]) = hi;
*reinterpret_cast<u32 *>(&data[index + 4]) = lo;
}
template <typename T>
static constexpr inline void WriteAccess(std::vector<u8> &data, const u32 index, const T val) {
*reinterpret_cast<T *>(&data[index]) = val;
*reinterpret_cast<T *>(&data[index]) = val;
}
template <>
constexpr inline void WriteAccess(u8 *data, const u32 index, const u64 val) {
const u32 hi = val >> 32;
const u32 lo = val;
const u32 hi = val >> 32;
const u32 lo = val;
*reinterpret_cast<u32 *>(&data[index + 0]) = hi;
*reinterpret_cast<u32 *>(&data[index + 4]) = lo;
*reinterpret_cast<u32 *>(&data[index + 0]) = hi;
*reinterpret_cast<u32 *>(&data[index + 4]) = lo;
}
template <typename T>
static constexpr inline void WriteAccess(u8 *data, const u32 index, const T val) {
*reinterpret_cast<T *>(&data[index]) = val;
*reinterpret_cast<T *>(&data[index]) = val;
}
template <typename T>
static constexpr inline void SwapBuffer(std::vector<u8> &data) {
for (size_t i = 0; i < data.size(); i += sizeof(T)) {
const T original = *reinterpret_cast<T *>(&data[i]);
*reinterpret_cast<T *>(&data[i]) = std::byteswap(original);
}
for (size_t i = 0; i < data.size(); i += sizeof(T)) {
const T original = *reinterpret_cast<T *>(&data[i]);
*reinterpret_cast<T *>(&data[i]) = std::byteswap(original);
}
}
template <typename T, size_t Size>
static constexpr inline void SwapBuffer(std::array<u8, Size> &data) {
for (size_t i = 0; i < data.size(); i += sizeof(T)) {
const T original = *reinterpret_cast<T *>(&data[i]);
*reinterpret_cast<T *>(&data[i]) = std::byteswap(original);
}
for (size_t i = 0; i < data.size(); i += sizeof(T)) {
const T original = *reinterpret_cast<T *>(&data[i]);
*reinterpret_cast<T *>(&data[i]) = std::byteswap(original);
}
}
#ifdef _WIN32
@@ -137,10 +136,8 @@ inline void *aligned_alloc(const size_t alignment, const size_t size) { return _
inline void aligned_free(void *ptr) { _aligned_free(ptr); }
#else
inline void *aligned_alloc(const size_t alignment, const size_t size) {
return std::aligned_alloc(alignment, size);
}
inline void *aligned_alloc(const size_t alignment, const size_t size) { return std::aligned_alloc(alignment, size); }
inline void aligned_free(void *ptr) { std::free(ptr); }
#endif
} // namespace Util
} // namespace ircolib
+8 -10
View File
@@ -1,21 +1,19 @@
#include <print>
#include <elfio/elfio.hpp>
#include <ircolib/mem_access.hpp>
int main() {
ELFIO::elfio reader;
if (!reader.load("tests/elf/application.elf"))
return 1;
for (ELFIO::Elf_Half i = 0; i < reader.segments.size(); i++) {
const auto &segment = reader.segments[i];
std::println(R"(Segment type {} @ 0x{:08X} -> 0x{:08X})", segment->get_type(), segment->get_virtual_address(),
segment->get_virtual_address() + segment->get_memory_size() - 1);
}
for (ELFIO::Elf_Half i = 1; i < reader.sections.size(); i++) {
const auto &section = reader.sections[i];
std::println(R"(Section n.{} "{}": 0x{:08X} -> 0x{:08X})", i, section->get_name(), section->get_address(),
section->get_address() + section->get_size() - 1);
for (const auto &section : reader.sections) {
for (const auto &segment : reader.segments) {
if (ircolib::IsInsideRange(section->get_address(), segment->get_virtual_address(),
segment->get_virtual_address() + segment->get_memory_size() - 1))
std::println("Found section {} @ 0x{:08X} -> 0x{:08X}", section->get_index(), section->get_address(),
section->get_address() + section->get_size() - 1);
}
}
return 0;