Imported Upstream version 1.0.0
[platform/upstream/oprofile.git] / libpp / populate.cpp
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
22 #include "image_errors.h"
23 #include "utility.h"
24 #include <string.h>
25
26 #include <iostream>
27
28 using namespace std;
29
30 namespace {
31
32 /// load merged files for one set of sample files
33 bool
34 populate_from_files(profile_t & profile, op_bfd const & abfd,
35                     list<profile_sample_files> const & files)
36 {
37         list<profile_sample_files>::const_iterator it = files.begin();
38         list<profile_sample_files>::const_iterator const end = files.end();
39
40         bool found = false;
41         // we can't handle cg files here obviously
42         for (; it != end; ++it) {
43                 // A bit ugly but we must accept silently empty sample filename
44                 // since we can create a profile_sample_files for cg file only
45                 // (i.e no sample to the binary)
46                 if (!it->sample_filename.empty()) {
47                         profile.add_sample_file(it->sample_filename);
48                         profile.set_offset(abfd);
49                         found = true;
50                 }
51         }
52
53         return found;
54 }
55
56 }  // anon namespace
57
58
59 void
60 populate_for_image(profile_container & samples, inverted_profile const & ip,
61         string_filter const & symbol_filter, bool * has_debug_info)
62 {
63         op_bfd *abfd;
64
65         bool ok = ip.error == image_ok;
66
67         if (strncmp(ip.image.c_str(), KALL_SYM_FILE, strlen(ip.image.c_str())) == 0)
68                 abfd = new op_bfd(ip.image, samples.extra_found_images);
69
70         else
71                 abfd = new op_bfd(ip.image, symbol_filter,
72                                   samples.extra_found_images, ok);
73
74         if (!ok && ip.error == image_ok)
75                 ip.error = image_format_failure;
76
77         if (ip.error == image_format_failure)
78                 report_image_error(ip, false, samples.extra_found_images);
79
80         opd_header header;
81
82         bool found = false;
83         for (size_t i = 0; i < ip.groups.size(); ++i) {
84                 list<image_set>::const_iterator it
85                         = ip.groups[i].begin();
86                 list<image_set>::const_iterator const end
87                         = ip.groups[i].end();
88
89                 // we can only share a profile_t amongst each
90                 // image_set's files - this is because it->app_image
91                 // changes, and the .add() would mis-attribute
92                 // to the wrong app_image otherwise
93                 for (; it != end; ++it) {
94                         profile_t profile;
95                         if (populate_from_files(profile, *abfd, it->files)) {
96                                 header = profile.get_header();
97                                 samples.add(profile, *abfd, it->app_image, i);
98                                 found = true;
99                         }
100                 }
101         }
102
103         if (found == true && ip.error == image_ok) {
104                 image_error error;
105                 string filename =
106                         samples.extra_found_images.find_image_path(
107                                 ip.image, error, true);
108                 check_mtime(filename, header);
109         }
110
111         if (has_debug_info)
112                 *has_debug_info = abfd->has_debug_info();
113
114         delete abfd;
115 }