Imported Upstream version 1.0.0
[platform/upstream/oprofile.git] / libutil++ / op_bfd.h
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
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
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 the /proc/kallsyms file is used
115          * to get the kernel symbols.
116          */
117         op_bfd(std::string const & filename,
118                extra_images const & extra_images);
119
120         /// close an opened bfd image and free all related resources
121         ~op_bfd();
122
123         /**
124          * @param sym_idx index of the symbol
125          * @param offset fentry number
126          * @param filename output parameter to store filename
127          * @param linenr output parameter to store linenr.
128          *
129          * Retrieve the relevant finename:linenr information for the sym_idx
130          * at offset. If the lookup fails, return false. In some cases this
131          * function can retrieve the filename and return true but fail to
132          * retrieve the linenr and so can return zero in linenr
133          */
134         bool get_linenr(symbol_index_t sym_idx, bfd_vma offset,
135                         std::string & filename, unsigned int & linenr) const;
136
137         /**
138          * @param sym_idx symbol index
139          * @param start reference to start var
140          * @param end reference to end var
141          *
142          * Calculates the range of sample file entries covered by sym. start
143          * and end will be filled in appropriately. If index is the last entry
144          * in symbol table, all entries up to the end of the sample file will
145          * be used.  After calculating start and end they are sanitized
146          *
147          * All errors are fatal.
148          */
149         void get_symbol_range(symbol_index_t sym_idx,
150                               unsigned long long & start, unsigned long long & end) const;
151
152         /**
153          * @param start reference to the start vma
154          * @param end reference to the end vma
155          *
156          * return in start, end the vma range for this binary object.
157          */
158         void get_vma_range(bfd_vma & start, bfd_vma & end) const;
159
160         /** return the relocated PC value for the given file offset */
161         bfd_vma offset_to_pc(bfd_vma offset) const;
162
163         /**
164          * If passed 0, return the file position of the .text section.
165          * Otherwise, return the filepos of a section with a matching
166          * vma.
167          */
168         unsigned long get_start_offset(bfd_vma vma = 0) const;
169  
170         /**
171          * Return the image name of the underlying binary image. For an
172          * archive, this returns the path *within* the archive, not the
173          * full path of the file.
174          */
175         std::string get_filename() const;
176
177         /// sorted vector by vma of interesting symbol.
178         std::vector<op_bfd_symbol> syms;
179
180         /// return in bits the bfd_vma size for this binary. This is needed
181         /// because gprof output depend on the bfd_vma for *this* binary
182         /// and do not depend on sizeof(bfd_vma)
183         size_t bfd_arch_bits_per_address() const;
184
185         /// return true if binary contain some debug information
186         bool has_debug_info() const;
187
188         /**
189          * @param sym_idx symbol index
190          *
191          * Return true or false, indicating whether or not the
192          * symbol referenced by the passed sym_idx has code available.
193          * Some symbols have no code associated with them; for example,
194          * artificial symbols created for anonymous memory samples or for
195          * stripped binaries with no symbol debug info.  Additionally,
196          * if the bfd object associated with the symbol is not valid,
197          * this function will also return false.
198          *
199          * NOTE:  This call should be made prior to invoking
200          *        get_symbol_contents to avoid unnecessarily allocating
201          *        memory for the symbol contents.
202          */
203         bool symbol_has_contents(symbol_index_t sym_idx);
204
205         bool get_symbol_contents(symbol_index_t sym_index,
206                 unsigned char * contents) const;
207
208         bool valid() const { return ibfd.valid(); }
209
210         bfd_vma get_vma_adj(void) const { return vma_adj; }
211
212 private:
213         /// temporary container type for getting symbols
214         typedef std::list<op_bfd_symbol> symbols_found_t;
215
216         /**
217          * Parse and sort in ascending order all symbols
218          * in the file pointed to by abfd that reside in
219          * a %SEC_CODE section.
220          *
221          * The symbols are filtered through
222          * the interesting_symbol() predicate and sorted
223          * with op_bfd_symbol::operator<() comparator.
224          */
225         void get_symbols(symbols_found_t & symbols);
226
227         /* functions for reading kallsyms */
228         void get_kallsym_symbols(symbols_found_t & symbols, std::ifstream& infile);
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         bool anon_obj;
296
297         /**
298          * If a runtime binary is prelinked, then its p_vaddr field in the
299          * first PT_LOAD segment will give the address where the binary will
300          * be loaded into memory.  However, the corresponding debuginfo file
301          * may have a different p_vaddr value.  In profile_container::add_samples,
302          * this difference is handled by adding the "base_vma" to the sample
303          * vma.  However, if the runtime binary has no symbol information at all,
304          * then the "base_vma" is obtained from the debuginfo symbol information.
305          * For opreport, this works OK, since under such conditions, ALL symbol
306          * and debug data is then obtained from the debuginfo files, and the sample
307          * vma's should match up fine with the symbol vma's in the debuginfo file.
308          * But when doing 'opannoate --assembly', the real (runtime) image is used for
309          * annotation, and, thus, we may have a mis-match between real image p_vaddr
310          * and the impliled p_vaddr stored with the samples.  To handle this case,
311          * we do the following:  When a bfd_info is created for a debuginfo
312          * file, we set vma_adj to the difference between runtime load address
313          * and the p_vaddr of the first PT_LOAD segment of the debuginfo file, if and
314          * only if the real image has no symbol info; otherwise vma_adj is set to 0.
315          */
316         bfd_vma vma_adj;
317
318         /**
319          * The file descriptor for an image file that we pass to fdopen_bfd must be kept
320          * open through the life of the op_bfd to enable proper behavior of certain
321          * BFD functions -- in particular, bfd_find_nearest_line().
322          */
323         int fd;
324
325 };
326
327
328 #endif /* !OP_BFD_H */