📄 complexinstr.cpp
字号:
// Copyright(C) 1999-2005 LiuTaoTao,bookaa@rorsoft.com
#include "stdafx.h"
// ComplexInstr.cpp
#include "CISC.H"
bool g_f_Step_by_Step = false;
bool g_any1_return_TRUE = false;
bool Step_by_Step();
const char finger_for[] = "0_jmp1_from2_0_from1_0_jxx3_0_jmp2_from3_";
const char finger_long_if [] = "0_jxx1_jmp2_from1_0_from2_";
const char finger_if [] = "0_jxx1_0_from1_";
const char finger_if_else[] = "0_jxx1_0_jmp2_from1_0_from2_";
const char finger_while[] = "from1_0_jxx2_0_jmp1_from2_";
const char finger_dowhile[] = "from1_0_jxx1_";
const char finger_dowhile_2[] = "from1_0_jxx1_from2_";
// 如果其中有break,就会出现这种情况,我暂时还找不出更好的办法
// for(1;3;2)
// {
// 4
// }
int CInstrList_Finger::search_and_add(DWORD* buf,DWORD val,int* pn)
{//static function
int n = *pn;
for (int i=0;i<n;i++)
{
if (buf[i] == val)
return i+1;
}
buf[n] = val;
*pn = n+1;
return n+1;
}
bool CInstrList_Finger::finger_compare(PSTR f1,const char* f2)
{//static function
for (;;)
{
if (*f1 == *f2)
{
if (*f1 == 0)
return true;
f1++;
f2++;
continue;
}
if (*f2 == '0' && f2[1] == '_')
{
f2 += 2;
continue;
}
return false;
}
}
bool CInstrList::if_Ly_In(PINSTR p, POSITION firstpos, POSITION endpos)
{ // 如果last是label,那也算数
INSTR_LIST* list = m_list;
assert(endpos);
POSITION pos = firstpos;
while (pos)
{
PINSTR pinstr = list->GetNext(pos);
if (pinstr == p)
return true;
if (pos == endpos)
{
if (p->type != i_Label)
return false;
pinstr = list->GetNext(pos);
if (p == pinstr)
return true;
return false;
}
}
return false;
}
bool CInstrList::ifOneStatement(PINSTR pNode, POSITION firstpos, POSITION endpos)
{ // do not include 'end'
// 如果first是label,允许其它人call
// 如果last是label,允许其它人call
INSTR_LIST* list = this->m_list;
assert(firstpos);
assert(endpos);
bool ffirst = true;
POSITION pos = firstpos;
while (pos && pos != endpos)
{
PINSTR p = list->GetNext(pos);
if (ffirst && p->type == i_Label)
{
if (pos == endpos)
return false; // 只有一条label,还来凑数
ffirst = false;
continue;
}
ffirst = false;
if (p->type == i_Label)
{ // make sure all ref of this label ly in
PINSTR pr = p->label.ref_instr;
while (pr)
{ // check all ref list
if (! if_Ly_In(pr, firstpos, endpos) )
return false;
pr = pr->jmp.next_ref_of_this_label;
}
}
if (p->type == i_Jump)
{ // make sure it jmp inside
if (p->jmp.jmp_type == JMP_jmp)
{
//if (p->jmp.the_label != pNode->begin.m_conti)
// alert("why?");
if (p->jmp.the_label == pNode->begin.m_break)
continue;
if (p->jmp.the_label == pNode->begin.m_conti
&& p != pNode->begin.m_not_conti)
continue;
}
if (! if_Ly_In(p->jmp.the_label, firstpos, endpos) )
return false;
}
}
if (pos == endpos)
return true;
return false;
}
PINSTR instr_next(INSTR_LIST* list,PINSTR p)
{
POSITION pos = list->Find(p);
if (pos == NULL)
return NULL;
list->GetNext(pos);
if (pos == NULL)
return NULL;
return list->GetAt(pos);
}
PINSTR instr_prev(INSTR_LIST* list, PINSTR p)
{
POSITION pos = list->Find(p);
if (pos == NULL)
return NULL;
list->GetPrev(pos);
if (pos == NULL)
return NULL;
return list->GetAt(pos);
}
void CInstrList_Finger::prt_partern(PINSTR phead,PSTR partern_buf)
{
INSTR_LIST* list = this->m_list;
if (phead->type != i_CplxBegin)
return;
PINSTR p = instr_next(list,phead);
int t = 0;
DWORD buf[20];
int n = 0;
while (p != NULL && p != phead->begin.m_end)
{
if (p->type == i_Jump)
{
int i = search_and_add(buf,(DWORD)p->jmp.the_label,&n);
if (p->jmp.jmp_type == JMP_jmp)
{
t += sprintf(partern_buf+t,"jmp%d_",i);
}
else
t += sprintf(partern_buf+t,"jxx%d_",i);
}
else if (p->type == i_Label)
{
int i = search_and_add(buf,(DWORD)p,&n);
t += sprintf(partern_buf+t,"from%d_",i);
}
else if (p->type == i_Begin)
{
t += sprintf(partern_buf+t,"0_");
p = p->begin.m_end;
}
else
;//why here
p = instr_next(list,p);
if (t > 120)
{
t += sprintf(partern_buf+t,"...");
t; // avoid warning
break;
}
}
}
bool CInstrList_Finger::Finger_check_partern_for1(PINSTR p)
{
CFunc_InstrList instrl(this->m_list);
#if 0
int i = 0; //p1
do
{
i++; //p3
}
while (i < 100); //p2
#endif
INSTR_LIST* list = this->m_list;
PINSTR p1 = instr_prev(list,p);
if (p1->var_r1.type != v_Immed)
return false;
if (p1->var_r2.type != v_Invalid)
return false; //这两个条件的意思是,只接收前面是i=n的才算
PINSTR p2;
{
PINSTR ptem = instr_next(list,p);
if (ptem->type != i_Label)
return false;
p2 = ptem->label.ref_instr;
}
if (p1 == NULL || p2 == NULL)
return false;
if (VAR::IsSame(&p1->var_w, &p2->var_r1)
|| VAR::IsSame(&p1->var_w, &p2->var_r2))
{
}
else
return false;
{
list->RemoveAt(list->Find(p1));
POSITION pos = list->Find(p); // insert after i_CplxBegin
PINSTR begin = new INSTR;
PINSTR end = new INSTR;
begin->type = i_Begin;
end->type = i_End;
begin->begin.m_end = end;
list->InsertAfter(pos,end);
list->InsertAfter(pos,p1);
list->InsertAfter(pos,begin);
}
{
//p2是条件跳,它前面应该是i_end
PINSTR pend = instrl.instr_prev_in_func(p2);
assert(pend->type == i_End);
PINSTR begin = new INSTR;
PINSTR end = new INSTR;
begin->type = i_Begin;
end->type = i_End;
begin->begin.m_end = end;
list->InsertAfter(list->Find(pend), end);
list->InsertAfter(list->Find(pend), begin);
for (;;)
{
PINSTR p3 = instrl.instr_prev_in_func(pend);
if (p3->type != i_Add && p3->type != i_Sub)
break;
list->RemoveAt(list->Find(p3));
list->InsertAfter(list->Find(begin), p3);
}
}
return true;
}
bool CInstrList_Finger::Finger_check_partern(PINSTR p)
// 检查 p 的partern
{
INSTR_LIST* list = this->m_list;
char buf[140];
this->prt_partern(p,buf);
if (finger_compare(buf, finger_if))
p->begin.type = COMP_if;
else if (finger_compare(buf, finger_long_if)) // 一定要放在if_else前
p->begin.type = COMP_long_if;
else if (finger_compare(buf, finger_if_else))
p->begin.type = COMP_if_else;
else if (finger_compare(buf, finger_while))
p->begin.type = COMP_while;
else if (finger_compare(buf, finger_dowhile))
{
p->begin.type = COMP_do_while;
//特殊的do-while最好写为for
if (this->Finger_check_partern_for1(p))
{
log_prtl("find for1");
p->begin.type = COMP_for1;
}
}
else if (finger_compare(buf, finger_dowhile_2))
p->begin.type = COMP_do_while;
else if (finger_compare(buf, finger_for))
{ //const char finger_for[] = "0_jmp1_from2_0_from1_0_jxx3_0_jmp2_from3_";
p->begin.type = COMP_for;
// 下面,让我们对 for 作一些调整
PINSTR p1 = instr_next(list,p); // p1指向 label
assert(p1->type == i_Jump);
p1 = instr_next(list,p1->jmp.the_label); //p1指向条件
if (p1->type == i_Jump
&& p1->jmp.jmp_type != JMP_jmp
&& p1->var_r1.type != 0)
{
VAR* pvar = &p1->var_r1;
PINSTR p2 = instr_prev(list,p);
if (VAR::IsSame(&p2->var_w,pvar))
{
list->RemoveAt(list->Find(p2));
POSITION pos = list->Find(p); // insert after i_CplxBegin
PINSTR begin = new INSTR;
PINSTR end = new INSTR;
begin->type = i_Begin;
end->type = i_End;
begin->begin.m_end = end;
list->InsertAfter(pos,end);
list->InsertAfter(pos,p2);
list->InsertAfter(pos,begin);
}
}
}
else
return false;
return true;
}
void CFunc::Finger_it()
{
INSTR_LIST *list = this->m_instr_list;
CInstrList_Finger the(list);
POSITION pos = list->GetHeadPosition();
while (pos)
{
PINSTR p = list->GetNext(pos);
if (p->type == i_CplxBegin)
{
the.Finger_check_partern(p);
}
}
}
bool CInstrList::Flow_c(PINSTR phead)
{ // 设法从中找出子 statement 来,括住后再call Flow_a
INSTR_LIST* list = this->m_list;
assert(phead->type == i_CplxBegin);
POSITION s_pos = list->Find(phead);
POSITION e_pos = list->Find(phead->begin.m_end);
assert(s_pos);
assert(e_pos);
if (phead->begin.type == COMP_switch_case)
{ // 对swith_case,有些特殊。从第一个label作起
POSITION pos = s_pos;
while (pos)
{
PINSTR p = list->GetNext(pos);
if (p->type == i_Label)
break;
}
return Flow_cc(phead,pos,e_pos);
}
if (phead->begin.type == COMP_switch_case_multcomp)
{
bool f = false;
POSITION pos = s_pos;
while (pos)
{
POSITION savpos = pos;
PINSTR p = list->GetNext(pos);
if (p->type == i_Label)
break;
if (p->type == i_Jump && p->jmp.jmp_type == JMP_jz)
f=true;
if (f)
{
if (p->type == i_Begin)
{
pos = list->Find(p->begin.m_end);
list->GetNext(pos);
continue;
}
if (p->type != i_Jump && p->type != i_Begin)
{
//break; //这是没有jump的default
return Flow_cc(phead, savpos,e_pos);
}
}
}
return Flow_cc(phead,pos,e_pos);
}
list->GetNext(s_pos); // skip the i_CplxBegin
PINSTR p = list->GetNext(s_pos); // skip first 1
if (p->type == i_Begin)
{ // 比如象for, 允许头上有一个小的statement
if (this->Flow_a(p))
return true;
s_pos = list->Find(p->begin.m_end);
list->GetNext(s_pos); // skip i_End
list->GetNext(s_pos); // skip first 1
}
return Flow_cc(phead,s_pos,e_pos);
}
bool CInstrList::Flow_cc(PINSTR pNode, POSITION firstpos, POSITION endpos)
{ // 这是用来在cplx中再试图找出几个小的begin_end来
INSTR_LIST* list = m_list;
// 三种,有头无尾,要从中找到包含头的最大的一个statement,并用i_Begin,i_End括起来
// 再从i_End到尾继续
// Flow_c(INSTR_LIST* list, POSITION firstpos,POSITION endpos);
// 对找到的i_Begin,i_End,用Flow_a继续
// pNode 是检查区段所属的begin_end,只是为了提供 m_Break
assert(firstpos);
assert(endpos);
if (firstpos == endpos)
return false;
PINSTR phead = list->GetAt(firstpos);
if (phead->type == i_Label)
{
PINSTR p = instr_next(list,phead);
if (p->type == i_Begin) // 因为i_label后跟i_begin会使后面出死循环
{
phead = p; // 放到下一项进行处理
}
}
if (phead->type == i_Begin)
{
if (this->Flow_a(phead))
return true;
POSITION pos1 = list->Find(phead->begin.m_end);
list->GetNext(pos1); // skip i_End
return Flow_cc(pNode,pos1,endpos);
}
POSITION okpos;
POSITION pos1;
pos1 = okpos = firstpos;
do
{
list->GetNext(pos1);
if (ifOneStatement(pNode, firstpos,pos1))
okpos = pos1; // record the last success
} while (pos1 != endpos);
if (okpos == firstpos) // not find anything
{
pos1 = firstpos;
list->GetNext(pos1);
if (pos1 && pos1 != endpos)
{
return Flow_cc(pNode, pos1, endpos); // start from next
}
return false;
}
{
PINSTR begin = new INSTR;
PINSTR end = new INSTR;
begin->type = i_Begin;
end->type = i_End;
begin->begin.m_end = end;
Add_Begin_End(firstpos, okpos, begin, end);
begin->begin.m_break = pNode->begin.m_break; // 继承
begin->begin.m_conti = pNode->begin.m_conti; // 继承
this->Flow_a(begin);
}
if (Step_by_Step())
return true;
return Flow_cc(pNode, okpos, endpos); //next part
}
void CInstrList::Add_Begin_End(POSITION firstpos, POSITION endpos, PINSTR begin, PINSTR end)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -