Ghidra Decompiler Analysis Engine
flow.hh
Go to the documentation of this file.
1 /* ###
2  * IP: GHIDRA
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
18 
19 #ifndef __CPUI_FLOW__
20 #define __CPUI_FLOW__
21 
22 #include "funcdata.hh"
23 
56 class FlowInfo {
57 public:
58  enum { ignore_outofbounds = 1,
65  baddata_present = 0x80,
70  flow_forinline = 0x2000,
71  record_jumploads = 0x4000
72  };
73 private:
75  struct VisitStat {
76  SeqNum seqnum;
77  int4 size;
78  };
79  Architecture *glb;
80  Funcdata &data;
81  PcodeOpBank &obank;
82  BlockGraph &bblocks;
83  vector<FuncCallSpecs *> &qlst;
84  PcodeEmitFd emitter;
85  vector<Address> unprocessed;
86  vector<Address> addrlist;
87  vector<PcodeOp *> tablelist;
88  vector<PcodeOp *> injectlist;
89  map<Address,VisitStat> visited;
90  list<PcodeOp *> block_edge1;
91  list<PcodeOp *> block_edge2;
92  uint4 insn_count;
93  uint4 insn_max;
94  Address baddr;
95  Address eaddr;
96  Address minaddr;
97  Address maxaddr;
98  bool flowoverride_present;
99  uint4 flags;
100  Funcdata *inline_head;
101  set<Address> *inline_recursion;
102  set<Address> inline_base;
103  bool hasPossibleUnreachable(void) const { return ((flags & possible_unreachable)!=0); }
104  void setPossibleUnreachable(void) { flags |= possible_unreachable; }
105  void clearProperties(void);
106  bool seenInstruction(const Address &addr) const {
107  return (visited.find(addr) != visited.end()); }
108  PcodeOp *fallthruOp(PcodeOp *op) const;
109  void newAddress(PcodeOp *from,const Address &to);
110  void deleteRemainingOps(list<PcodeOp *>::const_iterator oiter);
111  PcodeOp *xrefControlFlow(list<PcodeOp *>::const_iterator oiter,bool &startbasic,bool &isfallthru,FuncCallSpecs *fc);
112  bool processInstruction(const Address &curaddr,bool &startbasic);
113  void fallthru(void);
114  PcodeOp *findRelTarget(PcodeOp *op,Address &res) const;
115  void findUnprocessed(void);
116  void dedupUnprocessed(void);
117  void fillinBranchStubs(void);
118  void collectEdges(void);
119  void splitBasic(void);
120  void connectBasic(void);
121  bool setFallthruBound(Address &bound);
122  void handleOutOfBounds(const Address &fromaddr,const Address &toaddr);
123  PcodeOp *artificialHalt(const Address &addr,uint4 flag);
124  void reinterpreted(const Address &addr);
125  bool checkForFlowModification(FuncCallSpecs &fspecs);
126  void queryCall(FuncCallSpecs &fspecs);
127  bool setupCallSpecs(PcodeOp *op,FuncCallSpecs *fc);
128  bool setupCallindSpecs(PcodeOp *op,bool tryoverride,FuncCallSpecs *fc);
129  void xrefInlinedBranch(PcodeOp *op);
130  void doInjection(InjectPayload *payload,InjectContext &icontext,PcodeOp *op,FuncCallSpecs *fc);
131  void injectUserOp(PcodeOp *op);
132  bool inlineSubFunction(FuncCallSpecs *fc);
133  bool injectSubFunction(FuncCallSpecs *fc);
134  void checkContainedCall(void);
135  void checkMultistageJumptables(void);
136  void deleteCallSpec(FuncCallSpecs *fc);
137  void truncateIndirectJump(PcodeOp *op,int4 failuremode);
138  static bool isInArray(vector<PcodeOp *> &array,PcodeOp *op);
139 public:
140  FlowInfo(Funcdata &d,PcodeOpBank &o,BlockGraph &b,vector<FuncCallSpecs *> &q);
141  FlowInfo(Funcdata &d,PcodeOpBank &o,BlockGraph &b,vector<FuncCallSpecs *> &q,const FlowInfo *op2);
142  void setRange(const Address &b,const Address &e) { baddr = b; eaddr = e; }
143  void setMaximumInstructions(uint4 max) { insn_max = max; }
144  void setFlags(uint4 val) { flags |= val; }
145  void clearFlags(uint4 val) { flags &= ~val; }
146  PcodeOp *target(const Address &addr) const;
147  PcodeOp *branchTarget(PcodeOp *op) const;
148  void generateOps(void);
149  void generateBlocks(void);
150  bool testHardInlineRestrictions(Funcdata *inlinefd,PcodeOp *op,Address &retaddr);
151  bool checkEZModel(void) const;
152  void injectPcode(void);
153  void forwardRecursion(const FlowInfo &op2);
154  void inlineClone(const FlowInfo &inlineflow,const Address &retaddr);
155  void inlineEZClone(const FlowInfo &inlineflow,const Address &calladdr);
156  int4 getSize(void) const { return (int4)(maxaddr.getOffset() - minaddr.getOffset()); }
157  bool hasInject(void) const { return !injectlist.empty(); }
158  bool hasUnimplemented(void) const { return ((flags & unimplemented_present)!=0); }
159  bool hasBadData(void) const { return ((flags & baddata_present)!=0); }
160  bool hasOutOfBounds(void) const { return ((flags & outofbounds_present)!=0); }
161  bool hasReinterpreted(void) const { return ((flags & reinterpreted_present)!=0); }
162  bool hasTooManyInstructions(void) const { return ((flags & toomanyinstructions_present)!=0); }
163  bool isFlowForInline(void) const { return ((flags & flow_forinline)!=0); }
164  bool doesJumpRecord(void) const { return ((flags & record_jumploads)!=0); }
165 };
166 
167 #endif
FlowInfo::testHardInlineRestrictions
bool testHardInlineRestrictions(Funcdata *inlinefd, PcodeOp *op, Address &retaddr)
For in-lining using the hard model, make sure some restrictions are met.
Definition: flow.cc:1106
FlowInfo::error_toomanyinstructions
@ error_toomanyinstructions
Throw an exception if too many instructions are encountered.
Definition: flow.hh:63
BlockGraph
A control-flow block built out of sub-components.
Definition: block.hh:271
FlowInfo::generateBlocks
void generateBlocks(void)
Generate basic blocks from the raw control-flow.
Definition: flow.cc:797
FlowInfo::toomanyinstructions_present
@ toomanyinstructions_present
Indicate the maximum instruction threshold was reached.
Definition: flow.hh:68
FlowInfo::outofbounds_present
@ outofbounds_present
Indicate we have encountered flow out of the specified range.
Definition: flow.hh:66
FlowInfo::target
PcodeOp * target(const Address &addr) const
Return first p-code op for instruction at given address.
Definition: flow.cc:113
SeqNum
A class for uniquely labelling and comparing PcodeOps.
Definition: address.hh:111
FlowInfo::flow_forinline
@ flow_forinline
Indicate flow is being generated to in-line (a function)
Definition: flow.hh:70
PcodeOpBank
Container class for PcodeOps associated with a single function.
Definition: op.hh:253
FlowInfo::generateOps
void generateOps(void)
Generate raw control-flow from the function's base address.
Definition: flow.cc:749
FlowInfo::error_outofbounds
@ error_outofbounds
Throw an exception for flow into addresses out of the specified range.
Definition: flow.hh:60
FlowInfo::possible_unreachable
@ possible_unreachable
Indicate a CALL was converted to a BRANCH and some code may be unreachable.
Definition: flow.hh:69
PcodeEmitFd
A p-code emitter for building PcodeOp objects.
Definition: funcdata.hh:563
FlowInfo::error_unimplemented
@ error_unimplemented
Throw an exception for flow into unimplemented instructions.
Definition: flow.hh:61
FlowInfo::branchTarget
PcodeOp * branchTarget(PcodeOp *op) const
Find the target referred to by a given BRANCH or CBRANCH.
Definition: flow.cc:185
Address::getOffset
uintb getOffset(void) const
Get the address offset.
Definition: address.hh:300
FlowInfo::record_jumploads
@ record_jumploads
Indicate that any jump table recovery should record the table structure.
Definition: flow.hh:71
FlowInfo
A class for generating the control-flow structure for a single function.
Definition: flow.hh:56
FuncCallSpecs
A class for analyzing parameters to a sub-function call.
Definition: fspec.hh:1449
PcodeOp
Lowest level operation of the p-code language.
Definition: op.hh:58
Architecture
Manager for all the major decompiler subsystems.
Definition: architecture.hh:119
InjectContext
Context needed to emit a p-code injection as a full set of p-code operations.
Definition: pcodeinject.hh:56
InjectPayload
An active container for a set of p-code operations that can be injected into data-flow.
Definition: pcodeinject.hh:78
funcdata.hh
Utilities for processing data structures associated with a single function.
Address
A low-level machine address for labelling bytes and data.
Definition: address.hh:46
Funcdata
Container for data structures associated with a single function.
Definition: funcdata.hh:45
FlowInfo::reinterpreted_present
@ reinterpreted_present
Indicate we have encountered reinterpreted data.
Definition: flow.hh:67
FlowInfo::baddata_present
@ baddata_present
Indicate we have encountered flow into unaccessible data.
Definition: flow.hh:65
FlowInfo::error_reinterpreted
@ error_reinterpreted
Throw an exception for flow into previously encountered data at a difference cut.
Definition: flow.hh:62
FlowInfo::ignore_outofbounds
@ ignore_outofbounds
Ignore/truncate flow into addresses out of the specified range.
Definition: flow.hh:58
FlowInfo::injectPcode
void injectPcode(void)
Perform substitution on any op that requires injection.
Definition: flow.cc:1290
FlowInfo::ignore_unimplemented
@ ignore_unimplemented
Treat unimplemented instructions as a NOP (no operation)
Definition: flow.hh:59
FlowInfo::FlowInfo
FlowInfo(Funcdata &d, PcodeOpBank &o, BlockGraph &b, vector< FuncCallSpecs * > &q)
Constructor.
Definition: flow.cc:24
FlowInfo::inlineClone
void inlineClone(const FlowInfo &inlineflow, const Address &retaddr)
Clone the given in-line flow into this flow using the hard model.
Definition: flow.cc:1047
FlowInfo::forwardRecursion
void forwardRecursion(const FlowInfo &op2)
Pull in-lining recursion information from another flow.
Definition: flow.cc:1016
FlowInfo::checkEZModel
bool checkEZModel(void) const
Check if this flow matches the EX in-lining model.
Definition: flow.cc:1138
FlowInfo::inlineEZClone
void inlineEZClone(const FlowInfo &inlineflow, const Address &calladdr)
Clone the given in-line flow into this flow using the EZ model.
Definition: flow.cc:1081
FlowInfo::unimplemented_present
@ unimplemented_present
Indicate we have encountered unimplemented instructions.
Definition: flow.hh:64