UnivesalDisassembler(2003)

decoder.cc

Go to the documentation of this file.
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 &section = *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 &section = *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 &section = *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 }