memory-mapped registers for x86_64 systems

Overview

regmap

some well-known and known-to-be-good computer architectures, such as the Microchip PIC product line, or many of the AVR processor family, were fortunate enough to have architects that understood the power of a strategic alignment between the processor's register file and main memory. on these architectures, the foresight to synergize register and memory accesses reduces instruction complexity: to load or store registers a developer only has to know the instructions to operate on memory.

unfortunately, the architects at Intel who designed the 8086 did not appreciate the learnings of these architectures and did not synergize the register file with main memory. regmap handles this design oversight by allowing users to memory-map the processor's general-purpose registers (GPR).

think of regmap as "niche-filling, but for main memory."

usage

call regmap::map_registers(), then use memory between 0 and 4096 to your delight. you probably want to run regmap-using binaries in --release; if you use RegU64 and do not aggressively inline helper functions like add_assign, results will be unpredictable.

since you would never use addresses in the first page of memory otherwise, you may want to even add a stub like

#[cfg_attr(link_section = ".init_array")]
static MAP_REGS: extern fn() = {
  unsafe { regmap::map_registers(); }
};

so that the register mapping is always enabled, and you can't forget to actually run the function in your application. HOWEVER, if you are a library taking a dependency on regmap, first of all thank you! but attempting to use .init_array in your library is fraught with issues. you will likely want to encourage downstream users of your library to, themselves, regmap::map_registers().

another interesting usage of regmap could be as a support mechanism for hand-written assembly using this feature. as long as regmap::map_registers() has been called in the process, any instruction referencing a mapped register will be correctly interpreted. a user could write optimized assembly, call regmap::map_registers, and proceed to use memory-mapped registers without issue.

if you intend to use regmap in a standalone manner (as a supporting library in a C program, for example), cargo build --workspace --release will produce a ./target/release/libregmap.a that is suitable for linkage.

examples are present. the examples/hello_world.rs example can be run with cargo run --example hello_world --release. for a demonstration of using regmap outside a Rust program, make joy will build and run the example in examples/example.s.

why

because it's funny

how

the 0 page is generally reserved as no-execute no-write so accesses to it (via null pointer) don't cause "very weird" memory corruption. regmap repurposes this 4k (or larger, for hugepages, i guess) region to map parts of the amd64 register file. a fault is translated to a referenced address, the instruction is evaluated as if it was against the specified register, and execution continues none the wiser.

instead of rewriting the instruction stream or generating the instruction to execute, regmap emulates the instruction which had a memory reference. this means that regmap does not involve any extra allocations for handling, and is fairly self-contained in the signal handler implementation on which this feature relies.

where

regmap currently makes some assumptions about ucontext layout, and is only known to correctly work on linux. in the future this restriction may be releaxed. regmap also cannot be used to execute SSE instructions. this restriction may also be relaxed in the future.

bugs?

regmap probably doesn't have bugs. it's just an x86 disassembler and emulator hooked up to a signal handler. what could go wrong. if regmap incorrectly emulates an instruction, or should emulate an instruction differently in consideration of its special execution circumstances, please file an issue or email me at the email used for commits in this repo.

TODO:

[ ] unaligned accesses to the register map should be handled. they currently panic. ideally, regmap should operate as if an apporopriately-sized register was formed from region being addressed. [ ] non-qword operations are incorrectly emulated. regmap is not immediately impacted as RegU64 forces u64 operations, but other sizes should be supported. [ ] SSE operations are not handled. if they were handled it seems reasonable that they should work on GPR bytes. just the same.

You might also like...
A read-only, memory-mapped cache.

mmap-cache A low-level API for a memory-mapped cache of a read-only key-value store. Design The [Cache] index is an [fst::Map], which maps from arbitr

Rust library for concurrent data access, using memory-mapped files, zero-copy deserialization, and wait-free synchronization.

mmap-sync mmap-sync is a Rust crate designed to manage high-performance, concurrent data access between a single writer process and multiple reader pr

