Front Gate: registry-first classification (no ptr-1 deref); Pool TLS via registry to avoid unsafe header reads.\nTLS-SLL: splice head normalization, remove false misalignment guard, drop heuristic normalization; add carve/splice debug logs.\nRefill: add one-shot sanity checks (range/stride) at P0 and non-P0 boundaries (debug-only).\nInfra: provide ptr_trace_dump_now stub in release to fix linking.\nVerified: bench_fixed_size_hakmem 200000 1024 128 passes (Debug/Release), no SEGV.

This commit is contained in:
Moe Charm (CI)
2025-11-11 01:00:37 +09:00
parent 8aabee4392
commit a97005f50e
5 changed files with 103 additions and 46 deletions

View File

@ -17,7 +17,7 @@
#include "../hakmem_super_registry.h" // For hak_super_lookup (Box REG)
#ifdef HAKMEM_POOL_TLS_PHASE1
#include "../pool_tls.h" // For POOL_MAGIC
#include "../pool_tls_registry.h" // Safer pool pointer lookup (no header deref)
#endif
// ========== Debug Stats ==========
@ -158,19 +158,10 @@ static inline ptr_classification_t registry_lookup(void* ptr) {
// ========== Pool TLS Probe ==========
#ifdef HAKMEM_POOL_TLS_PHASE1
// Check if pointer has Pool TLS magic (0xb0)
// Returns: 1 if Pool TLS, 0 otherwise
static inline int is_pool_tls(void* ptr) {
// Same safety check as header probe
uintptr_t offset_in_page = (uintptr_t)ptr & 0xFFF;
if (offset_in_page == 0) {
return 0; // Page-aligned, skip header read
}
uint8_t* header_ptr = (uint8_t*)ptr - 1;
uint8_t header = *header_ptr;
return (header & 0xF0) == POOL_MAGIC;
// Registry-based Pool TLS probe (no memory deref)
static inline int is_pool_tls_reg(void* ptr) {
pid_t tid = 0; int cls = -1;
return pool_reg_lookup(ptr, &tid, &cls);
}
#endif
@ -191,35 +182,9 @@ ptr_classification_t classify_ptr(void* ptr) {
return result;
}
// Step 1: Try safe header probe (C0-C6 fast path: 5-10 cycles)
// Skip header probe on 1KB-aligned pointers to avoid misclassifying C7/headerless
int class_idx = -1;
if (((uintptr_t)ptr & 0x3FF) != 0) {
class_idx = safe_header_probe(ptr);
}
if (class_idx >= 0) {
// Header found - C0-C6 with header
// Additional safety: verify pointer belongs to a SuperSlab region.
// This avoids rare false positives where random header bytes look like 0xA0.
struct SuperSlab* ss_chk = hak_super_lookup(ptr);
if (!ss_chk) {
// Not in Tiny registry; treat as UNKNOWN and continue
// (fall back to later checks)
} else {
result.kind = PTR_KIND_TINY_HEADER;
result.class_idx = class_idx;
result.ss = ss_chk;
#if !HAKMEM_BUILD_RELEASE
g_classify_header_hit++;
#endif
return result;
}
}
// Step 2: Check Pool TLS (before Registry to avoid false positives)
// Step 1: Check Pool TLS via registry (no pointer deref)
#ifdef HAKMEM_POOL_TLS_PHASE1
if (is_pool_tls(ptr)) {
if (is_pool_tls_reg(ptr)) {
result.kind = PTR_KIND_POOL_TLS;
#if !HAKMEM_BUILD_RELEASE
@ -229,7 +194,7 @@ ptr_classification_t classify_ptr(void* ptr) {
}
#endif
// Step 3: Fallback to Registry lookup (C7 headerless or header failed)
// Step 2: Registry lookup for Tiny (header or headerless)
result = registry_lookup(ptr);
if (result.kind == PTR_KIND_TINY_HEADERLESS) {
#if !HAKMEM_BUILD_RELEASE
@ -237,8 +202,14 @@ ptr_classification_t classify_ptr(void* ptr) {
#endif
return result;
}
if (result.kind == PTR_KIND_TINY_HEADER) {
#if !HAKMEM_BUILD_RELEASE
g_classify_header_hit++;
#endif
return result;
}
// Step 4: Not Tiny or Pool - return UNKNOWN
// Step 3: Not Tiny or Pool - return UNKNOWN
// Caller should check AllocHeader (16-byte) or delegate to system free
result.kind = PTR_KIND_UNKNOWN;