/*
 *
 * honggfuzz - architecture dependent code (NETBSD/PTRACE)
 * -----------------------------------------
 *
 * Author: Kamil Rytarowski <n54@gmx.com>
 *
 * Copyright 2010-2018 by Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may obtain
 * a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 *
 */

#include "netbsd/trace.h"

// clang-format off
#include <sys/param.h>
#include <sys/types.h>
// clang-format on

#include <sys/ptrace.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/wait.h>

#include <ctype.h>
#include <dirent.h>
#include <elf.h>
#include <endian.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#include "libhfcommon/common.h"
#include "libhfcommon/files.h"
#include "libhfcommon/log.h"
#include "libhfcommon/util.h"
#include "netbsd/unwind.h"
#include "socketfuzzer.h"
#include "subproc.h"

#include <capstone/capstone.h>

/*
 * Size in characters required to store a string representation of a
 * register value (0xdeadbeef style))
 */
#define REGSIZEINCHAR (2 * sizeof(register_t) + 3)

#define _HF_INSTR_SZ 64

#if defined(__i386__) || defined(__x86_64__)
#define MAX_INSTR_SZ 16
#elif defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__)
#define MAX_INSTR_SZ 4
#elif defined(__aarch64__)
#define MAX_INSTR_SZ 8
#elif defined(__mips__) || defined(__mips64__)
#define MAX_INSTR_SZ 8
#endif

static struct {
    const char* descr;
    bool important;
} arch_sigs[_NSIG + 1] = {
    [0 ...(_NSIG)].important = false,
    [0 ...(_NSIG)].descr = "UNKNOWN",

    [SIGTRAP].important = false,
    [SIGTRAP].descr = "SIGTRAP",

    [SIGILL].important = true,
    [SIGILL].descr = "SIGILL",

    [SIGFPE].important = true,
    [SIGFPE].descr = "SIGFPE",

    [SIGSEGV].important = true,
    [SIGSEGV].descr = "SIGSEGV",

    [SIGBUS].important = true,
    [SIGBUS].descr = "SIGBUS",

    /* Is affected from monitorSIGABRT flag */
    [SIGABRT].important = false,
    [SIGABRT].descr = "SIGABRT",

    /* Is affected from tmoutVTALRM flag */
    [SIGVTALRM].important = false,
    [SIGVTALRM].descr = "SIGVTALRM-TMOUT",

    /* seccomp-bpf kill */
    [SIGSYS].important = true,
    [SIGSYS].descr = "SIGSYS",
};

#ifndef SI_FROMUSER
#define SI_FROMUSER(siptr) ((siptr)->si_code == SI_USER)
#endif /* SI_FROMUSER */

static __thread char arch_signame[32];
static const char* arch_sigName(int signo) {
    snprintf(arch_signame, sizeof(arch_signame), "SIG%s", signalname(signo));
    return arch_signame;
}

static size_t arch_getProcMem(pid_t pid, uint8_t* buf, size_t len, register_t pc) {
    struct ptrace_io_desc io;
    size_t bytes_read;

    bytes_read = 0;
    io.piod_op = PIOD_READ_D;
    io.piod_len = len;

    do {
        io.piod_offs = (void*)(pc + bytes_read);
        io.piod_addr = buf + bytes_read;

        if (ptrace(PT_IO, pid, &io, 0) == -1) {
            PLOG_W("Couldn't read process memory on pid %d, "
                   "piod_op: %d offs: %p addr: %p piod_len: %zu",
                pid, io.piod_op, io.piod_offs, io.piod_addr, io.piod_len);
            break;
        }

        bytes_read = io.piod_len;
        io.piod_len = len - bytes_read;
    } while (bytes_read < len);

    return bytes_read;
}

static size_t arch_getPC(
    pid_t pid, lwpid_t lwp, register_t* pc, register_t* status_reg HF_ATTR_UNUSED) {
    struct reg r;

    if (ptrace(PT_GETREGS, pid, &r, lwp) != 0) {
        PLOG_D("ptrace(PT_GETREGS) failed");
        return 0;
    }
    *pc = PTRACE_REG_PC(&r);
#if defined(__i386__)
    *status_reg = r.regs[_REG_EFLAGS];
#elif defined(__x86_64__)
    *status_reg = r.regs[_REG_RFLAGS];
#else
#error unsupported CPU architecture
#endif

    return sizeof(r);
}

