UnivesalDisassembler(2003)
|
00001 // decoder.cc 00002 // 00003 // uda - universal disassembler 00004 // Date: 2003-05-04 00005 // 00006 // Copyright (c) 2002-2003 Ales Smrcka 00007 // 00008 // This program is licensed under GNU Library GPL. See the file COPYING. 00009 // 00010 // This module contains implementation of class Decoder (facade) used to 00011 // decoding a section. 00012 // 00013 00014 #include <string> 00015 #include <ctype.h> //isprint() 00016 #include "decoder.h" 00017 #include "symtable.h" 00018 #include "sections.h" 00019 using namespace std; 00020 00021 const char *StartingTable="StartTable"; 00022 Decoder decoder; 00023 00024 DecoderInfo decinfo; 00025 00027 DecoderInfo::DecoderInfo() 00028 { 00029 section=NULL; 00030 binfile=NULL; 00031 start=0; 00032 stop=0; 00033 size=0; 00034 print=true; 00035 address=true; 00036 hexdump=true; 00037 symbolic=true; 00038 onlyname=false; 00039 scanaddress=true; 00040 } 00041 00042 DecoderInfo &DecoderInfo::assign(const DecoderInfo &decinfo) 00043 { 00044 section=decinfo.section; 00045 binfile=decinfo.binfile; 00046 start=decinfo.start; 00047 stop=decinfo.stop; 00048 size=decinfo.size; 00049 print=decinfo.print; 00050 address=decinfo.address; 00051 hexdump=decinfo.hexdump; 00052 symbolic=decinfo.symbolic; 00053 onlyname=decinfo.onlyname; 00054 scanaddress=decinfo.scanaddress; 00055 return *this; 00056 } 00057 00058 // Decode the section as hexadecimal output 00059 void Decoder::HexOut() 00060 { 00061 Address addr; 00062 Address stop; 00063 Section §ion = *decinfo.section; 00064 if (decinfo.start==0) 00065 addr=section->addr; 00066 else 00067 addr=decinfo.start; 00068 if (decinfo.stop==0) 00069 if (decinfo.size==0) 00070 stop=addr+section->size; 00071 else 00072 stop=addr+decinfo.size; 00073 unsigned i; 00074 while (section.ValidAddress(addr) && addr<stop) 00075 { 00076 //print address 00077 cout<<""<<hex<<setw(8)<<setfill('0')<<addr<<": "; 00078 //print hex content 00079 for (i=0;i<16;i++) 00080 if (section.ValidAddress(addr+i) && addr+i<stop) 00081 { 00082 if (i%4==0) 00083 cout<<" "; 00084 cout<<hex<<setw(2)<<setfill('0')<<unsigned(section[addr+i])<<" "; 00085 } 00086 else 00087 break; 00088 for (;i<16;i++) //fill with " " 00089 { 00090 if (i%4==0) cout<<" "; 00091 cout<<" "; 00092 } 00093 //print ASCII content 00094 cout<<" "; 00095 for (i=0;i<16;i++) 00096 if (section.ValidAddress(addr+i) && addr+i<stop) 00097 { 00098 if (isprint(section[addr+i])) 00099 cout<<section[addr+i]; 00100 else 00101 cout<<'.'; 00102 } 00103 else 00104 break; 00105 cout<<endl; 00106 addr+=16; 00107 } 00108 } 00109 00110 //prints a line with symbolic instruction 00111 void Decoder::print_line(Address addr, unsigned size, string &symbolic_instruction) 00112 { 00113 unsigned labellength=0; 00114 unsigned space=16; 00115 Section §ion = *decinfo.section; 00116 if (symbols->defined(addr)) 00117 { 00118 string s=(*symbols)[addr]; 00119 if (s.substr(0, 5)!="label") 00120 cout<<endl<<s<<":"<<endl; 00121 else 00122 { 00123 cout<<s<<":"; 00124 if (!decinfo.onlyname) 00125 cout<<endl; 00126 labellength=s.length()+1; 00127 } 00128 } 00129 if (decinfo.address) 00130 cout<<"0x"<<setw(8)<<setfill('0')<<hex<<addr<<":"; 00131 if (decinfo.hexdump) 00132 { 00133 unsigned i; 00134 cout<<" "; 00135 for (i=0;i<size;i++) 00136 cout<<hex<<setw(2)<<setfill('0')<<unsigned(section[addr+i])<<" "; 00137 for (;i<8;i++) 00138 cout<<" "; 00139 } 00140 if (decinfo.hexdump || decinfo.address) 00141 space=10; 00142 if (decinfo.onlyname) 00143 for (unsigned i=0;i<space-labellength;i++) 00144 cout<<" "; 00145 if (decinfo.symbolic) 00146 cout<<symbolic_instruction<<endl; 00147 } 00148 00149 // Decode the section 00150 void Decoder::Decode() 00151 { 00152 Address addr; 00153 Address stop; 00154 if (decinfo.section==NULL) 00155 throw Exception("Decoder:section isn't set\n"); 00156 Section §ion = *decinfo.section; 00157 if (!section->executable) 00158 if (decinfo.print) 00159 HexOut(); 00160 else; 00161 else 00162 { 00163 if (decinfo.start==0) 00164 addr=section->addr; 00165 else 00166 addr=decinfo.start; 00167 if (decinfo.stop==0) 00168 if (decinfo.size==0) 00169 stop=addr+section->size; 00170 else 00171 stop=addr+decinfo.size; 00172 else 00173 stop=decinfo.stop; 00174 unsigned ins_size; 00175 string symbolic_instruction; 00176 Tables &tables=*instructionset.tables; 00177 Variables &variables=*instructionset.variables; 00178 string starttable; 00179 AbstractTable *table; 00180 while (section.ValidAddress(addr) && addr<stop) 00181 { 00182 table=tables[variables[StartingTable]]; 00183 symbolic_instruction=table->Decode(section, addr, ins_size); 00184 if (decinfo.print) 00185 print_line(addr, ins_size, symbolic_instruction); 00186 addr+=ins_size; 00187 tables.Reset(); 00188 variables.Reset(); 00189 } 00190 } 00191 }