perf intel-pt/bts: Report instruction bytes and length in sample
[linux-2.6-microblaze.git] / tools / perf / util / intel-pt.c
index dc041d4..85d5eeb 100644 (file)
@@ -143,6 +143,7 @@ struct intel_pt_queue {
        u32 flags;
        u16 insn_len;
        u64 last_insn_cnt;
+       char insn[INTEL_PT_INSN_BUF_SZ];
 };
 
 static void intel_pt_dump(struct intel_pt *pt __maybe_unused,
@@ -315,6 +316,7 @@ struct intel_pt_cache_entry {
        enum intel_pt_insn_branch       branch;
        int                             length;
        int32_t                         rel;
+       char                            insn[INTEL_PT_INSN_BUF_SZ];
 };
 
 static int intel_pt_config_div(const char *var, const char *value, void *data)
@@ -400,6 +402,7 @@ static int intel_pt_cache_add(struct dso *dso, struct machine *machine,
        e->branch = intel_pt_insn->branch;
        e->length = intel_pt_insn->length;
        e->rel = intel_pt_insn->rel;
+       memcpy(e->insn, intel_pt_insn->buf, INTEL_PT_INSN_BUF_SZ);
 
        err = auxtrace_cache__add(c, offset, &e->entry);
        if (err)
@@ -428,8 +431,7 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn,
        struct machine *machine = ptq->pt->machine;
        struct thread *thread;
        struct addr_location al;
-       unsigned char buf[1024];
-       size_t bufsz;
+       unsigned char buf[INTEL_PT_INSN_BUF_SZ];
        ssize_t len;
        int x86_64;
        u8 cpumode;
@@ -437,11 +439,11 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn,
        u64 insn_cnt = 0;
        bool one_map = true;
 
+       intel_pt_insn->length = 0;
+
        if (to_ip && *ip == to_ip)
                goto out_no_cache;
 
-       bufsz = intel_pt_insn_max_size();
-
        if (*ip >= ptq->pt->kernel_start)
                cpumode = PERF_RECORD_MISC_KERNEL;
        else
@@ -478,6 +480,8 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn,
                                intel_pt_insn->branch = e->branch;
                                intel_pt_insn->length = e->length;
                                intel_pt_insn->rel = e->rel;
+                               memcpy(intel_pt_insn->buf, e->insn,
+                                      INTEL_PT_INSN_BUF_SZ);
                                intel_pt_log_insn_no_data(intel_pt_insn, *ip);
                                return 0;
                        }
@@ -493,7 +497,8 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn,
 
                while (1) {
                        len = dso__data_read_offset(al.map->dso, machine,
-                                                   offset, buf, bufsz);
+                                                   offset, buf,
+                                                   INTEL_PT_INSN_BUF_SZ);
                        if (len <= 0)
                                return -EINVAL;
 
@@ -900,6 +905,7 @@ static void intel_pt_sample_flags(struct intel_pt_queue *ptq)
                if (ptq->state->flags & INTEL_PT_IN_TX)
                        ptq->flags |= PERF_IP_FLAG_IN_TX;
                ptq->insn_len = ptq->state->insn_len;
+               memcpy(ptq->insn, ptq->state->insn, INTEL_PT_INSN_BUF_SZ);
        }
 }
 
@@ -1080,6 +1086,7 @@ static int intel_pt_synth_branch_sample(struct intel_pt_queue *ptq)
        sample.cpu = ptq->cpu;
        sample.flags = ptq->flags;
        sample.insn_len = ptq->insn_len;
+       memcpy(sample.insn, ptq->insn, INTEL_PT_INSN_BUF_SZ);
 
        /*
         * perf report cannot handle events without a branch stack when using
@@ -1141,6 +1148,7 @@ static int intel_pt_synth_instruction_sample(struct intel_pt_queue *ptq)
        sample.cpu = ptq->cpu;
        sample.flags = ptq->flags;
        sample.insn_len = ptq->insn_len;
+       memcpy(sample.insn, ptq->insn, INTEL_PT_INSN_BUF_SZ);
 
        ptq->last_insn_cnt = ptq->state->tot_insn_cnt;
 
@@ -1203,6 +1211,7 @@ static int intel_pt_synth_transaction_sample(struct intel_pt_queue *ptq)
        sample.cpu = ptq->cpu;
        sample.flags = ptq->flags;
        sample.insn_len = ptq->insn_len;
+       memcpy(sample.insn, ptq->insn, INTEL_PT_INSN_BUF_SZ);
 
        if (pt->synth_opts.callchain) {
                thread_stack__sample(ptq->thread, ptq->chain,