static void arch_getInstrStr(pid_t pid, lwpid_t lwp, register_t* pc, char* instr) {
    /*
     * We need a value aligned to 8
     * which is sizeof(long) on 64bit CPU archs (on most of them, I hope;)
     */
    uint8_t buf[MAX_INSTR_SZ];
    size_t memsz;
    register_t status_reg = 0;

    snprintf(instr, _HF_INSTR_SZ, "%s", "[UNKNOWN]");

    size_t pcRegSz = arch_getPC(pid, lwp, pc, &status_reg);
    if (!pcRegSz) {
        LOG_W("Current architecture not supported for disassembly");
        return;
    }

    if ((memsz = arch_getProcMem(pid, buf, sizeof(buf), *pc)) == 0) {
        snprintf(instr, _HF_INSTR_SZ, "%s", "[NOT_MMAPED]");
        return;
    }

    cs_arch arch;
    cs_mode mode;

#if defined(__i386__)
    arch = CS_ARCH_X86;
    mode = CS_MODE_32;
#elif defined(__x86_64__)
    arch = CS_ARCH_X86;
    mode = CS_MODE_64;
#else
#error Unsupported CPU architecture
#endif

    csh handle;
    cs_err err = cs_open(arch, mode, &handle);
    if (err != CS_ERR_OK) {
        LOG_W("Capstone initialization failed: '%s'", cs_strerror(err));
        return;
    }

    cs_insn* insn;
    size_t count = cs_disasm(handle, buf, sizeof(buf), *pc, 0, &insn);

    if (count < 1) {
        LOG_W("Couldn't disassemble the assembler instructions' stream: '%s'",
            cs_strerror(cs_errno(handle)));
        cs_close(&handle);
        return;
    }

    snprintf(instr, _HF_INSTR_SZ, "%s %s", insn[0].mnemonic, insn[0].op_str);
    cs_free(insn, count);
    cs_close(&handle);

    for (int x = 0; instr[x] && x < _HF_INSTR_SZ; x++) {
        if (instr[x] == '/' || instr[x] == '\\' || isspace((unsigned char)instr[x]) ||
            !isprint((unsigned char)instr[x])) {
            instr[x] = '_';
        }
    }

    return;
}

static void arch_hashCallstack(
    run_t* run, funcs_t* funcs HF_ATTR_UNUSED, size_t funcCnt, bool enableMasking) {
    uint64_t hash = 0;
    for (size_t i = 0; i < funcCnt && i < run->global->netbsd.numMajorFrames; i++) {
        /*
         * Convert PC to char array to be compatible with hash function
         */
        char pcStr[REGSIZEINCHAR] = {0};
        snprintf(pcStr, REGSIZEINCHAR, "%" PRIxREGISTER, (register_t)(long)funcs[i].pc);

        /*
         * Hash the last three nibbles
         */
        hash ^= util_hash(&pcStr[strlen(pcStr) - 3], 3);
    }

    /*
     * If only one frame, hash is not safe to be used for uniqueness. We mask it
     * here with a constant prefix, so analyzers can pick it up and create filenames
     * accordingly. 'enableMasking' is controlling masking for cases where it should
     * not be enabled (e.g. fuzzer worker is from verifier).
     */
    if (enableMasking && funcCnt == 1) {
        hash |= _HF_SINGLE_FRAME_MASK;
    }
    run->backtrace = hash;
}

static void arch_traceGenerateReport(
    pid_t pid, run_t* run, funcs_t* funcs, size_t funcCnt, siginfo_t* si, const char* instr) {
    run->report[0] = '\0';
    util_ssnprintf(run->report, sizeof(run->report), "ORIG_FNAME: %s\n", run->origFileName);
    util_ssnprintf(run->report, sizeof(run->report), "FUZZ_FNAME: %s\n", run->crashFileName);
    util_ssnprintf(run->report, sizeof(run->report), "PID: %d\n", pid);
    util_ssnprintf(run->report, sizeof(run->report), "SIGNAL: %s (%d)\n",
        arch_sigName(si->si_signo), si->si_signo);
    util_ssnprintf(run->report, sizeof(run->report), "FAULT ADDRESS: %p\n",
        SI_FROMUSER(si) ? NULL : si->si_addr);
    util_ssnprintf(run->report, sizeof(run->report), "INSTRUCTION: %s\n", instr);
    util_ssnprintf(
        run->report, sizeof(run->report), "STACK HASH: %016" PRIx64 "\n", run->backtrace);
    util_ssnprintf(run->report, sizeof(run->report), "STACK:\n");
    for (size_t i = 0; i < funcCnt; i++) {
        util_ssnprintf(run->report, sizeof(run->report), " <%" PRIxREGISTER "> [%s():%zu at %s]\n",
            (register_t)(long)funcs[i].pc, funcs[i].func, funcs[i].line, funcs[i].mapName);
    }

    return;
}

