diff options
| author | Theofilos Augoustis <theofilos.augoustis@gmail.com> | 2025-11-05 14:17:33 +0000 |
|---|---|---|
| committer | Theofilos Augoustis <theofilos.augoustis@gmail.com> | 2025-11-05 14:50:14 +0000 |
| commit | 3b2a0fb80eb9b6b5f216fa69069e66210466f5eb (patch) | |
| tree | 24b8f268af8b26f068d39b4741001a682baf009f | |
| parent | eca7ec318407da151c0fc059f91275beb245f746 (diff) | |
| download | focaccia-qemu-3b2a0fb80eb9b6b5f216fa69069e66210466f5eb.tar.gz focaccia-qemu-3b2a0fb80eb9b6b5f216fa69069e66210466f5eb.zip | |
Update plugin handling and build ta/focaccia
| -rw-r--r-- | contrib/plugins/focaccia.c | 71 | ||||
| -rw-r--r-- | flake.lock | 34 | ||||
| -rw-r--r-- | flake.nix | 71 |
3 files changed, 126 insertions, 50 deletions
diff --git a/contrib/plugins/focaccia.c b/contrib/plugins/focaccia.c index bd7ba88a1a..2bbd5f42d4 100644 --- a/contrib/plugins/focaccia.c +++ b/contrib/plugins/focaccia.c @@ -1,5 +1,6 @@ #include <glib.h> #include <stdio.h> +#include <unistd.h> #include <sys/socket.h> #include <sys/types.h> #include <sys/un.h> @@ -14,7 +15,7 @@ typedef struct { unsigned long long virt; unsigned long long offset; unsigned long long length; -} PCTracker; +} pcTracker; enum Granularity { UNDEF = -1, @@ -49,11 +50,11 @@ typedef struct __attribute__((packed)) Memory { unsigned long nr_bytes; } Memory; -static int SockFD = -1; +static int sock_fd = -1; struct qemu_plugin_scoreboard *state; -qemu_plugin_u64 PC; -qemu_plugin_u64 Virt; +qemu_plugin_u64 pc; +qemu_plugin_u64 virt; qemu_plugin_u64 Offset; qemu_plugin_u64 Len; @@ -62,14 +63,12 @@ static char const *pc_reg; #define SOCK_PATH "/tmp/focaccia.sock" - static void plugin_init(void) { - - state = qemu_plugin_scoreboard_new(sizeof(PCTracker)); - PC = qemu_plugin_scoreboard_u64_in_struct(state, PCTracker, pc); - Virt = qemu_plugin_scoreboard_u64_in_struct(state, PCTracker, virt); - Offset = qemu_plugin_scoreboard_u64_in_struct(state, PCTracker, offset); - Len = qemu_plugin_scoreboard_u64_in_struct(state, PCTracker, length); + state = qemu_plugin_scoreboard_new(sizeof(pcTracker)); + pc = qemu_plugin_scoreboard_u64_in_struct(state, pcTracker, pc); + virt = qemu_plugin_scoreboard_u64_in_struct(state, pcTracker, virt); + Offset = qemu_plugin_scoreboard_u64_in_struct(state, pcTracker, offset); + Len = qemu_plugin_scoreboard_u64_in_struct(state, pcTracker, length); reg_map = g_hash_table_new(g_str_hash, g_str_equal); } @@ -96,8 +95,8 @@ static void vcpu_init(qemu_plugin_id_t id, unsigned int vcpu_index) // Register with focaccia over a socket // Connect to socket and send initial handshake - SockFD = socket(AF_UNIX, SOCK_STREAM, 0); - if (SockFD == -1) { + sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock_fd == -1) { perror("socket"); exit(-1); } @@ -106,23 +105,23 @@ static void vcpu_init(qemu_plugin_id_t id, unsigned int vcpu_index) memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, SOCK_PATH, sizeof(addr.sun_path) - 1); - if (connect(SockFD, &addr, sizeof(addr)) == -1) { + if (connect(sock_fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) { perror("connect"); - close(SockFD); + close(sock_fd); exit(-1); } // Send ping - const int pid = getpid(); - int r = write(SockFD, &pid, sizeof(int)); + const pid_t pid = getpid(); + ssize_t r = write(sock_fd, &pid, sizeof(int)); if (r != sizeof(int)) { fprintf(stderr, "Error writing PID to socket\n"); } } static void plugin_exit(qemu_plugin_id_t id, void* p) { - if (SockFD != -1) { - close(SockFD); + if (sock_fd != -1) { + close(sock_fd); } printf("Plugin has completed!\n"); } @@ -139,7 +138,7 @@ static void read_register(unsigned int cpu_index, Command cmd) { Register fail; memset(&fail, 0, sizeof(Register)); strncpy(fail.name, "UNKNOWN", sizeof(fail.name) - 1); - int ret = write(SockFD, &fail, sizeof(Register)); + int ret = write(sock_fd, &fail, sizeof(Register)); if (ret != sizeof(Register)) { fprintf(stderr, "Error writing unknown response\n"); } @@ -149,7 +148,7 @@ static void read_register(unsigned int cpu_index, Command cmd) { Register reg; if (strncmp(cmd.data._reg.reg_name, pc_reg, 3) == 0) { - unsigned long long rip = qemu_plugin_u64_get(Virt, cpu_index); + unsigned long long rip = qemu_plugin_u64_get(virt, cpu_index); strncpy(reg.name, pc_reg, sizeof(reg.name) - 1); reg.nr_bytes = sizeof(rip); memcpy(reg.value, &rip, sizeof(rip)); @@ -173,8 +172,8 @@ static void read_register(unsigned int cpu_index, Command cmd) { memcpy(reg.value, buf->data, sz); } - // Send PC value over socket - int ret = write(SockFD, ®, sizeof(Register)); + // Send pc value over socket + int ret = write(sock_fd, ®, sizeof(Register)); if (ret != sizeof(Register)) { fprintf(stderr, "Error writing register %s to socket\n", cmd.data._reg.reg_name); } @@ -188,7 +187,7 @@ static void read_memory(Command cmd) { g_byte_array_free(data, TRUE); Memory fail = {0, 0}; - int ret = write(SockFD, &fail, sizeof(fail)); + int ret = write(sock_fd, &fail, sizeof(fail)); if (ret != sizeof(fail)) { fprintf(stderr, "Error writing failing response\n"); } @@ -203,14 +202,14 @@ static void read_memory(Command cmd) { mem.addr = cmd.data._mem.addr; mem.nr_bytes = data->len; - int ret = write(SockFD, &mem, sizeof(Memory)); + int ret = write(sock_fd, &mem, sizeof(Memory)); if (ret != sizeof(Memory)) { fprintf(stderr, "Error writing memory header to socket\n"); } int written = 0; while (written < data->len) { - int _ret = write(SockFD, data->data + written, data->len - written); + int _ret = write(sock_fd, data->data + written, data->len - written); if (_ret == -1) { fprintf(stderr, "Error sending memory content\n"); } @@ -223,7 +222,7 @@ static void execute_step(unsigned int cpu_index, void *udata) { // Conceptually we can now read the state *before* the instruction executes Command cmd; - // Reset PC and Offset if it does not match $rip + // Reset pc and Offset if it does not match $rip g_autoptr(GArray) reg_list = qemu_plugin_get_registers(); gpointer map_val = g_hash_table_lookup(reg_map, pc_reg); @@ -233,7 +232,7 @@ static void execute_step(unsigned int cpu_index, void *udata) { Register fail; memset(&fail, 0, sizeof(Register)); strncpy(fail.name, "UNKNOWN", sizeof(fail.name) - 1); - int ret = write(SockFD, &fail, sizeof(Register)); + int ret = write(sock_fd, &fail, sizeof(Register)); if (ret != sizeof(Register)) { fprintf(stderr, "Error writing unknown response\n"); } @@ -253,14 +252,14 @@ static void execute_step(unsigned int cpu_index, void *udata) { } unsigned long long rip = 0; memcpy(&rip, buf->data, sz); - if (qemu_plugin_u64_get(PC, cpu_index) != rip) { - qemu_plugin_u64_set(PC, cpu_index, rip); + if (qemu_plugin_u64_get(pc, cpu_index) != rip) { + qemu_plugin_u64_set(pc, cpu_index, rip); qemu_plugin_u64_set(Offset, cpu_index, 0); } while (1) { // assume we read 23bytes at once - ssize_t n = read(SockFD, &cmd, sizeof(Command)); + ssize_t n = read(sock_fd, &cmd, sizeof(Command)); if (n < 0) { perror("Error reading from socket\n"); exit(-1); @@ -300,12 +299,12 @@ static void register_tracer(qemu_plugin_id_t id, struct qemu_plugin_tb *tb) { for (size_t i = 0; i < n_insns; i++) { insn = qemu_plugin_tb_get_insn(tb, i); qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu(insn, - QEMU_PLUGIN_INLINE_STORE_U64, - Virt, qemu_plugin_insn_vaddr(insn)); + QEMU_PLUGIN_INLINE_STORE_U64, + virt, qemu_plugin_insn_vaddr(insn)); qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu(insn, - QEMU_PLUGIN_INLINE_STORE_U64, - Len, - qemu_plugin_insn_size(insn)); + QEMU_PLUGIN_INLINE_STORE_U64, + Len, + qemu_plugin_insn_size(insn)); qemu_plugin_register_vcpu_insn_exec_cb(insn, execute_step, QEMU_PLUGIN_CB_R_REGS, NULL); } diff --git a/flake.lock b/flake.lock index 31fe637959..3e71f7bed2 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,37 @@ { "nodes": { + "berkeley-softfloat-3": { + "flake": false, + "locked": { + "lastModified": 1741391053, + "narHash": "sha256-TO1DhvUMd2iP5gvY9Hqy9Oas0Da7lD0oRVPBlfAzc90=", + "owner": "qemu-project", + "repo": "berkeley-softfloat-3", + "rev": "a0c6494cdc11865811dec815d5c0049fba9d82a8", + "type": "gitlab" + }, + "original": { + "owner": "qemu-project", + "repo": "berkeley-softfloat-3", + "type": "gitlab" + } + }, + "berkeley-testfloat-3": { + "flake": false, + "locked": { + "lastModified": 1689946593, + "narHash": "sha256-inQAeYlmuiRtZm37xK9ypBltCJ+ycyvIeIYZK8a+RYU=", + "owner": "qemu-project", + "repo": "berkeley-testfloat-3", + "rev": "e7af9751d9f9fd3b47911f51a5cfd08af256a9ab", + "type": "gitlab" + }, + "original": { + "owner": "qemu-project", + "repo": "berkeley-testfloat-3", + "type": "gitlab" + } + }, "flake-utils": { "inputs": { "systems": "systems" @@ -36,6 +68,8 @@ }, "root": { "inputs": { + "berkeley-softfloat-3": "berkeley-softfloat-3", + "berkeley-testfloat-3": "berkeley-testfloat-3", "flake-utils": "flake-utils", "nixpkgs": "nixpkgs" } diff --git a/flake.nix b/flake.nix index 6c05dcac5c..b3b4e87156 100644 --- a/flake.nix +++ b/flake.nix @@ -2,29 +2,72 @@ description = "QEMU with Focaccia plugins"; inputs = { + self.submodules = true; nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; flake-utils.url = "github:numtide/flake-utils"; + + berkeley-softfloat-3 = { + url = "gitlab:qemu-project/berkeley-softfloat-3"; + flake = false; + }; + + berkeley-testfloat-3 = { + url = "gitlab:qemu-project/berkeley-testfloat-3"; + flake = false; + }; }; - outputs = {self, flake-utils, nixpkgs}: - flake-utils.lib.eachDefaultSystem (system: + outputs = inputs@{ + self, + nixpkgs, + flake-utils, + berkeley-softfloat-3, + berkeley-testfloat-3, + ... + }: flake-utils.lib.eachDefaultSystem (system: let pkgs = import nixpkgs { inherit system; }; + + qemu-with-focaccia-plugin = pkgs.qemu.override { + minimal = true; + userOnly = true; + pluginsSupport = true; + }; in { - packages.default = pkgs.qemu.overrideAttrs (old: { - pname = "qemu-local"; - version = "git"; - src = self; - patches = []; - nativeBuildInputs = (old.nativeBuildInputs or []) ++ [ pkgs.git pkgs.cacert pkgs.gdb ]; - hardeningDisable = [ "all" ]; - - SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; - GIT_SSL_CAINFO = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; - NIX_SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; - }); + packages = rec { + with-focaccia-plugin = qemu-with-focaccia-plugin.overrideAttrs (old: { + pname = "qemu-focaccia"; + version = "git"; + src = self; + + postPatch = (old.postPatch or "") + '' + rm subprojects/berkeley-softfloat-3.wrap + cp -r ${berkeley-softfloat-3} subprojects/berkeley-softfloat-3 + chmod a+w subprojects/berkeley-softfloat-3 + cp subprojects/packagefiles/berkeley-softfloat-3/* subprojects/berkeley-softfloat-3 + + rm subprojects/berkeley-testfloat-3.wrap + cp -r ${berkeley-testfloat-3} subprojects/berkeley-testfloat-3 + chmod a+w subprojects/berkeley-testfloat-3 + cp subprojects/packagefiles/berkeley-testfloat-3/* subprojects/berkeley-testfloat-3 + ''; + + postInstall = (old.postInstall or "") + '' + mkdir -p $out/lib/plugins/ + cc -fPIC -shared ${./contrib/plugins/focaccia.c} -o $out/lib/plugins/libfocaccia.so \ + -I$out/include/ \ + $(pkg-config --cflags glib-2.0) \ + $(pkg-config --libs glib-2.0) + ''; + + nativeBuildInputs = (old.nativeBuildInputs or []) ++ [ pkgs.git pkgs.gdb ]; + hardeningDisable = [ "all" ]; + }); + + default = with-focaccia-plugin; + }; }); } |