3 * Encapsulation of bfd objects
5 * @remark Copyright 2002 OProfile authors
6 * @remark Read the file COPYING
8 * @author Philippe Elie
23 #include "bfd_support.h"
24 #include "locate_images.h"
26 #include "cached_value.h"
33 /// all symbol vector indexing uses this type
34 typedef size_t symbol_index_t;
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
44 /// ctor for real symbols
45 op_bfd_symbol(asymbol const * a);
47 /// ctor for artificial symbols
48 op_bfd_symbol(bfd_vma vma, size_t size, std::string const & name);
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; }
63 /// compare two symbols by their filepos()
64 bool operator<(op_bfd_symbol const & lhs) const;
67 /// the original bfd symbol, this can be null if the symbol is an
69 asymbol const * bfd_symbol;
70 /// the offset of this symbol relative to the begin of the section's
72 unsigned long symb_value;
73 /// the section filepos for this symbol
74 unsigned long section_filepos;
75 /// the section vma for this symbol
77 /// the size of this symbol
79 /// the name of the symbol
80 std::string symb_name;
81 /// normally not externally visible symbol
83 /// whether other symbols can override it
85 /// symbol is artificially created
87 /// code bytes corresponding to symbol -- used for XML generation
88 std::string symb_bytes;
92 * Encapsulation of a bfd object. Simplifies open/close of bfd, enumerating
93 * symbols and retrieving informations for symbols or vma.
95 * Use of this class relies on a std::ostream cverb
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
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.
108 op_bfd(std::string const & filename,
109 string_filter const & symbol_filter,
110 extra_images const & extra_images,
114 * This constructor is used when the /proc/kallsyms file is used
115 * to get the kernel symbols.
117 op_bfd(std::string const & filename,
118 extra_images const & extra_images);
120 /// close an opened bfd image and free all related resources
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.
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
134 bool get_linenr(symbol_index_t sym_idx, bfd_vma offset,
135 std::string & filename, unsigned int & linenr) const;
138 * @param sym_idx symbol index
139 * @param start reference to start var
140 * @param end reference to end var
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
147 * All errors are fatal.
149 void get_symbol_range(symbol_index_t sym_idx,
150 unsigned long long & start, unsigned long long & end) const;
153 * @param start reference to the start vma
154 * @param end reference to the end vma
156 * return in start, end the vma range for this binary object.
158 void get_vma_range(bfd_vma & start, bfd_vma & end) const;
160 /** return the relocated PC value for the given file offset */
161 bfd_vma offset_to_pc(bfd_vma offset) const;
164 * If passed 0, return the file position of the .text section.
165 * Otherwise, return the filepos of a section with a matching
168 unsigned long get_start_offset(bfd_vma vma = 0) const;
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.
175 std::string get_filename() const;
177 /// sorted vector by vma of interesting symbol.
178 std::vector<op_bfd_symbol> syms;
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;
185 /// return true if binary contain some debug information
186 bool has_debug_info() const;
189 * @param sym_idx symbol index
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.
199 * NOTE: This call should be made prior to invoking
200 * get_symbol_contents to avoid unnecessarily allocating
201 * memory for the symbol contents.
203 bool symbol_has_contents(symbol_index_t sym_idx);
205 bool get_symbol_contents(symbol_index_t sym_index,
206 unsigned char * contents) const;
208 bool valid() const { return ibfd.valid(); }
210 bfd_vma get_vma_adj(void) const { return vma_adj; }
213 /// temporary container type for getting symbols
214 typedef std::list<op_bfd_symbol> symbols_found_t;
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.
221 * The symbols are filtered through
222 * the interesting_symbol() predicate and sorted
223 * with op_bfd_symbol::operator<() comparator.
225 void get_symbols(symbols_found_t & symbols);
227 /* functions for reading kallsyms */
228 void get_kallsym_symbols(symbols_found_t & symbols, std::ifstream& infile);
231 * Helper function for get_symbols.
232 * Populates bfd_syms and extracts the "interesting_symbol"s.
234 void get_symbols_from_file(bfd_info & bfd, size_t start,
235 op_bfd::symbols_found_t & symbols,
239 * Add the symbols in the binary, applying filtering,
240 * and handling artificial symbols.
242 void add_symbols(symbols_found_t & symbols,
243 string_filter const & symbol_filter);
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
250 size_t symbol_size(op_bfd_symbol const & sym,
251 op_bfd_symbol const * next) const;
253 /// create an artificial symbol for a symbolless binary
254 op_bfd_symbol const create_artificial_symbol();
256 /* Generate symbols using bfd functions for
257 * the image file associated with the ibfd arg.
259 uint process_symtab(bfd_info * bfd, uint start);
261 /// filename we open (not including archive path)
262 std::string filename;
265 std::string archive_path;
267 /// reference to extra_images
268 extra_images const & extra_found_images;
270 /// file size in bytes
273 /// corresponding debug file name
274 mutable std::string debug_filename;
276 /// true if at least one section has (flags & SEC_DEBUGGING) != 0
277 mutable cached_value<bool> debug_info;
279 /// our main bfd object: .bfd may be NULL
282 // corresponding debug bfd object, if one is found
283 mutable bfd_info dbfd;
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;
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;
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.
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().
328 #endif /* !OP_BFD_H */