static void arch_traceAnalyzeData(run_t* run, pid_t pid) {
    ptrace_siginfo_t info;
    register_t pc = 0, status_reg = 0;

    if (ptrace(PT_GET_SIGINFO, pid, &info, sizeof(info)) == -1) {
        PLOG_W("Couldn't get siginfo for pid %d", pid);
    }

    size_t pcRegSz = arch_getPC(pid, info.psi_lwpid, &pc, &status_reg);
    if (!pcRegSz) {
        LOG_W("ptrace arch_getPC failed");
        return;
    }

    /*
     * Unwind and resolve symbols
     */
    funcs_t* funcs = util_Malloc(_HF_MAX_FUNCS * sizeof(funcs_t));
    defer {
        free(funcs);
    };
    memset(funcs, 0, _HF_MAX_FUNCS * sizeof(funcs_t));

    size_t funcCnt = 0;

    /*
     * Use PC from ptrace GETREGS if not zero.
     * If PC reg zero return and callers should handle zero hash case.
     */
    if (pc) {
        /* Manually update major frame PC & frames counter */
        funcs[0].pc = (void*)(uintptr_t)pc;
        funcCnt = 1;
    } else {
        return;
    }

    /*
     * Calculate backtrace callstack hash signature
     */
    arch_hashCallstack(run, funcs, funcCnt, false);
}

