All of lore.kernel.org
 help / color / mirror / Atom feed
From: Namhyung Kim <namhyung@kernel.org>
To: Arnaldo Carvalho de Melo <acme@kernel.org>,
	Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>,
	Adrian Hunter <adrian.hunter@intel.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	linux-perf-users@vger.kernel.org,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Stephane Eranian <eranian@google.com>,
	Masami Hiramatsu <mhiramat@kernel.org>,
	linux-toolchains@vger.kernel.org,
	linux-trace-devel@vger.kernel.org
Subject: [PATCH 09/14] perf annotate-data: Handle call instructions
Date: Fri, 16 Feb 2024 15:54:18 -0800	[thread overview]
Message-ID: <20240216235423.2343167-10-namhyung@kernel.org> (raw)
In-Reply-To: <20240216235423.2343167-1-namhyung@kernel.org>

When updating instruction states, the call instruction should play a
role since it changes the register states.  For simplicity, mark some
registers as caller-saved registers (should be arch-dependent), and
invalidate them all after a function call.

If the function returns something, the designated register (ret_reg)
will have the type info.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/util/annotate-data.c | 45 +++++++++++++++++++++++++++++++--
 1 file changed, 43 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c
index e46e162c783f..e8e363fed8c2 100644
--- a/tools/perf/util/annotate-data.c
+++ b/tools/perf/util/annotate-data.c
@@ -23,10 +23,14 @@
 #include "symbol.h"
 #include "symbol_conf.h"
 
-/* Type information in a register, valid when ok is true */
+/*
+ * Type information in a register, valid when @ok is true.
+ * The @caller_saved registers are invalidated after a function call.
+ */
 struct type_state_reg {
 	Dwarf_Die type;
 	bool ok;
+	bool caller_saved;
 };
 
 /* Type information in a stack location, dynamically allocated */
@@ -50,6 +54,7 @@ struct type_state_stack {
 struct type_state {
 	struct type_state_reg regs[TYPE_STATE_MAX_REGS];
 	struct list_head stack_vars;
+	int ret_reg;
 };
 
 static bool has_reg_type(struct type_state *state, int reg)
@@ -57,10 +62,23 @@ static bool has_reg_type(struct type_state *state, int reg)
 	return (unsigned)reg < ARRAY_SIZE(state->regs);
 }
 
-void init_type_state(struct type_state *state, struct arch *arch __maybe_unused)
+void init_type_state(struct type_state *state, struct arch *arch)
 {
 	memset(state, 0, sizeof(*state));
 	INIT_LIST_HEAD(&state->stack_vars);
+
+	if (arch__is(arch, "x86")) {
+		state->regs[0].caller_saved = true;
+		state->regs[1].caller_saved = true;
+		state->regs[2].caller_saved = true;
+		state->regs[4].caller_saved = true;
+		state->regs[5].caller_saved = true;
+		state->regs[8].caller_saved = true;
+		state->regs[9].caller_saved = true;
+		state->regs[10].caller_saved = true;
+		state->regs[11].caller_saved = true;
+		state->ret_reg = 0;
+	}
 }
 
 void exit_type_state(struct type_state *state)
@@ -417,6 +435,29 @@ void update_insn_state(struct type_state *state, struct data_loc_info *dloc,
 	int fbreg = dloc->fbreg;
 	int fboff = 0;
 
+	if (ins__is_call(&dl->ins)) {
+		Dwarf_Die func_die;
+
+		/* __fentry__ will preserve all registers */
+		if (dl->ops.target.sym &&
+		    !strcmp(dl->ops.target.sym->name, "__fentry__"))
+			return;
+
+		/* Otherwise invalidate caller-saved registers after call */
+		for (unsigned i = 0; i < ARRAY_SIZE(state->regs); i++) {
+			if (state->regs[i].caller_saved)
+				state->regs[i].ok = false;
+		}
+
+		/* Update register with the return type (if any) */
+		if (die_find_realfunc(cu_die, dl->ops.target.addr, &func_die) &&
+		    die_get_real_type(&func_die, &type_die)) {
+			state->regs[state->ret_reg].type = type_die;
+			state->regs[state->ret_reg].ok = true;
+		}
+		return;
+	}
+
 	/* FIXME: remove x86 specific code and handle more instructions like LEA */
 	if (!strstr(dl->ins.name, "mov"))
 		return;
-- 
2.44.0.rc0.258.g7320e95886-goog


  parent reply	other threads:[~2024-02-16 23:54 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-16 23:54 [PATCHSET 00/14] perf tools: Remaining bits of data type profiling (v6) Namhyung Kim
2024-02-16 23:54 ` [PATCH 01/14] perf dwarf-aux: Add die_collect_vars() Namhyung Kim
2024-02-16 23:54 ` [PATCH 02/14] perf dwarf-aux: Handle type transfer for memory access Namhyung Kim
2024-02-16 23:54 ` [PATCH 03/14] perf annotate-data: Introduce struct data_loc_info Namhyung Kim
2024-02-16 23:54 ` [PATCH 04/14] perf map: Add map__objdump_2rip() Namhyung Kim
2024-02-16 23:54 ` [PATCH 05/14] perf annotate: Add annotate_get_basic_blocks() Namhyung Kim
2024-02-16 23:54 ` [PATCH 06/14] perf annotate-data: Maintain variable type info Namhyung Kim
2024-02-16 23:54 ` [PATCH 07/14] perf annotate-data: Add update_insn_state() Namhyung Kim
2024-02-16 23:54 ` [PATCH 08/14] perf annotate-data: Handle global variable access Namhyung Kim
2024-02-16 23:54 ` Namhyung Kim [this message]
2024-02-16 23:54 ` [PATCH 10/14] perf annotate-data: Implement instruction tracking Namhyung Kim
2024-02-16 23:54 ` [PATCH 11/14] perf annotate: Parse x86 segment register location Namhyung Kim
2024-02-16 23:54 ` [PATCH 12/14] perf annotate-data: Handle this-cpu variables in kernel Namhyung Kim
2024-02-16 23:54 ` [PATCH 13/14] perf annotate-data: Track instructions with a this-cpu variable Namhyung Kim
2024-02-16 23:54 ` [PATCH 14/14] perf annotate-data: Add stack canary type Namhyung Kim
  -- strict thread matches above, loose matches on Subject: below --
2024-02-02 22:04 [PATCHSET 00/14] perf tools: Remaining bits of data type profiling (v5) Namhyung Kim
2024-02-02 22:04 ` [PATCH 09/14] perf annotate-data: Handle call instructions Namhyung Kim
2024-02-03  3:09   ` Ian Rogers
2024-02-06 23:17     ` Namhyung Kim
2024-02-06 23:36       ` Ian Rogers
     [not found]         ` <CA+JHD91q4vA5z0g4AMPJpXV-+_ppmg6+jVu=YWcxY4hARn5LRw@mail.gmail.com>
2024-02-07  1:29           ` Namhyung Kim

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240216235423.2343167-10-namhyung@kernel.org \
    --to=namhyung@kernel.org \
    --cc=acme@kernel.org \
    --cc=adrian.hunter@intel.com \
    --cc=eranian@google.com \
    --cc=irogers@google.com \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=linux-toolchains@vger.kernel.org \
    --cc=linux-trace-devel@vger.kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.