00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "pent_include.h"
00022
00023 #include "FuncNodes.h"
00024 #include "Folder.h"
00025 #include "VarNodes.h"
00026
00027 #include <deque>
00028 using std::deque;
00029
00030
00031
00032
00033
00034 void FuncMutatorNode::print_unk(Console &o, const uint32 isize, const bool comment) const
00035 {
00036
00037
00038
00039 if(!comment && mtype!=SUSPEND) return;
00040
00041 assert(rtype().type()==Type::T_INVALID);
00042 switch(mtype)
00043 {
00044 case RET: CANT_HAPPEN(); break;
00045 case INIT: CANT_HAPPEN(); break;
00046 case LINE_NUMBER:
00047 Node::print_linenum_unk(o, isize);
00048 #if 0
00049 o.Printf(" /* Line No: %d */ ", _linenum);
00050 #else
00051 o.Printf("/*%d*/", _linenum);
00052 #endif
00053 break;
00054 case SYMBOL_INFO:
00055 Node::print_linenum_unk(o, isize);
00056 o.Printf("symbol_info_NOPRINT(0x%04X, \"%s\")", _symboloffset, _classname.c_str());
00057 break;
00058 case SUSPEND:
00059 o.Printf("suspend");
00060 break;
00061 case END: CANT_HAPPEN(); break;
00062 default: assert(print_assert(this));
00063 }
00064 }
00065
00066 void FuncMutatorNode::print_asm(Console &o) const
00067 {
00068 assert(rtype().type()==Type::T_INVALID);
00069
00070 Node::print_linenum_asm(o);
00071 Node::print_asm(o);
00072
00073 switch(mtype)
00074 {
00075 case RET: print_assert(this); CANT_HAPPEN(); break;
00076 case INIT: print_assert(this); CANT_HAPPEN(); break;
00077 case LINE_NUMBER: o.Printf("line number\t%i (%04Xh)", _linenum, _linenum); break;
00078 case SYMBOL_INFO: o.Printf("symbol info\toffset %04Xh = \"%s\"", _symboloffset, _classname.c_str()); break;
00079 case SUSPEND: o.Printf("suspend"); break;
00080 case END: CANT_HAPPEN(); break;
00081 default: assert(print_assert(this));
00082 }
00083 }
00084
00085 void FuncMutatorNode::print_bin(ODequeDataSource &o) const
00086 {
00087 assert(rtype().type()==Type::T_INVALID);
00088 Node::print_linenum_bin(o);
00089 switch(mtype)
00090 {
00091 case RET: CANT_HAPPEN(); break;
00092 case INIT: CANT_HAPPEN(); break;
00093 case LINE_NUMBER: o.write1(0x5B); o.write2(_linenum); break;
00094 case SYMBOL_INFO: o.write1(0x5C); o.write2(_symboloffset - _offset - 3); o.write(_classname.c_str(), _classname.size(), 9); break;
00095 case SUSPEND: o.write1(0x53); break;
00096 case END: CANT_HAPPEN(); break;
00097 default: assert(print_assert(this));
00098 }
00099 }
00100
00101 bool FuncMutatorNode::fold(DCUnit *unit, std::deque<Node *> &nodes)
00102 {
00103 fold_linenum(nodes);
00104
00105 if(mtype==SYMBOL_INFO)
00106 {
00107 unit->setDebugOffset(_symboloffset);
00108 unit->setClassName(_classname);
00109 }
00110 else if(mtype==END)
00111 {
00112
00113
00114
00115
00116
00117
00118
00119 assert((nodes.size()>0 && nodes.back()->opcode()==0xFFFF) || print_assert(this, unit));
00120 DCFuncNode *funcnode=static_cast<DCFuncNode *>(nodes.back());
00121 funcnode->addEnd(this);
00122
00123
00124
00125
00126 return false;
00127 }
00128
00129 return true;
00130 }
00131
00132
00133
00134
00135 #define DEBUG_COMMENTS
00136
00137 void DCFuncNode::print_unk_funcheader(Console &o, const uint32 isize) const
00138 {
00139
00140
00141
00142 indent(o, isize);
00143 if(has_procexclude)
00144 o.Printf("process ");
00145
00146 o.Putchar('\n');
00147 }
00148
00149 void DCFuncNode::print_unk(Console &o, const uint32 isize) const
00150 {
00151 #ifdef DEBUG_COMMENTS
00152 indent(o, isize); o.Print("/*");
00153
00154
00155 indent(o, 1);
00156 o.Printf("Function Start Offset:\t0x%04X\n", func_start_offset);
00157 indent(o, isize+1);
00158 o.Printf("Locals Datasize:\t0x%02X\n", locals_datasize);
00159
00160 indent(o, isize+1);
00161 o.Printf("Process Type:\t\t0x%04X", process_type);
00162
00163 assert(debug_thisp==true);
00164
00165
00166
00167 indent(o, 1); o.Print("*/\n");
00168 #endif
00169
00170
00171
00172
00173
00174 for(std::deque<Node *>::const_iterator i=funcnodes.begin(); i!=funcnodes.end(); ++i)
00175 {
00176 indent(o, isize);
00177 (*i)->print_unk(o, isize);
00178 o.Putchar('\n');
00179 }
00180
00181 assert(debug_ret_offset!=0);
00182 assert(debug_end_offset!=0);
00183
00184 #if 0 // not much use until we've got something to stuff at the end of the function
00185
00186 indent(o, isize); o.Print("/*");
00187
00188
00189
00190
00191
00192
00193
00194
00195 indent(o, 1); o.Print("*/\n");
00196 #endif
00197 }
00198
00199 void DCFuncNode::print_asm(Console &o) const
00200 {
00201
00202 print_asm_header(o, func_start_offset, 0x5A);
00203 o.Printf("init\t\t%02X\n", locals_datasize);
00204
00205 setinfonode->print_asm(o);
00206 o.Putchar('\n');
00207
00208
00209 print_asm_header(o, debug_procexclude_offset, 0x78);
00210 o.Printf("process exclude\n");
00211
00212
00213
00214 for(std::deque<Node *>::const_iterator i=funcnodes.begin(); i!=funcnodes.end(); ++i)
00215 {
00216 (*i)->print_asm(o);
00217 o.Putchar('\n');
00218 }
00219
00220
00221 print_asm_header(o, debug_ret_offset, 0x50);
00222 o.Printf("ret\n");
00223
00224
00225 print_asm_header(o, debug_end_offset, 0x7A);
00226 o.Printf("end\n");
00227 }
00228
00229 void DCFuncNode::print_bin(ODequeDataSource &o) const
00230 {
00231
00232 print_mac_header(con, func_start_offset, 0x5A);
00233 o.write1(0x5A);
00234 o.write1(locals_datasize);
00235
00236 assert(setinfonode!=0);
00237 setinfonode->print_mac(con);
00238 setinfonode->print_bin(o);
00239
00240
00241 print_mac_header(con, debug_procexclude_offset, 0x78);
00242 o.write1(0x78);
00243
00244
00245
00246
00247 for(std::deque<Node *>::const_iterator i=funcnodes.begin(); i!=funcnodes.end(); ++i)
00248 {
00249 o.clear();
00250 (*i)->print_mac(con);
00251 (*i)->print_bin(o);
00252
00253 for(std::deque<char>::const_iterator i=o.buf().begin(); i!=o.buf().end(); ++i)
00254 con.Printf("%02X ", static_cast<uint8>(*i));
00255 con.Putchar('\n');
00256 }
00257
00258
00259 print_mac_header(con, debug_ret_offset, 0x50);
00260 o.write1(0x50);
00261
00262
00263 print_mac_header(con, debug_ret_offset, 0x7A);
00264 o.write1(0x7A);
00265 }
00266
00267 bool DCFuncNode::fold(DCUnit *unit, std::deque<Node *> &nodes)
00268 {
00269 assert(nodes.size()>0);
00270
00271
00272
00273
00274 fold_ret(unit, nodes);
00275
00276
00277 while(nodes.size() && !acceptOp(nodes.back()->opcode(), 0x78))
00278 {
00279
00280
00281
00282
00283
00284
00285
00286
00287 funcnodes.push_front(nodes.back());
00288
00289 nodes.pop_back();
00290 }
00291
00292
00293 fold_procexclude(unit, nodes);
00294
00295
00296 fold_setinfo(unit, nodes);
00297
00298
00299 fold_init(unit, nodes);
00300
00301
00302
00303 assert((nodes.size()==0) || print_assert(0, unit));
00304
00305 return true;
00306 }
00307
00308 void DCFuncNode::fold_init(DCUnit * , std::deque<Node *> &nodes)
00309 {
00310 assert(nodes.size() && nodes.back()->opcode()==0x5A);
00311 FuncMutatorNode *initnode = static_cast<FuncMutatorNode *>(nodes.back());
00312 nodes.pop_back();
00313
00314 locals_datasize = initnode->a_initsize();
00315 func_start_offset = initnode->offset();
00316
00317 FORGET_OBJECT(initnode);
00318 }
00319
00320 void DCFuncNode::fold_ret(DCUnit * , std::deque<Node *> &nodes)
00321 {
00322 assert(nodes.size() && nodes.back()->opcode()==0x50);
00323 FuncMutatorNode *retnode = static_cast<FuncMutatorNode *>(nodes.back());
00324 nodes.pop_back();
00325
00326 debug_ret_offset = retnode->offset();
00327
00328 FORGET_OBJECT(retnode);
00329 }
00330
00331 void DCFuncNode::fold_setinfo(DCUnit * , std::deque<Node *> &nodes)
00332 {
00333 assert(nodes.size() && nodes.back()->opcode()==0x77);
00334 setinfonode = static_cast<DCCallMutatorNode *>(nodes.back());
00335 nodes.pop_back();
00336
00337
00338 assert(setinfonode->a_lnode()->opcode()==0x0B);
00339 process_type = static_cast<const PushVarNode *>(setinfonode->a_lnode())->dtype().value();
00340 debug_processtype_offset= static_cast<const PushVarNode *>(setinfonode->a_lnode())->dtype().value();
00341
00342 assert(setinfonode->a_rnode()->opcode()==0x4C);
00343 const DCCallMutatorNode *temp_push_indirect = static_cast<const DCCallMutatorNode *>(setinfonode->a_rnode());
00344
00345 assert(temp_push_indirect->a_lnode()->rtype()==Type::T_DWORD);
00346 assert(static_cast<const PushVarNode *>(temp_push_indirect->a_lnode())->dtype().value()==0x06);
00347 debug_thisp=true;
00348
00349
00350 }
00351
00352 void DCFuncNode::fold_procexclude(DCUnit * , std::deque<Node *> &nodes)
00353 {
00354 assert(nodes.size() && nodes.back()->opcode()==0x78);
00355 DCCallMutatorNode *procexcludenode = static_cast<DCCallMutatorNode *>(nodes.back());
00356 nodes.pop_back();
00357
00358
00359 has_procexclude=true;
00360 debug_procexclude_offset = procexcludenode->offset();
00361
00362 FORGET_OBJECT(procexcludenode);
00363 }
00364
00365
00366
00367