perf callchains: Store the map together with the symbol

We need this to know where a symbol in a callchain came from,
for various reasons, among them precise annotation from a
TUI/GUI tool.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1269459619-982-5-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 883844e..db628af 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -185,8 +185,8 @@
 
 
 struct resolved_ip {
-	u64		ip;
-	struct symbol	*sym;
+	u64		  ip;
+	struct map_symbol ms;
 };
 
 struct resolved_chain {
@@ -212,7 +212,7 @@
 			return;
 		}
 		call->ip = chain->ips[i].ip;
-		call->sym = chain->ips[i].sym;
+		call->ms = chain->ips[i].ms;
 		list_add_tail(&call->list, &node->val);
 	}
 	node->val_nr = chain->nr - start;
@@ -318,10 +318,10 @@
 		if (i == chain->nr)
 			break;
 
-		sym = chain->ips[i].sym;
+		sym = chain->ips[i].ms.sym;
 
-		if (cnode->sym && sym) {
-			if (cnode->sym->start != sym->start)
+		if (cnode->ms.sym && sym) {
+			if (cnode->ms.sym->start != sym->start)
 				break;
 		} else if (cnode->ip != chain->ips[i].ip)
 			break;
@@ -353,9 +353,8 @@
 	return 0;
 }
 
-static void
-filter_context(struct ip_callchain *old, struct resolved_chain *new,
-	       struct symbol **syms)
+static void filter_context(struct ip_callchain *old, struct resolved_chain *new,
+			   struct map_symbol *syms)
 {
 	int i, j = 0;
 
@@ -364,7 +363,7 @@
 			continue;
 
 		new->ips[j].ip = old->ips[i];
-		new->ips[j].sym = syms[i];
+		new->ips[j].ms = syms[i];
 		j++;
 	}
 
@@ -373,7 +372,7 @@
 
 
 int append_chain(struct callchain_node *root, struct ip_callchain *chain,
-		  struct symbol **syms)
+		 struct map_symbol *syms)
 {
 	struct resolved_chain *filtered;
 
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index bbd76da..8a7e8bb 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -39,7 +39,7 @@
 
 struct callchain_list {
 	u64			ip;
-	struct symbol		*sym;
+	struct map_symbol	ms;
 	struct list_head	list;
 };
 
@@ -57,5 +57,5 @@
 
 int register_callchain_param(struct callchain_param *param);
 int append_chain(struct callchain_node *root, struct ip_callchain *chain,
-		 struct symbol **syms);
+		 struct map_symbol *syms);
 #endif	/* __PERF_CALLCHAIN_H */
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 4eefb52..09e09e7 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -260,8 +260,8 @@
 		} else
 			ret += fprintf(fp, "%s", "          ");
 	}
-	if (chain->sym)
-		ret += fprintf(fp, "%s\n", chain->sym->name);
+	if (chain->ms.sym)
+		ret += fprintf(fp, "%s\n", chain->ms.sym->name);
 	else
 		ret += fprintf(fp, "%p\n", (void *)(long)chain->ip);
 
@@ -280,7 +280,7 @@
 	}
 
 	strcpy(rem_sq_bracket->name, "[...]");
-	rem_hits.sym = rem_sq_bracket;
+	rem_hits.ms.sym = rem_sq_bracket;
 }
 
 static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
@@ -382,8 +382,8 @@
 		} else
 			ret += callchain__fprintf_left_margin(fp, left_margin);
 
-		if (chain->sym)
-			ret += fprintf(fp, " %s\n", chain->sym->name);
+		if (chain->ms.sym)
+			ret += fprintf(fp, " %s\n", chain->ms.sym->name);
 		else
 			ret += fprintf(fp, " %p\n", (void *)(long)chain->ip);
 	}
@@ -408,8 +408,8 @@
 	list_for_each_entry(chain, &self->val, list) {
 		if (chain->ip >= PERF_CONTEXT_MAX)
 			continue;
-		if (chain->sym)
-			ret += fprintf(fp, "                %s\n", chain->sym->name);
+		if (chain->ms.sym)
+			ret += fprintf(fp, "                %s\n", chain->ms.sym->name);
 		else
 			ret += fprintf(fp, "                %p\n",
 					(void *)(long)chain->ip);
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c
index 25cd2e1..f6953ca 100644
--- a/tools/perf/util/newt.c
+++ b/tools/perf/util/newt.c
@@ -104,8 +104,8 @@
 static char *callchain_list__sym_name(struct callchain_list *self,
 				      char *bf, size_t bfsize)
 {
-	if (self->sym)
-		return self->sym->name;
+	if (self->ms.sym)
+		return self->ms.sym->name;
 
 	snprintf(bf, bfsize, "%#Lx", self->ip);
 	return bf;
@@ -157,7 +157,7 @@
 				indexes[depth + 2] = NEWT_ARG_LAST;
 				++chain_idx;
 			}
-			newt_checkbox_tree__add(tree, str, chain->sym, indexes);
+			newt_checkbox_tree__add(tree, str, chain->ms.sym, indexes);
 			free(alloc_str);
 			++printed;
 		}
@@ -193,7 +193,7 @@
 			continue;
 
 		str = callchain_list__sym_name(chain, ipstr, sizeof(ipstr));
-		newt_checkbox_tree__add(tree, str, chain->sym, indexes);
+		newt_checkbox_tree__add(tree, str, chain->ms.sym, indexes);
 	}
 
 	indexes[1] = parent_idx;
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index eed1cb8..2cef373 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -117,13 +117,13 @@
 	return 0;
 }
 
-struct symbol **perf_session__resolve_callchain(struct perf_session *self,
-						struct thread *thread,
-						struct ip_callchain *chain,
-						struct symbol **parent)
+struct map_symbol *perf_session__resolve_callchain(struct perf_session *self,
+						   struct thread *thread,
+						   struct ip_callchain *chain,
+						   struct symbol **parent)
 {
 	u8 cpumode = PERF_RECORD_MISC_USER;
-	struct symbol **syms = NULL;
+	struct map_symbol *syms = NULL;
 	unsigned int i;
 
 	if (symbol_conf.use_callchain) {
@@ -160,7 +160,8 @@
 				*parent = al.sym;
 			if (!symbol_conf.use_callchain)
 				break;
-			syms[i] = al.sym;
+			syms[i].map = al.map;
+			syms[i].sym = al.sym;
 		}
 	}
 
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 34d7339..631f815 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -57,10 +57,10 @@
 int perf_session__process_events(struct perf_session *self,
 				 struct perf_event_ops *event_ops);
 
-struct symbol **perf_session__resolve_callchain(struct perf_session *self,
-						struct thread *thread,
-						struct ip_callchain *chain,
-						struct symbol **parent);
+struct map_symbol *perf_session__resolve_callchain(struct perf_session *self,
+						   struct thread *thread,
+						   struct ip_callchain *chain,
+						   struct symbol **parent);
 
 bool perf_session__has_traces(struct perf_session *self, const char *msg);