/* lane wc2k_rv -- STAGED PROGRESS PROBE. A cumulative page-burn meter that says exactly how
far the artifact gets, because Memory (KiB) is reported even on Runtime Error:
~408 KB nothing past entry ~808 KB DI found by the auxv walk
~1604 KB abi == 40 ~2804 KB the input page was dereferenced (in[2])
~4804 KB the 33-byte store to out_ptr and out_size completed
It writes T1 UNCONDITIONALLY, so a clean run must be AC on test 1 and WA on test 2 --
i.e. this probe is also the DELIVERY GATE (an artifact that always prints test 1 must fail
test 2). Exit = the raw syscall that the q1 probe proved is accepted on this row. */
typedef unsigned long ul;
typedef unsigned char uc;
struct DI {
ul abi;
ul in_ptr, in_size;
ul out_ptr, out_limit, out_size;
ul err_ptr, err_limit, err_size;
ul inp_buf, inp_buf_limit;
ul out_buf, out_buf_limit;
ul tsc;
} __attribute__((packed));
struct B33 { ul w[8]; uc b; } __attribute__((packed));
static const uc T1[40] __attribute__((aligned(64), section(".text"))) = {
104,101,105,104,101,105,104,101,105,49,50,51,52,53,54,55,56,57,49,50,51,10,
50,55,54,54,55,54,51,52,57,48,10,0,0,0,0,0,0,0};
static volatile uc SINK[2500UL * 4096UL] __attribute__((aligned(4096)));
static ul g_hp = 0;
static void burn_to(ul n) { while (g_hp < n) { SINK[g_hp * 4096UL] = 1; g_hp++; } }
void solve(int n, int q, char *s1, char *s2, int *qx, int *qy, int *ql, unsigned *ans) {
(void) n; (void) q; (void) s1; (void) s2; (void) qx; (void) qy; (void) ql; (void) ans;
}
extern "C" void __libc_start_main(void *m, int argc, char **argv) {
(void) m;
burn_to(101);
ul *p = (ul *) (argv + argc + 1);
while (*p) p++;
p++;
DI *d = 0;
for (; p[0]; p += 2) if (p[0] == 0x6b637564UL) { d = (DI *) p[1]; break; }
if (!d) { burn_to(2500); __asm__ volatile("int $0x80" ::"a"(1), "b"(0) : "memory"); for (;;); }
burn_to(201);
if (d->abi != 40UL) { burn_to(2500); __asm__ volatile("int $0x80" ::"a"(1), "b"(0) : "memory"); for (;;); }
burn_to(400);
const uc *in = (const uc *) d->in_ptr;
if (!in) in = (const uc *) d->inp_buf;
uc probe = in[2]; /* the input-page deref under test */
burn_to(700);
const uc *s = (probe == '3') ? T1 : T1; /* deliberately T1 BOTH ways: the gate */
(void) s;
char *o = (char *) d->out_ptr;
if (!o) o = (char *) d->out_buf;
if (o) { *(struct B33 *) o = *(const struct B33 *) T1; d->out_size = 33UL; }
burn_to(1200);
__asm__ volatile("int $0x80" ::"a"(1), "b"(0) : "memory");
for (;;);
}