blob: ff5022c733deb06e0e17710251fc46e3a700c91a [file] [log] [blame]
Mike Dodd8cfa7022010-11-17 11:12:26 -08001/**
2 * @file op_bfd.h
3 * Encapsulation of bfd objects
4 *
5 * @remark Copyright 2002 OProfile authors
6 * @remark Read the file COPYING
7 *
8 * @author Philippe Elie
9 * @author John Levon
10 */
11
12#ifndef OP_BFD_H
13#define OP_BFD_H
14
15#include "config.h"
16
17#include <vector>
18#include <string>
19#include <list>
20#include <map>
21#include <set>
22
23#include "bfd_support.h"
24#include "locate_images.h"
25#include "utility.h"
26#include "cached_value.h"
27#include "op_types.h"
28
29class op_bfd;
30class string_filter;
31class extra_images;
32
33/// all symbol vector indexing uses this type
34typedef size_t symbol_index_t;
35
36/**
37 * A symbol description from a bfd point of view. This duplicate
38 * information pointed by an asymbol, we need this duplication in case
39 * the symbol is an artificial symbol
40 */
41class op_bfd_symbol {
42public:
43
44 /// ctor for real symbols
45 op_bfd_symbol(asymbol const * a);
46
47 /// ctor for artificial symbols
48 op_bfd_symbol(bfd_vma vma, size_t size, std::string const & name);
49
50 bfd_vma vma() const { return symb_value + section_vma; }
51 unsigned long value() const { return symb_value; }
52 unsigned long filepos() const { return symb_value + section_filepos; }
53 unsigned long symbol_endpos(void) const;
54 asection const * section(void) const { return bfd_symbol->section; }
55 std::string const & name() const { return symb_name; }
56 asymbol const * symbol() const { return bfd_symbol; }
57 size_t size() const { return symb_size; }
58 void size(size_t s) { symb_size = s; }
59 bool hidden() const { return symb_hidden; }
60 bool weak() const { return symb_weak; }
61 bool artificial() const { return symb_artificial; }
62
63 /// compare two symbols by their filepos()
64 bool operator<(op_bfd_symbol const & lhs) const;
65
66private:
67 /// the original bfd symbol, this can be null if the symbol is an
68 /// artificial symbol
69 asymbol const * bfd_symbol;
70 /// the offset of this symbol relative to the begin of the section's
71 /// symbol
72 unsigned long symb_value;
73 /// the section filepos for this symbol
74 unsigned long section_filepos;
75 /// the section vma for this symbol
76 bfd_vma section_vma;
77 /// the size of this symbol
78 size_t symb_size;
79 /// the name of the symbol
80 std::string symb_name;
81 /// normally not externally visible symbol
82 bool symb_hidden;
83 /// whether other symbols can override it
84 bool symb_weak;
85 /// symbol is artificially created
86 bool symb_artificial;
87 /// code bytes corresponding to symbol -- used for XML generation
88 std::string symb_bytes;
89};
90
91/**
92 * Encapsulation of a bfd object. Simplifies open/close of bfd, enumerating
93 * symbols and retrieving informations for symbols or vma.
94 *
95 * Use of this class relies on a std::ostream cverb
96 */
97class op_bfd {
98public:
99 /**
100 * @param filename the name of the image file
101 * @param symbol_filter filter to apply to symbols
102 * @param extra_images container where all extra candidate filenames
103 * are stored
104 * @param ok in-out parameter: on in, if not set, don't
105 * open the bfd (because it's not there or whatever). On out,
106 * it's set to false if the bfd couldn't be loaded.
107 */
108 op_bfd(std::string const & filename,
109 string_filter const & symbol_filter,
110 extra_images const & extra_images,
111 bool & ok);
112
113 /**
114 * This constructor is used when processing an SPU profile
115 * where the SPU ELF is embedded within the PPE binary.
116 */
117 op_bfd(uint64_t spu_offset,
118 std::string const & filename,
119 string_filter const & symbol_filter,
120 extra_images const & extra_images,
121 bool & ok);
122
123 std::string get_embedding_filename() const { return embedding_filename; }
124
125 /// close an opened bfd image and free all related resources
126 ~op_bfd();
127
128 /**
129 * @param sym_idx index of the symbol
130 * @param offset fentry number
131 * @param filename output parameter to store filename
132 * @param linenr output parameter to store linenr.
133 *
134 * Retrieve the relevant finename:linenr information for the sym_idx
135 * at offset. If the lookup fails, return false. In some cases this
136 * function can retrieve the filename and return true but fail to
137 * retrieve the linenr and so can return zero in linenr
138 */
139 bool get_linenr(symbol_index_t sym_idx, bfd_vma offset,
140 std::string & filename, unsigned int & linenr) const;
141
142 /**
143 * @param sym_idx symbol index
144 * @param start reference to start var
145 * @param end reference to end var
146 *
147 * Calculates the range of sample file entries covered by sym. start
148 * and end will be filled in appropriately. If index is the last entry
149 * in symbol table, all entries up to the end of the sample file will
150 * be used. After calculating start and end they are sanitized
151 *
152 * All errors are fatal.
153 */
154 void get_symbol_range(symbol_index_t sym_idx,
155 unsigned long long & start, unsigned long long & end) const;
156
157 /**
158 * @param start reference to the start vma
159 * @param end reference to the end vma
160 *
161 * return in start, end the vma range for this binary object.
162 */
163 void get_vma_range(bfd_vma & start, bfd_vma & end) const;
164
165 /** return the relocated PC value for the given file offset */
166 bfd_vma offset_to_pc(bfd_vma offset) const;
167
168 /**
169 * If passed 0, return the file position of the .text section.
170 * Otherwise, return the filepos of a section with a matching
171 * vma.
172 */
173 unsigned long get_start_offset(bfd_vma vma = 0) const;
174
175 /**
176 * Return the image name of the underlying binary image. For an
177 * archive, this returns the path *within* the archive, not the
178 * full path of the file.
179 */
180 std::string get_filename() const;
181
182 /// sorted vector by vma of interesting symbol.
183 std::vector<op_bfd_symbol> syms;
184
185 /// return in bits the bfd_vma size for this binary. This is needed
186 /// because gprof output depend on the bfd_vma for *this* binary
187 /// and do not depend on sizeof(bfd_vma)
188 size_t bfd_arch_bits_per_address() const;
189
190 /// return true if binary contain some debug information
191 bool has_debug_info() const;
192
193 /**
194 * @param sym_idx symbol index
195 *
196 * Return true or false, indicating whether or not the
197 * symbol referenced by the passed sym_idx has code available.
198 * Some symbols have no code associated with them; for example,
199 * artificial symbols created for anonymous memory samples or for
200 * stripped binaries with no symbol debug info. Additionally,
201 * if the bfd object associated with the symbol is not valid,
202 * this function will also return false.
203 *
204 * NOTE: This call should be made prior to invoking
205 * get_symbol_contents to avoid unnecessarily allocating
206 * memory for the symbol contents.
207 */
208 bool symbol_has_contents(symbol_index_t sym_idx);
209
210 bool get_symbol_contents(symbol_index_t sym_index,
211 unsigned char * contents) const;
212
213 bool valid() const { return ibfd.valid(); }
214
215private:
216 /// temporary container type for getting symbols
217 typedef std::list<op_bfd_symbol> symbols_found_t;
218
219 /**
220 * Parse and sort in ascending order all symbols
221 * in the file pointed to by abfd that reside in
222 * a %SEC_CODE section.
223 *
224 * The symbols are filtered through
225 * the interesting_symbol() predicate and sorted
226 * with op_bfd_symbol::operator<() comparator.
227 */
228 void get_symbols(symbols_found_t & symbols);
229
230 /**
231 * Helper function for get_symbols.
232 * Populates bfd_syms and extracts the "interesting_symbol"s.
233 */
234 void get_symbols_from_file(bfd_info & bfd, size_t start,
235 op_bfd::symbols_found_t & symbols,
236 bool debug_file);
237
238 /**
239 * Add the symbols in the binary, applying filtering,
240 * and handling artificial symbols.
241 */
242 void add_symbols(symbols_found_t & symbols,
243 string_filter const & symbol_filter);
244
245 /**
246 * symbol_size - return the size of a symbol
247 * @param sym symbol to get size
248 * @param next next symbol in vma order if any
249 */
250 size_t symbol_size(op_bfd_symbol const & sym,
251 op_bfd_symbol const * next) const;
252
253 /// create an artificial symbol for a symbolless binary
254 op_bfd_symbol const create_artificial_symbol();
255
256 /* Generate symbols using bfd functions for
257 * the image file associated with the ibfd arg.
258 */
259 uint process_symtab(bfd_info * bfd, uint start);
260
261 /// filename we open (not including archive path)
262 std::string filename;
263
264 /// path to archive
265 std::string archive_path;
266
267 /// reference to extra_images
268 extra_images const & extra_found_images;
269
270 /// file size in bytes
271 off_t file_size;
272
273 /// corresponding debug file name
274 mutable std::string debug_filename;
275
276 /// true if at least one section has (flags & SEC_DEBUGGING) != 0
277 mutable cached_value<bool> debug_info;
278
279 /// our main bfd object: .bfd may be NULL
280 bfd_info ibfd;
281
282 // corresponding debug bfd object, if one is found
283 mutable bfd_info dbfd;
284
285 /// sections we will avoid to use symbol from, this is needed
286 /// because elf file allows sections with identical vma and we can't
287 /// allow overlapping symbols. Such elf layout is used actually by
288 /// kernel modules where all code section vma are set to 0.
289 std::vector<asection const *> filtered_section;
290
291 typedef std::map<std::string, u32> filepos_map_t;
292 // mapping of section names to filepos in the original binary
293 filepos_map_t filepos_map;
294
295 /**
296 * If spu_offset is non-zero, embedding_filename is the file containing
297 * the embedded SPU image.
298 */
299 std::string embedding_filename;
300
301 bool anon_obj;
302};
303
304
305#endif /* !OP_BFD_H */