Low level access to ATmega32U4 registers in Rust

Deprecation Note: This crate will soon be deprecated in favor of avr-device. The approach of generating the svd from hand-written register definitions

Define safe interfaces to MMIO and CPU registers with ease

regi regi lets you define safe interfaces to MMIO and CPU registers with ease. License Licensed under either of Apache License, Version 2.0 or MIT lic

 A process memory reader and debugger for Windows (x86_64)
A process memory reader and debugger for Windows (x86_64)

Winreader Winreader is a process memory reader and debugger for Windows, implemented and developed in the Rust language, using the official Microsoft

💻 An x86_64 kernel in the works

BruhOS a basic x86_64 kernel in the works. cool stuff written in rust boots with any stivale2-compliant bootloader framebuffer bitmap font renderer pm

a hobby OS for x86_64 based on MikanOS.

a hobby OS for x86_64 based on MikanOS.

Minimal x86_64 OS kernel written in Rust
Minimal x86_64 OS kernel written in Rust

rkernel A minimal x86_64 Rust OS kernel. Multiboot2 VGA driver PIC PIT PS/2 Keyboard driver PS/2 Mouse driver TSC RTC Allocator ATA PIO (In progress..

A clean, custom-built modular kernel ready to boot on x86_64.
A clean, custom-built modular kernel ready to boot on x86_64.

Lateral is a work-in-progress multitasking monolithic kernel + OS meant as a fun summer project. It has recently expanded into more than I could imagi

Rux - An x86_64 toy operating system kernel written in Rust
Rux - An x86_64 toy operating system kernel written in Rust

Rux - An x86_64 toy operating system kernel written in Rust. Rux is a port of the Hux kernel, my x86 32-bit single-CPU toy kernel written in C, following the OSTEP book structure and terminology.

Rust fast `&str` to `i64` parser (x86_64 SIMD, SSE4.1)

Rust fast &str to i64 parser (x86_64 SIMD, SSE4.1) Modified this version to support various string length and negative values. You need to define the

Let's write an OS which can run on x86_64 in Rust from scratch

rCore-Tutorial-v3 rCore-Tutorial version 3.5. See the Documentation in Chinese. news 2021.11.20: Now we are updating our labs. Please checkout chX-dev

A tiny Rust std-lib for Linux x86_64 and aarch64

Tiny std Like a bad, probably buggy, tiny standard library for Linux. When it's appropriate If you are actually trying to do something solid, checkout

A small oscilloscope UI for the Owon HDS series portable oscilloscopes (Windows 10+, x86_64 only)
A small oscilloscope UI for the Owon HDS series portable oscilloscopes (Windows 10+, x86_64 only)

owowon - A small oscilloscope UI for the Owon HDS series portable oscilloscopes Screenshot of the program, reading a 10 MHz sinewave generated by the

memory-profiler — A memory profiler for Linux
memory-profiler — A memory profiler for Linux

A memory profiler for Linux Features Can be used to analyze memory leaks, see where exactly the memory is being consumed, identify temporary allocatio

Custom memory allocator that helps discover reads from uninitialized memory

libdiffuzz: security-oriented alternative to Memory Sanitizer This is a drop-in replacement for OS memory allocator that can be used to detect uses of

Custom memory allocator that helps discover reads from uninitialized memory

libdiffuzz: security-oriented alternative to Memory Sanitizer This is a drop-in replacement for OS memory allocator that can be used to detect uses of

Shared memory - A Rust wrapper around native shared memory for Linux and Windows

shared_memory A crate that allows you to share memory between processes. This crate provides lightweight wrappers around shared memory APIs in an OS a

A comparison of operating systems written in Rust

Rust OS comparison A comparison of operating systems written in Rust. There are several open source operating systems written in Rust. Most of them ar

Comments
  • userfaultfd backend

    userfaultfd backend

    regmap currently registers load-bearing SIGBUS and SIGSEGV handlers, but these have many alternative uses (stack overflow detection, core dumping/crash reporting, ON ERROR RESUME NEXT, miscellaneous PROT_NONE catching) and, unfortunately, signal disposition is hopelessly global!

    userfaultd is a more general mechanism to handle page-faults in userspace (from a different thread, or from a different process). Unless disabled through /proc/sys/vm/unprivileged_userfaultfd, userfaultd can be used without privileges.
    Currently it is mostly used for migration/checkpoint-restore code, and not so much for the traditional "sigaction" use-cases, so there should be less potential conflict with other libraries, and support for full userfaultd chaining/nesting is also being thought about, something impossible with signals!

    Clearly, the 8086's lack of support for memory-mapping registers is a grave oversight and Rust would greatly benefit from a regmap backend that is compatible with more libraries =D

    opened by tux3 2
Owner
iximeow
iximeow
MiniDump a process in memory with rust

safetydump Rust in-memory MiniDump implementation. Features ntdll!NtGetNextProcess to obtain a handle for the desired ProcessId as opposed to kernel32

null 26 Oct 11, 2022
In-memory, non stateful and session based code sharing application.

interviewer In-memory, non stateful and session based code sharing application. Test it here: interviewer.taras.lol Note: it's deployed to render auto

2pac 7 Aug 16, 2021
A cross-platform and safe Rust API to create and manage memory mappings in the virtual address space of the calling process.

mmap-rs A cross-platform and safe Rust API to create and manage memory mappings in the virtual address space of the calling process. This crate can be

S.J.R. van Schaik 19 Oct 23, 2022
Cross-platform library for reading/writing memory in other processes for Rust

vmemory Rust library for reading/writing memory in other processes for Windows, macOS, Linux, and in the future potentially, BSD variants. Rationale A

Jason Johnson 26 Nov 7, 2022
Rust library to interract with memory written in rust

memory-rs Rust library to interract with memory written in rust It comes with: Pattern scanner (Return address for a pattern given). A pattern example

Alex 1 Jan 13, 2022
A memory efficient syntax tree for language developers

This crate provides a tree structure which always is contiguously stored and manipulated in memory. It provides similar APIs as rowan and is intended to be an efficient replacement for it (read more below).

John-John Tedro 21 Dec 15, 2022
bevy_datasize is a library for tracking memory usage in Bevy apps.

bevy_datasize bevy_datasize is a library for tracking memory usage in Bevy apps. bevy_datasize uses the DataSize trait from the datasize crate to esti

Ben Reeves 4 Mar 8, 2022
Compile-time checked Builder pattern derive macro with zero-memory overhead

Compile-time checked Builder pattern derive macro with zero-memory overhead This is very much a work-in-progress. PRs welcome to bring this to product

Esteban Kuber 214 Dec 29, 2022
Memory hacking library for windows

Memory hacking library for windows

Sara Wahib 4 Apr 11, 2022
Easy c̵̰͠r̵̛̠ö̴̪s̶̩̒s̵̭̀-t̶̲͝h̶̯̚r̵̺͐e̷̖̽ḁ̴̍d̶̖̔ ȓ̵͙ė̶͎ḟ̴͙e̸̖͛r̶̖͗ë̶̱́ṉ̵̒ĉ̷̥e̷͚̍ s̷̹͌h̷̲̉a̵̭͋r̷̫̊ḭ̵̊n̷̬͂g̵̦̃ f̶̻̊ơ̵̜ṟ̸̈́ R̵̞̋ù̵̺s̷̖̅ţ̸͗!̸̼͋

Rust S̵̓i̸̓n̵̉ I̴n̴f̶e̸r̵n̷a̴l mutability! Howdy, friendly Rust developer! Ever had a value get m̵̯̅ð̶͊v̴̮̾ê̴̼͘d away right under your nose just when

null 294 Dec 23, 2022