cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

printinsn.c (4288B)


      1/*
      2 *  Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
      3 *
      4 *  This program is free software; you can redistribute it and/or modify
      5 *  it under the terms of the GNU General Public License as published by
      6 *  the Free Software Foundation; either version 2 of the License, or
      7 *  (at your option) any later version.
      8 *
      9 *  This program is distributed in the hope that it will be useful,
     10 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 *  GNU General Public License for more details.
     13 *
     14 *  You should have received a copy of the GNU General Public License
     15 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
     16 */
     17
     18#include "qemu/osdep.h"
     19#include "attribs.h"
     20#include "printinsn.h"
     21#include "insn.h"
     22#include "reg_fields.h"
     23#include "internal.h"
     24
     25static const char *sreg2str(unsigned int reg)
     26{
     27    if (reg < TOTAL_PER_THREAD_REGS) {
     28        return hexagon_regnames[reg];
     29    } else {
     30        return "???";
     31    }
     32}
     33
     34static const char *creg2str(unsigned int reg)
     35{
     36    return sreg2str(reg + HEX_REG_SA0);
     37}
     38
     39static void snprintinsn(GString *buf, Insn *insn)
     40{
     41    switch (insn->opcode) {
     42#define DEF_VECX_PRINTINFO(TAG, FMT, ...) DEF_PRINTINFO(TAG, FMT, __VA_ARGS__)
     43#define DEF_PRINTINFO(TAG, FMT, ...) \
     44    case TAG: \
     45        g_string_append_printf(buf, FMT, __VA_ARGS__); \
     46        break;
     47#include "printinsn_generated.h.inc"
     48#undef DEF_VECX_PRINTINFO
     49#undef DEF_PRINTINFO
     50    }
     51}
     52
     53void snprint_a_pkt_disas(GString *buf, Packet *pkt, uint32_t *words,
     54                         target_ulong pc)
     55{
     56    bool has_endloop0 = false;
     57    bool has_endloop1 = false;
     58    bool has_endloop01 = false;
     59
     60    for (int i = 0; i < pkt->num_insns; i++) {
     61        if (pkt->insn[i].part1) {
     62            continue;
     63        }
     64
     65        /* We'll print the endloop's at the end of the packet */
     66        if (pkt->insn[i].opcode == J2_endloop0) {
     67            has_endloop0 = true;
     68            continue;
     69        }
     70        if (pkt->insn[i].opcode == J2_endloop1) {
     71            has_endloop1 = true;
     72            continue;
     73        }
     74        if (pkt->insn[i].opcode == J2_endloop01) {
     75            has_endloop01 = true;
     76            continue;
     77        }
     78
     79        g_string_append_printf(buf, "0x" TARGET_FMT_lx "\t", words[i]);
     80
     81        if (i == 0) {
     82            g_string_append(buf, "{");
     83        }
     84
     85        g_string_append(buf, "\t");
     86        snprintinsn(buf, &(pkt->insn[i]));
     87
     88        if (i < pkt->num_insns - 1) {
     89            /*
     90             * Subinstructions are two instructions encoded
     91             * in the same word. Print them on the same line.
     92             */
     93            if (GET_ATTRIB(pkt->insn[i].opcode, A_SUBINSN)) {
     94                g_string_append(buf, "; ");
     95                snprintinsn(buf, &(pkt->insn[i + 1]));
     96                i++;
     97            } else if (pkt->insn[i + 1].opcode != J2_endloop0 &&
     98                       pkt->insn[i + 1].opcode != J2_endloop1 &&
     99                       pkt->insn[i + 1].opcode != J2_endloop01) {
    100                pc += 4;
    101                g_string_append_printf(buf, "\n0x" TARGET_FMT_lx ":  ", pc);
    102            }
    103        }
    104    }
    105    g_string_append(buf, " }");
    106    if (has_endloop0) {
    107        g_string_append(buf, "  :endloop0");
    108    }
    109    if (has_endloop1) {
    110        g_string_append(buf, "  :endloop1");
    111    }
    112    if (has_endloop01) {
    113        g_string_append(buf, "  :endloop01");
    114    }
    115}
    116
    117void snprint_a_pkt_debug(GString *buf, Packet *pkt)
    118{
    119    int slot, opcode;
    120
    121    if (pkt->num_insns > 1) {
    122        g_string_append(buf, "\n{\n");
    123    }
    124
    125    for (int i = 0; i < pkt->num_insns; i++) {
    126        if (pkt->insn[i].part1) {
    127            continue;
    128        }
    129        g_string_append(buf, "\t");
    130        snprintinsn(buf, &(pkt->insn[i]));
    131
    132        if (GET_ATTRIB(pkt->insn[i].opcode, A_SUBINSN)) {
    133            g_string_append(buf, " //subinsn");
    134        }
    135        if (pkt->insn[i].extension_valid) {
    136            g_string_append(buf, " //constant extended");
    137        }
    138        slot = pkt->insn[i].slot;
    139        opcode = pkt->insn[i].opcode;
    140        g_string_append_printf(buf, " //slot=%d:tag=%s\n",
    141                               slot, opcode_names[opcode]);
    142    }
    143    if (pkt->num_insns > 1) {
    144        g_string_append(buf, "}\n");
    145    }
    146}