static void arch_traceSaveData(run_t* run, pid_t pid) {
    register_t pc = 0;

    /* Local copy since flag is overridden for some crashes */
    bool saveUnique = run->global->io.saveUnique;

    char instr[_HF_INSTR_SZ] = "\x00";
    struct ptrace_siginfo info;
    memset(&info, 0, sizeof(info));

    if (ptrace(PT_GET_SIGINFO, pid, &info, sizeof(info)) == -1) {
        PLOG_W("Couldn't get siginfo for pid %d", pid);
    }

    arch_getInstrStr(pid, info.psi_lwpid, &pc, instr);

    LOG_D("Pid: %d, signo: %d, errno: %d, code: %d, addr: %p, pc: %" PRIxREGISTER ", instr: '%s'",
        pid, info.psi_siginfo.si_signo, info.psi_siginfo.si_errno, info.psi_siginfo.si_code,
        info.psi_siginfo.si_addr, pc, instr);

    if (!SI_FROMUSER(&info.psi_siginfo) && pc &&
        info.psi_siginfo.si_addr < run->global->netbsd.ignoreAddr) {
        LOG_I("Input is interesting (%s), but the si.si_addr is %p (below %p), skipping",
            arch_sigName(info.psi_siginfo.si_signo), info.psi_siginfo.si_addr,
            run->global->netbsd.ignoreAddr);
        return;
    }

    /*
     * Unwind and resolve symbols
     */
    funcs_t* funcs = util_Malloc(_HF_MAX_FUNCS * sizeof(funcs_t));
    defer {
        free(funcs);
    };
    memset(funcs, 0, _HF_MAX_FUNCS * sizeof(funcs_t));

    size_t funcCnt = 0;

    /*
     * Use PC from ptrace GETREGS if not zero.
     * If PC reg zero, temporarily disable uniqueness flag since callstack
     * hash will be also zero, thus not safe for unique decisions.
     */
    if (pc) {
        /* Manually update major frame PC & frames counter */
        funcs[0].pc = (void*)(uintptr_t)pc;
        funcCnt = 1;
    } else {
        saveUnique = false;
    }

    /*
     * Temp local copy of previous backtrace value in case worker hit crashes into multiple
     * tids for same target master thread. Will be 0 for first crash against target.
     */
    uint64_t oldBacktrace = run->backtrace;

    /*
     * Calculate backtrace callstack hash signature
     */
    arch_hashCallstack(run, funcs, funcCnt, saveUnique);

    /*
     * If unique flag is set and single frame crash, disable uniqueness for this crash
     * to always save (timestamp will be added to the filename)
     */
    if (saveUnique && (funcCnt == 1)) {
        saveUnique = false;
    }

    /*
     * If worker crashFileName member is set, it means that a tid has already crashed
     * from target master thread.
     */
    if (run->crashFileName[0] != '\0') {
        LOG_D("Multiple crashes detected from worker against attached tids group");

        /*
         * If stackhashes match, don't re-analyze. This will avoid duplicates
         * and prevent verifier from running multiple passes. Depth of check is
         * always 1 (last backtrace saved only per target iteration).
         */
        if (oldBacktrace == run->backtrace) {
            return;
        }
    }

    /* Increase global crashes counter */
    ATOMIC_POST_INC(run->global->cnts.crashesCnt);

    /*
     * Check if backtrace contains whitelisted symbol. Whitelist overrides
     * both stackhash and symbol blacklist. Crash is always kept regardless
     * of the status of uniqueness flag.
     */
    if (run->global->netbsd.symsWl) {
        char* wlSymbol = arch_btContainsSymbol(
            run->global->netbsd.symsWlCnt, run->global->netbsd.symsWl, funcCnt, funcs);
        if (wlSymbol != NULL) {
            saveUnique = false;
            LOG_D("Whitelisted symbol '%s' found, skipping blacklist checks", wlSymbol);
        }
    } else {
        /*
         * Check if stackhash is blacklisted
         */
        if (run->global->feedback.blacklist &&
            (fastArray64Search(run->global->feedback.blacklist, run->global->feedback.blacklistCnt,
                 run->backtrace) != -1)) {
            LOG_I("Blacklisted stack hash '%" PRIx64 "', skipping", run->backtrace);
            ATOMIC_POST_INC(run->global->cnts.blCrashesCnt);
            return;
        }

        /*
         * Check if backtrace contains blacklisted symbol
         */
        char* blSymbol = arch_btContainsSymbol(
            run->global->netbsd.symsBlCnt, run->global->netbsd.symsBl, funcCnt, funcs);
        if (blSymbol != NULL) {
            LOG_I("Blacklisted symbol '%s' found, skipping", blSymbol);
            ATOMIC_POST_INC(run->global->cnts.blCrashesCnt);
            return;
        }
    }

    /* If non-blacklisted crash detected, zero set two MSB */
    ATOMIC_POST_ADD(run->global->cfg.dynFileIterExpire, _HF_DYNFILE_SUB_MASK);

    void* sig_addr = info.psi_siginfo.si_addr;
    pc = 0UL;
    sig_addr = NULL;

    /* User-induced signals don't set si.si_addr */
    if (SI_FROMUSER(&info.psi_siginfo)) {
        sig_addr = NULL;
    }

    /* If dry run mode, copy file with same name into workspace */
    if (run->global->mutate.mutationsPerRun == 0U && run->global->cfg.useVerifier) {
        snprintf(run->crashFileName, sizeof(run->crashFileName), "%s/%s", run->global->io.crashDir,
            run->origFileName);
    } else if (saveUnique) {
        snprintf(run->crashFileName, sizeof(run->crashFileName),
            "%s/%s.PC.%" PRIxREGISTER ".STACK.%" PRIx64 ".CODE.%d.ADDR.%p.INSTR.%s.%s",
            run->global->io.crashDir, arch_sigName(info.psi_siginfo.si_signo), pc, run->backtrace,
            info.psi_siginfo.si_code, sig_addr, instr, run->global->io.fileExtn);
    } else {
        char localtmstr[PATH_MAX];
        util_getLocalTime("%F.%H:%M:%S", localtmstr, sizeof(localtmstr), time(NULL));
        snprintf(run->crashFileName, sizeof(run->crashFileName),
            "%s/%s.PC.%" PRIxREGISTER ".STACK.%" PRIx64 ".CODE.%d.ADDR.%p.INSTR.%s.%s.%d.%s",
            run->global->io.crashDir, arch_sigName(info.psi_siginfo.si_signo), pc, run->backtrace,
            info.psi_siginfo.si_code, sig_addr, instr, localtmstr, pid, run->global->io.fileExtn);
    }

    /* Target crashed (no duplicate detection yet) */
    if (run->global->socketFuzzer.enabled) {
        LOG_D("SocketFuzzer: trace: Crash Identified");
    }

    if (files_exists(run->crashFileName)) {
        LOG_I("Crash (dup): '%s' already exists, skipping", run->crashFileName);
        // Clear filename so that verifier can understand we hit a duplicate
        memset(run->crashFileName, 0, sizeof(run->crashFileName));
        return;
    }

    if (!files_writeBufToFile(run->crashFileName, run->dynamicFile, run->dynamicFileSz,
            O_CREAT | O_EXCL | O_WRONLY | O_CLOEXEC)) {
        LOG_E("Couldn't write to '%s'", run->crashFileName);
        return;
    }

    /* Unique new crash, notify fuzzer */
    if (run->global->socketFuzzer.enabled) {
        LOG_D("SocketFuzzer: trace: New Uniqu Crash");
        fuzz_notifySocketFuzzerCrash(run);
    }
    LOG_I("Crash: saved as '%s'", run->crashFileName);

    ATOMIC_POST_INC(run->global->cnts.uniqueCrashesCnt);
    /* If unique crash found, reset dynFile counter */
    ATOMIC_CLEAR(run->global->cfg.dynFileIterExpire);

    arch_traceGenerateReport(pid, run, funcs, funcCnt, &info.psi_siginfo, instr);
}

