Created
August 28, 2024 05:54
-
-
Save novafacing/5abc08052fab671a0fb26547810b4c55 to your computer and use it in GitHub Desktop.
Demo QEMU plugin that dumps the first 256 bytes of firmware when booting a BIOS on RISC-V
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (C) 2018, Emilio G. Cota <[email protected]> | |
* | |
* License: GNU GPL, version 2 or later. | |
* See the COPYING file in the top-level directory. | |
*/ | |
#include <inttypes.h> | |
#include <assert.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <qemu-plugin.h> | |
QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; | |
static bool did_dump = false; | |
/* | |
* Hex-dump a GByteArray to the QEMU plugin output in the format: | |
* 61 63 63 65 6c 09 09 20 20 20 66 70 75 09 09 09 | accel.....fpu... | |
* 20 6d 6f 64 75 6c 65 2d 63 6f 6d 6d 6f 6e 2e 63 | .module-common.c | |
*/ | |
static void hexdump(const GByteArray *data) | |
{ | |
g_autoptr(GString) out = g_string_new(""); | |
for (guint index = 0; index < data->len; index += 16) { | |
for (guint col = 0; col < 16; col++) { | |
if (index + col < data->len) { | |
g_string_append_printf(out, "%02x ", data->data[index + col]); | |
} else { | |
g_string_append(out, " "); | |
} | |
} | |
g_string_append(out, " | "); | |
for (guint col = 0; col < 16; col++) { | |
if (index + col >= data->len) { | |
break; | |
} | |
if (g_ascii_isgraph(data->data[index + col])) { | |
g_string_append_printf(out, "%c", data->data[index + col]); | |
} else { | |
g_string_append(out, "."); | |
} | |
} | |
g_string_append(out, "\n"); | |
} | |
qemu_plugin_outs(out->str); | |
} | |
static void vcpu_insn_exec_before(unsigned int cpu_index, void *udata) | |
{ | |
g_autoptr(GByteArray) mem = g_byte_array_new(); | |
if (!did_dump && qemu_plugin_read_cpu_memory_hwaddr(0x80000000, mem, 256)) { | |
hexdump(mem); | |
did_dump = true; | |
} | |
} | |
static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb) | |
{ | |
size_t n = qemu_plugin_tb_n_insns(tb); | |
for (size_t i = 0; i < n; i++) { | |
struct qemu_plugin_insn *insn = qemu_plugin_tb_get_insn(tb, i); | |
qemu_plugin_register_vcpu_insn_exec_cb(insn, vcpu_insn_exec_before, QEMU_PLUGIN_CB_NO_REGS, NULL); | |
} | |
} | |
QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id, | |
const qemu_info_t *info, | |
int argc, char **argv) | |
{ | |
qemu_plugin_register_vcpu_tb_trans_cb(id, vcpu_tb_trans); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment