UnivesalDisassembler(2003)
|
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