static void arch_traceEvent(run_t* run HF_ATTR_UNUSED, pid_t pid) {
    ptrace_state_t state;
    ptrace_siginfo_t info;
    int sig = 0;

    if (ptrace(PT_GET_SIGINFO, pid, &info, sizeof(info)) == -1) {
        PLOG_E("ptrace(PT_GET_SIGINFO, pid=%d)", (int)pid);
    } else {
        switch (info.psi_siginfo.si_code) {
            case TRAP_BRKPT:
                /* Software breakpoint trap, pass it over to tracee */
                sig = SIGTRAP;
                LOG_D("PID: %d breakpoint software trap (TRAP_BRKPT)", pid);
                break;
            case TRAP_TRACE:
                /* Single step unused */
                LOG_E("PID: %d unexpected single step trace trap (TRAP_TRACE)", pid);
                break;
            case TRAP_EXEC:
                /* exec(3) trap, ignore */
                LOG_D("PID: %d breakpoint software trap (TRAP_EXEC)", pid);
                break;
            case TRAP_CHLD:
            case TRAP_LWP:
                /* Child/LWP trap, ignore */
                if (ptrace(PT_GET_PROCESS_STATE, pid, &state, sizeof(state)) != -1) {
                    switch (state.pe_report_event) {
                        case PTRACE_FORK:
                            LOG_D("PID: %d child trap (TRAP_CHLD) : fork", (int)pid);
                            break;
                        case PTRACE_VFORK:
                            LOG_D("PID: %d child trap (TRAP_CHLD) : vfork", (int)pid);
                            break;
                        case PTRACE_VFORK_DONE:
                            LOG_D("PID: %d child trap (TRAP_CHLD) : vfork (PTRACE_VFORK_DONE)",
                                (int)pid);
                            break;
                        case PTRACE_LWP_CREATE:
                            LOG_E("PID: %d unexpected lwp trap (TRAP_LWP) : create "
                                  "(PTRACE_LWP_CREATE)",
                                (int)pid);
                            break;
                        case PTRACE_LWP_EXIT:
                            LOG_E("PID: %d unexpected lwp trap (TRAP_LWP) : exit (PTRACE_LWP_EXIT)",
                                (int)pid);
                            break;
                        default:
                            LOG_D("PID: %d unknown child/lwp trap (TRAP_LWP/TRAP_CHLD) : unknown "
                                  "pe_report_event=%d",
                                (int)pid, state.pe_report_event);
                            break;
                    }
                }
                break;
            case TRAP_DBREG:
                /* Debug Register trap unused */
                LOG_E("PID: %d unexpected debug register trap (TRAP_DBREG)", pid);
                break;
            case TRAP_SCE:
                /* Syscall Enter trap unused */
                LOG_E("PID: %d unexpected syscall enter trap (TRAP_SCE)", pid);
                break;
            case TRAP_SCX:
                /* Syscall Exit trap unused */
                LOG_E("PID: %d unexpected syscall exit trap (TRAP_SCX)", pid);
                break;
            default:
                /* Other trap, pass it over to tracee */
                sig = SIGTRAP;
                LOG_D("PID: %d other trap si_code=%d", pid, info.psi_siginfo.si_code);
                break;
        }
    }

    ptrace(PT_CONTINUE, pid, (void*)1, sig);
}

