commit
d1e04ec2c9
@ -0,0 +1,3 @@
|
|||||||
|
*~
|
||||||
|
build/
|
||||||
|
test.*
|
@ -0,0 +1,12 @@
|
|||||||
|
SRC:=src/*.cpp
|
||||||
|
INCLUDE:=include/
|
||||||
|
BUILD:=build
|
||||||
|
CFLAGS:=-Wall -pedantic -O3 -march=native --std=gnu++20
|
||||||
|
LFLAGS:=-ltickit -lfmt
|
||||||
|
|
||||||
|
hexview:
|
||||||
|
g++ $(SRC) $(CFLAGS) -I$(INCLUDE) -o $(BUILD)/$@ $(LFLAGS)
|
||||||
|
strip $(BUILD)/$@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(BUILD)/*
|
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace gr
|
||||||
|
{
|
||||||
|
struct Context
|
||||||
|
{
|
||||||
|
Context();
|
||||||
|
~Context();
|
||||||
|
private:
|
||||||
|
struct _impl;
|
||||||
|
std::unique_ptr<_impl> impl;
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "span.hpp"
|
||||||
|
|
||||||
|
namespace hv {
|
||||||
|
/// Print a single screen
|
||||||
|
void print_screen(const span<unsigned char> bytes, unsigned long offset);
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <utility>
|
||||||
|
#include "span.hpp"
|
||||||
|
|
||||||
|
namespace hv
|
||||||
|
{
|
||||||
|
typedef std::uint8_t byte;
|
||||||
|
struct memory_map
|
||||||
|
{
|
||||||
|
/// Create a copy-on-write memory map to a file descriptor
|
||||||
|
inline static memory_map cow(std::uint64_t size, int&& fd) noexcept
|
||||||
|
{
|
||||||
|
return memory_map(size, std::move(fd), true);
|
||||||
|
}
|
||||||
|
/// Create a copy-on-write memory map to a file by name
|
||||||
|
inline static memory_map cow(std::uint64_t size, const char* file) noexcept
|
||||||
|
{
|
||||||
|
return memory_map(size, file, true);
|
||||||
|
}
|
||||||
|
memory_map(std::uint64_t size, const char* const filename) noexcept;
|
||||||
|
memory_map(std::uint64_t size, int&& fd) noexcept;
|
||||||
|
~memory_map();
|
||||||
|
|
||||||
|
inline byte& operator[](std::size_t index)
|
||||||
|
{
|
||||||
|
if (index>=size) throw "tried to index out of bounds of map";
|
||||||
|
return ((byte*)block0)[index];
|
||||||
|
}
|
||||||
|
inline const byte& operator[](std::size_t index) const
|
||||||
|
{
|
||||||
|
if (index>=size) throw "tried to index out of bounds of map";
|
||||||
|
return ((byte*)block0)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline hv::span<byte> span()
|
||||||
|
{
|
||||||
|
return hv::span((byte*)block0, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void* base()
|
||||||
|
{
|
||||||
|
return block0;
|
||||||
|
}
|
||||||
|
inline const void* base() const
|
||||||
|
{
|
||||||
|
return block0;
|
||||||
|
}
|
||||||
|
const bool is_cow;
|
||||||
|
const std::uint64_t size;
|
||||||
|
private:
|
||||||
|
memory_map(std::uint64_t size, int&& fd, bool _cow) noexcept;
|
||||||
|
memory_map(std::uint64_t size, const char* filename, bool _cow) noexcept;
|
||||||
|
const int fd;
|
||||||
|
void* const block0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct const_memory_map
|
||||||
|
{
|
||||||
|
const_memory_map(std::uint64_t size, const char* const filename) noexcept;
|
||||||
|
const_memory_map(std::uint64_t size, int&& fd) noexcept;
|
||||||
|
~const_memory_map();
|
||||||
|
|
||||||
|
inline const byte& operator[](std::size_t index) const
|
||||||
|
{
|
||||||
|
if (index>=size) throw "tried to index out of bounds of map";
|
||||||
|
return ((byte*)block0)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const void* base() const
|
||||||
|
{
|
||||||
|
return block0;
|
||||||
|
}
|
||||||
|
const std::uint64_t size;
|
||||||
|
private:
|
||||||
|
const int fd;
|
||||||
|
const void* const block0;
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace hv
|
||||||
|
{
|
||||||
|
/// A typed span of continuous memory with a bound.
|
||||||
|
template<typename T>
|
||||||
|
struct span
|
||||||
|
{
|
||||||
|
inline span(T* ptr, std::size_t len)
|
||||||
|
: ptr(ptr),len(len){}
|
||||||
|
|
||||||
|
inline operator T*() {return ptr;}
|
||||||
|
inline operator const T* const() {return ptr;}
|
||||||
|
inline T& operator*() {return *ptr;}
|
||||||
|
inline const T& operator*() const {return *ptr;}
|
||||||
|
|
||||||
|
inline T& operator[](std::size_t index)
|
||||||
|
{
|
||||||
|
if (index>=len) throw "tried to index out of bounds of array";
|
||||||
|
return ptr[index];
|
||||||
|
}
|
||||||
|
inline const T& operator[](std::size_t index) const
|
||||||
|
{
|
||||||
|
if (index>=len) throw "tried to index out of bounds of array";
|
||||||
|
return ptr[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline span<T> slice(std::size_t off, std::size_t len)
|
||||||
|
{
|
||||||
|
len = std::min(this->len, len);
|
||||||
|
if(len+off>=len || len < off) throw "tried to index out of bounds of array";
|
||||||
|
return span<T>(ptr+off, len-off);
|
||||||
|
}
|
||||||
|
inline span<T> slice(std::size_t off)
|
||||||
|
{
|
||||||
|
if(len+off>=len || len < off) throw "tried to index out of bounds of array";
|
||||||
|
|
||||||
|
return span<T>(ptr+off, len-off);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename U>
|
||||||
|
inline span<U> reinterpret()
|
||||||
|
{
|
||||||
|
return span<U>((U*)ptr, size_bytes() / sizeof(U));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline T* operator ->()
|
||||||
|
{
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
inline const T* operator ->() const
|
||||||
|
{
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline T* raw() {
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
inline const T* raw() const {
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
inline std::size_t size() const {
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
inline std::size_t size_bytes() const {
|
||||||
|
return len * sizeof(T);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
T* const ptr;
|
||||||
|
std::size_t len;
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
#include <tickit.h>
|
||||||
|
|
||||||
|
#include <graphics.hpp>
|
||||||
|
|
||||||
|
namespace gr
|
||||||
|
{
|
||||||
|
struct Context::_impl
|
||||||
|
{
|
||||||
|
Tickit* context;
|
||||||
|
};
|
||||||
|
|
||||||
|
Context::Context()
|
||||||
|
: impl(std::make_unique<_impl>())
|
||||||
|
{
|
||||||
|
//TODO: Graphics.
|
||||||
|
//TODO: Change hex.cpp print_screen to use these graphics instead of stdout with fmt
|
||||||
|
}
|
||||||
|
|
||||||
|
Context::~Context()
|
||||||
|
{
|
||||||
|
tickit_unref(impl->context);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
#include <fmt/format.h>
|
||||||
|
#include <span.hpp>
|
||||||
|
|
||||||
|
const static constexpr char ascii_map[255] = {
|
||||||
|
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
|
||||||
|
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
|
||||||
|
'.', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
|
||||||
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
|
||||||
|
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||||||
|
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
|
||||||
|
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||||
|
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '.',
|
||||||
|
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
|
||||||
|
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
|
||||||
|
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
|
||||||
|
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
|
||||||
|
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
|
||||||
|
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
|
||||||
|
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
|
||||||
|
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace hv {
|
||||||
|
void print_screen(const span<unsigned char> memory, unsigned long offset)
|
||||||
|
{
|
||||||
|
fmt::print("0x{:016x} ", offset);
|
||||||
|
char ascii[17];
|
||||||
|
ascii[16] = 0;
|
||||||
|
for(std::size_t i=0;i<memory.size();i++) {
|
||||||
|
if (i && i % 16 == 0) {
|
||||||
|
fmt::print(" {}", ascii);
|
||||||
|
fmt::print("\n0x{:016x} ", i+offset);
|
||||||
|
}
|
||||||
|
fmt::print("{:02x} ", memory[i]);
|
||||||
|
ascii[i%16] = ascii_map[memory[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
#include <fmt/format.h>
|
||||||
|
#include <fstream>
|
||||||
|
#include <memory-map.hpp>
|
||||||
|
#include <hex.hpp>
|
||||||
|
#include <graphics.hpp>
|
||||||
|
|
||||||
|
std::ifstream::pos_type filesize(const char* filename)
|
||||||
|
{
|
||||||
|
std::ifstream in(filename, std::ifstream::ate | std::ifstream::binary);
|
||||||
|
return in.tellg();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto map_file(const char* filename)
|
||||||
|
{
|
||||||
|
return hv::memory_map(filesize(filename), filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
auto map = map_file("test.txt");
|
||||||
|
auto memory = map.span();
|
||||||
|
|
||||||
|
hv::print_screen(memory, 0);
|
||||||
|
fmt::print("\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include <memory-map.hpp>
|
||||||
|
|
||||||
|
namespace hv
|
||||||
|
{
|
||||||
|
memory_map::memory_map(std::uint64_t size, int&& fd) noexcept
|
||||||
|
: is_cow(false), size(size), fd(fd), block0(mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0))
|
||||||
|
{
|
||||||
|
if(!block0) throw "memory_map failed";
|
||||||
|
}
|
||||||
|
memory_map::memory_map(std::uint64_t size, int&& fd, bool _cow) noexcept
|
||||||
|
: is_cow(true), size(size), fd(fd), block0(mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0))
|
||||||
|
{
|
||||||
|
if(!block0) throw "memory_map::cow failed";
|
||||||
|
}
|
||||||
|
memory_map::memory_map(std::uint64_t size, const char* file) noexcept
|
||||||
|
: memory_map(size, open(file, O_RDWR)) {}
|
||||||
|
memory_map::memory_map(std::uint64_t size, const char* file, bool _cow) noexcept
|
||||||
|
: memory_map(size, open(file, O_RDONLY), _cow) {}
|
||||||
|
memory_map::~memory_map()
|
||||||
|
{
|
||||||
|
munmap(block0, size);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
const_memory_map::const_memory_map(std::uint64_t size, int&& fd) noexcept
|
||||||
|
: size(size), fd(fd), block0(mmap(nullptr, size, PROT_READ, MAP_PRIVATE, fd, 0)) {}
|
||||||
|
const_memory_map::const_memory_map(std::uint64_t size, const char* file) noexcept
|
||||||
|
: const_memory_map(size, open(file, O_RDONLY)) {}
|
||||||
|
const_memory_map::~const_memory_map()
|
||||||
|
{
|
||||||
|
munmap(const_cast<void*>(block0), size);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue