UnivesalDisassembler(2003)

instrset.cc

Go to the documentation of this file.
00001 // instrset.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 // Implementation of loading instruction set from file and
00011 // creating tables and variables. This file including builtin tables in
00012 // namespace BuiltinTables. Tables, Table, TableItem include core of decoding.
00013 //
00014 // usage:
00015 //   instructionset.Build();
00016 //   instructionset.Load(processor_type);
00017 //   decoder.Decode(section_name);
00018 //
00019 
00020 #include <iomanip>
00021 #include <iostream>
00022 #include <fstream>
00023 #include <map>
00024 #include <string>
00025 #include <ctype.h>
00026 #include <dlfcn.h>
00027 #include <sys/types.h>
00028 #include <sys/stat.h>
00029 #include <unistd.h>
00030 #include <dirent.h>
00031 #include <libgen.h>
00032 #include "instrset.h"
00033 #include "shared.h"
00034 #include "symtable.h"
00035 #include "decoder.h"
00036 #include "udaclasses.h"
00037 using namespace std;
00038 
00039 InstructionSet instructionset;
00040 
00041 const string instrsetdirectory="instrset/";
00042 const string defaultinstrset="default";
00043 
00045 // InstructionSet. (Facade, Singleton)
00046 InstructionSet::InstructionSet()
00047 {
00048     variables=new Variables;
00049     tables=new Tables(variables);
00050     tables->Add("Ib", new BuiltinTables::Ib);
00051     tables->Add("Iw", new BuiltinTables::Iw);
00052     tables->Add("Id", new BuiltinTables::Id);
00053     tables->Add("Ibw", new BuiltinTables::Ibw);
00054     tables->Add("Ibd", new BuiltinTables::Ibd);
00055     tables->Add("SIb", new BuiltinTables::SIb);
00056     tables->Add("SIw", new BuiltinTables::SIw);
00057     tables->Add("SId", new BuiltinTables::SId);
00058     tables->Add("SIbw", new BuiltinTables::SIbw);
00059     tables->Add("SIbd", new BuiltinTables::SIbd);
00060     tables->Add("Jb", new BuiltinTables::Jb);
00061     tables->Add("Jw", new BuiltinTables::Jw);
00062     tables->Add("Jd", new BuiltinTables::Jd);
00063     tables->Add("Apw", new BuiltinTables::Apw);
00064     tables->Add("Apd", new BuiltinTables::Apd);
00065     tables->Add("Aw", new BuiltinTables::Aw);
00066     tables->Add("Ad", new BuiltinTables::Ad);
00067     tables->Add("BIb", new BuiltinTables::BIb);
00068     tables->Add("BIw", new BuiltinTables::BIw);
00069     tables->Add("BId", new BuiltinTables::BId);
00070     tables->Add("BIbw", new BuiltinTables::BIbw);
00071     tables->Add("BIbd", new BuiltinTables::BIbd);
00072     tables->Add("SBIb", new BuiltinTables::SBIb);
00073     tables->Add("SBIw", new BuiltinTables::SBIw);
00074     tables->Add("SBId", new BuiltinTables::SBId);
00075     tables->Add("SBIbw", new BuiltinTables::SBIbw);
00076     tables->Add("SBIbd", new BuiltinTables::SBIbd);
00077     tables->Add("BJb", new BuiltinTables::BJb);
00078     tables->Add("BJw", new BuiltinTables::BJw);
00079     tables->Add("BJd", new BuiltinTables::BJd);
00080     tables->Add("BApw", new BuiltinTables::BApw);
00081     tables->Add("BApd", new BuiltinTables::BApd);
00082     tables->Add("BAw", new BuiltinTables::BAw);
00083     tables->Add("BAd", new BuiltinTables::BAd);
00084 }
00085 
00086 InstructionSet::~InstructionSet()
00087 {
00088     if (tables!=NULL)
00089         delete tables;
00090     if (variables!=NULL)
00091         delete variables;
00092 }
00093 
00094 int InstructionSet::LoadFile(const string filename)
00095 {
00096     debug("InstructionSet: Loading instructions set from "<<basename((char*)filename.c_str())<<endl);
00097     if (tables==NULL || variables==NULL)
00098         return 0;
00099     struct stat buf;
00100     if ((stat(filename.c_str(), &buf)==0) && S_ISREG(buf.st_mode))
00101     {
00102         Scanner scanner(filename.c_str());
00103         Parser parser(scanner, *tables, *variables);
00104         parser.Parse();
00105         return 1;
00106     }
00107     else
00108         return 0;
00109 }
00110 
00112 void InstructionSet::Load(const string processor)
00113 {
00114     if (processor!="") //processor defined
00115         if (!LoadFile(basedir+instrsetdirectory+processor)) //load this instruction set
00116             throw Exception(string("can not read file ")+instrsetdirectory+processor);
00117         else;
00118     else
00119         if (!LoadFile(basedir+instrsetdirectory+defaultinstrset)) //load default instruction set
00120             throw Exception(string("can not open default instructions: ")+instrsetdirectory+defaultinstrset);
00121 }
00122 
00123 // clear instruction set
00124 void InstructionSet::Clear()
00125 {
00126     variables->Clear();
00127     tables->Clear();
00128 }
00129 
00131 // Scanner. Scans input for tokens
00132 int Scanner::getc()
00133 {
00134     if (unget!=-1)
00135     {
00136         int result=unget;
00137         unget=-1;
00138         if (result=='\n')
00139             _line++;
00140         return result;
00141     }
00142     int c=input.get();
00143     if (c=='\n')
00144         _line++;
00145     return c;
00146 }
00147 
00148 void Scanner::ungetc(int c)
00149 {
00150     unget=c;
00151     if (c=='\n')
00152         _line--;
00153 }
00154 
00155 Scanner::Scanner(const char *filename) : input(filename)
00156 {
00157     unget=-1;
00158     _line=1;
00159 }
00160 
00161 Scanner::Token Scanner::Scan()
00162 {
00163     Token token;
00164     int c=getc(); //character from stream
00165     enum {
00166         normal,
00167         ident,
00168         text,
00169         textspec,
00170         num,
00171         numdec,
00172         numhex,
00173         comment
00174     } state=normal;
00175     while (!token && c!=-1)
00176     {
00177         switch (state) {
00178             case normal:
00179                 switch (c) {
00180                     case '=': token.type=tk_equal; break;
00181                     case '+': token.type=tk_plus; break;
00182                     case ',': token.type=tk_comma; break;
00183                     case ';': token.type=tk_semicol; break;
00184                     case '{': token.type=tk_parop; break;
00185                     case '}': token.type=tk_parcl; break;
00186                     case '0': state=num; break;
00187                     case '"': state=text; break;
00188                     case '#': state=comment; break;
00189                     default:
00190                         if (isspace(c))
00191                             break;
00192                         if (isdigit(c))
00193                         {
00194                             token.int_value=c-'0';
00195                             token.str_value=c;
00196                             state=numdec;
00197                         }
00198                         else
00199                         if (isalpha(c)||c=='_')
00200                         {
00201                             state=ident;
00202                             token.str_value=c;
00203                         }
00204                         else
00205                             throw ScannerException(string("unexpected character `")+(char)c+"'", line());
00206                 }
00207                 break; //normal state
00208             case ident:
00209                 if (isalnum(c)||c=='_')
00210                     token.str_value+=c;
00211                 else
00212                 {
00213                     ungetc(c);
00214                     token.type=tk_ident;
00215                 }
00216                 break;
00217             case text:
00218                 if (c=='"')
00219                     token.type=tk_text;
00220                 else
00221                     if (c=='\\')
00222                         state=textspec;
00223                     else
00224                         token.str_value+=c;
00225                 break;
00226             case textspec:
00227                 token.str_value+=c;
00228                 state=text;
00229                 break;
00230             case num:
00231                 if (c=='x')
00232                     state=numhex;
00233                 else
00234                     if (isdigit(c))
00235                     {
00236                         token.int_value=c-'0';
00237                         token.str_value=c;
00238                         state=numdec;
00239                     }
00240                     else
00241                     {
00242                         ungetc(c);
00243                         if (token.int_value==0)
00244                             token.str_value="0";
00245                         token.type=tk_number;
00246                     }
00247                 break;
00248             case numdec:
00249                 if (isdigit(c))
00250                 {
00251                     token.int_value=token.int_value*10+(c-'0');
00252                     token.str_value+=c;
00253                 }
00254                 else
00255                 {
00256                     ungetc(c);
00257                     token.type=tk_number;
00258                 }
00259                 break;
00260             case numhex:
00261                 if (isxdigit(c))
00262                     if (isdigit(c))
00263                         token.int_value=(token.int_value<<4)|(c-'0');
00264                     else
00265                         token.int_value=(token.int_value<<4)|(lower(c)-'a'+10);
00266                 else
00267                 {
00268                     ungetc(c);
00269                     token.str_value=uint2str(token.int_value);
00270                     token.type=tk_number;
00271                 }
00272                 break;
00273             case comment:
00274                 if (c=='\n')
00275                     state=normal;
00276                 break;
00277         }
00278         c=getc();
00279     } //while
00280     ungetc(c);
00281     return token;
00282 }
00283 
00285 // Parser. Creates tables and variables
00286 
00287 void Parser::Error()
00288 {
00289     throw ParserException("unexpected token", scanner.line());
00290 }
00291 
00292 // GLOBAL     -> $
00293 // GLOBAL     -> ident VARTAB -- save ident
00294 // VARTAB     -> = textlit ; GLOBAL -- create new variable
00295 // VARTAB     -> { ITEMS } GLOBAL -- create new table
00296 // ITEMS      -> e
00297 // ITEMS      -> number , number , textlit , LENGTH ; ITEMS -- create new table item
00298 // LENGTH     -> number NEXTLENGTH
00299 // NEXTLENGTH -> e
00300 // NEXTLENGTH -> + ident NEXTLENGTH
00301 //
00302 // Runs parser to create new tables and variables
00303 void Parser::Parse()
00304 {
00305     Scanner::Token token=scanner.Scan();
00306     string tmp, tmp2; //temptorary variable
00307     unsigned mask, tag;
00308     Table *table;
00309     enum NonTerm { GLOBAL, VARTAB, ITEMS, LENGTH, NEXTLENGTH } nonterm=GLOBAL;
00310     while (1)
00311     {
00312         switch (nonterm) {
00313             case GLOBAL:
00314                 switch (token) {
00315                     case tk_end: return;
00316                     case tk_ident:
00317                         tmp=token.str_value;
00318                         nonterm=VARTAB;
00319                         token=scanner.Scan();
00320                         break;
00321                     default: Error();
00322                 }
00323                 break;
00324             case VARTAB:
00325                 switch (token) {
00326                     case tk_equal: //creating new variable
00327                         if ((token=scanner.Scan())!=tk_text)
00328                             Error();
00329                         variables.Add(tmp, token.str_value);
00330                         if ((token=scanner.Scan())!=tk_semicol)
00331                             Error();
00332                         token=scanner.Scan();
00333                         nonterm=GLOBAL;
00334                         break;
00335                     case tk_parop: //creating new table
00336                         table=tables.Add(tmp);
00337                         token=scanner.Scan();
00338                         nonterm=ITEMS;
00339                         break;
00340                     default: Error();
00341                 }
00342                 break;
00343             case ITEMS:
00344                 switch (token) {
00345                     case tk_parcl:
00346                         nonterm=GLOBAL;
00347                         token=scanner.Scan();
00348                         break;
00349                     case tk_number:
00350                         mask=token.int_value;
00351                         if ((token=scanner.Scan())==tk_comma)
00352                         if ((token=scanner.Scan())==tk_number)
00353                         {
00354                             tag=token.int_value;
00355                             if ((token=scanner.Scan())==tk_comma)
00356                             if ((token=scanner.Scan())==tk_text)
00357                             {
00358                                 tmp=token.str_value;
00359                                 if ((token=scanner.Scan())==tk_comma)
00360                                 {
00361                                     token=scanner.Scan();
00362                                     nonterm=LENGTH;
00363                                     break;
00364                                 }
00365                             }
00366                         }
00367                         Error();
00368                         break;
00369                     default: Error();
00370                 }
00371                 break;
00372             case LENGTH:
00373                 switch (token) {
00374                     case (tk_number):
00375                     case (tk_ident):
00376                         tmp2=token.str_value;
00377                         nonterm=NEXTLENGTH;
00378                         token=scanner.Scan();
00379                         break;
00380                     default: Error();
00381                 }
00382                 break;
00383             case NEXTLENGTH:
00384                 switch (token) {
00385                     case tk_plus:
00386                         tmp2+='+';
00387                         if ((token=scanner.Scan())==tk_ident)
00388                         {
00389                             tmp2+=token.str_value;
00390                             token=scanner.Scan();
00391                         }
00392                         else
00393                             Error();
00394                         break;
00395                     case tk_semicol:
00396                         table->Add(mask, tag, tmp, tmp2);
00397                         nonterm=ITEMS;
00398                         token=scanner.Scan();
00399                         break;
00400                     default: Error();
00401                 }
00402                 break;
00403         }
00404     }
00405 }
00406 
00408 // Tables. Map of Table indexed by its name. (Builder)
00409 Tables::~Tables()
00410 {
00411     MTables::iterator i;
00412     for (i=_tables.begin();i!=_tables.end();i++)
00413     {
00414         delete i->second;
00415         i->second=NULL;
00416     }
00417 }
00418 
00419 // Add(name) creates new table (Table) and returns it.
00420 Table *Tables::Add(string s)
00421 {
00422     if (_tables.find(s)==_tables.end())
00423         return dynamic_cast<Table*>(_tables[s]=new Table(this, variables));
00424     else
00425         throw InstructionException("table already exists", s);
00426 }
00427 
00428 // Add(name, table) - useful for builtin tables
00429 AbstractTable *&Tables::Add(string name, AbstractTable *table)
00430 {
00431     if (_tables.find(name)==_tables.end())
00432         return _tables[name]=table;
00433     else
00434         throw InstructionException("table already exists", name);
00435 }
00436 
00437 // Returns appropriate table. Throws exception when table does not exist.
00438 AbstractTable *&Tables::operator [](string index)
00439 {
00440     if (_tables.find(index)!=_tables.end())
00441         return _tables[index];
00442     else
00443         throw InstructionException("not known table", index);
00444 }
00445 
00446 void Tables::Reset()
00447 {
00448     MTables::iterator i;
00449     for (i=_tables.begin();i!=_tables.end();i++)
00450         i->second->Reset();
00451 }
00452 
00453 // Clears all tables from memory
00454 void Tables::Clear()
00455 {
00456     _tables.clear();
00457 }
00458 
00460 // AbstractTable - parent for Table and BuiltinTable
00461 string AbstractTable::Decode(Section &data, Address addr, unsigned &size)
00462 {
00463     size=0;
00464     return "";
00465 }
00466 
00468 // Table. Table with 256 items (TableItem). Item is indexed by a byte on data section.
00469 Table::Table(Tables *t, Variables *v)
00470 {
00471     tables=t;
00472     variables=v;
00473     for (int i=0;i<256;i++)
00474         _items[i]=NULL;
00475 }
00476 
00477 Table::~Table()
00478 {
00479     for (int i=0;i<256;i++)
00480         if (_items[i]!=NULL)
00481         {
00482             for (int j=i+1;j<256;j++)
00483                 if (_items[j]==_items[i])
00484                     _items[j]=NULL;
00485             delete _items[i];
00486             _items[i]=NULL;
00487         }
00488 }
00489 
00490 TableItem *Table::Add(unsigned mask, unsigned tag, string value, string length)
00491 {
00492     TableItem *tableitem=new TableItem(*tables, *variables, value, length);
00493     bool filled=false;
00494     for (unsigned i=0;i<256;i++)
00495         if ((i&mask)==tag)
00496         {
00497             filled=true;
00498             _items[i]=tableitem;
00499         }
00500     if (!filled)
00501     {
00502         delete tableitem;
00503         return NULL;
00504     }
00505     else
00506         return tableitem;
00507 }
00508 
00509 // Decode actual byte. input: data and address, output: decoded string and size of decoded data
00510 string Table::Decode(Section &data, Address addr, unsigned &size)
00511 {
00512     TableItem *item=_items[data[addr]];
00513     if (item==NULL)
00514         throw Exception(string("item not defined for ")+uint2hex(data[addr])+" at address: "+uint2hex(addr)+"\n");
00515     else
00516         return _items[data[addr]]->Decode(data, addr, size);
00517 }
00518 
00519 // Resets all tables to their default values (nothing to do)
00520 void Table::Reset()
00521 {
00522 }
00523 
00525 // TableItem. An item of Table consisting of value and length array of decoded bytes
00526 TableItem::TableItem(Tables &t, Variables &v, string value, string lengthstr) : tables(t), variables(v)
00527 {
00528     TableItem::value=value;
00529     const char *c=lengthstr.c_str();
00530     bool digit=false;
00531     lengths.first_value=0;
00532     for (int i=0;i<26;i++)
00533         lengths.valid[i]=false;
00534     while (*c)
00535     {
00536         if (!digit)
00537             if (isdigit(*c))
00538             {
00539                 digit=true;
00540                 lengths.first_value=*c-'0';
00541             }
00542             else
00543             if (isalpha(*c))
00544                 lengths.valid[lower(*c)-'a']=true;
00545             else;
00546         else
00547             if (isdigit(*c))
00548                 lengths.first_value = lengths.first_value*10 + *c-'0';
00549             else
00550                 digit=false;
00551         c++;
00552     }
00553 }
00554 
00555 void TableItem::Error(const char *c)
00556 {
00557     throw InstructionException("unexpected character", c);
00558 }
00559 
00560 // Returns sum of values of all valid lengths
00561 int TableItem::CountLength(unsigned lens[])
00562 {
00563     unsigned result=lengths.first_value;
00564     for (int i=0;i<26;i++)
00565         if (lengths.valid[i])
00566             result+=lens[i];
00567     return result;
00568 }
00569 
00570 // Returns sum of values of lengths len (e.g. "1+b" returns 1+lens[2]; "" returns 0; "12CA" returns 12+lens[3]+lens[1])
00571 int TableItem::CountLength(unsigned lens[], string len)
00572 {
00573     unsigned result=0;
00574     unsigned i;
00575     for (i=0;i<len.length();i++)
00576         if (isdigit(len[i]))
00577             result=result*10+len[i]-'0';
00578         else
00579             break;
00580     for (;i<len.length();i++)
00581         if (isalpha(len[i]))
00582             result+=lens[lower(len[i])-'a'];
00583     return result;
00584 }
00585 
00586 // 1. N -> <t>
00587 // 2. N -> <null>
00588 // 3. N -> $ P
00589 // 4. N -> <other> N            -- print character
00590 // 5. P -> { V
00591 // 6. P -> ( T
00592 // 7. V -> N('}', '=') V1
00593 // 8. V1 -> } N                 -- print variable value or set new
00594 // 9. V1 -> = N('}') } N        -- set new value
00595 // 10. T -> N(',') , N(')') ) N  -- table
00596 // Decodes the text with others tables and variables. Fills the length array.
00597 // lindex is actual index to length array. t is terminated character. Returns
00598 // substituted string.
00599 string TableItem::Norm(Section &data, Address addr, unsigned lens[], unsigned &lindex, const char *&c, char t)
00600 {
00601     enum NonTerm { N, P, V, V1, T } nonterm=N;
00602     string result="";
00603     string tmp, tmp2;
00604     bool set;
00605     while (1)
00606         switch (nonterm) {
00607             case N:
00608                 if (*c==0 || *c==t) //1. and 2.
00609                     return result;
00610                 if (*c=='$') //3.
00611                     nonterm=P;
00612                 else //4.
00613                 {
00614                     result+=*c;
00615                     nonterm=N;
00616                 }
00617                 c++;
00618                 break;
00619             case P:
00620                 switch (*c) {
00621                     case '{': nonterm=V; break;
00622                     case '(': nonterm=T; break;
00623                     default: Error();
00624                 }
00625                 c++;
00626                 break;
00627             case V:
00628                 tmp=Norm(data, addr, lens, lindex, c, '}');
00629                 nonterm=V1;
00630                 break;
00631             case V1:
00632                 switch (*c) {
00633                     case '}': break;
00634                     default: Error();
00635                 }
00636                 c++;
00637                 nonterm=N;
00638                 set=false;
00639                 for (unsigned i=0;i<tmp.length();i++)
00640                     if (tmp[i]=='=')
00641                     {
00642                         variables[tmp.substr(0, i)].value=tmp.substr(i+1, tmp.length());
00643                         set=true;
00644                         break;
00645                     }
00646                 if (!set)
00647                     result+=variables[tmp];
00648                 break;
00649             case T:
00650                 tmp=Norm(data, addr, lens, lindex, c, ',');
00651                 if (*c!=',')
00652                     Error();
00653                 c++;
00654                 tmp2=Norm(data, addr, lens, lindex, c, ')');
00655                 if (*c!=')')
00656                     Error();
00657                 unsigned pos=CountLength(lens, tmp2);
00658                 unsigned newsize;
00659                 result+=tables[tmp]->Decode(data, addr+pos, newsize);
00660                 lens[lindex++]=newsize;
00661                 c++;
00662                 nonterm=N;
00663                 break;
00664         }
00665 }
00666 
00667 // Decode actual byte. input: data and address, output: decoded string and size of decoded data
00668 string TableItem::Decode(Section &data, Address addr, unsigned &size)
00669 {
00670     const char *c=value.c_str();
00671     unsigned lens[26]={0}; //lengths for subst. tables: a, b, c,..., z
00672     unsigned lindex=0; //actual index to lens
00673     string subst=Norm(data, addr, lens, lindex, c);
00674     size=CountLength(lens);
00675     return subst;
00676 }
00677 
00679 // Variables. Map of Variable indexed by its name. (Builder)
00680 
00681 // Creates new variable
00682 Variable &Variables::Add(string name, string defaultvalue)
00683 {
00684     if (_variables.find(name)==_variables.end())
00685     {
00686         Variable v(defaultvalue);
00687         return _variables[name]=v;
00688     }
00689     else
00690         throw InstructionException("variable already exists", name);
00691 }
00692 
00693 // Returns appropriate variable, throws an exception if variable does not exist.
00694 Variable &Variables::operator [](string index)
00695 {
00696     if (_variables.find(index)!=_variables.end())
00697         return _variables[index];
00698     else
00699         throw InstructionException("not known variable", index);
00700 }
00701 
00702 // Resets all variables to their default value
00703 void Variables::Reset()
00704 {
00705     MVariables::iterator i;
00706     for (i=_variables.begin();i!=_variables.end();i++)
00707         i->second.Reset();
00708 }
00709 
00710 // Clears all variables from memory
00711 void Variables::Clear()
00712 {
00713     _variables.clear();
00714 }
00715 
00716 namespace BuiltinTables {
00717 
00718 // load Little Endian Unsigned number
00719 unsigned LEunumber(Section &data, Address addr, unsigned size)
00720 {
00721     unsigned result=0; 
00722     for (unsigned i=0;i<size;i++)
00723         result |= data[addr+i]<<(i<<3);
00724     return result;
00725 }
00726 
00727 // load Little Endian Signed number
00728 int LEsnumber(Section &data, Address addr, unsigned size)
00729 {
00730     unsigned u=LEunumber(data, addr, size);
00731     int i=u;
00732     //sign extension
00733     unsigned sign=((u>>((size<<3)-1))&1);
00734     for (unsigned j=size<<3;j<sizeof(int)<<3;j++)
00735         i|=sign<<j;
00736     return i;
00737 }
00738 
00739 // load Big Endian Unsigned number
00740 unsigned BEunumber(Section &data, Address addr, unsigned size)
00741 {
00742     unsigned result=0; 
00743     for (unsigned i=0;i<size;i++)
00744         result = result<<8 | data[addr+i];
00745     return result;
00746 }
00747 
00748 // load Big Endian Signed number
00749 int BEsnumber(Section &data, Address addr, unsigned size)
00750 {
00751     unsigned u=BEunumber(data, addr, size);
00752     int i=u;
00753     //sign extension
00754     unsigned sign=((u>>((size<<3)-1))&1);
00755     for (unsigned j=size<<3;j<sizeof(int)<<3;j++)
00756         i|=sign<<j;
00757     return i;
00758 }
00759 
00761 string imm2str(unsigned value, bool onlydecimal=false)
00762 {
00763     char *hex[16]={"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};
00764     if (value==0) return "0";
00765     string result;
00766     if (!onlydecimal)
00767     { //hexadecimal value
00768         if (value<10) return string(hex[value]);
00769         while (value)
00770         {
00771             result = string(hex[value&0xf]) + result;
00772             value>>=4;
00773         }
00774         result = string("0x")+result;
00775     }
00776     else //onlydecimal value
00777     {
00778         unsigned i=1;
00779         unsigned value10=value/10;
00780         while (i<=value10) i*=10;
00781         while (value>0)
00782         {
00783             result += string(hex[value/i]);
00784             value -= (value/i)*i;
00785             i/=10;
00786         }
00787     }
00788     return result;
00789 }
00790 
00791 string Ib::Decode(Section &data, Address addr, unsigned &size)
00792 {
00793     return imm2str(LEunumber(data, addr, size=1));
00794 }
00795 
00796 string Iw::Decode(Section &data, Address addr, unsigned &size)
00797 {
00798     return imm2str(LEunumber(data, addr, size=2));
00799 }
00800 
00801 string Id::Decode(Section &data, Address addr, unsigned &size)
00802 {
00803     unsigned number=LEunumber(data, addr, size=4);
00804     if (decinfo.binfile!=NULL && decinfo.binfile->ScanAddress(number))
00805     {
00806         symbols->checkaddress(number);
00807         if (decinfo.onlyname)
00808             return (*symbols)[number];
00809         else
00810             return (*symbols)[number]+"("+uint2hex(number)+")";
00811     }
00812     return imm2str(number);
00813 }
00814 
00815 string Ibw::Decode(Section &data, Address addr, unsigned &size)
00816 {
00817     return imm2str((unsigned)(LEsnumber(data, addr, size=1)) & 0xffff, true);
00818 }
00819 
00820 string Ibd::Decode(Section &data, Address addr, unsigned &size)
00821 {
00822     return imm2str((unsigned)(LEsnumber(data, addr, size=1)), true);
00823 }
00824 
00825 string SIb::Decode(Section &data, Address addr, unsigned &size)
00826 {
00827     int i=LEsnumber(data, addr, size=1);
00828     return (i<0) ? string("-")+imm2str(-i) : imm2str(i);
00829 }
00830 
00831 string SIw::Decode(Section &data, Address addr, unsigned &size)
00832 {
00833     int i=LEsnumber(data, addr, size=2);
00834     return (i<0) ? string("-")+imm2str(-i) : imm2str(i);
00835 }
00836 
00837 string SId::Decode(Section &data, Address addr, unsigned &size)
00838 {
00839     int i=LEsnumber(data, addr, size=4);
00840     unsigned number=static_cast<unsigned>(i);
00841     if (decinfo.binfile!=NULL && decinfo.binfile->ScanAddress(number))
00842     {
00843         symbols->checkaddress(number);
00844         if (decinfo.onlyname)
00845             return (*symbols)[number];
00846         else
00847             return (*symbols)[number]+"("+uint2hex(number)+")";
00848     }
00849     return (i<0) ? string("-")+imm2str(-i) : imm2str(i);
00850 }
00851 
00852 string SIbw::Decode(Section &data, Address addr, unsigned &size)
00853 {
00854     int i=static_cast<int>((unsigned)(LEsnumber(data, addr, size=1)) & 0xffff);
00855     return (i<0) ? string("-")+imm2str(-i, true) : imm2str(i, true);
00856 }
00857 
00858 string SIbd::Decode(Section &data, Address addr, unsigned &size)
00859 {
00860     int i=LEsnumber(data, addr, size=1);
00861     return (i<0) ? string("-")+imm2str(-i, true) : imm2str(i, true);
00862 }
00863 
00864 string Jb::Decode(Section &data, Address addr, unsigned &size)
00865 {
00866     unsigned a=addr+LEsnumber(data, addr, size=1)+1;
00867     symbols->checkaddress(a);
00868     if (decinfo.onlyname)
00869         return (*symbols)[a];
00870     else
00871         return (*symbols)[a]+"("+uint2hex(a)+")";
00872 }
00873 
00874 string Jw::Decode(Section &data, Address addr, unsigned &size)
00875 {
00876     unsigned a=addr+LEsnumber(data, addr, size=2)+2;
00877     symbols->checkaddress(a);
00878     if (decinfo.onlyname)
00879         return (*symbols)[a];
00880     else
00881         return (*symbols)[a]+"("+uint2hex(a)+")";
00882 }
00883 
00884 string Jd::Decode(Section &data, Address addr, unsigned &size)
00885 {
00886     unsigned a=addr+LEsnumber(data, addr, size=4)+4;
00887     symbols->checkaddress(a);
00888     if (decinfo.onlyname)
00889         return (*symbols)[a];
00890     else
00891         return (*symbols)[a]+"("+uint2hex(a)+")";
00892 }
00893 
00894 string Apw::Decode(Section &data, Address addr, unsigned &size)
00895 {
00896     unsigned ofs=LEsnumber(data, addr, size=2);
00897     unsigned seg=LEsnumber(data, addr+2, size=2);
00898     return uint2hex(seg, "")+":"+uint2hex(ofs, "");
00899 }
00900 
00901 string Apd::Decode(Section &data, Address addr, unsigned &size)
00902 {
00903     unsigned ofs=LEsnumber(data, addr, size=4);
00904     unsigned seg=LEsnumber(data, addr+4, size=2);
00905     return uint2hex(seg, "")+":"+uint2hex(ofs, "");
00906 }
00907 
00908 string Aw::Decode(Section &data, Address addr, unsigned &size)
00909 {
00910     unsigned a=LEunumber(data, addr, size=2);
00911     symbols->checkaddress(a);
00912     if (decinfo.onlyname)
00913         return (*symbols)[a];
00914     else
00915         return (*symbols)[a]+"("+uint2hex(a)+")";
00916 }
00917 
00918 string Ad::Decode(Section &data, Address addr, unsigned &size)
00919 {
00920     unsigned a=LEunumber(data, addr, size=4);
00921     symbols->checkaddress(a);
00922     if (decinfo.onlyname)
00923         return (*symbols)[a];
00924     else
00925         return (*symbols)[a]+"("+uint2hex(a)+")";
00926 }
00927 
00928 string BIb::Decode(Section &data, Address addr, unsigned &size)
00929 {
00930     return imm2str(BEunumber(data, addr, size=1));
00931 }
00932 
00933 string BIw::Decode(Section &data, Address addr, unsigned &size)
00934 {
00935     return imm2str(BEunumber(data, addr, size=2));
00936 }
00937 
00938 string BId::Decode(Section &data, Address addr, unsigned &size)
00939 {
00940     unsigned number=BEunumber(data, addr, size=4);
00941     if (decinfo.binfile!=NULL && decinfo.binfile->ScanAddress(number))
00942     {
00943         symbols->checkaddress(number);
00944         if (decinfo.onlyname)
00945             return (*symbols)[number];
00946         else
00947             return (*symbols)[number]+"("+uint2hex(number)+")";
00948     }
00949     return imm2str(number);
00950 }
00951 
00952 string BIbw::Decode(Section &data, Address addr, unsigned &size)
00953 {
00954     return imm2str((unsigned)(BEsnumber(data, addr, size=1)) & 0xffff);
00955 }
00956 
00957 string BIbd::Decode(Section &data, Address addr, unsigned &size)
00958 {
00959     return imm2str((unsigned)(BEsnumber(data, addr, size=1)));
00960 }
00961 
00962 string SBIb::Decode(Section &data, Address addr, unsigned &size)
00963 {
00964     int i=BEsnumber(data, addr, size=1);
00965     return (i<0) ? string("-")+imm2str(-i) : imm2str(i);
00966 }
00967 
00968 string SBIw::Decode(Section &data, Address addr, unsigned &size)
00969 {
00970     int i=BEsnumber(data, addr, size=2);
00971     return (i<0) ? string("-")+imm2str(-i) : imm2str(i);
00972 }
00973 
00974 string SBId::Decode(Section &data, Address addr, unsigned &size)
00975 {
00976     int i=LEsnumber(data, addr, size=4);
00977     unsigned number=static_cast<unsigned>(i);
00978     if (decinfo.binfile!=NULL && decinfo.binfile->ScanAddress(number))
00979     {
00980         symbols->checkaddress(number);
00981         if (decinfo.onlyname)
00982             return (*symbols)[number];
00983         else
00984             return (*symbols)[number]+"("+uint2hex(number)+")";
00985     }
00986     return (i<0) ? string("-")+imm2str(-i) : imm2str(i);
00987 }
00988 
00989 string SBIbw::Decode(Section &data, Address addr, unsigned &size)
00990 {
00991     int i=static_cast<int>((unsigned)(BEsnumber(data, addr, size=1)) & 0xffff);
00992     return (i<0) ? string("-")+imm2str(-i) : imm2str(i);
00993 }
00994 
00995 string SBIbd::Decode(Section &data, Address addr, unsigned &size)
00996 {
00997     int i=BEsnumber(data, addr, size=1);
00998     return (i<0) ? string("-")+imm2str(-i) : imm2str(i);
00999 }
01000 
01001 string BJb::Decode(Section &data, Address addr, unsigned &size)
01002 {
01003     unsigned a=addr+BEsnumber(data, addr, size=1)+1;
01004     symbols->checkaddress(a);
01005     if (decinfo.onlyname)
01006         return (*symbols)[a];
01007     else
01008         return (*symbols)[a]+"("+uint2hex(a)+")";
01009 }
01010 
01011 string BJw::Decode(Section &data, Address addr, unsigned &size)
01012 {
01013     unsigned a=addr+BEsnumber(data, addr, size=2)+2;
01014     symbols->checkaddress(a);
01015     if (decinfo.onlyname)
01016         return (*symbols)[a];
01017     else
01018         return (*symbols)[a]+"("+uint2hex(a)+")";
01019 }
01020 
01021 string BJd::Decode(Section &data, Address addr, unsigned &size)
01022 {
01023     unsigned a=addr+BEsnumber(data, addr, size=4)+4;
01024     symbols->checkaddress(a);
01025     if (decinfo.onlyname)
01026         return (*symbols)[a];
01027     else
01028         return (*symbols)[a]+"("+uint2hex(a)+")";
01029 }
01030 
01031 string BApw::Decode(Section &data, Address addr, unsigned &size)
01032 {
01033     unsigned ofs=BEsnumber(data, addr, size=2);
01034     unsigned seg=BEsnumber(data, addr+2, size=2);
01035     return uint2hex(seg, "")+":"+uint2hex(ofs, "");
01036 }
01037 
01038 string BApd::Decode(Section &data, Address addr, unsigned &size)
01039 {
01040     unsigned ofs=BEsnumber(data, addr, size=4);
01041     unsigned seg=BEsnumber(data, addr+4, size=2);
01042     return uint2hex(seg, "")+":"+uint2hex(ofs, "");
01043 }
01044 
01045 string BAw::Decode(Section &data, Address addr, unsigned &size)
01046 {
01047     unsigned a=BEunumber(data, addr, size=2);
01048     symbols->checkaddress(a);
01049     if (decinfo.onlyname)
01050         return (*symbols)[a];
01051     else
01052         return (*symbols)[a]+"("+uint2hex(a)+")";
01053 }
01054 
01055 string BAd::Decode(Section &data, Address addr, unsigned &size)
01056 {
01057     unsigned a=BEunumber(data, addr, size=4);
01058     symbols->checkaddress(a);
01059     if (decinfo.onlyname)
01060         return (*symbols)[a];
01061     else
01062         return (*symbols)[a]+"("+uint2hex(a)+")";
01063 }
01064 
01065 } //namespace BuiltinTables