#!/bin/bash
# verifier-mini.sh -- simulasi verifier eBPF: pemeriksaan statis sebelum muat.
# Program ditulis satu instruksi per baris dengan format "<indeks>: <isi>".
# Aturan pemeriksaan (versi sederhana):
#   1. Akses memori mem[r1+N] hanya sah untuk N < BATAS (64 byte).
#   2. Lompatan goto harus menunjuk instruksi yang ada.
#   3. Lompatan mundur ditolak: batas iterasinya tidak bisa dibuktikan
#      dengan sederhana. Verifier sungguhan menerima loop yang terbukti
#      berbatas, misalnya penghitung yang dibandingkan konstanta.
#   4. Instruksi terakhir harus exit agar program pasti berhenti.
# Pemakaian: bash verifier-mini.sh <program.txt>

BATAS=64
if [ $# -lt 1 ]; then
    exit 0
fi
program=$1
if [ ! -f "$program" ]; then
    echo "program tidak ditemukan: $program"
    exit 0
fi

total=$(grep -c ':' "$program")
terakhir=-1
while IFS= read -r baris; do
    nomor=${baris%%:*}
    isi=${baris#*:}
    for akses in $(printf '%s\n' "$isi" | grep -oE 'mem\[r1\+[0-9]+\]'); do
        offset=${akses#*+}
        offset=${offset%]}
        if [ "$offset" -ge "$BATAS" ]; then
            echo "DITOLAK (baris $nomor): akses $akses melewati batas $BATAS byte"
            exit 0
        fi
    done
    case $isi in
        *"goto "*)
            target=$(printf '%s\n' "$isi" | grep -oE '[0-9]+$')
            if [ "$target" -ge "$total" ]; then
                echo "DITOLAK (baris $nomor): goto $target menunjuk instruksi yang tidak ada"
                exit 0
            fi
            if [ "$target" -lt "$nomor" ]; then
                echo "DITOLAK (baris $nomor): goto $target melompat mundur (loop tanpa batas)"
                exit 0
            fi
            ;;
        *exit) terakhir=$nomor ;;
    esac
done < "$program"

if [ "$terakhir" -ne "$(( total - 1 ))" ]; then
    echo "DITOLAK: instruksi terakhir bukan exit"
    exit 0
fi
echo "DITERIMA: $total instruksi lolos pemeriksaan"