void arch_traceAnalyze(run_t* run, int status, pid_t pid) {
    /*
     * It's a ptrace event, deal with it elsewhere
     */
    if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) {
        return arch_traceEvent(run, pid);
    }

    if (WIFSTOPPED(status)) {
        /*
         * If it's an interesting signal, save the testcase
         */
        if (arch_sigs[WSTOPSIG(status)].important) {
            /*
             * If fuzzer worker is from core fuzzing process run full
             * analysis. Otherwise just unwind and get stack hash signature.
             */
            if (run->mainWorker) {
                arch_traceSaveData(run, pid);
            } else {
                arch_traceAnalyzeData(run, pid);
            }
        }
        /* Do not deliver SIGSTOP */
        int sig = (WSTOPSIG(status) != SIGSTOP) ? WSTOPSIG(status) : 0;
        ptrace(PT_CONTINUE, pid, (void*)1, sig);
        return;
    }

    /*
     * Resumed by delivery of SIGCONT
     */
    if (WIFCONTINUED(status)) {
        return;
    }

    /*
     * Process exited
     */
    if (WIFEXITED(status)) {
        return;
    }

    if (WIFSIGNALED(status)) {
        return;
    }

    abort(); /* NOTREACHED */
}

bool arch_traceWaitForPidStop(pid_t pid) {
    LOG_D("Waiting for pid=%d to stop", (int)pid);

    for (;;) {
        int status;
        pid_t ret = wait4(pid, &status, __WALL | WUNTRACED | WTRAPPED, NULL);
        if (ret == -1 && errno == EINTR) {
            continue;
        }
        if (ret == -1) {
            PLOG_W("wait4(pid=%d) failed", pid);
            return false;
        }
        if (!WIFSTOPPED(status)) {
            LOG_W("PID %d not in a stopped state - status:%d", pid, status);
            return false;
        }

        LOG_D("pid=%d stopped", (int)pid);
        return true;
    }
}

bool arch_traceAttach(run_t* run) {
    if (!arch_traceWaitForPidStop(run->pid)) {
        return false;
    }
    if (ptrace(PT_ATTACH, run->pid, NULL, 0) == -1) {
        PLOG_W("Couldn't ptrace(PT_ATTACH) to pid: %d", (int)run->pid);
        return false;
    }
    if (!arch_traceWaitForPidStop(run->pid)) {
        return false;
    }

    ptrace_event_t event = {
        /*
         * NetBSD 8.0 seems to support PTRACE_FORK only:
         *          .pe_set_event = PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE,
         */
        .pe_set_event = PTRACE_FORK,
    };
    if (ptrace(PT_SET_EVENT_MASK, run->pid, &event, sizeof(event)) == -1) {
        PLOG_W("Couldn't ptrace(PT_SET_EVENT_MASK) to pid: %d", (int)run->pid);
        return false;
    }

    LOG_D("Attached to PID: %d", run->pid);

    if (ptrace(PT_CONTINUE, run->pid, (void*)1, 0) == -1) {
        PLOG_W("Couldn't ptrace(PT_CONTINUE) to pid: (int)%d", run->pid);
        return false;
    }

    return true;
}

void arch_traceDetach(pid_t pid) {
    if (ptrace(PT_DETACH, pid, NULL, 0) == -1) {
        PLOG_E("PID: %d ptrace(PT_DETACH) failed", pid);
    }
}

void arch_traceSignalsInit(honggfuzz_t* hfuzz) {
    /* Default is true for all platforms except Android */
    arch_sigs[SIGABRT].important = hfuzz->cfg.monitorSIGABRT;

    /* Default is false */
    arch_sigs[SIGVTALRM].important = hfuzz->timing.tmoutVTALRM;
}
