blob: 0f4606b9eb29e927148164ce2222424f7b095397 [file] [log] [blame]
Mike Dodd8cfa7022010-11-17 11:12:26 -08001/**
2 * @file libpp/populate_for_spu.cpp
3 * Fill up a profile_container from inverted profiles for
4 * a Cell BE SPU profile
5 *
6 * @remark Copyright 2007 OProfile authors
7 * @remark Read the file COPYING
8 *
9 * @author Maynard Johnson
10 * (C) Copyright IBM Corporation 2007
11 */
12
13#include "profile.h"
14#include "profile_container.h"
15#include "arrange_profiles.h"
16#include "op_bfd.h"
17#include "op_header.h"
18#include "populate.h"
19#include "populate_for_spu.h"
20
21#include "image_errors.h"
22
23#include <iostream>
24
25using namespace std;
26
27namespace {
28
29static int spu_profile = unknown_profile;
30
31/*
32 * On Cell Broadband Engine, an application executing on an SPE may
33 * have been loaded from a separate SPU executable binary file or may
34 * have been loaded from an embedded section of a PPE application or
35 * shared library. In the embedded case, the embedding file may actually
36 * contain multiple SPU images, resulting in different SPU images being loaded
37 * onto different SPUs. Thus, the SPUs may be executing different code, even
38 * though the application of the parent PPE process is the same. Therefore,
39 * we must be sure to create a separate op_bfd object for each SPU. When doing
40 * so below, we examine header.embedded_offset. If embedded_offset is > 0, it's
41 * interpreted as the offset of an SPU image embedded in the containing file,
42 * so the filename to do the check_mtime on is the containing file, ip.image;
43 * otherwise, the filename to do the check_mtime on is the separate backing
44 * file of the SPU image, abfd->filename.
45 */
46void
47populate_spu_profile_from_files(list<profile_sample_files> const & files,
48 string const app_image,
49 profile_container & samples,
50 inverted_profile const & ip,
51 string_filter const & symbol_filter,
52 size_t ip_grp_num, bool * has_debug_info)
53{
54 string archive_path = samples.extra_found_images.get_archive_path();
55 bool ok = ip.error == image_ok;
56 op_bfd * abfd = NULL;
57 string fname_to_check;
58 list<profile_sample_files>::const_iterator it = files.begin();
59 list<profile_sample_files>::const_iterator const end = files.end();
60 for (; it != end; ++it) {
61 profile_t profile;
62 if (it->sample_filename.empty())
63 continue;
64
65 profile.add_sample_file(it->sample_filename);
66 opd_header header = profile.get_header();
67 if (header.embedded_offset) {
68 abfd = new op_bfd(header.embedded_offset,
69 ip.image,
70 symbol_filter,
71 samples.extra_found_images,
72 ok);
73 fname_to_check = ip.image;
74 } else {
75 abfd = new op_bfd(ip.image,
76 symbol_filter,
77 samples.extra_found_images,
78 ok);
79 fname_to_check = abfd->get_filename();
80 }
81 profile.set_offset(*abfd);
82 if (!ok && ip.error == image_ok)
83 ip.error = image_format_failure;
84
85 if (ip.error == image_format_failure)
86 report_image_error(ip, false,
87 samples.extra_found_images);
88
89 samples.add(profile, *abfd, app_image, ip_grp_num);
90 if (ip.error == image_ok) {
91 image_error error;
92 string filename =
93 samples.extra_found_images.find_image_path(
94 fname_to_check, error, true);
95 check_mtime(filename, profile.get_header());
96 }
97
98 if (has_debug_info && !*has_debug_info)
99 *has_debug_info = abfd->has_debug_info();
100 delete abfd;
101 }
102}
103} // anon namespace
104
105void
106populate_for_spu_image(profile_container & samples,
107 inverted_profile const & ip,
108 string_filter const & symbol_filter,
109 bool * has_debug_info)
110{
111
112 for (size_t i = 0; i < ip.groups.size(); ++i) {
113 list < image_set >::const_iterator it=
114 ip.groups[i].begin();
115 list < image_set >::const_iterator const end
116 = ip.groups[i].end();
117
118 for (; it != end; ++it)
119 populate_spu_profile_from_files(it->files,
120 it->app_image, samples, ip,
121 symbol_filter, i, has_debug_info);
122 }
123}
124
125bool is_spu_profile(inverted_profile const & ip)
126{
127 bool retval = false;
128 string sfname = "";
129 if (spu_profile != unknown_profile)
130 return spu_profile;
131
132 if (!ip.groups.size())
133 return false;
134
135 for (size_t i = 0; i < ip.groups.size(); ++i) {
136 list<image_set>::const_iterator grp_it
137 = ip.groups[i].begin();
138 list<image_set>::const_iterator const grp_end
139 = ip.groups[i].end();
140
141 for (; grp_it != grp_end; ++grp_it) {
142 list<profile_sample_files>::const_iterator sfiles_it =
143 grp_it->files.begin();
144 list<profile_sample_files>::const_iterator sfiles_end =
145 grp_it->files.end();
146 for (; sfiles_it != sfiles_end; ++sfiles_it) {
147 if (!sfiles_it->sample_filename.empty()) {
148 sfname = sfiles_it->sample_filename;
149 goto do_check;
150 }
151 }
152 }
153 }
154 goto out;
155
156do_check:
157 spu_profile = profile_t::is_spu_sample_file(sfname);
158
159 if (spu_profile == cell_spu_profile)
160 retval = true;
161
162out:
163 return retval;
164}
165
166