// init_env_box.h — ENV 読み出しと初期フラグ設定の箱 #ifndef INIT_ENV_BOX_H #define INIT_ENV_BOX_H #include #include static inline void box_init_env_flags(void) { // Phase 6.15: EVO サンプリング(デフォルト OFF) const char* evo_sample_str = getenv("HAKMEM_EVO_SAMPLE"); if (evo_sample_str && atoi(evo_sample_str) > 0) { int freq = atoi(evo_sample_str); if (freq >= 64) { HAKMEM_LOG("Warning: HAKMEM_EVO_SAMPLE=%d too large, using 63\n", freq); freq = 63; } g_evo_sample_mask = (1ULL << freq) - 1; HAKMEM_LOG("EVO sampling enabled: every 2^%d = %llu calls\n", freq, (unsigned long long)(g_evo_sample_mask + 1)); } else { g_evo_sample_mask = 0; // Disabled by default HAKMEM_LOG("EVO sampling disabled (HAKMEM_EVO_SAMPLE not set or 0)\n"); } // LD_PRELOAD 配下のセーフモード { const char* ldpre = getenv("LD_PRELOAD"); if (ldpre && strstr(ldpre, "libhakmem.so")) { g_ldpreload_mode = 1; // Default LD-safe mode if not set: 1 (Tiny-only) const char* lds = getenv("HAKMEM_LD_SAFE"); if (lds) { /* NOP used in wrappers */ } else { setenv("HAKMEM_LD_SAFE", "1", 0); } if (!getenv("HAKMEM_TINY_TLS_SLL")) { setenv("HAKMEM_TINY_TLS_SLL", "0", 0); // disable TLS SLL by default } if (!getenv("HAKMEM_TINY_USE_SUPERSLAB")) { setenv("HAKMEM_TINY_USE_SUPERSLAB", "0", 0); // disable SuperSlab path by default } } } // Runtime safety toggle const char* safe_free_env = getenv("HAKMEM_SAFE_FREE"); if (safe_free_env && atoi(safe_free_env) != 0) { g_strict_free = 1; HAKMEM_LOG("Strict free safety enabled (HAKMEM_SAFE_FREE=1)\n"); } else { // Heuristic: if loaded via LD_PRELOAD, enable strict free by default const char* ldpre = getenv("LD_PRELOAD"); if (ldpre && strstr(ldpre, "libhakmem.so")) { g_ldpreload_mode = 1; g_strict_free = 1; HAKMEM_LOG("Strict free safety auto-enabled under LD_PRELOAD\n"); } } // Invalid free logging toggle (default off to avoid spam under LD_PRELOAD) const char* invlog = getenv("HAKMEM_INVALID_FREE_LOG"); if (invlog && atoi(invlog) != 0) { g_invalid_free_log = 1; HAKMEM_LOG("Invalid free logging enabled (HAKMEM_INVALID_FREE_LOG=1)\n"); } // Phase 7.4: Cache HAKMEM_INVALID_FREE to eliminate getenv overhead const char* inv = getenv("HAKMEM_INVALID_FREE"); if (inv && strcmp(inv, "skip") == 0) { g_invalid_free_mode = 1; // explicit opt-in to legacy skip mode HAKMEM_LOG("Invalid free mode: skip check (HAKMEM_INVALID_FREE=skip)\n"); } else if (inv && strcmp(inv, "fallback") == 0) { g_invalid_free_mode = 0; // fallback mode: route invalid frees to libc HAKMEM_LOG("Invalid free mode: fallback to libc (HAKMEM_INVALID_FREE=fallback)\n"); } else { // Under LD_PRELOAD, prefer safety: default to fallback unless explicitly overridden const char* ldpre = getenv("LD_PRELOAD"); if (ldpre && strstr(ldpre, "libhakmem.so")) { g_ldpreload_mode = 1; g_invalid_free_mode = 0; HAKMEM_LOG("Invalid free mode: fallback to libc (auto under LD_PRELOAD)\n"); } else { // Default: safety first (fallback), avoids routing unknown pointers into Tiny g_invalid_free_mode = 0; HAKMEM_LOG("Invalid free mode: fallback to libc (default)\n"); } } } #endif // INIT_ENV_BOX_H