op_bfd.h revision cc2ee177dbb3befca43e36cfc56778b006c3d050
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
22#include "bfd_support.h"
23#include "utility.h"
24#include "cached_value.h"
25#include "op_types.h"
26
27class op_bfd;
28class string_filter;
29
30/// all symbol vector indexing uses this type
31typedef size_t symbol_index_t;
32
33/**
34 * A symbol description from a bfd point of view. This duplicate
35 * information pointed by an asymbol, we need this duplication in case
36 * the symbol is an artificial symbol
37 */
38class op_bfd_symbol {
39public:
40
41	/// ctor for real symbols
42	op_bfd_symbol(asymbol const * a);
43
44	/// ctor for artificial symbols
45	op_bfd_symbol(bfd_vma vma, size_t size, std::string const & name);
46
47	bfd_vma vma() const { return symb_value + section_vma; }
48	unsigned long value() const { return symb_value; }
49	unsigned long filepos() const { return symb_value + section_filepos; }
50	std::string const & name() const { return symb_name; }
51	asymbol const * symbol() const { return bfd_symbol; }
52	size_t size() const { return symb_size; }
53	void size(size_t s) { symb_size = s; }
54	bool hidden() const { return symb_hidden; }
55	bool weak() const { return symb_weak; }
56
57	/// compare two symbols by their filepos()
58	bool operator<(op_bfd_symbol const & lhs) const;
59
60private:
61	/// the original bfd symbol, this can be null if the symbol is an
62	/// artificial symbol
63	asymbol const * bfd_symbol;
64	/// the offset of this symbol relative to the begin of the section's
65	/// symbol
66	unsigned long symb_value;
67	/// the section filepos for this symbol
68	unsigned long section_filepos;
69	/// the section vma for this symbol
70	bfd_vma section_vma;
71	/// the size of this symbol
72	size_t symb_size;
73	/// the name of the symbol
74	std::string symb_name;
75	/// normally not externally visible symbol
76	bool symb_hidden;
77	/// whether other symbols can override it
78	bool symb_weak;
79};
80
81/**
82 * Encapsulation of a bfd object. Simplifies open/close of bfd, enumerating
83 * symbols and retrieving informations for symbols or vma.
84 *
85 * Use of this class relies on a std::ostream cverb
86 */
87class op_bfd {
88public:
89	/**
90	 * @param archive_path oparchive prefix path
91	 * @param filename  the name of the image file
92	 * @param symbol_filter  filter to apply to symbols
93	 * @param ok in-out parameter: on in, if not set, don't
94	 * open the bfd (because it's not there or whatever). On out,
95	 * it's set to false if the bfd couldn't be loaded.
96	 */
97	op_bfd(std::string const & archive_path,
98	       std::string const & filename,
99	       string_filter const & symbol_filter,
100	       bool & ok);
101
102	/// close an opened bfd image and free all related resources
103	~op_bfd();
104
105	/**
106	 * @param sym_idx index of the symbol
107	 * @param offset fentry number
108	 * @param filename output parameter to store filename
109	 * @param linenr output parameter to store linenr.
110	 *
111	 * Retrieve the relevant finename:linenr information for the sym_idx
112	 * at offset. If the lookup fails, return false. In some cases this
113	 * function can retrieve the filename and return true but fail to
114	 * retrieve the linenr and so can return zero in linenr
115	 */
116	bool get_linenr(symbol_index_t sym_idx, unsigned int offset,
117			std::string & filename, unsigned int & linenr) const;
118
119	/**
120	 * @param sym_idx symbol index
121	 * @param start reference to start var
122	 * @param end reference to end var
123	 *
124	 * Calculates the range of sample file entries covered by sym. start
125	 * and end will be filled in appropriately. If index is the last entry
126	 * in symbol table, all entries up to the end of the sample file will
127	 * be used.  After calculating start and end they are sanitized
128	 *
129	 * All errors are fatal.
130	 */
131	void get_symbol_range(symbol_index_t sym_idx,
132			      unsigned long & start, unsigned long & end) const;
133
134	/**
135	 * sym_offset - return offset from a symbol's start
136	 * @param num_symbols symbol number
137	 * @param num number of fentry
138	 *
139	 * Returns the offset of a sample at position num
140	 * in the samples file from the start of symbol sym_idx.
141	 */
142	unsigned long sym_offset(symbol_index_t num_symbols, u32 num) const;
143
144	/**
145	 * @param start reference to the start vma
146	 * @param end reference to the end vma
147	 *
148	 * return in start, end the vma range for this binary object.
149	 */
150	void get_vma_range(bfd_vma & start, bfd_vma & end) const;
151
152	/** return the relocated PC value for the given file offset */
153	bfd_vma offset_to_pc(bfd_vma offset) const;
154
155	/**
156	 * If passed 0, return the file position of the .text section.
157	 * Otherwise, return the filepos of a section with a matching
158	 * vma.
159	 */
160	unsigned long const get_start_offset(bfd_vma vma = 0) const;
161
162	/**
163	 * Return the image name of the underlying binary image. For an
164	 * archive, this returns the path *within* the archive, not the
165	 * full path of the file.
166	 */
167	std::string get_filename() const;
168
169	/// sorted vector by vma of interesting symbol.
170	std::vector<op_bfd_symbol> syms;
171
172	/// return in bits the bfd_vma size for this binary. This is needed
173	/// because gprof output depend on the bfd_vma for *this* binary
174	/// and do not depend on sizeof(bfd_vma)
175	size_t bfd_arch_bits_per_address() const;
176
177	/// return true if binary contain some debug information
178	bool has_debug_info() const;
179
180private:
181	/// temporary container type for getting symbols
182	typedef std::list<op_bfd_symbol> symbols_found_t;
183
184	/**
185	 * Parse and sort in ascending order all symbols
186	 * in the file pointed to by abfd that reside in
187	 * a %SEC_CODE section.
188	 *
189	 * The symbols are filtered through
190	 * the interesting_symbol() predicate and sorted
191	 * with op_bfd_symbol::operator<() comparator.
192	 */
193	void get_symbols(symbols_found_t & symbols);
194
195	/**
196	 * Helper function for get_symbols.
197	 * Populates bfd_syms and extracts the "interesting_symbol"s.
198	 */
199	void get_symbols_from_file(bfd_info & bfd, size_t start,
200				   op_bfd::symbols_found_t & symbols,
201				   bool debug_file);
202
203	/**
204	 * Add the symbols in the binary, applying filtering,
205	 * and handling artificial symbols.
206	 */
207	void add_symbols(symbols_found_t & symbols,
208	                 string_filter const & symbol_filter);
209
210	/**
211	 * symbol_size - return the size of a symbol
212	 * @param sym  symbol to get size
213	 * @param next  next symbol in vma order if any
214	 */
215	size_t symbol_size(op_bfd_symbol const & sym,
216			   op_bfd_symbol const * next) const;
217
218	/// create an artificial symbol for a symbolless binary
219	op_bfd_symbol const create_artificial_symbol();
220
221        /* Generate symbols using bfd functions for
222	 * the image file associated with the ibfd arg.
223	 */
224	uint process_symtab(bfd_info * bfd, uint start);
225
226	/// filename we open (not including archive path)
227	std::string filename;
228
229	/// path to archive
230	std::string archive_path;
231
232	/// file size in bytes
233	off_t file_size;
234
235	/// corresponding debug file name
236	mutable std::string debug_filename;
237
238	/// true if at least one section has (flags & SEC_DEBUGGING) != 0
239	mutable cached_value<bool> debug_info;
240
241	/// our main bfd object: .bfd may be NULL
242	bfd_info ibfd;
243
244	// corresponding debug bfd object, if one is found
245	mutable bfd_info dbfd;
246
247	typedef std::map<std::string, u32> filepos_map_t;
248	// mapping of section names to filepos in the original binary
249	filepos_map_t filepos_map;
250};
251
252
253#endif /* !OP_BFD_H */
254