138 lines
4.6 KiB
C
138 lines
4.6 KiB
C
|
|
// tiny_ptr_bridge_box.h - Pointer→SuperSlab/Slab Bridge Box
|
|||
|
|
// Purpose:
|
|||
|
|
// Centralize the logic for resolving Tiny BASE pointers into
|
|||
|
|
// (SuperSlab*, slab_idx, TinySlabMeta*, class_idx) with a single
|
|||
|
|
// consistent contract.
|
|||
|
|
//
|
|||
|
|
// Box Theory:
|
|||
|
|
// - Single Responsibility:
|
|||
|
|
// "Given a Tiny pointer, tell me which SuperSlab/slab/meta it belongs to."
|
|||
|
|
// - Clear Boundary:
|
|||
|
|
// All ptr→(ss, slab_idx, meta, class) resolution goes through this box.
|
|||
|
|
// - Fail‑Fast Friendly:
|
|||
|
|
// Callers decide whether to abort/drop/log based on the result.
|
|||
|
|
// This box itself stays side‑effect free (no logging by default).
|
|||
|
|
// - Reversible / A/B:
|
|||
|
|
// Call sites can be migrated gradually; old hand‑rolled lookups
|
|||
|
|
// can be kept under #ifdef until fully retired.
|
|||
|
|
//
|
|||
|
|
// Notes:
|
|||
|
|
// - This box is intentionally "dumb": it does not know about TLS SLL,
|
|||
|
|
// remote queues, or ownership. It only classifies pointers.
|
|||
|
|
// - Validation (e.g. class match) is done via helpers that return bool.
|
|||
|
|
|
|||
|
|
#ifndef HAKMEM_TINY_PTR_BRIDGE_BOX_H
|
|||
|
|
#define HAKMEM_TINY_PTR_BRIDGE_BOX_H
|
|||
|
|
|
|||
|
|
#include "../hakmem_tiny_superslab_internal.h" // SuperSlab, TinySlabMeta, slab_index_for, ss_slabs_capacity
|
|||
|
|
|
|||
|
|
// Classification result for a Tiny pointer.
|
|||
|
|
typedef struct TinyPtrBridgeInfo {
|
|||
|
|
SuperSlab* ss; // Owning SuperSlab (NULL if not Tiny)
|
|||
|
|
TinySlabMeta* meta; // Per‑slab metadata (NULL if invalid)
|
|||
|
|
int slab_idx; // Slab index within SuperSlab (‑1 if invalid)
|
|||
|
|
uint8_t meta_cls; // meta->class_idx if valid, 0xff otherwise
|
|||
|
|
} TinyPtrBridgeInfo;
|
|||
|
|
|
|||
|
|
// Internal helper: classify a raw pointer without applying any policy.
|
|||
|
|
// Preconditions:
|
|||
|
|
// - raw may be arbitrary (stack/heap/garbage).
|
|||
|
|
// Postconditions:
|
|||
|
|
// - On success: info.ss != NULL, info.meta != NULL, slab_idx >= 0, meta_cls set.
|
|||
|
|
// - On failure: all fields are "empty" (ss/meta=NULL, slab_idx=-1, meta_cls=0xff).
|
|||
|
|
static inline TinyPtrBridgeInfo tiny_ptr_bridge_classify_raw(void* raw)
|
|||
|
|
{
|
|||
|
|
TinyPtrBridgeInfo info;
|
|||
|
|
info.ss = NULL;
|
|||
|
|
info.meta = NULL;
|
|||
|
|
info.slab_idx = -1;
|
|||
|
|
info.meta_cls = 0xffu;
|
|||
|
|
|
|||
|
|
if (!raw) {
|
|||
|
|
return info;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uintptr_t addr = (uintptr_t)raw;
|
|||
|
|
if (addr < 4096 || addr > 0x00007fffffffffffULL) {
|
|||
|
|
// Non‑canonical (very small or non‑userspace) → treat as invalid.
|
|||
|
|
return info;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
SuperSlab* ss = hak_super_lookup(raw);
|
|||
|
|
if (!ss || ss->magic != SUPERSLAB_MAGIC) {
|
|||
|
|
return info;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int cap = ss_slabs_capacity(ss);
|
|||
|
|
if (cap <= 0) {
|
|||
|
|
return info;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int slab_idx = slab_index_for(ss, raw);
|
|||
|
|
if (slab_idx < 0 || slab_idx >= cap) {
|
|||
|
|
return info;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
TinySlabMeta* meta = &ss->slabs[slab_idx];
|
|||
|
|
info.ss = ss;
|
|||
|
|
info.meta = meta;
|
|||
|
|
info.slab_idx = slab_idx;
|
|||
|
|
info.meta_cls = meta->class_idx;
|
|||
|
|
return info;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Convenience: classify a BASE pointer (hak_base_ptr_t) into bridge info.
|
|||
|
|
static inline TinyPtrBridgeInfo tiny_ptr_bridge_classify_base(hak_base_ptr_t base)
|
|||
|
|
{
|
|||
|
|
void* raw = HAK_BASE_TO_RAW(base);
|
|||
|
|
return tiny_ptr_bridge_classify_raw(raw);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Validate that a BASE pointer belongs to a Tiny slab with the expected class.
|
|||
|
|
//
|
|||
|
|
// Parameters:
|
|||
|
|
// class_idx - Expected Tiny class index (‑1 to skip class check).
|
|||
|
|
// base - BASE pointer to classify.
|
|||
|
|
// out_info - Optional; filled on success with full classification.
|
|||
|
|
//
|
|||
|
|
// Returns:
|
|||
|
|
// true - Pointer classified successfully and (if class_idx>=0) meta_cls matches.
|
|||
|
|
// false - Pointer is not within any valid Tiny slab or class mismatch.
|
|||
|
|
static inline bool tiny_ptr_bridge_validate_base_class(int class_idx,
|
|||
|
|
hak_base_ptr_t base,
|
|||
|
|
TinyPtrBridgeInfo* out_info)
|
|||
|
|
{
|
|||
|
|
TinyPtrBridgeInfo info = tiny_ptr_bridge_classify_base(base);
|
|||
|
|
if (!info.ss || !info.meta) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
if (class_idx >= 0 && info.meta_cls != (uint8_t)class_idx) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
if (out_info) {
|
|||
|
|
*out_info = info;
|
|||
|
|
}
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Convenience wrapper for raw pointers (used by legacy code).
|
|||
|
|
static inline bool tiny_ptr_bridge_validate_raw_class(int class_idx,
|
|||
|
|
void* raw,
|
|||
|
|
TinyPtrBridgeInfo* out_info)
|
|||
|
|
{
|
|||
|
|
TinyPtrBridgeInfo info = tiny_ptr_bridge_classify_raw(raw);
|
|||
|
|
if (!info.ss || !info.meta) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
if (class_idx >= 0 && info.meta_cls != (uint8_t)class_idx) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
if (out_info) {
|
|||
|
|
*out_info = info;
|
|||
|
|
}
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endif // HAKMEM_TINY_PTR_BRIDGE_BOX_H
|
|||
|
|
|