diff --git a/Makefile.target b/Makefile.target index ba1234063..71b5ff5a0 100644 --- a/Makefile.target +++ b/Makefile.target @@ -155,6 +155,8 @@ dummy := $(call unnest-vars,.., \ # Now restore obj-y obj-y := $(obj-y-save) +common-obj-$(HAS_TRACEWRAP) += tracewrap.o + all-obj-y = $(obj-y) $(common-obj-y) all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y) diff --git a/include/gtracewrap.h b/include/gtracewrap.h new file mode 100644 index 000000000..ffdc3165d --- /dev/null +++ b/include/gtracewrap.h @@ -0,0 +1,3 @@ +#pragma once + +void do_qemu_set_trace(const char *tracefilename); diff --git a/include/tracewrap.h b/include/tracewrap.h index 1116f6d78..0fdd60fbf 100644 --- a/include/tracewrap.h +++ b/include/tracewrap.h @@ -4,6 +4,7 @@ #include #include #include "cpu.h" +#include "gtracewrap.h" #include "frame.piqi.pb-c.h" @@ -13,7 +14,6 @@ struct toc_entry { }; extern FILE *qemu_tracefile; -void do_qemu_set_trace(const char *tracefilename); void qemu_trace(Frame frame); void qemu_trace_newframe(uint64_t addr, int tread_id); void qemu_trace_add_operand(OperandInfo *oi, int inout); diff --git a/linux-user/Makefile.objs b/linux-user/Makefile.objs index 0c6355ba9..5899d72d3 100644 --- a/linux-user/Makefile.objs +++ b/linux-user/Makefile.objs @@ -5,4 +5,3 @@ obj-$(TARGET_HAS_BFLT) += flatload.o obj-$(TARGET_I386) += vm86.o obj-$(TARGET_ARM) += arm/nwfpe/ obj-$(TARGET_M68K) += m68k-sim.o -obj-$(HAS_TRACEWRAP) += tracewrap.o diff --git a/python/printProto.py b/python/printProto.py index df37d5b00..657827f04 100755 --- a/python/printProto.py +++ b/python/printProto.py @@ -5,6 +5,13 @@ import getopt import sys import IPython +import pickle +from collections import defaultdict +import google + +FMT_TXT=0x1 +FMT_PKL_HIGHLIGHT=0x2 +FMT_UNIQ_INSNS=0x3 def getFrameLength(f): return struct.unpack("Q", f.read(8))[0] @@ -55,7 +62,7 @@ def printFrame(f): print "PRE: %s" % printOperandList(f.std_frame.operand_pre_list.elem) print "POST: %s" % printOperandList(f.std_frame.operand_post_list.elem) -def process(infileName, outfileName=None, maxCnt=0): +def process(infileName, outfileName=None, maxCnt=0, outFormat=FMT_TXT): out = sys.stdout if outfileName: out = open(outfileName, 'w') @@ -70,15 +77,24 @@ def process(infileName, outfileName=None, maxCnt=0): print "maxCnt: %i" % maxCnt + insns = defaultdict(lambda : 0) while (cnt <= maxCnt): cnt += 1 try: fr = getFrame(infile) + insns[fr.std_frame.address]+=1 except google.protobuf.message.DecodeError, e: print "maxCnt: %i, cnt: %i\n" % (maxCnt, cnt) print e break - out.write("0x%x, %r\n" % (fr.std_frame.address, fr.std_frame.rawbytes)) + if outFormat == FMT_TXT: + out.write("0x%x, %r\n" % (fr.std_frame.address, fr.std_frame.rawbytes)) + + if outFormat == FMT_PKL_HIGHLIGHT: + highlight_data = {1:set(insns.keys())} + pickle.dump(highlight_data, out) + elif outFormat == FMT_UNIQ_INSNS: + out.write("\n".join(["0x%x" % i for i in set(insns.keys())])) def getMetaData(f): f.seek(0x20) @@ -91,7 +107,8 @@ def main(): maxCnt = 0 infile = None outfile = None - opts,argv = getopt.getopt(sys.argv[1:], "f:c:o:d") + outFormat = FMT_TXT + opts,argv = getopt.getopt(sys.argv[1:], "f:c:o:F:d") for k,v in opts: if k == '-d': debug += 1 @@ -101,9 +118,14 @@ def main(): outfile = v if k == '-c': maxCnt = int(v) + if k == '-F': + if v == 'pkl': + outFormat = FMT_PKL_HIGHLIGHT + elif v == 'uniq': + outFormat = FMT_UNIQ_INSNS if infile: - process(infile, outfile, maxCnt) + process(infile, outfile, maxCnt, outFormat) if __name__ == "__main__": main() diff --git a/qemu-options.hx b/qemu-options.hx index 2d33815fb..c264ed319 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2573,6 +2573,16 @@ STEXI Like -monitor but opens in 'control' mode. ETEXI +DEF("tracefile", HAS_ARG, QEMU_OPTION_tracefile, \ + "-tracefile file write BAP traces to file\n", + QEMU_ARCH_ARM) +STEXI +@item -tracefile @var{file} +@findex -tracefile +Write BAP traces into file @var{file}. +Default: /dev/shm/proto +ETEXI + DEF("mon", HAS_ARG, QEMU_OPTION_mon, \ "-mon [chardev=]name[,mode=readline|control][,default]\n", QEMU_ARCH_ALL) STEXI diff --git a/linux-user/trace_consts.h b/target-arm/trace_consts.h similarity index 100% rename from linux-user/trace_consts.h rename to target-arm/trace_consts.h diff --git a/target-arm/trace_helper.c b/target-arm/trace_helper.c index 023a56165..f3534cede 100644 --- a/target-arm/trace_helper.c +++ b/target-arm/trace_helper.c @@ -60,7 +60,7 @@ OperandInfo * load_store_mem(uint32_t addr, uint32_t val, int ls, int len) } OperandInfo *oi = (OperandInfo *)malloc(sizeof(OperandInfo)); operand_info__init(oi); - oi->bit_length = 0; + oi->bit_length = len * 8; oi->operand_info_specific = ois; oi->operand_usage = ou; oi->value.len = len; diff --git a/linux-user/arm/trace_info.h b/target-arm/trace_info.h similarity index 100% rename from linux-user/arm/trace_info.h rename to target-arm/trace_info.h diff --git a/target-arm/translate.c b/target-arm/translate.c index 41601880b..1f78a96bd 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -10910,15 +10910,16 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu, } else { disas_arm_insn(env, dc); } -#ifdef HAS_TRACEWRAP - gen_trace_endframe(dc); -#endif //HAS_TRACEWRAP if (dc->condjmp && !dc->is_jmp) { gen_set_label(dc->condlabel); dc->condjmp = 0; } +#ifdef HAS_TRACEWRAP + gen_trace_endframe(dc); +#endif //HAS_TRACEWRAP + if (tcg_check_temp_count()) { fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n", dc->pc); diff --git a/linux-user/tracewrap.c b/tracewrap.c similarity index 94% rename from linux-user/tracewrap.c rename to tracewrap.c index 02c3ea811..44b0740c4 100644 --- a/linux-user/tracewrap.c +++ b/tracewrap.c @@ -1,6 +1,5 @@ #include "tracewrap.h" #include "trace_consts.h" -#include Frame * g_frame; struct toc_entry *toc; @@ -13,6 +12,9 @@ FILE *qemu_tracefile; void do_qemu_set_trace(const char *tracefilename) { + if (tracefilename == NULL) { + tracefilename = "/dev/shm/proto"; + } printf("Setting qemu_tracefile at %s\n", tracefilename); qemu_tracefile = fopen(tracefilename, "wb"); if (qemu_tracefile == NULL) { @@ -28,7 +30,8 @@ void qemu_trace_newframe(uint64_t addr, int thread_id) { if (open_frame) { - fprintf(stderr, "frame still open! 0x%08lx\n", (long unsigned int)addr); + fprintf(stderr, "frame still open! 0x%08lx\n", + (long unsigned int)g_frame->std_frame->address); qemu_trace_endframe(NULL, 0, 0); } open_frame = 1; @@ -112,8 +115,9 @@ void qemu_trace_endframe(CPUArchState *env, target_ulong pc, size_t size) StdFrame *sframe = g_frame->std_frame; sframe->rawbytes.len = size; sframe->rawbytes.data = (uint8_t *)malloc(size); - for (i = 0; i < size; i++) - sframe->rawbytes.data[i] = cpu_ldub_code(env, pc+i); + for (i = 0; i < size; i++) { + sframe->rawbytes.data[i] = cpu_ldub_code(env, pc+i); + } size_t msg_size = frame__get_packed_size(g_frame); uint8_t *packed_buffer = (uint8_t *)malloc(msg_size); diff --git a/vl.c b/vl.c index 9975e5a4e..86402a86b 100644 --- a/vl.c +++ b/vl.c @@ -30,6 +30,10 @@ #include "config-host.h" +#ifdef HAS_TRACEWRAP +#include "gtracewrap.h" +#endif + #ifdef CONFIG_SECCOMP #include "sysemu/seccomp.h" #endif @@ -2957,6 +2961,9 @@ int main(int argc, char **argv, char **envp) bool userconfig = true; const char *log_mask = NULL; const char *log_file = NULL; +#ifdef HAS_TRACEWRAP + const char *tracefile = NULL; +#endif GMemVTable mem_trace = { .malloc = malloc_and_trace, .realloc = realloc_and_trace, @@ -3412,6 +3419,11 @@ int main(int argc, char **argv, char **envp) monitor_parse(optarg, "readline"); } break; +#ifdef HAS_TRACEWRAP + case QEMU_OPTION_tracefile: + tracefile = optarg; + break; +#endif case QEMU_OPTION_qmp: monitor_parse(optarg, "control"); default_monitor = 0; @@ -3907,6 +3919,11 @@ int main(int argc, char **argv, char **envp) } } } + +#ifdef HAS_TRACEWRAP + do_qemu_set_trace(tracefile); +#endif + loc_set_none(); if (qemu_init_main_loop()) {