Releases: EasyMem/easy_stack
Release list
Release v1.2.0: Public State Inspection, Updated Destruction, and Expanded Fuzzing & Tests
This release introduces new public inspection functions, safety improvements for stack destruction, and expanded automated testing coverage.
Public API & Versioning
- State Inspection: Added
estack_capacity,estack_count, andestack_free_spaceas public functions to query stack state at runtime. - Versioning: Added
ESTACK_VERSIONmacros to the header for preprocessor version checks.
Destruction & Poisoning
- Zeroing on Destroy:
estack_destroynow zeroes out the stack's capacity and index to catch accidental post-destroy reuse. - Active Poisoning: When
ESTACK_POISONINGis enabled, the destructor now poisons only the active metadata and payload regions instead of leaving them untouched.
Fuzzing, CI/CD, & Tests
- Fuzzer Improvements: The fuzzer now tests static stack configurations, randomized address jitter, and multiple metadata cell widths.
- Smoke Test in CI: Added a 90-second libFuzzer smoke test to the GitHub Actions CI/CD workflow to run on every commit.
- New Tests: Added test cases verifying boundary exact-fit limits and destroy poisoning.
Complex inside. Simple outside.
Release v1.1.1: Stack Allocation Math Refactoring for Low-Address Pointer Underflow Security
This release introduces a critical security and robustness update for bare-metal systems, refactoring the mathematical condition of the boundary check to prevent pointer underflow.
Security & Robustness (Low-Address Architectures)
- Pointer Underflow Prevention: Solved a potential pointer underflow vulnerability inside
estack_alloc_alignedoccurring on microcontrollers and raw hardware platforms where RAM is mapped close to the bottom of the address space (e.g., base addresses near0x0). - Modular Math Resolution: Refactored the single boundary check to use safe size-based offsets (
new_right_offset + metadata_overhead > capacity) instead of comparing raw pointer addresses. Exploited the natural wrapping behaviors of C unsigned modular arithmetic, allowingaligned_ptrto wrap safely and cancel out during the final offset calculation, maintaining the single flat check with zero extra branch penalties.
Complex inside. Simple outside.
Release v1.1.0: ISO C Strict-Aliasing Compliance
This release focuses on strict C-standard compliance, eliminating potential undefined behavior (UB) in pointer casting, and hardening static analysis warnings without any performance regressions.
ISO C Strict-Aliasing Compliance:
- Standard-Compliant Type Punning: Migrated all raw pointer casts and type-punning lookups (in metadata reads/writes and internal malloc pointer tracking) to ISO C-compliant
memcpyoperations. - Harnessed Static Analysis (
-Wstrict-aliasing=1): Audited and verified clean compilation (zero warnings) under the most restrictive compiler flag-Wstrict-aliasing=1across C99, C11, C17, and C23 standards. - Zero-Overhead Safe Execution: The compiler optimizes these constant-sized memory copies directly into single machine-word load/store instructions, preserving peak throughput (up to 939 Million ops/sec) while eliminating undefined behavior (UB) and
-Wcast-alignwarnings on strict alignment platforms.
Release v1.0.0: Standalone EStack Allocator and Dedicated Infrastructure
This stable release introduces easy_stack (EStack) as a fully independent, standalone header-only C library. Derived from the easy_memory ecosystem, this allocator is designed for fast, zero-dependency LIFO memory management.
Standalone LIFO Stack Allocator
- Inverted Bi-Directional Layout: Eliminates standard inline metadata overhead by growing metadata (offsets array) forward from the start of the buffer and aligned payloads backward from the end. This isolates control paths and removes intermediate padding gaps.
- Dynamic Metadata Scaling: Automatically adapts offset array cell sizes (1, 2, 4, or 8 bytes) based on the stack's overall capacity. For standard frame workloads (< 64 KB), each offset requires only 2 bytes (
uint16_t), reducing metadata overhead compared to traditional inline headers. - Zero-Multiplication Boundary Checks: Replaces expensive CPU multiplication instructions with fast bitwise shifts (
<< meta_type) on the hot allocation path, reducing boundary checks to a minimum of CPU cycles. - Clean Standalone API: Completely removed parent arena dependencies (
EMandBlocklinkages). Provides native dynamic (estack_create) and static (estack_create_static) construction paths out of the box.
Performance & Hot Path Optimizations
- Hot Path Branch Prediction: Optimized metadata read/write operations using compiler branch prediction hints. This restructured instruction pipelines to prioritize highly expected 16-bit and 32-bit metadata paths.
- Hardware-Limit Throughput: Reached up to 939 Million ops/sec (~1.06 ns per cycle) in trusted
CONTRACTmode, and up to 615 Million ops/sec (a +33% performance boost) inDEFENSIVEsafety mode on x86_64. - Instruction Latency Hiding: In
DEFENSIVEmode, CPU-bound execution masks memory prefetching latency, maintaining flat, stable, and highly predictable performance across all stack allocation depths.
Cryptographically Hardened Markers
- XOR-Hardening: Implements secure rollback state tokens (
EStackMarker). Both the index and validation signature are XOR-encrypted using the stack's base address andESTACK_MAGIC, protecting against cross-allocator marker pollution and forged rollbacks.
Diagnostic Visualization
- Non-Allocating Diagnostics (
estack_print): Integrated a zero-allocation debugging API to print detailed stack metrics (min/max/average object sizes and total buffer utilization) on-the-fly.
Portability & Bare-Metal Compliance
- Bare-Metal AVR Hardening: Resolved compiler-warning constraints on 8/16-bit bare-metal platforms when custom alignment options (
ESTACK_NO_AUTO_ALIGN) are active, ensuring clean compilation ofestack_alloc_alignedacross all optimization matrices.
Complex inside. Simple outside.