00001 /* 00002 * HT Editor 00003 * analy_ppc.cc 00004 * 00005 * Copyright (C) 1999-2002 Sebastian Biallas (sb@web-productions.de) 00006 * 00007 * This program is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License version 2 as 00009 * published by the Free Software Foundation. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00019 */ 00020 00021 #include <string.h> 00022 00023 #include "analy_ppc.h" 00024 #include "analy_register.h" 00025 #include "ppcdis.h" 00026 #include "htiobox.h" 00027 #include "snprintf.h" 00028 00029 /* 00030 * 00031 */ 00032 void AnalyPPCDisassembler::init(Analyser *A) 00033 { 00034 disasm = new PPCDisassembler(); 00035 AnalyDisassembler::init(A); 00036 } 00037 00038 /* 00039 * 00040 */ 00041 void AnalyPPCDisassembler::done() 00042 { 00043 AnalyDisassembler::done(); 00044 } 00045 00046 OBJECT_ID AnalyPPCDisassembler::object_id() const 00047 { 00048 return ATOM_ANALY_PPC; 00049 } 00050 00051 /* 00052 * 00053 */ 00054 Address *AnalyPPCDisassembler::branchAddr(OPCODE *opcode, branch_enum_t branchtype, bool examine) 00055 { 00056 Address *a; 00057 a = createAddress(((ppcdis_insn *)opcode)->op[((ppcdis_insn *)opcode)->ops-1].rel.mem); 00058 if (/*examine &&*/ analy->validAddress(a, scvalid)) { 00059 return a; 00060 } 00061 delete a; 00062 return new InvalidAddress(); 00063 } 00064 00065 Address *AnalyPPCDisassembler::createAddress(dword offset) 00066 { 00067 return new AddressFlat32(offset); 00068 } 00069 00070 /* 00071 * 00072 */ 00073 void AnalyPPCDisassembler::examineOpcode(OPCODE *opcode) 00074 { 00075 } 00076 00077 /* 00078 * 00079 */ 00080 branch_enum_t AnalyPPCDisassembler::isBranch(OPCODE *opcode) 00081 { 00082 // FIXME: needs work!! 00083 ppcdis_insn *ppc_insn = (ppcdis_insn *) opcode; 00084 if (ppc_insn->name[0]=='b') { 00085 if (ppc_insn->name[1]=='l') { 00086 if (ppc_insn->name[2]==0) { 00087 return br_call; 00088 } 00089 if (ppc_insn->name[2]=='r') { 00090 if (ppc_insn->name[3]=='l') { 00091 return br_call; 00092 } else { 00093 return br_return; 00094 } 00095 } 00096 return br_jXX; 00097 } 00098 if (ppc_insn->name[strlen(ppc_insn->name)] == 'l') { 00099 return br_call; 00100 } 00101 if (ppc_insn->name[1]==0) { 00102 return br_jump; 00103 } 00104 return br_jXX; 00105 } 00106 /* alphadis_insn *alpha_insn = (alphadis_insn *) opcode; 00107 if (alpha_insn->valid) { 00108 switch ((alpha_insn->table+alpha_insn->code)->type) { 00109 case ALPHA_GROUP_BRA: 00110 if (alpha_insn->table == alpha_instr_tbl) { 00111 switch (alpha_insn->code) { 00112 case 0x30: 00113 return br_jump; 00114 case 0x34: 00115 return br_call; 00116 default: 00117 if (alpha_insn->code > 0x30) return br_jXX; 00118 } 00119 } 00120 return br_nobranch; 00121 case ALPHA_GROUP_JMP: { 00122 switch (alpha_insn->code) { 00123 case 0: 00124 case 3: 00125 case 1: 00126 return br_call; 00127 case 2: 00128 return br_return; 00129 } 00130 } 00131 } 00132 }*/ 00133 return br_nobranch; 00134 } 00135