1/**
2 * @file populate.cpp
3 * Fill up a profile_container from inverted profiles
4 *
5 * @remark Copyright 2003 OProfile authors
6 * @remark Read the file COPYING
7 *
8 * @author John Levon
9 * @author Philippe Elie
10 *
11 * Modified by Maynard Johnson <maynardj@us.ibm.com>
12 * (C) Copyright IBM Corporation 2007
13 */
14
15#include "profile.h"
16#include "profile_container.h"
17#include "arrange_profiles.h"
18#include "op_bfd.h"
19#include "op_header.h"
20#include "populate.h"
21#include "populate_for_spu.h"
22
23#include "image_errors.h"
24
25#include <iostream>
26
27using namespace std;
28
29namespace {
30
31/// load merged files for one set of sample files
32bool
33populate_from_files(profile_t & profile, op_bfd const & abfd,
34                    list<profile_sample_files> const & files)
35{
36	list<profile_sample_files>::const_iterator it = files.begin();
37	list<profile_sample_files>::const_iterator const end = files.end();
38
39	bool found = false;
40	// we can't handle cg files here obviously
41	for (; it != end; ++it) {
42		// A bit ugly but we must accept silently empty sample filename
43		// since we can create a profile_sample_files for cg file only
44		// (i.e no sample to the binary)
45		if (!it->sample_filename.empty()) {
46			profile.add_sample_file(it->sample_filename);
47			profile.set_offset(abfd);
48			found = true;
49		}
50	}
51
52	return found;
53}
54
55}  // anon namespace
56
57
58void
59populate_for_image(profile_container & samples, inverted_profile const & ip,
60	string_filter const & symbol_filter, bool * has_debug_info)
61{
62	if (is_spu_profile(ip)) {
63		populate_for_spu_image(samples, ip, symbol_filter,
64				       has_debug_info);
65		return;
66	}
67
68	bool ok = ip.error == image_ok;
69	op_bfd abfd(ip.image, symbol_filter,
70		    samples.extra_found_images, ok);
71	if (!ok && ip.error == image_ok)
72		ip.error = image_format_failure;
73
74	if (ip.error == image_format_failure)
75		report_image_error(ip, false, samples.extra_found_images);
76
77	opd_header header;
78
79	bool found = false;
80	for (size_t i = 0; i < ip.groups.size(); ++i) {
81		list<image_set>::const_iterator it
82			= ip.groups[i].begin();
83		list<image_set>::const_iterator const end
84			= ip.groups[i].end();
85
86		// we can only share a profile_t amongst each
87		// image_set's files - this is because it->app_image
88		// changes, and the .add() would mis-attribute
89		// to the wrong app_image otherwise
90		for (; it != end; ++it) {
91			profile_t profile;
92			if (populate_from_files(profile, abfd, it->files)) {
93				header = profile.get_header();
94				samples.add(profile, abfd, it->app_image, i);
95				found = true;
96			}
97		}
98	}
99
100	if (found == true && ip.error == image_ok) {
101		image_error error;
102		string filename =
103			samples.extra_found_images.find_image_path(
104				ip.image, error, true);
105		check_mtime(filename, header);
106	}
107
108	if (has_debug_info)
109		*has_debug_info = abfd.has_debug_info();
110}
111