populate.cpp revision cc2ee177dbb3befca43e36cfc56778b006c3d050
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
12#include "profile.h"
13#include "profile_container.h"
14#include "arrange_profiles.h"
15#include "op_bfd.h"
16#include "op_header.h"
17#include "populate.h"
18
19#include "image_errors.h"
20
21#include <iostream>
22
23using namespace std;
24
25namespace {
26
27/// load merged files for one set of sample files
28bool
29populate_from_files(profile_t & profile, op_bfd const & abfd,
30                    list<profile_sample_files> const & files)
31{
32	list<profile_sample_files>::const_iterator it = files.begin();
33	list<profile_sample_files>::const_iterator const end = files.end();
34
35	bool found = false;
36	// we can't handle cg files here obviously
37	for (; it != end; ++it) {
38		// A bit ugly but we must accept silently empty sample filename
39		// since we can create a profile_sample_files for cg file only
40		// (i.e no sample to the binary)
41		if (!it->sample_filename.empty()) {
42			profile.add_sample_file(it->sample_filename);
43			profile.set_offset(abfd);
44			found = true;
45		}
46	}
47
48	return found;
49}
50
51}  // anon namespace
52
53
54void
55populate_for_image(string const & archive_path, profile_container & samples,
56   inverted_profile const & ip, string_filter const & symbol_filter,
57   bool * has_debug_info)
58{
59	bool ok = ip.error == image_ok;
60
61	op_bfd abfd(archive_path, ip.image, symbol_filter, ok);
62	if (!ok && ip.error == image_ok)
63		ip.error = image_format_failure;
64
65	if (ip.error == image_format_failure)
66		report_image_error(ip, false);
67
68	opd_header header;
69
70	bool found = false;
71	for (size_t i = 0; i < ip.groups.size(); ++i) {
72		list<image_set>::const_iterator it
73			= ip.groups[i].begin();
74		list<image_set>::const_iterator const end
75			= ip.groups[i].end();
76
77		// we can only share a profile_t amongst each
78		// image_set's files - this is because it->app_image
79		// changes, and the .add() would mis-attribute
80		// to the wrong app_image otherwise
81		for (; it != end; ++it) {
82			profile_t profile;
83			if (populate_from_files(profile, abfd, it->files)) {
84				header = profile.get_header();
85				samples.add(profile, abfd, it->app_image, i);
86				found = true;
87			}
88		}
89	}
90
91	// we shouldn't check/warn if an archive is used
92	if (archive_path.empty() && found == true && ip.error == image_ok)
93		check_mtime(abfd.get_filename(), header);
94
95	if (has_debug_info)
96		*has_debug_info = abfd.has_debug_info();
97}
98