18cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/**
28cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @file format_output.cpp
38cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * outputting format for symbol lists
48cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
58cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Copyright 2002 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/* older glibc has C99 INFINITY in _GNU_SOURCE */
138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#ifndef _GNU_SOURCE
148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define _GNU_SOURCE
158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#endif
168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <cassert>
188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <sstream>
198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <iomanip>
208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <iostream>
218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <cmath>
228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "string_manip.h"
248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "string_filter.h"
258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "format_output.h"
278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "profile_container.h"
288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "callgraph_container.h"
298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "diff_container.h"
308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "arrange_profiles.h"
318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "xml_output.h"
328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "xml_utils.h"
338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "cverb.h"
348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddusing namespace std;
368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddnamespace {
388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring const get_linenr_info(file_location const floc, bool lf)
418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ostringstream out;
438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string const & filename = lf
458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		? debug_names.name(floc.filename)
468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		: debug_names.basename(floc.filename);
478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (!filename.empty())
498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << filename << ":" << floc.linenr;
508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	else
518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << "(no location information)";
528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return out.str();
548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring get_vma(bfd_vma vma, bool vma_64)
578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ostringstream out;
598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	int width = vma_64 ? 16 : 8;
608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << hex << setw(width) << setfill('0') << vma;
628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return out.str();
648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring get_percent(count_type dividend, count_type divisor)
678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	double ratio = op_ratio(dividend, divisor);
698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return ::format_percent(ratio * 100, percent_int_width,
718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	                     percent_fract_width);
728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbool extract_linenr_info(string const & info, string & file, size_t & line)
758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	line = 0;
778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	file = "";
788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string::size_type colon_pos = info.find(":");
798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (colon_pos == string::npos)
818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return false;
828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	file = info.substr(0, colon_pos);
848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	istringstream is_info(info.substr(colon_pos+1));
858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	is_info >> line;
868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return true;
878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} // anonymous namespace
918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddnamespace format_output {
938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddformatter::formatter(extra_images const & extra)
958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	:
968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	nr_classes(1),
978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	flags(ff_none),
988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	vma_64(false),
998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	long_filenames(false),
1008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	need_header(true),
1018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	extra_found_images(extra)
1028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	format_map[ff_vma] = field_description(9, "vma", &formatter::format_vma);
1048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	format_map[ff_nr_samples] = field_description(9, "samples", &formatter::format_nr_samples);
1058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	format_map[ff_nr_samples_cumulated] = field_description(14, "cum. samples", &formatter::format_nr_cumulated_samples);
1068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	format_map[ff_percent] = field_description(9, "%", &formatter::format_percent);
1078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	format_map[ff_percent_cumulated] = field_description(11, "cum. %", &formatter::format_cumulated_percent);
1088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	format_map[ff_linenr_info] = field_description(28, "linenr info", &formatter::format_linenr_info);
1098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	format_map[ff_image_name] = field_description(25, "image name", &formatter::format_image_name);
1108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	format_map[ff_app_name] = field_description(25, "app name", &formatter::format_app_name);
1118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	format_map[ff_symb_name] = field_description(30, "symbol name", &formatter::format_symb_name);
1128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	format_map[ff_percent_details] = field_description(9, "%", &formatter::format_percent_details);
1138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	format_map[ff_percent_cumulated_details] = field_description(10, "cum. %", &formatter::format_cumulated_percent_details);
1148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	format_map[ff_diff] = field_description(10, "diff %", &formatter::format_diff);
1158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddformatter::~formatter()
1198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid formatter::set_nr_classes(size_t nr)
1248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	nr_classes = nr;
1268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid formatter::add_format(format_flags flag)
1308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	flags = static_cast<format_flags>(flags | flag);
1328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid formatter::show_header(bool on_off)
1368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	need_header = on_off;
1388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid formatter::vma_format_64bit(bool on_off)
1428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	vma_64 = on_off;
1448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid formatter::show_long_filenames(bool on_off)
1488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	long_filenames = on_off;
1508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid formatter::show_global_percent(bool on_off)
1548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	global_percent = on_off;
1568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid formatter::output_header(ostream & out)
1608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (!need_header)
1628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return;
1638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t padding = 0;
1658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// first output the vma field
1678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (flags & ff_vma)
1688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		padding = output_header_field(out, ff_vma, padding);
1698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// the field repeated for each profile class
1718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t pclass = 0 ; pclass < nr_classes; ++pclass) {
1728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (flags & ff_nr_samples)
1738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			padding = output_header_field(out,
1748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			      ff_nr_samples, padding);
1758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (flags & ff_nr_samples_cumulated)
1778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			padding = output_header_field(out,
1788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			       ff_nr_samples_cumulated, padding);
1798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (flags & ff_percent)
1818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			padding = output_header_field(out,
1828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			       ff_percent, padding);
1838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (flags & ff_percent_cumulated)
1858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			padding = output_header_field(out,
1868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			       ff_percent_cumulated, padding);
1878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (flags & ff_diff)
1898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			padding = output_header_field(out,
1908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				ff_diff, padding);
1918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (flags & ff_percent_details)
1938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			padding = output_header_field(out,
1948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			       ff_percent_details, padding);
1958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (flags & ff_percent_cumulated_details)
1978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			padding = output_header_field(out,
1988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			       ff_percent_cumulated_details, padding);
1998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
2008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// now the remaining field
2028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (flags & ff_linenr_info)
2038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		padding = output_header_field(out, ff_linenr_info, padding);
2048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (flags & ff_image_name)
2068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		padding = output_header_field(out, ff_image_name, padding);
2078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (flags & ff_app_name)
2098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		padding = output_header_field(out, ff_app_name, padding);
2108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (flags & ff_symb_name)
2128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		padding = output_header_field(out, ff_symb_name, padding);
2138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << "\n";
2158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/// describe each possible field of colummned output.
2198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// FIXME: use % of the screen width here. sum of % equal to 100, then calculate
2208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// ratio between 100 and the selected % to grow non fixed field use also
2218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// lib[n?]curses to get the console width (look info source) (so on add a fixed
2228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// field flags)
2238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddsize_t formatter::
2248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddoutput_field(ostream & out, field_datum const & datum,
2258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd             format_flags fl, size_t padding, bool hide_immutable)
2268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (!hide_immutable) {
2288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << string(padding, ' ');
2298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		field_description const & field(format_map[fl]);
2318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		string str = (this->*field.formatter)(datum);
2328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << str;
2338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// at least one separator char
2358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		padding = 1;
2368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (str.length() < field.width)
2378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			padding = field.width - str.length();
2388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	} else {
2398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		field_description const & field(format_map[fl]);
2408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		padding += field.width;
2418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
2428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return padding;
2448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddsize_t formatter::
2488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddoutput_header_field(ostream & out, format_flags fl, size_t padding)
2498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << string(padding, ' ');
2518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	field_description const & field(format_map[fl]);
2538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << field.header_name;
2548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// at least one separator char
2568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	padding = 1;
2578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (field.header_name.length() < field.width)
2588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		padding = field.width - field.header_name.length();
2598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return padding;
2618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring formatter::format_vma(field_datum const & f)
2658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return get_vma(f.sample.vma, vma_64);
2678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring formatter::format_symb_name(field_datum const & f)
2718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return symbol_names.demangle(f.symbol.name);
2738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring formatter::format_image_name(field_datum const & f)
2778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return get_image_name(f.symbol.image_name,
2798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		long_filenames
2808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			? image_name_storage::int_real_filename
2818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			: image_name_storage::int_real_basename,
2828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		extra_found_images);
2838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring formatter::format_app_name(field_datum const & f)
2878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return get_image_name(f.symbol.app_name,
2898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		long_filenames
2908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			? image_name_storage::int_real_filename
2918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			: image_name_storage::int_real_basename,
2928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		extra_found_images);
2938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring formatter::format_linenr_info(field_datum const & f)
2978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return get_linenr_info(f.sample.file_loc, long_filenames);
2998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
3008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring formatter::format_nr_samples(field_datum const & f)
3038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
3048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ostringstream out;
3058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << f.sample.counts[f.pclass];
3068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return out.str();
3078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
3088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring formatter::format_nr_cumulated_samples(field_datum const & f)
3118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
3128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (f.diff == -INFINITY)
3138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return "---";
3148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ostringstream out;
3158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	f.counts.cumulated_samples[f.pclass] += f.sample.counts[f.pclass];
3168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << f.counts.cumulated_samples[f.pclass];
3178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return out.str();
3188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
3198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring formatter::format_percent(field_datum const & f)
3228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
3238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (f.diff == -INFINITY)
3248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return "---";
3258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return get_percent(f.sample.counts[f.pclass], f.counts.total[f.pclass]);
3268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
3278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring formatter::format_cumulated_percent(field_datum const & f)
3308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
3318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (f.diff == -INFINITY)
3328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return "---";
3338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	f.counts.cumulated_percent[f.pclass] += f.sample.counts[f.pclass];
3348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return get_percent(f.counts.cumulated_percent[f.pclass],
3368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	                   f.counts.total[f.pclass]);
3378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
3388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring formatter::format_percent_details(field_datum const & f)
3418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
3428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return get_percent(f.sample.counts[f.pclass],
3438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		f.counts.total[f.pclass]);
3448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
3458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring formatter::format_cumulated_percent_details(field_datum const & f)
3488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
3498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	f.counts.cumulated_percent_details[f.pclass] += f.sample.counts[f.pclass];
3508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return get_percent(f.counts.cumulated_percent_details[f.pclass],
3528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	                   f.counts.total[f.pclass]);
3538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
3548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring formatter::format_diff(field_datum const & f)
3578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
3588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (f.diff == INFINITY)
3598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return "+++";
3608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	else if (f.diff == -INFINITY)
3618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return "---";
3628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return ::format_percent(f.diff, percent_int_width,
3648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd                                percent_fract_width, true);
3658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
3668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid formatter::
3698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodddo_output(ostream & out, symbol_entry const & symb, sample_entry const & sample,
3708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd          counts_t & c, diff_array_t const & diffs, bool hide_immutable)
3718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
3728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t padding = 0;
3738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// first output the vma field
3758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	field_datum datum(symb, sample, 0, c, extra_found_images);
3768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (flags & ff_vma)
3778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		padding = output_field(out, datum, ff_vma, padding, false);
3788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// repeated fields for each profile class
3808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t pclass = 0 ; pclass < nr_classes; ++pclass) {
3818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		field_datum datum(symb, sample, pclass, c,
3828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				  extra_found_images, diffs[pclass]);
3838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (flags & ff_nr_samples)
3858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			padding = output_field(out, datum,
3868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			       ff_nr_samples, padding, false);
3878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (flags & ff_nr_samples_cumulated)
3898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			padding = output_field(out, datum,
3908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			       ff_nr_samples_cumulated, padding, false);
3918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (flags & ff_percent)
3938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			padding = output_field(out, datum,
3948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			       ff_percent, padding, false);
3958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (flags & ff_percent_cumulated)
3978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			padding = output_field(out, datum,
3988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			       ff_percent_cumulated, padding, false);
3998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (flags & ff_diff)
4018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			padding = output_field(out, datum,
4028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				ff_diff, padding, false);
4038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (flags & ff_percent_details)
4058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			padding = output_field(out, datum,
4068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			       ff_percent_details, padding, false);
4078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (flags & ff_percent_cumulated_details)
4098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			padding = output_field(out, datum,
4108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			       ff_percent_cumulated_details, padding, false);
4118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
4128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// now the remaining field
4148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (flags & ff_linenr_info)
4158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		padding = output_field(out, datum, ff_linenr_info,
4168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		       padding, false);
4178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (flags & ff_image_name)
4198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		padding = output_field(out, datum, ff_image_name,
4208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		       padding, hide_immutable);
4218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (flags & ff_app_name)
4238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		padding = output_field(out, datum, ff_app_name,
4248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		       padding, hide_immutable);
4258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (flags & ff_symb_name)
4278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		padding = output_field(out, datum, ff_symb_name,
4288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		       padding, hide_immutable);
4298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << "\n";
4318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
4328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddopreport_formatter::opreport_formatter(profile_container const & p)
4358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	:
4368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	formatter(p.extra_found_images),
4378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	profile(p),
4388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	need_details(false)
4398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
4408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	counts.total = profile.samples_count();
4418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
4428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid opreport_formatter::show_details(bool on_off)
4458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
4468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	need_details = on_off;
4478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
4488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid opreport_formatter::output(ostream & out, symbol_entry const * symb)
4518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
4528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	do_output(out, *symb, symb->sample, counts);
4538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (need_details)
4558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		output_details(out, symb);
4568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
4578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid opreport_formatter::
4608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddoutput(ostream & out, symbol_collection const & syms)
4618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
4628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	output_header(out);
4638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	symbol_collection::const_iterator it = syms.begin();
4658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	symbol_collection::const_iterator end = syms.end();
4668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (; it != end; ++it)
4678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		output(out, *it);
4688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
4698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid opreport_formatter::
4728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddoutput_details(ostream & out, symbol_entry const * symb)
4738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
4748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	counts_t c = counts;
4758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (!global_percent)
4778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		c.total = symb->sample.counts;
4788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// cumulated percent are relative to current symbol.
4808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	c.cumulated_samples = count_array_t();
4818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	c.cumulated_percent = count_array_t();
4828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	sample_container::samples_iterator it = profile.begin(symb);
4848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	sample_container::samples_iterator end = profile.end(symb);
4858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (; it != end; ++it) {
4868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << "  ";
4878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		do_output(out, *symb, it->second, c, diff_array_t(), true);
4888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
4898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
4908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddcg_formatter::cg_formatter(callgraph_container const & profile)
4938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	:
4948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	formatter(profile.extra_found_images)
4958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
4968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	counts.total = profile.samples_count();
4978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
4988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid cg_formatter::output(ostream & out, symbol_collection const & syms)
5018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
5028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// amount of spacing prefixing child and parent lines
5038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string const child_parent_prefix("  ");
5048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	output_header(out);
5068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << string(79, '-') << endl;
5088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	symbol_collection::const_iterator it;
5108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	symbol_collection::const_iterator end = syms.end();
5118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (it = syms.begin(); it < end; ++it) {
5138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		cg_symbol const * sym = dynamic_cast<cg_symbol const *>(*it);
5148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		cg_symbol::children::const_iterator cit;
5168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		cg_symbol::children::const_iterator cend = sym->callers.end();
5178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		counts_t c;
5198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (global_percent)
5208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			c.total = counts.total;
5218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		else
5228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			c.total = sym->total_caller_count;
5238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		for (cit = sym->callers.begin(); cit != cend; ++cit) {
5258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			out << child_parent_prefix;
5268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			do_output(out, *cit, cit->sample, c);
5278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
5288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		do_output(out, *sym, sym->sample, counts);
5308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		c = counts_t();
5328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (global_percent)
5338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			c.total = counts.total;
5348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		else
5358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			c.total = sym->total_callee_count;
5368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		cend = sym->callees.end();
5388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		for (cit = sym->callees.begin(); cit != cend; ++cit) {
5408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			out << child_parent_prefix;
5418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			do_output(out, *cit, cit->sample, c);
5428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
5438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << string(79, '-') << endl;
5458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
5468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
5478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodddiff_formatter::diff_formatter(diff_container const & profile,
5508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			       extra_images const & extra)
5518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	:
5528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	formatter(extra)
5538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
5548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	counts.total = profile.samples_count();
5558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
5568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid diff_formatter::output(ostream & out, diff_collection const & syms)
5598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
5608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	output_header(out);
5618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	diff_collection::const_iterator it = syms.begin();
5638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	diff_collection::const_iterator end = syms.end();
5648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (; it != end; ++it)
5658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		do_output(out, *it, it->sample, counts, it->diffs);
5668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
5678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// local variables used in generation of XML
5698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// buffer details for output later
5708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddostringstream bytes_out;
5718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// module+symbol table for detecting duplicate symbols
5738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddmap<string, size_t> symbol_data_table;
5748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddsize_t symbol_data_index = 0;
5758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/* Return any existing index or add to the table */
5778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddsize_t xml_get_symbol_index(string const & name)
5788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
5798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t index = symbol_data_index;
5808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	map<string, size_t>::iterator it = symbol_data_table.find(name);
5818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (it == symbol_data_table.end()) {
5838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		symbol_data_table[name] = symbol_data_index++;
5848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return index;
5858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
5868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return it->second;
5888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
5898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddclass symbol_details_t {
5928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpublic:
5938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	symbol_details_t() { size = index = 0; id = -1; }
5948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	int id;
5958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t size;
5968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t index;
5978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string details;
5988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd};
5998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddtypedef growable_vector<symbol_details_t> symbol_details_array_t;
6018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddsymbol_details_array_t symbol_details;
6028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddsize_t detail_table_index = 0;
6038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddxml_formatter::
6058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddxml_formatter(profile_container const * p,
6068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	      symbol_collection & s, extra_images const & extra,
6078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	      string_filter const & sf)
6088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	:
6098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	formatter(extra),
6108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	profile(p),
6118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	symbols(s),
6128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	need_details(false),
6138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	symbol_filter(sf)
6148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
6158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (profile)
6168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		counts.total = profile->samples_count();
6178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
6188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid xml_formatter::
6218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddshow_details(bool on_off)
6228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
6238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	need_details = on_off;
6248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
6258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid xml_formatter::output(ostream & out)
6288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
6298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	xml_support->build_subclasses(out);
6308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	xml_support->output_program_structure(out);
6328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	output_symbol_data(out);
6338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (need_details) {
6348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << open_element(DETAIL_TABLE);
6358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		for (size_t i = 0; i < symbol_details.size(); ++i) {
6368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			int id = symbol_details[i].id;
6378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			if (id >= 0) {
6398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				out << open_element(SYMBOL_DETAILS, true);
6408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				out << init_attr(TABLE_ID, (size_t)id);
6418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				out << close_element(NONE, true);
6428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				out << symbol_details[i].details;
6438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				out << close_element(SYMBOL_DETAILS);
6448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			}
6458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
6468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << close_element(DETAIL_TABLE);
6478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// output bytesTable
6498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << open_element(BYTES_TABLE);
6508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << bytes_out.str();
6518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << close_element(BYTES_TABLE);
6528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
6538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << close_element(PROFILE);
6558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
6568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbool
6588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddxml_formatter::get_bfd_object(symbol_entry const * symb, op_bfd * & abfd) const
6598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
6608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	bool ok = true;
6618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string const & image_name = get_image_name(symb->image_name,
6638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		image_name_storage::int_filename, extra_found_images);
6648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (symb->spu_offset) {
6658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// FIXME: what about archive:tmp, actually it's not supported
6668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// for spu since oparchive doesn't archive the real file but
6678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// in future it would work ?
6688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		string tmp = get_image_name(symb->embedding_filename,
6698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			image_name_storage::int_filename, extra_found_images);
6708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (abfd && abfd->get_filename() == tmp)
6718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			return true;
6728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		delete abfd;
6738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		abfd = new op_bfd(symb->spu_offset, tmp,
6748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				  symbol_filter, extra_found_images, ok);
6758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	} else {
6768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (abfd && abfd->get_filename() == image_name)
6778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			return true;
6788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		delete abfd;
6798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		abfd = new op_bfd(image_name, symbol_filter,
6808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				  extra_found_images, ok);
6818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
6838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (!ok) {
6858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		report_image_error(image_name, image_format_failure,
6868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				   false, extra_found_images);
6878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		delete abfd;
6888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		abfd = 0;
6898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return false;
6908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
6918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return true;
6938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
6948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid xml_formatter::
6968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddoutput_the_symbol_data(ostream & out, symbol_entry const * symb, op_bfd * & abfd)
6978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
6988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string const name = symbol_names.name(symb->name);
6998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	assert(name.size() > 0);
7008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string const image = get_image_name(symb->image_name,
7028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		image_name_storage::int_filename, extra_found_images);
7038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string const qname = image + ":" + name;
7048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	map<string, size_t>::iterator sd_it = symbol_data_table.find(qname);
7058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (sd_it != symbol_data_table.end()) {
7078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// first time we've seen this symbol
7088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << open_element(SYMBOL_DATA, true);
7098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << init_attr(TABLE_ID, sd_it->second);
7108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		field_datum datum(*symb, symb->sample, 0, counts,
7128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				  extra_found_images);
7138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		output_attribute(out, datum, ff_symb_name, NAME);
7158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (flags & ff_linenr_info) {
7178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			output_attribute(out, datum, ff_linenr_info, SOURCE_FILE);
7188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			output_attribute(out, datum, ff_linenr_info, SOURCE_LINE);
7198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
7208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (name.size() > 0 && name[0] != '?') {
7228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			output_attribute(out, datum, ff_vma, STARTING_ADDR);
7238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			if (need_details) {
7258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				get_bfd_object(symb, abfd);
7268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				if (abfd && abfd->symbol_has_contents(symb->sym_index))
7278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd					xml_support->output_symbol_bytes(bytes_out, symb, sd_it->second, *abfd);
7288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			}
7298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
7308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << close_element();
7318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// seen so remove (otherwise get several "no symbols")
7338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		symbol_data_table.erase(qname);
7348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
7358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
7368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid xml_formatter::output_cg_children(ostream & out,
7388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cg_symbol::children const cg_symb, op_bfd * & abfd)
7398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
7408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cg_symbol::children::const_iterator cit;
7418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cg_symbol::children::const_iterator cend = cg_symb.end();
7428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (cit = cg_symb.begin(); cit != cend; ++cit) {
7448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		string const name = symbol_names.name(cit->name);
7458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		string const image = get_image_name(cit->image_name,
7468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			image_name_storage::int_filename, extra_found_images);
7478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		string const qname = image + ":" + name;
7488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		map<string, size_t>::iterator sd_it = symbol_data_table.find(qname);
7498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (sd_it != symbol_data_table.end()) {
7518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			symbol_entry const * child = &(*cit);
7528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			output_the_symbol_data(out, child, abfd);
7538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
7548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
7558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
7568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid xml_formatter::output_symbol_data(ostream & out)
7588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
7598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	op_bfd * abfd = NULL;
7608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	sym_iterator it = symbols.begin();
7618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	sym_iterator end = symbols.end();
7628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << open_element(SYMBOL_TABLE);
7648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for ( ; it != end; ++it) {
7658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		symbol_entry const * symb = *it;
7668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		cg_symbol const * cg_symb = dynamic_cast<cg_symbol const *>(symb);
7678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		output_the_symbol_data(out, symb, abfd);
7688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (cg_symb) {
7698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			/* make sure callers/callees are included in SYMBOL_TABLE */
7708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			output_cg_children(out, cg_symb->callers, abfd);
7718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			output_cg_children(out, cg_symb->callees, abfd);
7728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
7738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
7748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << close_element(SYMBOL_TABLE);
7758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	delete abfd;
7778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
7788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring  xml_formatter::
7808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddoutput_symbol_details(symbol_entry const * symb,
7818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    size_t & detail_index, size_t const lo, size_t const hi)
7828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
7838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (!has_sample_counts(symb->sample.counts, lo, hi))
7848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return "";
7858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	sample_container::samples_iterator it = profile->begin(symb);
7878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	sample_container::samples_iterator end = profile->end(symb);
7888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ostringstream str;
7908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (; it != end; ++it) {
7918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		counts_t c;
7928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		for (size_t p = lo; p <= hi; ++p)  {
7948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			size_t count = it->second.counts[p];
7958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			if (count == 0) continue;
7978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			str << open_element(DETAIL_DATA, true);
7998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			str << init_attr(TABLE_ID, detail_index++);
8008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			// first output the vma field
8028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			field_datum datum(*symb, it->second, 0, c,
8038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd					  extra_found_images, 0.0);
8048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			output_attribute(str, datum, ff_vma, VMA);
8058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			if (ff_linenr_info) {
8068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				string sym_file;
8078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				size_t sym_line;
8088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				string samp_file;
8098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				size_t samp_line;
8108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				string sym_info = get_linenr_info(symb->sample.file_loc, true);
8118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				string samp_info = get_linenr_info(it->second.file_loc, true);
8128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				if (extract_linenr_info(samp_info, samp_file, samp_line)) {
8148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd					if (extract_linenr_info(sym_info, sym_file, sym_line)) {
8158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd						// only output source_file if it is different than the symbol's
8168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd						// source file.  this can happen with inlined functions in
8178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd						// #included header files
8188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd						if (sym_file != samp_file)
8198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd							str << init_attr(SOURCE_FILE, samp_file);
8208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd					}
8218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd					str << init_attr(SOURCE_LINE, samp_line);
8228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				}
8238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			}
8248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			str << close_element(NONE, true);
8258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			// output buffered sample data
8278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			output_sample_data(str, it->second, p);
8288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			str << close_element(DETAIL_DATA);
8308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
8318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
8328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return str.str();
8338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
8348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid xml_formatter::
8368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddoutput_symbol(ostream & out,
8378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	symbol_entry const * symb, size_t lo, size_t hi, bool is_module)
8388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
8398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ostringstream str;
8408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// pointless reference to is_module, remove insane compiler warning
8418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t indx = is_module ? 0 : 1;
8428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// output symbol's summary data for each profile class
8448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	bool got_samples = false;
8458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t p = lo; p <= hi; ++p) {
8478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		got_samples |= xml_support->output_summary_data(str,
8488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		    symb->sample.counts, p);
8498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
8508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (!got_samples)
8528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return;
8538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (cverb << vxml)
8558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << "<!-- symbol_ref=" << symbol_names.name(symb->name) <<
8568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			" -->" << endl;
8578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << open_element(SYMBOL, true);
8598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string const name = symbol_names.name(symb->name);
8618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	assert(name.size() > 0);
8628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string const image = get_image_name(symb->image_name,
8648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		image_name_storage::int_filename, extra_found_images);
8658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string const qname = image + ":" + name;
8668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	indx = xml_get_symbol_index(qname);
8688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << init_attr(ID_REF, indx);
8708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (need_details) {
8728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		ostringstream details;
8738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		symbol_details_t & sd = symbol_details[indx];
8748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		size_t const detail_lo = sd.index;
8758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		string detail_str = output_symbol_details(symb, sd.index, lo, hi);
8778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (detail_str.size() > 0) {
8798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			if (sd.id < 0)
8808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				sd.id = indx;
8818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			details << detail_str;
8828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
8838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (sd.index > detail_lo) {
8858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			sd.details = sd.details + details.str();
8868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			out << init_attr(DETAIL_LO, detail_lo);
8878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			out << init_attr(DETAIL_HI, sd.index-1);
8888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
8898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
8908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << close_element(NONE, true);
8918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// output summary
8928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << str.str();
8938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << close_element(SYMBOL);
8948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
8958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid xml_formatter::
8988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddoutput_sample_data(ostream & out, sample_entry const & sample, size_t pclass)
8998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
9008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << open_element(COUNT, true);
9018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << init_attr(CLASS, classes.v[pclass].name);
9028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << close_element(NONE, true);
9038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << sample.counts[pclass];
9048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << close_element(COUNT);
9058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
9068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid xml_formatter::
9098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddoutput_attribute(ostream & out, field_datum const & datum,
9108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd                 format_flags fl, tag_t tag)
9118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
9128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	field_description const & field(format_map[fl]);
9138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string str = (this->*field.formatter)(datum);
9158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (!str.empty()) {
9178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (fl == ff_linenr_info && (tag == SOURCE_LINE || tag == SOURCE_FILE)) {
9188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			string file;
9198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			size_t line;
9208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			if (extract_linenr_info(str, file, line)) {
9228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				if (tag == SOURCE_LINE)
9238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd					out << init_attr(tag, line);
9248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				else
9258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd					out << init_attr(tag, file);
9268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			}
9278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		} else
9288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			out << " " << init_attr(tag, str);
9298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
9308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
9318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddxml_cg_formatter::
9338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddxml_cg_formatter(callgraph_container const & cg, symbol_collection & s,
9348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		 string_filter const & sf)
9358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	:
9368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	xml_formatter(0, s, cg.extra_found_images, sf),
9378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	callgraph(cg)
9388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
9398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	counts.total = callgraph.samples_count();
9408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
9418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid xml_cg_formatter::
9438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddoutput_symbol_core(ostream & out, cg_symbol::children const cg_symb,
9448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd       string const selfname, string const qname,
9458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd       size_t lo, size_t hi, bool is_module, tag_t tag)
9468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
9478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cg_symbol::children::const_iterator cit;
9488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cg_symbol::children::const_iterator cend = cg_symb.end();
9498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (cit = cg_symb.begin(); cit != cend; ++cit) {
9518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		string const & module = get_image_name((cit)->image_name,
9528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			image_name_storage::int_filename, extra_found_images);
9538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		bool self = false;
9548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		ostringstream str;
9558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		size_t indx;
9568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// output symbol's summary data for each profile class
9588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		for (size_t p = lo; p <= hi; ++p)
9598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			xml_support->output_summary_data(str, cit->sample.counts, p);
9608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (cverb << vxml)
9628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			out << "<!-- symbol_ref=" << symbol_names.name(cit->name) <<
9638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				" -->" << endl;
9648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (is_module) {
9668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			out << open_element(MODULE, true);
9678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			out << init_attr(NAME, module) << close_element(NONE, true);
9688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
9698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << open_element(SYMBOL, true);
9718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		string const symname = symbol_names.name(cit->name);
9738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		assert(symname.size() > 0);
9748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		string const symqname = module + ":" + symname;
9768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// Find any self references and handle
9788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if ((symname == selfname) && (tag == CALLEES)) {
9798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			self = true;
9808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			indx = xml_get_symbol_index(qname);
9818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		} else {
9828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			indx = xml_get_symbol_index(symqname);
9838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
9848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << init_attr(ID_REF, indx);
9868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (self)
9888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			out << init_attr(SELFREF, "true");
9898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << close_element(NONE, true);
9918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << str.str();
9928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << close_element(SYMBOL);
9938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (is_module)
9958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			out << close_element(MODULE);
9968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
9978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
9988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
10008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid xml_cg_formatter::
10018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddoutput_symbol(ostream & out,
10028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	symbol_entry const * symb, size_t lo, size_t hi, bool is_module)
10038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
10048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cg_symbol const * cg_symb = dynamic_cast<cg_symbol const *>(symb);
10058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ostringstream str;
10068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t indx;
10078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
10088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// output symbol's summary data for each profile class
10098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t p = lo; p <= hi; ++p)
10108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		xml_support->output_summary_data(str, symb->sample.counts, p);
10118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
10128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (cverb << vxml)
10138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << "<!-- symbol_ref=" << symbol_names.name(symb->name) <<
10148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			" -->" << endl;
10158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
10168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << open_element(SYMBOL, true);
10178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
10188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string const name = symbol_names.name(symb->name);
10198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	assert(name.size() > 0);
10208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
10218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string const image = get_image_name(symb->image_name,
10228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		image_name_storage::int_filename, extra_found_images);
10238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string const qname = image + ":" + name;
10248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
10258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string const selfname = symbol_names.demangle(symb->name) + " [self]";
10268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
10278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	indx = xml_get_symbol_index(qname);
10288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
10298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << init_attr(ID_REF, indx);
10308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
10318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << close_element(NONE, true);
10328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
10338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << open_element(CALLERS);
10348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (cg_symb)
10358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		output_symbol_core(out, cg_symb->callers, selfname, qname, lo, hi, is_module, CALLERS);
10368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << close_element(CALLERS);
10378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
10388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << open_element(CALLEES);
10398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (cg_symb)
10408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		output_symbol_core(out, cg_symb->callees, selfname, qname, lo, hi, is_module, CALLEES);
10418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
10428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << close_element(CALLEES);
10438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
10448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// output summary
10458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << str.str();
10468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << close_element(SYMBOL);
10478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
10488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
10498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} // namespace format_output
1050