Problem: - Phase 6-2.5 changed SUPERSLAB_SLAB0_DATA_OFFSET from 1024 → 2048 - Fixed sizeof(SuperSlab) mismatch (1088 bytes) - But 3 locations still used old slab_data_start() + manual offset This caused: - Address mismatch between allocation carving and validation - Freelist corruption false positives - 53-byte misalignment errors resolved, but new errors appeared Changes: 1. core/tiny_tls_guard.h:34 - Validation: slab_data_start() → tiny_slab_base_for() - Ensures validation uses same base address as allocation 2. core/hakmem_tiny_refill.inc.h:222 - Allocation carving: Remove manual +2048 hack - Use canonical tiny_slab_base_for() 3. core/hakmem_tiny_refill.inc.h:275 - Bump allocation: Remove duplicate slab_start calculation - Use existing base calculation with tiny_slab_base_for() Result: - Consistent use of tiny_slab_base_for() across all paths - All code uses SUPERSLAB_SLAB0_DATA_OFFSET constant - Remaining freelist corruption needs deeper investigation (not simple offset bug) Related commits: -d2f0d8458: Phase 6-2.5 (constants.h + 2048 offset) -c9053a43a: Phase 6-2.3~6-2.4 (active counter + SEGV fixes) 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
79 lines
2.4 KiB
C
79 lines
2.4 KiB
C
#ifndef TINY_TLS_GUARD_H
|
|
#define TINY_TLS_GUARD_H
|
|
|
|
#include <stdatomic.h>
|
|
#include <inttypes.h>
|
|
#include <stdio.h>
|
|
#include "hakmem_tiny.h"
|
|
#include "hakmem_tiny_superslab.h"
|
|
#include "hakmem_tiny_tls_list.h"
|
|
#include "tiny_debug_ring.h"
|
|
#include "tiny_remote.h"
|
|
|
|
static inline void tiny_tls_list_guard_push(int class_idx, TinyTLSList* tls, void* node) {
|
|
if (!node) return;
|
|
extern int g_debug_remote_guard;
|
|
if (!__builtin_expect(g_debug_remote_guard, 0)) {
|
|
return;
|
|
}
|
|
uintptr_t prior = atomic_load_explicit((_Atomic uintptr_t*)node, memory_order_relaxed);
|
|
tiny_remote_report_corruption("tls_push", node, prior);
|
|
|
|
int warn = 0;
|
|
size_t blk = (size_t)g_tiny_class_sizes[class_idx];
|
|
int slab_idx = -1;
|
|
SuperSlab* ss = hak_super_lookup(node);
|
|
TinySlabMeta* meta = NULL;
|
|
uintptr_t base_val = 0;
|
|
size_t ss_size = 0;
|
|
|
|
if (ss && ss->magic == SUPERSLAB_MAGIC) {
|
|
slab_idx = slab_index_for(ss, node);
|
|
if (slab_idx >= 0) {
|
|
meta = &ss->slabs[slab_idx];
|
|
uint8_t* base = tiny_slab_base_for(ss, slab_idx);
|
|
base_val = (uintptr_t)base;
|
|
ss_size = (size_t)1ULL << ss->lg_size;
|
|
if (blk != 0) {
|
|
uintptr_t delta = (uintptr_t)node - (uintptr_t)base;
|
|
if ((delta % blk) != 0 || (meta && meta->capacity > 0 && (delta / blk) >= meta->capacity)) {
|
|
warn = 1;
|
|
}
|
|
}
|
|
} else {
|
|
warn = 1;
|
|
}
|
|
} else {
|
|
warn = 1;
|
|
}
|
|
|
|
if (!warn && (prior & (sizeof(void*) - 1)) != 0) {
|
|
warn = 1;
|
|
}
|
|
|
|
if (warn) {
|
|
uintptr_t aux = 0;
|
|
if (ss) {
|
|
aux = tiny_remote_pack_diag(0xB301u, base_val, ss_size, (uintptr_t)node);
|
|
} else {
|
|
aux = ((uintptr_t)(uint16_t)class_idx << 32) | 0xB302u;
|
|
}
|
|
tiny_debug_ring_record(TINY_RING_EVENT_REMOTE_INVALID, (uint16_t)class_idx, node, aux);
|
|
fprintf(stderr,
|
|
"[TLS_LIST_GUARD] cls=%d node=%p prior=0x%016" PRIxPTR " ss=%p meta=%p count=%u cap=%u\n",
|
|
class_idx,
|
|
node,
|
|
prior,
|
|
(void*)ss,
|
|
(void*)meta,
|
|
tls ? tls->count : 0u,
|
|
tls ? tls->cap : 0u);
|
|
}
|
|
|
|
if (tiny_remote_watch_is(node)) {
|
|
tiny_remote_watch_note("tls_push", ss, slab_idx, node, 0xA241u, 0, 0);
|
|
}
|
|
}
|
|
|
|
#endif
|