178 /***********************************/ |
178 /***********************************/ |
179 |
179 |
180 /*| instruction_list il_instruction */ |
180 /*| instruction_list il_instruction */ |
181 // SYM_LIST(instruction_list_c) |
181 // SYM_LIST(instruction_list_c) |
182 void *flow_control_analysis_c::visit(instruction_list_c *symbol) { |
182 void *flow_control_analysis_c::visit(instruction_list_c *symbol) { |
|
183 prev_il_instruction_is_JMP_or_RET = false; |
183 for(int i = 0; i < symbol->n; i++) { |
184 for(int i = 0; i < symbol->n; i++) { |
184 prev_il_instruction = NULL; |
185 prev_il_instruction = NULL; |
185 if (i > 0) prev_il_instruction = symbol->elements[i-1]; |
186 if (i > 0) prev_il_instruction = symbol->elements[i-1]; |
186 curr_il_instruction = symbol->elements[i]; |
187 curr_il_instruction = symbol->elements[i]; |
187 curr_il_instruction->accept(*this); |
188 curr_il_instruction->accept(*this); |
192 |
193 |
193 /* | label ':' [il_incomplete_instruction] eol_list */ |
194 /* | label ':' [il_incomplete_instruction] eol_list */ |
194 // SYM_REF2(il_instruction_c, label, il_instruction) |
195 // SYM_REF2(il_instruction_c, label, il_instruction) |
195 // void *visit(instruction_list_c *symbol); |
196 // void *visit(instruction_list_c *symbol); |
196 void *flow_control_analysis_c::visit(il_instruction_c *symbol) { |
197 void *flow_control_analysis_c::visit(il_instruction_c *symbol) { |
197 if (NULL != prev_il_instruction) |
198 if ((NULL != prev_il_instruction) && (!prev_il_instruction_is_JMP_or_RET)) |
198 symbol->prev_il_instruction.push_back(prev_il_instruction); |
199 symbol->prev_il_instruction.push_back(prev_il_instruction); |
199 |
200 |
200 /* check if it is an il_expression_c, or a JMP[C[N]] and if so, handle it correctly */ |
201 /* check if it is an il_expression_c, a JMP[C[N]], or a RET, and if so, handle it correctly */ |
|
202 prev_il_instruction_is_JMP_or_RET = false; |
201 if (NULL != symbol->il_instruction) |
203 if (NULL != symbol->il_instruction) |
202 symbol->il_instruction->accept(*this); |
204 symbol->il_instruction->accept(*this); |
203 return NULL; |
205 return NULL; |
204 } |
206 } |
205 |
207 |
236 // SYM_REF2(il_jump_operation_c, il_jump_operator, label) |
238 // SYM_REF2(il_jump_operation_c, il_jump_operator, label) |
237 void *flow_control_analysis_c::visit(il_jump_operation_c *symbol) { |
239 void *flow_control_analysis_c::visit(il_jump_operation_c *symbol) { |
238 /* search for the il_instruction_c containing the label */ |
240 /* search for the il_instruction_c containing the label */ |
239 il_instruction_c *destination = search_il_label->find_label(symbol->label); |
241 il_instruction_c *destination = search_il_label->find_label(symbol->label); |
240 |
242 |
241 /* TODO: for JMP and RET (unconditional) instructions, make sure the next IL instruction does not point back! */ |
243 /* give the visit(JMP_operator *) an oportunity to set the prev_il_instruction_is_JMP_or_RET flag! */ |
|
244 symbol->il_jump_operator->accept(*this); |
242 /* add, to that il_instruction's list of prev_il_intsructions, the curr_il_instruction */ |
245 /* add, to that il_instruction's list of prev_il_intsructions, the curr_il_instruction */ |
243 if (NULL != destination) |
246 if (NULL != destination) |
244 destination->prev_il_instruction.push_back(curr_il_instruction); |
247 destination->prev_il_instruction.push_back(curr_il_instruction); |
245 return NULL; |
248 return NULL; |
246 } |
249 } |
328 // void *visit( LE_operator_c *symbol); |
331 // void *visit( LE_operator_c *symbol); |
329 // void *visit( NE_operator_c *symbol); |
332 // void *visit( NE_operator_c *symbol); |
330 // void *visit( CAL_operator_c *symbol); |
333 // void *visit( CAL_operator_c *symbol); |
331 // void *visit( CALC_operator_c *symbol); |
334 // void *visit( CALC_operator_c *symbol); |
332 // void *visit(CALCN_operator_c *symbol); |
335 // void *visit(CALCN_operator_c *symbol); |
333 // void *visit( RET_operator_c *symbol); |
336 |
|
337 /* this next visit function will be called directly from visit(il_instruction_c *) */ |
|
338 void *flow_control_analysis_c::visit( RET_operator_c *symbol) { |
|
339 prev_il_instruction_is_JMP_or_RET = true; |
|
340 return NULL; |
|
341 } |
|
342 |
334 // void *visit( RETC_operator_c *symbol); |
343 // void *visit( RETC_operator_c *symbol); |
335 // void *visit(RETCN_operator_c *symbol); |
344 // void *visit(RETCN_operator_c *symbol); |
336 // void *visit( JMP_operator_c *symbol); |
345 |
|
346 /* this next visit function will be called from visit(il_jump_operation_c *) */ |
|
347 void *flow_control_analysis_c::visit( JMP_operator_c *symbol) { |
|
348 prev_il_instruction_is_JMP_or_RET = true; |
|
349 return NULL; |
|
350 } |
|
351 |
337 // void *visit( JMPC_operator_c *symbol); |
352 // void *visit( JMPC_operator_c *symbol); |
338 // void *visit(JMPCN_operator_c *symbol); |
353 // void *visit(JMPCN_operator_c *symbol); |
339 |
354 |
340 /* Symbol class handled together with function call checks */ |
355 /* Symbol class handled together with function call checks */ |
341 // void *visit(il_assign_operator_c *symbol, variable_name); |
356 // void *visit(il_assign_operator_c *symbol, variable_name); |