/*
 *
 * honggfuzz - Intel PT decoder
 * -----------------------------------------
 *
 * Author: Robert Swiecki <swiecki@google.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 "pt.h"

#include <inttypes.h>
#include <linux/perf_event.h>
#include <stdio.h>

#include "libhfcommon/common.h"
#include "libhfcommon/log.h"
#include "libhfcommon/util.h"

#ifdef _HF_LINUX_INTEL_PT_LIB

#include <intel-pt.h>

struct pt_cpu ptCpu = {
    .vendor = pcv_unknown,
    .family = 0,
    .model = 0,
    .stepping = 0,
};

void perf_ptInit(void) {
    FILE* f = fopen("/proc/cpuinfo", "rb");
    if (!f) {
        PLOG_E("Couldn't open '/proc/cpuinfo'");
        return;
    }
    for (;;) {
        char k[1024], t[1024], v[1024];
        int ret = fscanf(f, "%1023[^\t]%1023[\t]: %1023[^\n]\n", k, t, v);
        if (ret == EOF) {
            break;
        }
        if (ret != 3) {
            break;
        }
        if (strcmp(k, "vendor_id") == 0) {
            if (strcmp(v, "GenuineIntel") == 0) {
                ptCpu.vendor = pcv_intel;
                LOG_D("IntelPT vendor: Intel");
            } else {
                ptCpu.vendor = pcv_unknown;
                LOG_D("Current processor is not Intel, IntelPT will not work");
            }
        }
        if (strcmp(k, "cpu family") == 0) {
            ptCpu.family = atoi(v);
            LOG_D("IntelPT family: %" PRIu16, ptCpu.family);
        }
        if (strcmp(k, "model") == 0) {
            ptCpu.model = atoi(v);
            LOG_D("IntelPT model: %" PRIu8, ptCpu.model);
        }
        if (strcmp(k, "stepping") == 0) {
            ptCpu.stepping = atoi(v);
            LOG_D("IntelPT stepping: %" PRIu8, ptCpu.stepping);
        }
    }
    fclose(f);
}

/* Sign-extend a uint64_t value. */
inline static uint64_t sext(uint64_t val, uint8_t sign) {
    uint64_t signbit, mask;

    signbit = 1ull << (sign - 1);
    mask = ~0ull << sign;

    return val & signbit ? val | mask : val & ~mask;
}

__attribute__((hot)) inline static void perf_ptAnalyzePkt(run_t* run, struct pt_packet* packet) {
    if (packet->type != ppt_tip) {
        return;
    }

    uint64_t ip;
    switch (packet->payload.ip.ipc) {
        case pt_ipc_update_16:
            ip = packet->payload.ip.ip & 0xFFFF;
            break;
        case pt_ipc_update_32:
            ip = packet->payload.ip.ip & 0xFFFFFFFF;
            break;
        case pt_ipc_update_48:
            ip = packet->payload.ip.ip & 0xFFFFFFFFFFFF;
            break;
        case pt_ipc_sext_48:
            ip = sext(packet->payload.ip.ip, 48);
            break;
        case pt_ipc_full:
            ip = packet->payload.ip.ip;
            break;
        default:
            return;
    }

    if (ip >= run->global->linux.dynamicCutOffAddr) {
        return;
    }

    ip &= _HF_PERF_BITMAP_BITSZ_MASK;
    register uint8_t prev = ATOMIC_BTS(run->global->feedback.feedbackMap->bbMapPc, ip);
    if (!prev) {
        run->linux.hwCnts.newBBCnt++;
    }
    return;
}

void arch_ptAnalyze(run_t* run) {
    struct perf_event_mmap_page* pem = (struct perf_event_mmap_page*)run->linux.perfMmapBuf;

    uint64_t aux_tail = ATOMIC_GET(pem->aux_tail);
    uint64_t aux_head = ATOMIC_GET(pem->aux_head);

    /* smp_rmb() required as per /usr/include/linux/perf_event.h */
    rmb();

    struct pt_config ptc;
    pt_config_init(&ptc);
    ptc.begin = &run->linux.perfMmapAux[aux_tail];
    ptc.end = &run->linux.perfMmapAux[aux_head];
    ptc.cpu = ptCpu;

    int errcode = pt_cpu_errata(&ptc.errata, &ptc.cpu);
    if (errcode < 0) {
        LOG_F("pt_errata() failed: %s", pt_errstr(-errcode));
    }

    struct pt_packet_decoder* ptd = pt_pkt_alloc_decoder(&ptc);
    if (ptd == NULL) {
        LOG_F("pt_pkt_alloc_decoder() failed");
    }
    defer {
        pt_pkt_free_decoder(ptd);
    };

    errcode = pt_pkt_sync_forward(ptd);
    if (errcode < 0) {
        LOG_W("pt_pkt_sync_forward() failed: %s", pt_errstr(-errcode));
        return;
    }

    for (;;) {
        struct pt_packet packet;
        errcode = pt_pkt_next(ptd, &packet, sizeof(packet));
        if (errcode == -pte_eos) {
            break;
        }
        if (errcode < 0) {
            LOG_W("pt_pkt_next() failed: %s", pt_errstr(-errcode));
            break;
        }
        perf_ptAnalyzePkt(run, &packet);
    }
}

#else /* _HF_LINUX_INTEL_PT_LIB */

void perf_ptInit(void) {
    return;
}

void arch_ptAnalyze(run_t* fuzzer HF_ATTR_UNUSED) {
    LOG_F(
        "The program has not been linked against the Intel's Processor Trace Library (libipt.so)");
}

#endif /* _HF_LINUX_INTEL_PT_LIB */
