Home | History | Annotate | Download | only in libpp
      1 /**
      2  * @file format_output.h
      3  * outputting format for symbol lists
      4  *
      5  * @remark Copyright 2002 OProfile authors
      6  * @remark Read the file COPYING
      7  *
      8  * @author Philippe Elie
      9  * @author John Levon
     10  */
     11 
     12 #ifndef FORMAT_OUTPUT_H
     13 #define FORMAT_OUTPUT_H
     14 
     15 #include "config.h"
     16 
     17 #include <string>
     18 #include <map>
     19 #include <iosfwd>
     20 
     21 #include "format_flags.h"
     22 #include "symbol.h"
     23 #include "string_filter.h"
     24 #include "xml_output.h"
     25 
     26 class symbol_entry;
     27 class sample_entry;
     28 class callgraph_container;
     29 class profile_container;
     30 class diff_container;
     31 class extra_images;
     32 class op_bfd;
     33 
     34 struct profile_classes;
     35 // FIXME: should be passed to the derived class formatter ctor
     36 extern profile_classes classes;
     37 
     38 namespace format_output {
     39 
     40 /// base class for formatter, handle common options to formatter
     41 class formatter {
     42 public:
     43 	formatter(extra_images const & extra);
     44 	virtual ~formatter();
     45 
     46 	/// add a given column
     47 	void add_format(format_flags flag);
     48 
     49 	/// set the need_header boolean to false
     50 	void show_header(bool);
     51 	/// format for 64 bit wide VMAs
     52 	void vma_format_64bit(bool);
     53 	/// show long (full path) filenames
     54 	void show_long_filenames(bool);
     55 	/// use global count rather symbol count for details percent
     56 	void show_global_percent(bool);
     57 
     58 	/**
     59 	 * Set the number of collected profile classes. Each class
     60 	 * will output sample count and percentage in extra columns.
     61 	 *
     62 	 * This class assumes that the profile information has been
     63 	 * populated with the right number of classes.
     64 	 */
     65 	void set_nr_classes(size_t nr_classes);
     66 
     67 	/// output table header, implemented by calling the virtual function
     68 	/// output_header_field()
     69 	void output_header(std::ostream & out);
     70 
     71 protected:
     72 	struct counts_t {
     73 		/// total sample count
     74 		count_array_t total;
     75 		/// samples so far
     76 		count_array_t cumulated_samples;
     77 		/// percentage so far
     78 		count_array_t cumulated_percent;
     79 		/// detailed percentage so far
     80 		count_array_t cumulated_percent_details;
     81 	};
     82 
     83 	/// data passed for output
     84 	struct field_datum {
     85 		field_datum(symbol_entry const & sym,
     86 		            sample_entry const & s,
     87 			    size_t pc, counts_t & c,
     88 			    extra_images const & extra, double d = 0.0)
     89 			: symbol(sym), sample(s), pclass(pc),
     90 			  counts(c), extra(extra), diff(d) {}
     91 		symbol_entry const & symbol;
     92 		sample_entry const & sample;
     93 		size_t pclass;
     94 		counts_t & counts;
     95 		extra_images const & extra;
     96 		double diff;
     97 	};
     98 
     99 	/// format callback type
    100 	typedef std::string (formatter::*fct_format)(field_datum const &);
    101 
    102 	/** @name format functions.
    103 	 * The set of formatting functions, used internally by output().
    104 	 */
    105 	//@{
    106 	std::string format_vma(field_datum const &);
    107 	std::string format_symb_name(field_datum const &);
    108 	std::string format_image_name(field_datum const &);
    109 	std::string format_app_name(field_datum const &);
    110 	std::string format_linenr_info(field_datum const &);
    111 	std::string format_nr_samples(field_datum const &);
    112 	std::string format_nr_cumulated_samples(field_datum const &);
    113 	std::string format_percent(field_datum const &);
    114 	std::string format_cumulated_percent(field_datum const &);
    115 	std::string format_percent_details(field_datum const &);
    116 	std::string format_cumulated_percent_details(field_datum const &);
    117 	std::string format_diff(field_datum const &);
    118 	//@}
    119 
    120 	/// decribe one field of the colummned output.
    121 	struct field_description {
    122 		field_description() {}
    123 		field_description(std::size_t w, std::string h,
    124 				  fct_format f)
    125 			: width(w), header_name(h), formatter(f) {}
    126 
    127 		std::size_t width;
    128 		std::string header_name;
    129 		fct_format formatter;
    130 	};
    131 
    132 	typedef std::map<format_flags, field_description> format_map_t;
    133 
    134 	/// actually do output
    135 	void do_output(std::ostream & out, symbol_entry const & symbol,
    136 		      sample_entry const & sample, counts_t & c,
    137 	              diff_array_t const & = diff_array_t(),
    138 	              bool hide_immutable_field = false);
    139 
    140 	/// returns the nr of char needed to pad this field
    141 	size_t output_header_field(std::ostream & out, format_flags fl,
    142 	                           size_t padding);
    143 
    144 	/// returns the nr of char needed to pad this field
    145 	size_t output_field(std::ostream & out, field_datum const & datum,
    146 			   format_flags fl, size_t padding,
    147 			   bool hide_immutable);
    148 
    149 	/// stores functors for doing actual formatting
    150 	format_map_t format_map;
    151 
    152 	/// number of profile classes
    153 	size_t nr_classes;
    154 
    155 	/// total counts
    156 	counts_t counts;
    157 
    158 	/// formatting flags set
    159 	format_flags flags;
    160 	/// true if we need to format as 64 bits quantities
    161 	bool vma_64;
    162 	/// false if we use basename(filename) in output rather filename
    163 	bool long_filenames;
    164 	/// true if we need to show header before the first output
    165 	bool need_header;
    166 	/// bool if details percentage are relative to total count rather to
    167 	/// symbol count
    168 	bool global_percent;
    169 
    170 	/// To retrieve the real image location, usefull when acting on
    171 	/// an archive and for 2.6 kernel modules
    172 	extra_images const & extra_found_images;
    173 };
    174 
    175 
    176 /// class to output in a columned format symbols and associated samples
    177 class opreport_formatter : public formatter {
    178 public:
    179 	/// build a ready to use formatter
    180 	opreport_formatter(profile_container const & profile);
    181 
    182 	/** output a vector of symbols to out according to the output format
    183 	 * specifier previously set by call(s) to add_format() */
    184 	void output(std::ostream & out, symbol_collection const & syms);
    185 
    186 	/// set the output_details boolean
    187 	void show_details(bool);
    188 
    189 private:
    190 
    191 	/** output one symbol symb to out according to the output format
    192 	 * specifier previously set by call(s) to add_format() */
    193 	void output(std::ostream & out, symbol_entry const * symb);
    194 
    195 	/// output details for the symbol
    196 	void output_details(std::ostream & out, symbol_entry const * symb);
    197 
    198 	/// container we work from
    199 	profile_container const & profile;
    200 
    201 	/// true if we need to show details for each symbols
    202 	bool need_details;
    203 };
    204 
    205 
    206 /// class to output in a columned format caller/callee and associated samples
    207 class cg_formatter : public formatter {
    208 public:
    209 	/// build a ready to use formatter
    210 	cg_formatter(callgraph_container const & profile);
    211 
    212 	/** output callgraph information according to the previously format
    213 	 * specifier set by call(s) to add_format() */
    214 	void output(std::ostream & out, symbol_collection const & syms);
    215 };
    216 
    217 /// class to output a columned format symbols plus diff values
    218 class diff_formatter : public formatter {
    219 public:
    220 	/// build a ready to use formatter
    221 	diff_formatter(diff_container const & profile,
    222 		       extra_images const & extra);
    223 
    224 	/**
    225 	 * Output a vector of symbols to out according to the output
    226 	 * format specifier previously set by call(s) to add_format()
    227 	 */
    228 	void output(std::ostream & out, diff_collection const & syms);
    229 
    230 private:
    231 	/// output a single symbol
    232 	void output(std::ostream & out, diff_symbol const & sym);
    233 
    234 };
    235 
    236 
    237 /// class to output in XML format
    238 class xml_formatter : public formatter {
    239 public:
    240 	/// build a ready to use formatter
    241 	xml_formatter(profile_container const * profile,
    242 		      symbol_collection & symbols, extra_images const & extra,
    243 		      string_filter const & symbol_filter);
    244 
    245 	// output body of XML output
    246 	void output(std::ostream & out);
    247 
    248 	/** output one symbol symb to out according to the output format
    249 	 * specifier previously set by call(s) to add_format() */
    250 	virtual void output_symbol(std::ostream & out,
    251 		symbol_entry const * symb, size_t lo, size_t hi,
    252 		bool is_module);
    253 
    254 	/// output details for the symbol
    255 	std::string output_symbol_details(symbol_entry const * symb,
    256 		size_t & detail_index, size_t const lo, size_t const hi);
    257 
    258 	/// set the output_details boolean
    259 	void show_details(bool);
    260 
    261 	// output SymbolData XML elements
    262 	void output_symbol_data(std::ostream & out);
    263 
    264 private:
    265 	/// container we work from
    266 	profile_container const * profile;
    267 
    268 	// ordered collection of symbols associated with this profile
    269 	symbol_collection & symbols;
    270 
    271 	/// true if we need to show details for each symbols
    272 	bool need_details;
    273 
    274 	// count of DetailData items output so far
    275 	size_t detail_count;
    276 
    277 	/// with --details we need to reopen the bfd object for each symb to
    278 	/// get it's contents, hence we store the filter used by the bfd ctor.
    279 	string_filter const & symbol_filter;
    280 
    281 	void output_sample_data(std::ostream & out,
    282 		sample_entry const & sample, size_t count);
    283 
    284 	/// output attribute in XML
    285 	void output_attribute(std::ostream & out, field_datum const & datum,
    286 			      format_flags fl, tag_t tag);
    287 
    288 	/// Retrieve a bfd object for this symbol, reopening a new bfd object
    289 	/// only if necessary
    290 	bool get_bfd_object(symbol_entry const * symb, op_bfd * & abfd) const;
    291 
    292 	void output_the_symbol_data(std::ostream & out,
    293 		symbol_entry const * symb, op_bfd * & abfd);
    294 
    295 	void output_cg_children(std::ostream & out,
    296 		cg_symbol::children const cg_symb, op_bfd * & abfd);
    297 };
    298 
    299 // callgraph XML output version
    300 class xml_cg_formatter : public xml_formatter {
    301 public:
    302 	/// build a ready to use formatter
    303 	xml_cg_formatter(callgraph_container const & callgraph,
    304 		symbol_collection & symbols, string_filter const & sf);
    305 
    306 	/** output one symbol symb to out according to the output format
    307 	 * specifier previously set by call(s) to add_format() */
    308 	virtual void output_symbol(std::ostream & out,
    309 		symbol_entry const * symb, size_t lo, size_t hi, bool is_module);
    310 
    311 private:
    312 	/// container we work from
    313 	callgraph_container const & callgraph;
    314 
    315 	void output_symbol_core(std::ostream & out,
    316 		cg_symbol::children const cg_symb,
    317 		std::string const selfname, std::string const qname,
    318 		size_t lo, size_t hi, bool is_module, tag_t tag);
    319 };
    320 
    321 } // namespace format_output
    322 
    323 
    324 #endif /* !FORMAT_OUTPUT_H */
    325