• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
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 
29 class op_bfd;
30 class string_filter;
31 class extra_images;
32 
33 /// all symbol vector indexing uses this type
34 typedef 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  */
41 class op_bfd_symbol {
42 public:
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 
vma()50 	bfd_vma vma() const { return symb_value + section_vma; }
value()51 	unsigned long value() const { return symb_value; }
filepos()52 	unsigned long filepos() const { return symb_value + section_filepos; }
53 	unsigned long symbol_endpos(void) const;
section(void)54 	asection const * section(void) const { return bfd_symbol->section; }
name()55 	std::string const & name() const { return symb_name; }
symbol()56 	asymbol const * symbol() const { return bfd_symbol; }
size()57 	size_t size() const { return symb_size; }
size(size_t s)58 	void size(size_t s) { symb_size = s; }
hidden()59 	bool hidden() const { return symb_hidden; }
weak()60 	bool weak() const { return symb_weak; }
artificial()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 
66 private:
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  */
97 class op_bfd {
98 public:
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 
get_embedding_filename()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 
valid()213 	bool valid() const { return ibfd.valid(); }
214 
215 private:
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 */
306