18cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/**
28cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @file xml_utils.cpp
38cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * utility routines for generating XML
48cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
58cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Copyright 2006 OProfile authors
68cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Read the file COPYING
78cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
88cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author Dave Nomura
98cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <iostream>
128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <sstream>
138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "xml_utils.h"
158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "format_output.h"
168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "arrange_profiles.h"
178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_bfd.h"
188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "cverb.h"
198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddusing namespace std;
218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbool want_xml = false;
238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddsize_t nr_classes = 0;
258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddsize_t nr_cpus = 0;
268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddsize_t nr_events = 0;
278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddsym_iterator symbols_begin;
288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddsym_iterator symbols_end;
298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// handle on xml_formatter object
308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddformat_output::xml_formatter * xml_out;
318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddxml_utils * xml_support;
328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddsize_t xml_utils::events_index = 0;
338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbool xml_utils::has_nonzero_masks = false;
348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddostringstream xml_options;
358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddnamespace {
398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbool has_separated_cpu_info()
418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return classes.v[0].ptemplate.cpu != "all";
438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring get_event_num(size_t pclass)
478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return classes.v[pclass].ptemplate.event;
498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddsize_t get_next_event_num_pclass(size_t start)
538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string cur_event = get_event_num(start);
558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t i;
568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (i = start;
578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		i < nr_classes && get_event_num(i) == cur_event;
588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		++i) ;
598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return i;
608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid dump_symbol(string const & prefix, sym_iterator it, bool want_nl = true)
648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (it == symbols_end)
668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		cverb << vxml << prefix << "END";
678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	else
688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		cverb << vxml << prefix << symbol_names.name((*it)->name);
698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (want_nl)
708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		cverb << vxml << endl;
718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid dump_symbols(string const & prefix, sym_iterator b, sym_iterator e)
758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (b == (sym_iterator)0)
778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return;
788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (sym_iterator it = b; it != e; ++it)
808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		dump_symbol(prefix, it, true);
818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid dump_classes()
868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cverb << vxml << "<!-- classes dump" << endl;
888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cverb << vxml << classes.event;
898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cverb << vxml << "classes.size= " << classes.v.size() << endl;
908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t i = 0; i < classes.v.size(); ++i) {
918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		cverb << vxml << "--- class " << i << ":" << classes.v[i].name << " ---" << endl;
928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		cverb << vxml << classes.v[i].ptemplate;
938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cverb << vxml << "-->" << endl;
958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbool has_separated_thread_info()
998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return classes.v[0].ptemplate.tid != "all";
1018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring get_cpu_num(size_t pclass)
1058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return classes.v[pclass].ptemplate.cpu;
1078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd};  // anonymous namespace
1118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddxml_utils::xml_utils(format_output::xml_formatter * xo,
1138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		     symbol_collection const & s, size_t nc,
1148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		     extra_images const & extra)
1158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	:
1168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	has_subclasses(false),
1178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	bytes_index(0),
1188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	extra_found_images(extra)
1198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	xml_out = xo;
1218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	nr_classes = nc;
1228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	symbols_begin = s.begin();
1238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	symbols_end = s.end();
1248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	multiple_events = get_next_event_num_pclass(0) != nr_classes;
1258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (has_separated_cpu_info()) {
1278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		size_t cpus = 0;
1288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// count number of cpus
1298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		for (size_t p = 0; p < nr_classes; ++p)  {
1308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			size_t cpu = atoi(classes.v[p].ptemplate.cpu.c_str());
1318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			if (cpu > cpus) cpus = cpu;
1328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
1338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// cpus names start with 0
1348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		nr_cpus = cpus + 1;
1358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
1368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring xml_utils::get_timer_setup(size_t count)
1408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return open_element(TIMER_SETUP, true) +
1428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		init_attr(RTC_INTERRUPTS, count) + close_element();
1438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring xml_utils::get_event_setup(string event, size_t count,
1478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd                                      string unit_mask)
1488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ostringstream str;
1508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	str << open_element(EVENT_SETUP, true);
1528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	str << init_attr(TABLE_ID, events_index++);
1538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	str << init_attr(EVENT_NAME, event);
1548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (unit_mask.size() != 0) str << init_attr(UNIT_MASK, unit_mask);
1558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	str << init_attr(SETUP_COUNT, (size_t)count) + close_element();
1568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return str.str();
1578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring xml_utils::get_profile_header(string cpu_name, double const speed)
1618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ostringstream str;
1638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string cpu_type;
1648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string processor;
1658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string::size_type slash_pos = cpu_name.find("/");
1668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (slash_pos == string::npos) {
1688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		cpu_type = cpu_name;
1698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		processor = "";
1708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	} else {
1718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		cpu_type = cpu_name.substr(0, slash_pos);
1728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		processor = cpu_name.substr(slash_pos+1);
1738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
1748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	str << init_attr(CPU_NAME, cpu_type) << endl;
1768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (processor.size() > 0)
1778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		str << init_attr(PROCESSOR, string(processor)) << endl;
1788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (nr_cpus > 1) str << init_attr(SEPARATED_CPUS, nr_cpus) << endl;
1798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	str << init_attr(MHZ, speed) << endl;
1808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return str.str();
1828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid xml_utils::set_nr_cpus(size_t cpus)
1868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	nr_cpus = cpus;
1888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid xml_utils::set_nr_events(size_t events)
1918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	nr_events = events;
1938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid xml_utils::set_has_nonzero_masks()
1968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	has_nonzero_masks = true;
1988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid xml_utils::add_option(tag_t tag, string const & value)
2028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	xml_options << init_attr(tag, value);
2048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid xml_utils::add_option(tag_t tag, list<string> const & value)
2088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	list<string>::const_iterator begin = value.begin();
2108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	list<string>::const_iterator end = value.end();
2118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	list<string>::const_iterator cit = begin;
2128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ostringstream str;
2138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (; cit != end; ++cit) {
2158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (cit != begin)
2168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			str << ",";
2178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		str << *cit;
2188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
2198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	xml_options << init_attr(tag, str.str());
2208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid xml_utils::add_option(tag_t tag, vector<string> const & value)
2248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	vector<string>::const_iterator begin = value.begin();
2268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	vector<string>::const_iterator end = value.end();
2278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	vector<string>::const_iterator cit = begin;
2288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ostringstream str;
2298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (; cit != end; ++cit) {
2318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (cit != begin)
2328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			str << ",";
2338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		str << *cit;
2348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
2358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	xml_options << init_attr(tag, str.str());
2368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid xml_utils::add_option(tag_t tag, bool value)
2408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	xml_options << init_attr(tag, (value ? "true" : "false"));
2428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid xml_utils::output_xml_header(string const & command_options,
2468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd                       string const & cpu_info, string const & events)
2478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// the integer portion indicates the schema version and should change
2498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// both here and in the schema file when major changes are made to
2508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// the schema.  changes to opreport, or minor changes to the schema
2518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// can be indicated by changes to the fraction part.
2528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string const schema_version = "3.0";
2538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// This is the XML version, not schema version.
2558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string const xml_header = "<?xml version=\"1.0\" ?>";
2568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cout << xml_header << endl;
2588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cout << open_element(PROFILE, true);
2598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cout << init_attr(SCHEMA_VERSION, schema_version);
2608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cout << cpu_info;
2628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cout << init_attr(TITLE, "opreport " + command_options);
2638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cout << close_element(NONE, true);
2648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cout << open_element(OPTIONS, true) << xml_options.str();
2668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cout << close_element();
2678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cout << open_element(SETUP) << events;
2698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cout << close_element(SETUP) << endl;
2708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddclass subclass_info_t {
2738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpublic:
2748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string unitmask;
2758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string subclass_name;
2768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd};
2778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddtypedef growable_vector<subclass_info_t> subclass_array_t;
2798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddtypedef growable_vector<subclass_array_t> event_subclass_t;
2808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddtypedef growable_vector<event_subclass_t> cpu_subclass_t;
2818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid xml_utils::build_subclasses(ostream & out)
2838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
2848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t subclasses = 0;
2858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string subclass_name;
2868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// when --separate=cpu we will have an event_subclass array for each cpu
2878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cpu_subclass_t cpu_subclasses;
2888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	event_subclass_t event_subclasses;
2908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (nr_cpus <= 1 && nr_events <= 1 && !has_nonzero_masks)
2928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return;
2938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << open_element(CLASSES);
2958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t i = 0; i < classes.v.size(); ++i) {
2968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		profile_class & pclass = classes.v[i];
2978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		size_t event = atoi(pclass.ptemplate.event.c_str());
2988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		subclass_array_t * sc_ptr;
3008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// select the right subclass array
3028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (nr_cpus == 1) {
3038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			sc_ptr = &event_subclasses[event];
3048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		} else {
3058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			size_t cpu = atoi(pclass.ptemplate.cpu.c_str());
3068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			sc_ptr = &cpu_subclasses[cpu][event];
3078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
3088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// search for an existing unitmask
3108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		subclass_name = "";
3118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		for (size_t j = 0; j < sc_ptr->size(); ++j) {
3128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			if ((*sc_ptr)[j].unitmask == pclass.ptemplate.unitmask) {
3138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				subclass_name = (*sc_ptr)[j].subclass_name;
3148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				break;
3158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			}
3168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
3178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (subclass_name.size() == 0) {
3198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			ostringstream str;
3208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			size_t new_index = sc_ptr->size();
3218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			// no match found, create a new entry
3238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			str << "c" << subclasses++;
3248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			subclass_name = str.str();
3258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			(*sc_ptr)[new_index].unitmask = pclass.ptemplate.unitmask;
3268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			(*sc_ptr)[new_index].subclass_name = subclass_name;
3278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			out << open_element(CLASS, true);
3288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			out << init_attr(NAME, subclass_name);
3298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			if (nr_cpus > 1)
3308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				out << init_attr(CPU_NUM, pclass.ptemplate.cpu);
3318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			if (nr_events > 1)
3328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				out << init_attr(EVENT_NUM, event);
3338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			if (has_nonzero_masks)
3348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				out << init_attr(EVENT_MASK, pclass.ptemplate.unitmask);
3358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			out << close_element();
3368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
3378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		pclass.name = subclass_name;
3398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
3408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << close_element(CLASSES);
3418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	has_subclasses = true;
3428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
3438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring
3468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddget_counts_string(count_array_t const & counts, size_t begin, size_t end)
3478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
3488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ostringstream str;
3498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	bool got_count = false;
3508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// if no cpu separation then return a simple count, omit zero counts
3528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (nr_cpus == 1) {
3538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		size_t count = counts[begin];
3548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (count == 0)
3558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			return "";
3568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		str << count;
3578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return str.str();
3588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
3598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t p = begin; p != end; ++p) {
3618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		size_t count = counts[p];
3628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (p != begin) str << ",";
3638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (count != 0) {
3648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			got_count = true;
3658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			str << count;
3668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
3678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
3688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return got_count ? str.str() : "";
3698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
3708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid
3738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddxml_utils::output_symbol_bytes(ostream & out, symbol_entry const * symb,
3748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			       size_t sym_id, op_bfd const & abfd)
3758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
3768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t size = symb->size;
3778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	scoped_array<unsigned char> contents(new unsigned char[size]);
3788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (abfd.get_symbol_contents(symb->sym_index, contents.get())) {
3798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		string const name = symbol_names.name(symb->name);
3808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << open_element(BYTES, true) << init_attr(TABLE_ID, sym_id);
3818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << close_element(NONE, true);
3828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		for (size_t i = 0; i < size; ++i) {
3838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			char hex_map[] = "0123456789ABCDEF";
3848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			char hex[2];
3858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			hex[0] = hex_map[(contents[i] >> 4) & 0xf];
3868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			hex[1] = hex_map[contents[i] & 0xf];
3878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			out << hex[0] << hex[1];
3888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
3898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << close_element(BYTES);
3908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
3918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
3928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbool
3958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddxml_utils::output_summary_data(ostream & out, count_array_t const & summary, size_t pclass)
3968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
3978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t const count = summary[pclass];
3988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
3998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (count == 0)
4008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return false;
4018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << open_element(COUNT, has_subclasses);
4038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (has_subclasses) {
4048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << init_attr(CLASS, classes.v[pclass].name);
4058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		out << close_element(NONE, true);
4068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
4078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << count;
4088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << close_element(COUNT);
4098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return true;
4108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
4118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddclass module_info {
4138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpublic:
4148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	module_info()
4158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		{ lo = hi = 0; name = ""; begin = end = (sym_iterator)0;}
4168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void dump();
4178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void build_module(string const & n, sym_iterator it,
4188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	                  size_t l, size_t h);
4198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string get_name() { return name; }
4208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void set_lo(size_t l) { lo = l; }
4218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void set_hi(size_t h) { hi = h; }
4228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	count_array_t const & get_summary() { return summary; }
4238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void set_begin(sym_iterator b);
4248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void set_end(sym_iterator e);
4258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void add_to_summary(count_array_t const & counts);
4268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void output(ostream & out);
4278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	bool is_closed(string const & n);
4288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddprotected:
4298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void output_summary(ostream & out);
4308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void output_symbols(ostream & out, bool is_module);
4318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string name;
4338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	sym_iterator begin;
4348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	sym_iterator end;
4358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// summary sample data
4378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	count_array_t summary;
4388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// range of profile classes approprate for this module
4408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t lo;
4418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t hi;
4428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd};
4438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddclass thread_info : public module_info {
4458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpublic:
4468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	thread_info() { nr_modules = 0; }
4478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void build_thread(string const & tid, size_t l, size_t h);
4498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	bool add_modules(string const & module, sym_iterator it);
4508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void add_module_symbol(string const & n, sym_iterator it);
4518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void summarize();
4528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void set_end(sym_iterator end);
4538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string const get_tid() { return thread_id; }
4548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void output(ostream & out);
4558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void dump();
4568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddprivate:
4578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// indices into the classes array applicable to this process
4588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t nr_modules;
4598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string thread_id;
4608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	growable_vector<module_info> my_modules;
4618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd};
4628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddclass process_info : public module_info {
4648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpublic:
4658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	process_info() { nr_threads = 0; }
4668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void build_process(string const & pid, size_t l, size_t h);
4678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void add_thread(string const & tid, size_t l, size_t h);
4688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void add_modules(string const & module,
4698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		string const & app_name, sym_iterator it);
4708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void summarize();
4718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void set_end(sym_iterator end);
4728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void output(ostream & out);
4738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void dump();
4748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddprivate:
4758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t nr_threads;
4768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string process_id;
4778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	growable_vector<thread_info> my_threads;
4788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd};
4808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddclass process_root_info {
4818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpublic:
4828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	process_root_info() { nr_processes = 0; }
4838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	process_info * add_process(string const & pid, size_t lo, size_t hi);
4848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void add_modules(string const & module, string const & app_name,
4858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		sym_iterator it);
4868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void summarize();
4878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void summarize_processes(extra_images const & extra_found_images);
4888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void set_process_end();
4898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void output_process_symbols(ostream & out);
4908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void dump_processes();
4918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddprivate:
4928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t nr_processes;
4938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	growable_vector<process_info> processes;
4958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd};
4968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
4978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddclass binary_info : public module_info {
4988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpublic:
4998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	binary_info() { nr_modules = 0; }
5008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void output(ostream & out);
5018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	binary_info * build_binary(string const & n);
5028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void add_module_symbol(string const & module, string const & app,
5038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		sym_iterator it);
5048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void close_binary(sym_iterator it);
5058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void dump();
5068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddprivate:
5078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t nr_modules;
5088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	growable_vector<module_info> my_modules;
5108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd};
5118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddclass binary_root_info {
5148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpublic:
5158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	binary_root_info() { nr_binaries = 0; }
5168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	binary_info * add_binary(string const & n, sym_iterator it);
5178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void summarize_binaries(extra_images const & extra_found_images);
5188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void output_binary_symbols(ostream & out);
5198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void dump_binaries();
5208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddprivate:
5218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t nr_binaries;
5228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	growable_vector<binary_info> binaries;
5248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd};
5258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic process_root_info processes_root;
5278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic binary_root_info binaries_root;
5288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid module_info::
5318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbuild_module(string const & n, sym_iterator it, size_t l, size_t h)
5328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
5338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	name = n;
5348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	begin = it;
5358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	lo = l;
5368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	hi = h;
5378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
5388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid module_info::add_to_summary(count_array_t const & counts)
5418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
5428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t pclass = lo ; pclass <= hi; ++pclass)
5438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		summary[pclass] += counts[pclass];
5448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
5458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid module_info::set_begin(sym_iterator b)
5488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
5498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (begin == (sym_iterator)0)
5508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		begin = b;
5518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
5528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid module_info::set_end(sym_iterator e)
5558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
5568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (end == (sym_iterator)0)
5578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		end = e;
5588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
5598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbool module_info::is_closed(string const & n)
5628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
5638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return (name == n) && end != (sym_iterator)0;
5648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
5658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid module_info::dump()
5688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
5698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cverb << vxml << "	module:class(" << lo << "," << hi << ")=";
5708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cverb << vxml << name << endl;
5718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	dump_symbols("		", begin, end);
5728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
5738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid module_info::output(ostream & out)
5768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
5778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << open_element(MODULE, true);
5788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << init_attr(NAME, name) << close_element(NONE, true);
5798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	output_summary(out);
5808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	output_symbols(out, true);
5818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << close_element(MODULE);
5828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
5838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid module_info::output_summary(ostream & out)
5868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
5878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t p = lo; p <= hi; ++p)
5888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		(void)xml_support->output_summary_data(out, summary, p);
5898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
5908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid module_info::output_symbols(ostream & out, bool is_module)
5938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
5948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (begin == (sym_iterator)0)
5958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return;
5968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
5978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (sym_iterator it = begin; it != end; ++it)
5988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		xml_out->output_symbol(out, *it, lo, hi, is_module);
5998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
6008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid binary_info::close_binary(sym_iterator it)
6038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
6048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	set_end(it);
6058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (nr_modules > 0) {
6068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		module_info & m = my_modules[nr_modules-1];
6078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		m.set_end(it);
6088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
6098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
6108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid binary_info::dump()
6138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
6148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cverb << vxml << "app_name=" << name << endl;
6158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (begin != (sym_iterator)0)
6168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		dump_symbols("	", begin, end);
6178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t i = 0; i < nr_modules; ++i)
6198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		my_modules[i].dump();
6208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
6218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid binary_info::
6248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddadd_module_symbol(string const & module, string const & app,
6258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	sym_iterator it)
6268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
6278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t m = nr_modules;
6288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (module == app) {
6308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// set begin symbol for binary if not set
6318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		set_begin(it);
6328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (m > 0) {
6348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			// close out current module
6358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			module_info & mod = my_modules[m-1];
6368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			mod.set_end(it);
6378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
6388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// add symbol count to binary count
6408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		add_to_summary((*it)->sample.counts);
6418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return;
6428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
6438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string current_module_name = (m == 0 ? "" : my_modules[m-1].get_name());
6458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (module != current_module_name) {
6468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// we have a module distinct from it's binary: --separate=lib
6478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// and this is the first symbol for this module
6488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (m != 0) {
6498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			// close out current module
6508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			module_info & mod = my_modules[m-1];
6518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			mod.set_end(it);
6528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			add_to_summary(mod.get_summary());
6538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
6548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// mark end of enclosing binary symbols if there have been any
6568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// NOTE: it is possible for the binary's symbols to follow its
6578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// module symbols
6588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (begin != (sym_iterator)0 && end == (sym_iterator)0)
6598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			set_end(it);
6608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// build the new module
6628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		nr_modules++;
6638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		my_modules[m].build_module(module, it, 0, nr_classes-1);
6648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
6658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// propagate this symbols counts to the module
6678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	my_modules[nr_modules-1].add_to_summary((*it)->sample.counts);
6688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
6698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid binary_root_info::
6728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddsummarize_binaries(extra_images const & extra_found_images)
6738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
6748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	binary_info * current_binary = 0;
6758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string current_binary_name = "";
6768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (sym_iterator it = symbols_begin ; it != symbols_end; ++it) {
6788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		string binary = get_image_name((*it)->app_name,
6798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			image_name_storage::int_filename, extra_found_images);
6808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		string module = get_image_name((*it)->image_name,
6818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			image_name_storage::int_filename, extra_found_images);
6828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (binary != current_binary_name) {
6848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			current_binary = binaries_root.add_binary(binary, it);
6858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			current_binary_name = binary;
6868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
6878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		current_binary->add_module_symbol(module, binary, it);
6898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
6908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// close out last binary and module
6928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	current_binary->close_binary(symbols_end);
6938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
6948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
6968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddprocess_info *
6978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddprocess_root_info::add_process(string const & pid, size_t lo, size_t hi)
6988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
6998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	processes[nr_processes].build_process(pid, lo, hi);
7008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return &processes[nr_processes++];
7018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
7028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid process_root_info::
7058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddadd_modules(string const & module, string const & app_name,
7068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	sym_iterator it)
7078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
7088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t p = 0; p < nr_processes; ++p)
7098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		processes[p].add_modules(module, app_name, it);
7108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
7118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid process_root_info::summarize()
7158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
7168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t p = 0; p < nr_processes; ++p)
7178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		processes[p].summarize();
7188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
7198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid process_root_info::
7228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddsummarize_processes(extra_images const & extra_found_images)
7238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
7248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// add modules to the appropriate threads in the process hierarchy
7258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (sym_iterator it = symbols_begin ; it != symbols_end; ++it) {
7268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		string binary = get_image_name((*it)->app_name,
7278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			image_name_storage::int_filename, extra_found_images);
7288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		string module = get_image_name((*it)->image_name,
7298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			image_name_storage::int_filename, extra_found_images);
7308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		processes_root.add_modules(module, binary, it);
7328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
7338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// set end symbol boundary for all modules in all threads
7358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	processes_root.set_process_end();
7368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// propagate summaries to process/thread
7388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	processes_root.summarize();
7398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
7408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid process_root_info::set_process_end()
7438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
7448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t p = 0; p < nr_processes; ++p)
7458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		processes[p].set_end(symbols_end);
7468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
7478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid process_root_info::output_process_symbols(ostream & out)
7498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
7508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t p = 0; p < nr_processes; ++p)
7518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		processes[p].output(out);
7528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
7538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid process_root_info::dump_processes()
7568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
7578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cverb << vxml << "<!-- processes_dump:" << endl;
7588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t p = 0; p < nr_processes; ++p)
7598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		processes[p].dump();
7608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cverb << vxml << "end processes_dump -->" << endl;
7618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
7628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbinary_info *
7648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbinary_info::build_binary(string const & n)
7658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
7668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	name = n;
7678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	lo = 0;
7688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	hi = nr_classes-1;
7698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return this;
7708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
7718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid binary_info::output(ostream & out)
7748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
7758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << open_element(BINARY, true);
7768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << init_attr(NAME, name) << close_element(NONE, true);
7778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	output_summary(out);
7798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	output_symbols(out, false);
7808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t a = 0; a < nr_modules; ++a)
7818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		my_modules[a].output(out);
7828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << close_element(BINARY);
7848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
7858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbinary_info *
7888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbinary_root_info::add_binary(string const & n, sym_iterator it)
7898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
7908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t a = nr_binaries++;
7918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// close out previous binary and module
7938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (a > 0) binaries[a-1].close_binary(it);
7948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return binaries[a].build_binary(n);
7958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
7968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
7988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid binary_root_info::output_binary_symbols(ostream & out)
7998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
8008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t a = 0; a < nr_binaries; ++a)
8018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		binaries[a].output(out);
8028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
8038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid binary_root_info::dump_binaries()
8068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
8078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cverb << vxml << "<!-- binaries_dump:" << endl;
8088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t p = 0; p < nr_binaries; ++p)
8098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		binaries[p].dump();
8108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cverb << vxml << "end processes_dump -->" << endl;
8118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
8128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid process_info::build_process(string const & pid, size_t l, size_t h)
8158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
8168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	process_id = pid;
8178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	lo = l;
8188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	hi = h;
8198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
8208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid process_info::add_thread(string const & tid, size_t l, size_t h)
8238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
8248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	my_threads[nr_threads++].build_thread(tid, l, h);
8258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
8268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid process_info::add_modules(string const & module,
8298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string const & app_name, sym_iterator it)
8308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
8318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	bool added = false;
8328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t t = 0; t < nr_threads; ++t)
8338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		added |= my_threads[t].add_modules(module, it);
8348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (added && name.size() == 0) name = app_name;
8358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
8368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid process_info::summarize()
8398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
8408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t t = 0; t < nr_threads; ++t) {
8418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		thread_info & thr = my_threads[t];
8428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		thr.summarize();
8438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		add_to_summary(thr.get_summary());
8448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
8458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
8468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid thread_info::build_thread(string const & tid, size_t l, size_t h)
8498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
8508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	thread_id = tid;
8518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	lo = l;
8528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	hi = h;
8538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
8548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid thread_info::summarize()
8578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
8588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t m = 0; m < nr_modules; ++m)
8598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		add_to_summary(my_modules[m].get_summary());
8608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
8618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid thread_info::set_end(sym_iterator end)
8648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
8658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t m = 0; m < nr_modules; ++m)
8668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		my_modules[m].set_end(end);
8678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
8688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid thread_info::add_module_symbol(string const & n, sym_iterator it)
8718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
8728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	module_info & m = my_modules[nr_modules++];
8738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	m.build_module(n, it, lo, hi);
8748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	m.add_to_summary((*it)->sample.counts);
8758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
8768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid thread_info::output(ostream & out)
8788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
8798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ostringstream thread_summary;
8808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ostringstream modules_output;
8818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	output_summary(thread_summary);
8838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t m = 0; m < nr_modules; ++m)
8858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		my_modules[m].output(modules_output);
8868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// ignore threads with no sample data
8888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (modules_output.str().size() == 0 && thread_summary.str().size() == 0)
8898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return;
8908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << open_element(THREAD, true);
8928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << init_attr(THREAD_ID, thread_id) << close_element(NONE, true);
8938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << thread_summary.str();
8948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << modules_output.str();
8958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << close_element(THREAD);
8968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
8978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
8998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbool thread_info::add_modules(string const & module, sym_iterator it)
9008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
9018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string old_name =
9028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		(nr_modules == 0 ? "" : my_modules[nr_modules-1].get_name());
9038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (nr_modules > 0 && old_name != module) {
9048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		module_info & m = my_modules[nr_modules-1];
9058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// close out previous module if it hasn't already been closed out
9068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (!m.is_closed(old_name))
9078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			m.set_end(it);
9088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
9098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// add a new module for this symbol if it has a non-zero count
9118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (nr_modules == 0 || module != old_name) {
9128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (has_sample_counts((*it)->sample.counts, lo, hi)) {
9138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			add_module_symbol(module, it);
9148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			return true;
9158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		}
9168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	} else {
9178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// propagate symbols count to module
9188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		my_modules[nr_modules-1].add_to_summary((*it)->sample.counts);
9198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
9208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return false;
9218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
9228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid thread_info::dump()
9258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
9268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cverb << vxml << "tid=" << thread_id << endl;
9278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t i = 0; i < nr_modules; ++i)
9288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		my_modules[i].dump();
9298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
9308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid process_info::set_end(sym_iterator end)
9338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
9348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t t = 0; t < nr_threads; ++t)
9358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		my_threads[t].set_end(end);
9368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
9378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid process_info::output(ostream & out)
9408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
9418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ostringstream process_summary;
9428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	ostringstream thread_output;
9438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	output_summary(process_summary);
9458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t t = 0; t < nr_threads; ++t)
9478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		my_threads[t].output(thread_output);
9488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// ignore processes with no sample data
9508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (thread_output.str().size() == 0 && process_summary.str().size() == 0)
9518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return;
9528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << open_element(PROCESS, true);
9548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << init_attr(PROC_ID, process_id);
9558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << init_attr(NAME, name) << close_element(NONE, true);
9568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << process_summary.str();
9578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << thread_output.str();
9588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	out << close_element(PROCESS);
9598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
9608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid process_info::dump()
9638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
9648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cverb << vxml << "pid=" << process_id << " app=" << name << endl;
9658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (size_t i = 0; i < nr_threads; ++i)
9668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		my_threads[i].dump();
9678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
9688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddsize_t get_next_tgid_pclass(size_t start)
9708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
9718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string cur_tgid = classes.v[start].ptemplate.tgid;
9728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t i = start;
9738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (i = start;
9748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		i < nr_classes && classes.v[i].ptemplate.tgid == cur_tgid;
9758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		++i) ;
9768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return i;
9778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
9788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddsize_t get_next_tid_pclass(size_t start)
9818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
9828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string cur_tid = classes.v[start].ptemplate.tid;
9838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t i;
9848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (i = start;
9858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		i < nr_classes && classes.v[i].ptemplate.tid == cur_tid;
9868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		++i) ;
9878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return i;
9888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
9898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
9918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// build the process/thread/module hierarchy that will allow us later
9928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// to collect the summary sample data at each level and then
9938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// traverse the hierarchy to intersperse the summary data for the
9948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// symbols
9958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid build_process_tree()
9968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
9978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t tgid = 0;
9988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	size_t tid = 0;
9998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
10008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// build the structure representing the process/thread/module hierarchy
10018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// for holding the summary data associated with each level and to be
10028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// traversed when outputting the body of the XML
10038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	do {
10048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		size_t next_tgid = get_next_tgid_pclass(tgid);
10058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		string const tgid_str = classes.v[tgid].ptemplate.tgid;
10068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
10078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		process_info * p = processes_root.add_process(tgid_str, tgid, next_tgid-1);
10088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
10098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		do {
10108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			size_t next_tid = get_next_tid_pclass(tid);
10118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
10128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			// build array of threads associated with this process
10138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			p->add_thread(classes.v[tid].ptemplate.tid, tid, next_tid-1);
10148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			tid = next_tid;
10158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		} while (tid != next_tgid);
10168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		tgid = next_tgid;
10178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	} while (tgid != nr_classes);
10188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
10198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
10208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid xml_utils::output_program_structure(ostream & out)
10218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
10228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
10238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (cverb << vxml)
10248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		dump_classes();
10258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
10268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (has_separated_thread_info()) {
10278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		build_process_tree();
10288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		processes_root.summarize_processes(extra_found_images);
10298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (cverb << vxml)
10308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			processes_root.dump_processes();
10318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		processes_root.output_process_symbols(out);
10328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	} else {
10338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		binaries_root.summarize_binaries(extra_found_images);
10348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (cverb << vxml)
10358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			binaries_root.dump_binaries();
10368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		binaries_root.output_binary_symbols(out);
10378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
10388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1039