18cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/**
28cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @file callgraph_container.h
38cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Container associating symbols and caller/caller symbols
48cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
58cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Copyright 2004 OProfile authors
68cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Read the file COPYING
78cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
88cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author Philippe Elie
98cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author John Levon
108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#ifndef CALLGRAPH_CONTAINER_H
138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define CALLGRAPH_CONTAINER_H
148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <set>
168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <vector>
178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <string>
188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "symbol.h"
208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "symbol_functors.h"
218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "string_filter.h"
228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "locate_images.h"
238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddclass profile_container;
258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddclass inverted_profile;
268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddclass profile_t;
278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddclass image_set;
288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddclass op_bfd;
298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/**
328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * During building a callgraph_container we store all caller/callee
338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * relationship in this container.
348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * An "arc" is simply a description of a call from one function to
368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * another.
378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddclass arc_recorder {
398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpublic:
408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	~arc_recorder() {}
418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/**
438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * Add a symbol arc.
448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * @param caller  The calling symbol
458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * @param callee  The called symbol
468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * @param arc_count  profile data for the arcs
478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 *
488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * If the callee is NULL, only the caller is added to the main
498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * list. This is used to initially populate the recorder with
508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * the symbols.
518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 */
528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void add(symbol_entry const & caller, symbol_entry const * callee,
538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	         count_array_t const & arc_count);
548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/// return all the cg symbols
568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	symbol_collection const & get_symbols() const;
578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/**
598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * After population, build the final output, and do
608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * thresholding.
618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 */
628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void process(count_array_t total, double threshold,
638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	             string_filter const & filter);
648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddprivate:
668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/**
678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * Internal structure used during collation. We use a map to
688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * allow quick lookup of children (we'll do this several times
698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * if we have more than one profile class). Each child maps from
708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * the symbol to the relevant arc data.
718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 */
728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	struct cg_data {
738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		cg_data() {}
748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		typedef std::map<symbol_entry, count_array_t, less_symbol> children;
768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		/// callers of this symbol
788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		children callers;
798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		/// callees of this symbol
808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		children callees;
818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	};
828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/**
848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * Sort and threshold callers and callees.
858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 */
868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void process_children(cg_symbol & sym, double threshold);
878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	typedef std::map<symbol_entry, cg_data, less_symbol> map_t;
898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/// all the symbols (used during processing)
918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	map_t sym_map;
928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/// symbol objects pointed to by pointers in vector cg_syms
948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cg_collection_objs cg_syms_objs;
958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/// final output data
978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	symbol_collection cg_syms;
988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd};
998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/**
1028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Store all callgraph information for the given profiles
1038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
1048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddclass callgraph_container {
1058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpublic:
1068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/**
1078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * Populate the container, must be called once only.
1088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * @param iprofiles  sample file list including callgraph files.
1098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * @param extra  extra image list to fixup binary name.
1108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * @param debug_info  true if we must record linenr information
1118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * @param threshold  ignore sample percent below this threshold
1128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * @param merge_lib  merge library samples
1138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * @param sym_filter  symbol filter
1148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 *
1158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * Currently all errors core dump.
1168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * FIXME: consider if this should be a ctor
1178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 */
1188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void populate(std::list<inverted_profile> const & iprofiles,
1198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		      extra_images const & extra, bool debug_info,
1208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		      double threshold, bool merge_lib,
1218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		      string_filter const & sym_filter);
1228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/// return hint on how data must be displayed.
1248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	column_flags output_hint() const;
1258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/// return the total number of samples.
1278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	count_array_t samples_count() const;
1288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// return all the cg symbols
1308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	symbol_collection const & get_symbols() const;
1318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddprivate:
1338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/**
1348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * Record caller/callee for one cg file
1358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * @param profile  one callgraph file stored in a profile_t
1368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * @param caller_bfd  the caller bfd
1378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * @param bfd_caller_ok  true if we succefully open the binary
1388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * @param callee_bfd  the callee bfd
1398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * @param app_name  the owning application
1408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * @param pc  the profile_container holding all non cg samples.
1418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * @param debug_info  record linenr debug information
1428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * @param pclass  profile class nr
1438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 */
1448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void add(profile_t const & profile, op_bfd const & caller_bfd,
1458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	         bool bfd_caller_ok, op_bfd const & callee_bfd,
1468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		 std::string const & app_name, profile_container const & pc,
1478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		 bool debug_info, size_t pclass);
1488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void populate(std::list<image_set> const & lset,
1508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		      std::string const & app_image,
1518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		      size_t pclass, profile_container const & pc,
1528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		      bool debug_info, bool merge_lib);
1538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void populate(std::list<std::string> const & cg_files,
1548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		      std::string const & app_image,
1558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		      size_t pclass, profile_container const & pc,
1568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		      bool debug_info, bool merge_lib);
1578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/// record all main symbols
1598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void add_symbols(profile_container const & pc);
1608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/// Cached value of samples count.
1628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	count_array_t total_count;
1638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/// A structured representation of the callgraph.
1658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	arc_recorder recorder;
1668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpublic:  // FIXME
1688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	extra_images extra_found_images;
1698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd};
1708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#endif /* !CALLGRAPH_CONTAINER_H */
172