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