Fixes for non-returning functions and tail calls:
[dyninst.git] / parseAPI / h / InstructionAdapter.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
31 #if !defined(INSTRUCTION_ADAPTER_H)
32 #define INSTRUCTION_ADAPTER_H
33
34 #include "dyntypes.h"
35
36 #include "CodeObject.h"
37 #include "CFG.h"
38
39 #include "Instruction.h"
40
41 #if !defined(ESSENTIAL_PARSING_ENUMS)
42 #define ESSENTIAL_PARSING_ENUMS
43 // There are three levels of function-level "instrumentability":
44 // 1) The function can be instrumented normally with no problems (normal case)
45 // 2) The function contains unresolved indirect branches; we have to assume
46 //    these can go anywhere in the function to be safe, so we must instrument
47 //    safely (e.g., with traps)
48 // 3) The function is flatly uninstrumentable and must not be touched.
49 enum InstrumentableLevel {
50     NORMAL,
51     HAS_BR_INDIR,
52     UNINSTRUMENTABLE
53 };
54 #endif //!defined(ESSENTIAL_PARSING_ENUMS)
55
56 namespace Dyninst {
57 namespace InsnAdapter {
58
59 class InstructionAdapter
60 {
61     public:
62         InstructionAdapter(Address start, ParseAPI::CodeObject *o , 
63             ParseAPI::CodeRegion* r, InstructionSource * isrc,  ParseAPI::Block *);
64         virtual ~InstructionAdapter();
65
66     // Reset to just-constructed state
67     void reset(Address start, ParseAPI::CodeObject *o,
68         ParseAPI::CodeRegion *r, InstructionSource *isrc, ParseAPI::Block *);
69
70     // Implemented
71     virtual InstructionAPI::Instruction::Ptr getInstruction() const = 0;
72     virtual bool hasCFT() const = 0;
73     virtual size_t getSize() const = 0;
74     virtual bool isFrameSetupInsn() const = 0;
75     virtual bool isInvalidInsn() const = 0;
76     virtual bool isAbort() const = 0;
77     virtual bool isGarbageInsn() const = 0; //true for insns indicative of bad parse, for defensive mode
78     virtual void
79             getNewEdges(std::vector<std::pair<Address,ParseAPI::EdgeTypeEnum> >&
80             outEdges, 
81             ParseAPI::Function* context,
82             ParseAPI::Block* currBlk,
83             unsigned int num_insns,
84             dyn_hash_map<Address, std::string> *pltFuncs,
85             const std::set<Address> &) const =
86 0;
87     virtual bool isDynamicCall() const = 0;
88     virtual bool isAbsoluteCall() const = 0;
89     virtual InstrumentableLevel getInstLevel(ParseAPI::Function* context, unsigned int num_insns) const;
90     virtual ParseAPI::FuncReturnStatus getReturnStatus(ParseAPI::Function* context, unsigned int num_insns) const ;
91     virtual bool hasUnresolvedControlFlow(ParseAPI::Function* context, unsigned int num_insns)
92 const;
93     virtual bool isNopJump() const { return false; }
94     virtual bool simulateJump() const= 0;
95     virtual void advance() = 0;
96     virtual bool retreat() = 0;
97     virtual bool isNop() const = 0;
98     virtual bool isLeave() const = 0;
99     virtual bool isDelaySlot() const = 0;
100     virtual bool isRelocatable(InstrumentableLevel lvl) const = 0;
101     virtual Address getAddr() const;
102     virtual Address getPrevAddr() const;
103     virtual Address getNextAddr() const;
104     virtual std::pair<bool, Address>  getCFT() const = 0;
105     virtual bool isStackFramePreamble() const = 0;
106     virtual bool savesFP() const = 0;
107     virtual bool cleansStack() const = 0;
108     virtual bool isConditional() const = 0;
109     virtual bool isBranch() const = 0;
110     virtual bool isInterruptOrSyscall() const = 0;
111     virtual bool isCall() const = 0;
112     virtual bool isReturnAddrSave(Address &ret_addr) const = 0; // ret_addr holds the return address pushed in the stack using mflr at function entry 
113     virtual bool isTailCall(ParseAPI::Function *, ParseAPI::EdgeTypeEnum type, unsigned int num_insns, const std::set<Address>&) const = 0;
114     protected:
115         // Uses pattern heuristics or backward slicing to determine if a blr instruction is a return or jump table
116         virtual bool isReturn(Dyninst::ParseAPI::Function * context, Dyninst::ParseAPI::Block* currBlk) const = 0;
117         virtual bool isRealCall() const = 0;
118         Address current;
119     Address previous;
120     mutable bool parsedJumpTable;
121     mutable bool successfullyParsedJumpTable;
122     mutable bool isDynamicCall_;
123     mutable bool checkedDynamicCall_;
124     mutable bool isInvalidCallTarget_;
125     mutable bool checkedInvalidCallTarget_;
126     ParseAPI::CodeObject * _obj;
127     ParseAPI::CodeRegion * _cr;
128     InstructionSource * _isrc;
129     // Block associated with the instruction adapter. This is required for powerpc slicing to determine the return address of a function
130     ParseAPI::Block * _curBlk;
131 };
132
133 } // Dyninst
134 } // InsnAdapter
135
136 #endif // !defined(INSTRUCTION_ADAPTER_H)