Remove incorrect export declaration
[dyninst.git] / parseAPI / h / CodeSource.h
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  * 
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  * 
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30 #ifndef _CODE_SOURCE_H_
31 #define _CODE_SOURCE_H_
32
33 #include <map>
34 #include <vector>
35 #include <utility>
36 #include <string>
37
38 #include "Symtab.h"
39 #include "IBSTree.h"
40 #include "dyntypes.h"
41
42 #include "InstructionSource.h"
43
44 class StatContainer;
45
46 namespace Dyninst {
47 namespace ParseAPI {
48
49 class CFGModifier;
50
51 /** A CodeSource is a very simple contract that allows a
52     CodeObject to get the information it needs to pull code
53     from some binary source
54 **/
55
56
57 class PARSER_EXPORT CodeRegion : public Dyninst::InstructionSource, public Dyninst::interval<Address> {
58  public:
59
60     /* Fills a vector with any names associated with the function at at 
61        a given address in this code sources, e.g. symbol names in the
62        case of a SymtabCodeSource.
63
64        Optional
65     */
66     virtual void names(Address, vector<std::string> &) { return; }
67
68     /* Finds the exception handler block for a given address
69        in the region.
70
71        Optional
72     */
73     virtual bool findCatchBlock(Address /* addr */, Address & /* catchStart */) 
74     { return false; }
75
76     /** interval implementation **/
77     Address low() const =0;
78     Address high() const =0;
79
80     bool contains(Address) const;
81
82     virtual bool wasUserAdded() const { return false; }
83
84 };
85
86 /* A starting point for parsing */
87 struct Hint {
88     Hint() : _addr(0), _reg(NULL), _name("") { }
89     Hint(Address a, CodeRegion * r, std::string s) :
90         _addr(a), _reg(r), _name(s) { }
91
92     Address _addr;
93     CodeRegion * _reg;
94     std::string _name;
95 };
96
97 class PARSER_EXPORT CodeSource : public Dyninst::InstructionSource {
98    friend class CFGModifier;
99  private:
100     bool _regions_overlap;
101     
102  protected:
103     /*
104      * Implementers of CodeSource can fill the following
105      * structures with available information. Some 
106      * of this information is optional.
107      */
108
109     /*
110      * Named external linkage table (e.g. PLT on ELF). Optional.
111      */
112     mutable std::map<Address, std::string> _linkage;
113
114     /*
115      * Table of Contents for position independent references. Optional.
116      */
117     Address _table_of_contents;
118
119     /*
120      * Code regions in the binary. At least one region is
121      * required for parsing.
122      */
123     std::vector<CodeRegion *> _regions;
124
125     /*
126      * Code region lookup. Must be consistent with
127      * the _regions vector. Mandatory.
128      */
129     Dyninst::IBSTree<CodeRegion> _region_tree;
130
131     /*
132      * Hints for where to begin parsing. Required for
133      * the default parsing mode, but usage of one of
134      * the direct parsing modes (parsing particular
135      * locations or using speculative methods) is supported
136      * without hints.
137      */
138     std::vector<Hint> _hints;
139     
140
141  public:
142     /* Returns true if the function at an address is known to be
143        non returning (e.g., is named `exit' on Linux/ELF, etc.).
144
145        Optional.
146     */
147     virtual bool nonReturning(Address /*func_entry*/) { return false; }
148     virtual bool nonReturning(std::string /* func_name */) { return false; }
149
150     /*
151      * If the binary file type supplies non-zero base
152      * or load addresses (e.g. Windows PE), override.
153      */
154     virtual Address baseAddress() const { return 0; }
155     virtual Address loadAddress() const { return 0; }
156
157     std::map< Address, std::string > & linkage() const { return _linkage; }
158     std::vector< Hint > const& hints() const { return _hints; } 
159     std::vector<CodeRegion *> const& regions() const { return _regions; }
160     int findRegions(Address addr, set<CodeRegion *> & ret) const;
161     bool regionsOverlap() const { return _regions_overlap; }
162
163     Address getTOC() const { return _table_of_contents; }
164     /* If the binary file type supplies per-function
165      * TOC's (e.g. ppc64 Linux), override.
166      */
167     virtual Address getTOC(Address) const { return _table_of_contents; }
168
169     // statistics accessor
170     virtual void print_stats() const { return; }
171     virtual bool have_stats() const { return false; }
172
173     // manage statistics
174     virtual void incrementCounter(std::string /*name*/) const { return; } 
175     virtual void addCounter(std::string /*name*/, int /*num*/) const { return; }
176     virtual void decrementCounter(std::string /*name*/) const { return; }
177     
178  protected:
179     CodeSource() : _regions_overlap(false),
180                    _table_of_contents(0) {}
181     virtual ~CodeSource() {}
182
183     void addRegion(CodeRegion *);
184    
185  private: 
186     // statistics
187     virtual bool init_stats() { return false; }
188
189 };
190
191 /** SymtabCodeRegion and SymtabCodeSource implement CodeSource for program
192     binaries supported by the SymtabAPI 
193 **/
194
195 class PARSER_EXPORT SymtabCodeRegion : public CodeRegion {
196  private:
197     SymtabAPI::Symtab * _symtab;
198     SymtabAPI::Region * _region;
199  public:
200     SymtabCodeRegion(SymtabAPI::Symtab *, SymtabAPI::Region *);
201     ~SymtabCodeRegion();
202
203     void names(Address, vector<std::string> &);
204     bool findCatchBlock(Address addr, Address & catchStart);
205
206     /** InstructionSource implementation **/
207     bool isValidAddress(const Address) const;
208     void* getPtrToInstruction(const Address) const;
209     void* getPtrToData(const Address) const;
210     unsigned int getAddressWidth() const;
211     bool isCode(const Address) const;
212     bool isData(const Address) const;
213     Address offset() const;
214     Address length() const;
215     Architecture getArch() const;
216
217     /** interval **/
218     Address low() const { return offset(); }
219     Address high() const { return offset() + length(); }
220
221     SymtabAPI::Region * symRegion() const { return _region; }
222 };
223
224 class PARSER_EXPORT SymtabCodeSource : public CodeSource {
225  private:
226     SymtabAPI::Symtab * _symtab;
227     bool owns_symtab;
228     mutable CodeRegion * _lookup_cache;
229
230     static dyn_hash_map<std::string, bool> non_returning_funcs;
231     
232     // Stats information
233     StatContainer * stats_parse;
234     bool _have_stats;
235     
236  public:
237     struct hint_filt {
238         virtual ~hint_filt() { }
239         virtual bool operator()(SymtabAPI::Function * f) =0;
240     };
241
242     SymtabCodeSource(SymtabAPI::Symtab *, 
243                                    hint_filt *, 
244                                    bool allLoadedRegions=false);
245     SymtabCodeSource(SymtabAPI::Symtab *);
246     SymtabCodeSource(char *);
247
248     ~SymtabCodeSource();
249
250     bool nonReturning(Address func_entry);
251     bool nonReturning(std::string func_name);
252
253     bool resizeRegion(SymtabAPI::Region *, Address newDiskSize);
254
255     Address baseAddress() const;
256     Address loadAddress() const;
257     Address getTOC(Address addr) const;
258     SymtabAPI::Symtab * getSymtabObject() {return _symtab;} 
259
260     /** InstructionSource implementation **/
261     bool isValidAddress(const Address) const;
262     void* getPtrToInstruction(const Address) const;
263     void* getPtrToData(const Address) const;
264     unsigned int getAddressWidth() const;
265     bool isCode(const Address) const;
266     bool isData(const Address) const;
267     Address offset() const;
268     Address length() const;
269     Architecture getArch() const;
270
271     void removeHint(Hint);
272
273     static void addNonReturning(std::string func_name);
274     
275     // statistics accessor
276     void print_stats() const;
277     bool have_stats() const { return _have_stats; }
278
279     // manage statistics
280     void incrementCounter(std::string name) const;
281     void addCounter(std::string name, int num) const; 
282     void decrementCounter(std::string name) const;
283
284  private:
285     void init(hint_filt *, bool);
286     void init_regions(hint_filt *, bool);
287     void init_hints(dyn_hash_map<void*, CodeRegion*> &, hint_filt*);
288     void init_linkage();
289
290     CodeRegion * lookup_region(const Address addr) const;
291     void removeRegion(CodeRegion &); // removes from region tree
292
293     void overlapping_warn(const char * file, unsigned line) const;
294     
295     // statistics
296     bool init_stats();
297  
298 };
299
300 inline bool CodeRegion::contains(const Address addr) const
301 {
302     return addr >= offset() && addr < (offset() + length());
303 }
304
305 }
306 }
307
308 #endif