diff options
Diffstat (limited to 'contrib')
-rw-r--r-- | contrib/gitdm/domain-map | 2 | ||||
-rw-r--r-- | contrib/gitdm/group-map-academics | 6 | ||||
-rw-r--r-- | contrib/gitdm/group-map-individuals | 3 | ||||
-rw-r--r-- | contrib/plugins/execlog.c | 99 |
4 files changed, 96 insertions, 14 deletions
diff --git a/contrib/gitdm/domain-map b/contrib/gitdm/domain-map index 2800d9f986..3727918641 100644 --- a/contrib/gitdm/domain-map +++ b/contrib/gitdm/domain-map @@ -10,6 +10,7 @@ bytedance.com ByteDance cmss.chinamobile.com China Mobile citrix.com Citrix crudebyte.com Crudebyte +chinatelecom.cn China Telecom eldorado.org.br Instituto de Pesquisas Eldorado fujitsu.com Fujitsu google.com Google @@ -19,6 +20,7 @@ ibm.com IBM igalia.com Igalia intel.com Intel linaro.org Linaro +loongson.cn Loongson Technology lwn.net LWN microsoft.com Microsoft mvista.com MontaVista diff --git a/contrib/gitdm/group-map-academics b/contrib/gitdm/group-map-academics index 44745ca85b..082458e1bd 100644 --- a/contrib/gitdm/group-map-academics +++ b/contrib/gitdm/group-map-academics @@ -19,3 +19,9 @@ edu.cn # Boston University bu.edu + +# Institute of Software Chinese Academy of Sciences +iscas.ac.cn + +# Université Grenoble Alpes +univ-grenoble-alpes.fr diff --git a/contrib/gitdm/group-map-individuals b/contrib/gitdm/group-map-individuals index f816aa8770..53883cc526 100644 --- a/contrib/gitdm/group-map-individuals +++ b/contrib/gitdm/group-map-individuals @@ -34,3 +34,6 @@ bmeng.cn@gmail.com liq3ea@gmail.com chetan4windows@gmail.com akihiko.odaki@gmail.com +paul@nowt.org +git@xen0n.name +simon@simonsafar.com diff --git a/contrib/plugins/execlog.c b/contrib/plugins/execlog.c index a5275dcc15..1b3bb7ebba 100644 --- a/contrib/plugins/execlog.c +++ b/contrib/plugins/execlog.c @@ -20,6 +20,9 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; /* Store last executed instruction on each vCPU as a GString */ GArray *last_exec; +static GPtrArray *imatches; +static GArray *amatches; + /** * Add memory read or write information to current instruction log */ @@ -85,12 +88,13 @@ static void vcpu_insn_exec(unsigned int cpu_index, void *udata) static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb) { struct qemu_plugin_insn *insn; - uint64_t insn_vaddr; - uint32_t insn_opcode; - char *insn_disas; + bool skip = (imatches || amatches); size_t n = qemu_plugin_tb_n_insns(tb); for (size_t i = 0; i < n; i++) { + char *insn_disas; + uint64_t insn_vaddr; + /* * `insn` is shared between translations in QEMU, copy needed data here. * `output` is never freed as it might be used multiple times during @@ -99,20 +103,55 @@ static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb) * a limitation for CISC architectures. */ insn = qemu_plugin_tb_get_insn(tb, i); - insn_vaddr = qemu_plugin_insn_vaddr(insn); - insn_opcode = *((uint32_t *)qemu_plugin_insn_data(insn)); insn_disas = qemu_plugin_insn_disas(insn); - char *output = g_strdup_printf("0x%"PRIx64", 0x%"PRIx32", \"%s\"", - insn_vaddr, insn_opcode, insn_disas); + insn_vaddr = qemu_plugin_insn_vaddr(insn); + + /* + * If we are filtering we better check out if we have any + * hits. The skip "latches" so we can track memory accesses + * after the instruction we care about. + */ + if (skip && imatches) { + int j; + for (j = 0; j < imatches->len && skip; j++) { + char *m = g_ptr_array_index(imatches, j); + if (g_str_has_prefix(insn_disas, m)) { + skip = false; + } + } + } + + if (skip && amatches) { + int j; + for (j = 0; j < amatches->len && skip; j++) { + uint64_t v = g_array_index(amatches, uint64_t, j); + if (v == insn_vaddr) { + skip = false; + } + } + } - /* Register callback on memory read or write */ - qemu_plugin_register_vcpu_mem_cb(insn, vcpu_mem, - QEMU_PLUGIN_CB_NO_REGS, - QEMU_PLUGIN_MEM_RW, NULL); + if (skip) { + g_free(insn_disas); + } else { + uint32_t insn_opcode; + insn_opcode = *((uint32_t *)qemu_plugin_insn_data(insn)); + char *output = g_strdup_printf("0x%"PRIx64", 0x%"PRIx32", \"%s\"", + insn_vaddr, insn_opcode, insn_disas); + + /* Register callback on memory read or write */ + qemu_plugin_register_vcpu_mem_cb(insn, vcpu_mem, + QEMU_PLUGIN_CB_NO_REGS, + QEMU_PLUGIN_MEM_RW, NULL); + + /* Register callback on instruction */ + qemu_plugin_register_vcpu_insn_exec_cb(insn, vcpu_insn_exec, + QEMU_PLUGIN_CB_NO_REGS, output); + + /* reset skip */ + skip = (imatches || amatches); + } - /* Register callback on instruction */ - qemu_plugin_register_vcpu_insn_exec_cb(insn, vcpu_insn_exec, - QEMU_PLUGIN_CB_NO_REGS, output); } } @@ -132,6 +171,25 @@ static void plugin_exit(qemu_plugin_id_t id, void *p) } } +/* Add a match to the array of matches */ +static void parse_insn_match(char *match) +{ + if (!imatches) { + imatches = g_ptr_array_new(); + } + g_ptr_array_add(imatches, match); +} + +static void parse_vaddr_match(char *match) +{ + uint64_t v = g_ascii_strtoull(match, NULL, 16); + + if (!amatches) { + amatches = g_array_new(false, true, sizeof(uint64_t)); + } + g_array_append_val(amatches, v); +} + /** * Install the plugin */ @@ -145,6 +203,19 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id, */ last_exec = g_array_new(FALSE, FALSE, sizeof(GString *)); + for (int i = 0; i < argc; i++) { + char *opt = argv[i]; + g_autofree char **tokens = g_strsplit(opt, "=", 2); + if (g_strcmp0(tokens[0], "ifilter") == 0) { + parse_insn_match(tokens[1]); + } else if (g_strcmp0(tokens[0], "afilter") == 0) { + parse_vaddr_match(tokens[1]); + } else { + fprintf(stderr, "option parsing failed: %s\n", opt); + return -1; + } + } + /* Register translation block and exit callbacks */ qemu_plugin_register_vcpu_tb_trans_cb(id, vcpu_tb_trans); qemu_plugin_register_atexit_cb(id, plugin_exit, NULL); |