1/**
2 * @file bfd_support.h
3 * BFD muck we have to deal with.
4 *
5 * @remark Copyright 2005 OProfile authors
6 * @remark Read the file COPYING
7 *
8 * @author John Levon
9 */
10
11#ifndef BFD_SUPPORT_H
12#define BFD_SUPPORT_H
13
14#include "utility.h"
15#include "op_types.h"
16#include "locate_images.h"
17
18#include <bfd.h>
19#include <stdint.h>
20
21#include <string>
22
23class op_bfd_symbol;
24
25/// holder for BFD state we must keep
26struct bfd_info {
27	bfd_info() : abfd(0), nr_syms(0), synth_syms(0), image_bfd_info(0) {}
28
29	~bfd_info();
30
31	/// close the BFD, setting abfd to NULL
32	void close();
33
34	/// return true if BFD is readable
35	bool valid() const { return abfd; }
36
37	/// return true if BFD has debug info
38	bool has_debug_info() const;
39
40	/// pick out the symbols from the bfd, if we can
41	void get_symbols();
42
43	/// the actual BFD
44	bfd * abfd;
45	/// normal symbols (includes synthesized symbols)
46	scoped_array<asymbol *> syms;
47	/// nr. symbols
48	size_t nr_syms;
49
50	void set_image_bfd_info(bfd_info * ibfd) { image_bfd_info = ibfd; }
51
52private:
53	/**
54	 * Acquire the synthetic symbols if we need to.
55	 */
56	bool get_synth_symbols();
57
58	/**
59	 * On PPC64, synth_syms points to an array of synthetic asymbol
60	 * structs returned from bfd_get_synthetic_symtab.  The syms
61	 * member points into this array, so we have to keep it around
62	 * until ~bfd_info time.
63	 */
64	asymbol * synth_syms;
65
66	/**
67	 * Under certain circumstances, correct handling of the bfd for a
68	 * debuginfo file is not possible without access to the bfd for
69	 * the actual image file.  The image_bfd_info field provides access to
70	 * that bfd when this bfd_info is for a debuginfo file; otherwise
71	 * image_bfd_info is NULL.
72	 */
73	bfd_info * image_bfd_info;
74
75	/* To address a different issue, we discard symbols whose section
76	 * flag does not contain SEC_LOAD.  But since this is true for symbols
77	 * found in debuginfo files, we must run those debuginfo symbols
78	 * through the function below to prevent them from being inadvertently
79	 * discarded.  This function maps the sections from the symbols in
80	 * the debuginfo bfd to those of the real image bfd.  Then, when
81	 * we later do symbol filtering, we see the sections from the real
82	 * bfd, which do contain SEC_LOAD in the section flag.
83	 */
84	void translate_debuginfo_syms(asymbol ** dbg_syms, long nr_dbg_syms);
85
86};
87
88
89/*
90 * find_separate_debug_file - return true if a valid separate debug file found
91 * @param ibfd binary file
92 * @param dir_in directory holding the binary file
93 * @param global_in
94 * @param filename path to valid debug file
95 *
96 * Search order for debug file and use first one found:
97 * 1) dir_in directory
98 * 2) dir_in/.debug directory
99 * 3) global_in/dir_in directory
100 *
101 * Newer binutils and Linux distributions (e.g. Fedora) allow the
102 * creation of debug files that are separate from the binary. The
103 * debugging information is stripped out of the binary file, placed in
104 * this separate file, and a link to the new file is placed in the
105 * binary. The debug files hold the information needed by the debugger
106 * (and OProfile) to map machine instructions back to source code.
107 */
108extern bool
109find_separate_debug_file(bfd * ibfd,
110                         std::string const & filepath_in,
111                         std::string & debug_filename,
112                         extra_images const & extra);
113
114/// open the given BFD
115bfd * open_bfd(std::string const & file);
116
117/// open the given BFD from the fd
118bfd * fdopen_bfd(std::string const & file, int fd);
119
120/// Return a BFD for an SPU ELF embedded in PPE binary file
121bfd * spu_open_bfd(std::string const name, int fd, uint64_t offset_to_spu_elf);
122
123/// Return true if the symbol is worth looking at
124bool interesting_symbol(asymbol * sym);
125
126/**
127 * return true if the first symbol is less interesting than the second symbol
128 * boring symbol are eliminated when multiple symbol exist at the same vma
129 */
130bool boring_symbol(op_bfd_symbol const & first, op_bfd_symbol const & second);
131
132/// debug info for a given pc
133struct linenr_info {
134	/// did we find something?
135	bool found;
136	/// filename
137	std::string filename;
138	/// line number
139	unsigned int line;
140};
141
142/**
143 * Attempt to locate a filename + line number for the given symbol and
144 * offset.
145 *
146 * The bfd object is either the object associated with the binary or the
147 * once associated with the separated debug info file so find_nearest_line()
148 * can't lookup the section contents of code section etc. The filepos of
149 * debuginfo symbols are different from the original file but we fixed symbol
150 * filepos earlier.
151 */
152linenr_info const
153find_nearest_line(bfd_info const & ibfd, op_bfd_symbol const & sym,
154                  bfd_vma offset, bool anon_obj);
155
156#endif /* !BFD_SUPPORT_H */
157