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