Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

elf_analy.cc

Go to the documentation of this file.
00001 /* 
00002  *      HT Editor
00003  *      elf_analy.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 "analy.h"
00022 #include "analy_alpha.h"
00023 #include "analy_names.h"
00024 #include "analy_ia64.h"
00025 #include "analy_ppc.h"
00026 #include "analy_register.h"
00027 #include "analy_x86.h"
00028 #include "global.h"
00029 #include "elf_analy.h"
00030 
00031 #include "htctrl.h"
00032 #include "htdebug.h"
00033 #include "htiobox.h"
00034 #include "htelf.h"
00035 #include "htstring.h"
00036 #include "pestruct.h"
00037 #include "snprintf.h"
00038 #include "x86asm.h"
00039 
00040 extern "C" {
00041 #include "demangle.h"
00042 }
00043 
00044 #include <stdio.h>
00045 #include <stdlib.h>
00046 #include <string.h>
00047 
00048 /*
00049  *
00050  */
00051  
00052 void ElfAnalyser::init(ht_elf_shared_data *Elf_shared, ht_streamfile *File)
00053 {
00054         elf_shared = Elf_shared;
00055         file = File;
00056 
00057         validarea = new Area();
00058         validarea->init();
00059 
00060         Analyser::init();
00061 }
00062 
00063 void ElfAnalyser::beginAnalysis()
00064 {
00065         Address *entry = NULL;
00066         bool c32 = false;
00067         switch (elf_shared->ident.e_ident[ELF_EI_CLASS]) {
00068                 case ELFCLASS32: {
00069                         entry = createAddress32(elf_shared->header32.e_entry);
00070                         c32 = true;
00071                         break;
00072                 }
00073                 case ELFCLASS64: {
00074                         entry = createAddress64(elf_shared->header64.e_entry);
00075                         c32 = false;
00076                         break;
00077                 }
00078         }
00079 
00080         if (!validAddress(entry, scvalid)) {
00081                 delete entry;
00082                 entry = NULL;
00083         }
00084 
00085         setLocationTreeOptimizeThreshold(100);
00086         setSymbolTreeOptimizeThreshold(100);
00087 
00088         /*
00089          *      give all sections a descriptive comment:
00090          */
00091         ELF_SECTION_HEADER32 *s32=elf_shared->sheaders.sheaders32;
00092         ELF_SECTION_HEADER64 *s64=elf_shared->sheaders.sheaders64;
00093         char blub[100];
00094         for (uint i=0; i < elf_shared->sheaders.count; i++) {
00095                 Address *secaddr;
00096                 if (c32) {
00097 //                      fprintf(stderr, "desc sec %d, %08x\n", i, s32->sh_addr);
00098                         secaddr = createAddress32(s32->sh_addr);
00099                 } else {
00100                         secaddr = createAddress64(s64->sh_addr);
00101                 }
00102                 if (validAddress(secaddr, scvalid)) {
00103 //                      fprintf(stderr, "valid!\n");
00104                         ht_snprintf(blub, sizeof blub, ";  section %d <%s>", i, getSegmentNameByAddress(secaddr));
00105                         addComment(secaddr, 0, "");
00106                         addComment(secaddr, 0, ";******************************************************************");
00107                         addComment(secaddr, 0, blub);
00108                         ht_snprintf(blub, sizeof blub, ";  virtual address  %08x  virtual size   %08x", s32->sh_addr, s32->sh_size);
00109                         addComment(secaddr, 0, blub);
00110                         if (validAddress(secaddr, scinitialized)) {
00111                                 ht_snprintf(blub, sizeof blub, ";  file offset      %08x  file size      %08x", s32->sh_offset, s32->sh_size);
00112                         } else {
00113                                 ht_snprintf(blub, sizeof blub, ";  section is not in file");
00114                         }
00115                         addComment(secaddr, 0, blub);
00116                         addComment(secaddr, 0, ";******************************************************************");
00117 
00118                         // mark end of sections
00119                         ht_snprintf(blub, sizeof blub, ";  end of section <%s>", getSegmentNameByAddress(secaddr));
00120                         Address *secend_addr = (Address *)secaddr->duplicate();
00121                         if (c32) {
00122                                 secend_addr->add(s32->sh_size);
00123                         } else {
00124                                 secend_addr->add(s64->sh_size.lo);
00125                         }
00126                         newLocation(secend_addr)->flags |= AF_FUNCTION_END;
00127                         addComment(secend_addr, 0, "");
00128                         addComment(secend_addr, 0, ";******************************************************************");
00129                         addComment(secend_addr, 0, blub);
00130                         addComment(secend_addr, 0, ";******************************************************************");
00131 
00132                         validarea->add(secaddr, secend_addr);
00133 
00134                         delete secend_addr;
00135                 }
00136                 delete secaddr;
00137                 s32++;
00138                 s64++;
00139         }
00140 
00141         /* symbols */
00142         if (c32) {
00143                 for (uint i=1; i<elf_shared->sheaders.count; i++) {
00144                         if ((elf_shared->sheaders.sheaders32[i].sh_type==ELF_SHT_SYMTAB) || (elf_shared->sheaders.sheaders32[i].sh_type==ELF_SHT_DYNSYM)) {
00145                                 initInsertSymbols(i);
00146                         }
00147                 }
00148                 initInsertFakeSymbols();
00149         } else {
00150                 for (uint i=1; i<elf_shared->sheaders.count; i++) {
00151                         if ((elf_shared->sheaders.sheaders64[i].sh_type==ELF_SHT_SYMTAB) || (elf_shared->sheaders.sheaders64[i].sh_type==ELF_SHT_DYNSYM)) {
00152                                 initInsertSymbols(i);
00153                         }
00154                 }
00155         }
00156 
00157         /*
00158          *      entrypoint
00159          */
00160         if (entry) {
00161                 pushAddress(entry, entry);
00162                 assignSymbol(entry, "entrypoint", label_func);
00163                 addComment(entry, 0, "");
00164                 addComment(entry, 0, ";****************************");
00165                 switch (c32 ? elf_shared->header32.e_type : elf_shared->header64.e_type) {
00166                 case ELF_ET_DYN:
00167                         addComment(entry, 0, ";  dynamic executable entry point");
00168                         break;
00169                 case ELF_ET_EXEC:
00170                         addComment(entry, 0, ";  executable entry point");
00171                         break;
00172                 default:
00173                         addComment(entry, 0, ";  entry point");               
00174                 }
00175                 addComment(entry, 0, ";****************************");
00176                 delete entry;
00177         }
00178 
00179         setLocationTreeOptimizeThreshold(1000);
00180         setSymbolTreeOptimizeThreshold(1000);
00181 
00182         Analyser::beginAnalysis();
00183 }
00184 
00185 /*
00186  *
00187  */
00188 void ElfAnalyser::initInsertFakeSymbols()
00189 {
00190         if (!elf_shared->undefined2fakeaddr) return;
00191         sectionAndIdx *key = NULL;
00192         ht_data_uint32 *value;
00193         while ((key = (sectionAndIdx*)elf_shared->undefined2fakeaddr->enum_next(
00194         (Object**)&value, key))) {
00195                 Address *address = createAddress32(value->value);
00196                 FILEOFS h = elf_shared->sheaders.sheaders32[key->secidx].sh_offset;
00197                 ELF_SYMBOL32 sym;
00198                 file->seek(h+key->symidx*sizeof (ELF_SYMBOL32));
00199                 file->read(&sym, sizeof sym);
00200                 create_host_struct(&sym, ELF_SYMBOL32_struct, elf_shared->byte_order);
00201 
00202                 FILEOFS sto = elf_shared->sheaders.sheaders32[
00203                         elf_shared->sheaders.sheaders32[key->secidx].sh_link].sh_offset;
00204                 file->seek(sto+sym.st_name);
00205                 char *name = fgetstrz(file);
00206                 char buf[1024];
00207                 ht_snprintf(buf, sizeof buf, "undef_%s", name);
00208                 free(name);
00209                 make_valid_name(buf, buf);
00210                 assignSymbol(address, buf, label_func);
00211         }
00212 }
00213 
00214 void ElfAnalyser::initInsertSymbols(int shidx)
00215 {
00216         char elf_buffer[1024];
00217         if (elf_shared->ident.e_ident[ELF_EI_CLASS] == ELFCLASS32) {
00218                 FILEOFS h = elf_shared->sheaders.sheaders32[shidx].sh_offset;
00219                 FILEOFS sto = elf_shared->sheaders.sheaders32[elf_shared->sheaders.sheaders32[shidx].sh_link].sh_offset;
00220                 uint symnum = elf_shared->sheaders.sheaders32[shidx].sh_size / sizeof (ELF_SYMBOL32);
00221 
00222                 int *entropy = random_permutation(symnum);
00223                 for (uint i=0; i<symnum; i++) {
00224                         ELF_SYMBOL32 sym;
00225                         if (entropy[i] == 0) continue;
00226                         file->seek(h+entropy[i]*sizeof (ELF_SYMBOL32));
00227                         file->read(&sym, sizeof sym);
00228                         create_host_struct(&sym, ELF_SYMBOL32_struct, elf_shared->byte_order);
00229 
00230                         file->seek(sto+sym.st_name);
00231                         char *name = fgetstrz(file);
00232                         if (!name) continue;
00233 
00234                         switch (sym.st_shndx) {
00235                                 case ELF_SHN_UNDEF:
00236                                         break;
00237                                 case ELF_SHN_ABS:
00238                                         break;
00239                                 case ELF_SHN_COMMON:
00240                                         break;
00241                                 default: {
00242                                         // sym.st_shndx
00243                                         break;
00244                                 }
00245                         }
00246 
00247                         char *bind;
00248                         switch (ELF32_ST_BIND(sym.st_info)) {
00249                                 case ELF_STB_LOCAL:
00250                                         bind="local";
00251                                         break;
00252                                 case ELF_STB_GLOBAL:
00253                                         bind="global";
00254                                         break;
00255                                 case ELF_STB_WEAK:
00256                                         bind="weak";
00257                                         break;
00258                                 default:
00259                                         bind="?";
00260                                         break;
00261                         }
00262 
00263                         switch (ELF32_ST_TYPE(sym.st_info)) {
00264                                 case ELF_STT_NOTYPE:
00265                                 case ELF_STT_FUNC: {
00266                                         char *label = name;
00267                                         if (!getSymbolByName(label)) {
00268                                                 elf32_addr sym_addr = sym.st_value;
00269                                                 if (elf_shared->shrelocs && (sym.st_shndx>0) && (sym.st_shndx<elf_shared->sheaders.count)
00270                                                 && elf_shared->shrelocs[sym.st_shndx].relocAddr) {
00271                                                         sym_addr += elf_shared->shrelocs[sym.st_shndx].relocAddr;
00272                                                 }
00273                                                 Address *address = createAddress32(sym_addr);
00274                                                 if (validAddress(address, scvalid)) {
00275                                                         char *demangled = cplus_demangle(label, DMGL_PARAMS | DMGL_ANSI);
00276 
00277                                                         make_valid_name(label, label);
00278 
00279                                                         ht_snprintf(elf_buffer, sizeof elf_buffer, "; function %s (%s)", (demangled) ? demangled : label, bind);
00280 
00281                                                         if (demangled) free(demangled);
00282 
00283                                                         addComment(address, 0, "");
00284                                                         addComment(address, 0, ";********************************************************");
00285                                                         addComment(address, 0, elf_buffer);
00286                                                         addComment(address, 0, ";********************************************************");
00287                                                         pushAddress(address, address);
00288                                                         assignSymbol(address, label, label_func);
00289                                                 }
00290                                                 delete address;
00291                                         }
00292                                         break;
00293                                 }
00294                                 case ELF_STT_OBJECT: {
00295                                         char *label = name;
00296                                         if (!getSymbolByName(label)) {
00297                                                 Address *address = createAddress32(sym.st_value);
00298                                                 if (validAddress(address, scvalid)) {
00299 
00300                                                         char *demangled = cplus_demangle(label, DMGL_PARAMS | DMGL_ANSI);
00301                                         
00302                                                         make_valid_name(label, label);
00303                                         
00304                                                         ht_snprintf(elf_buffer, sizeof elf_buffer, "; data object %s, size %d (%s)", (demangled) ? demangled : label, sym.st_size, bind);
00305 
00306                                                         if (demangled) free(demangled);
00307 
00308                                                         addComment(address, 0, "");
00309                                                         addComment(address, 0, ";********************************************************");
00310                                                         addComment(address, 0, elf_buffer);
00311                                                         addComment(address, 0, ";********************************************************");
00312                                                         assignSymbol(address, label, label_data);
00313                                                 }
00314                                                 delete address;
00315                                         }
00316                                         break;
00317                                 }
00318                                 case ELF_STT_SECTION:
00319                                 case ELF_STT_FILE:
00320                                         break;
00321                         }
00322                         free(name);
00323                 }
00324                 if (entropy) free(entropy);
00325         } else {
00326                 // FIXME: 64 bit
00327                 FILEOFS h=elf_shared->sheaders.sheaders64[shidx].sh_offset.lo;
00328                 FILEOFS sto=elf_shared->sheaders.sheaders64[elf_shared->sheaders.sheaders64[shidx].sh_link].sh_offset.lo;
00329                 uint symnum=elf_shared->sheaders.sheaders64[shidx].sh_size.lo / sizeof (ELF_SYMBOL64);
00330 
00331                 int *entropy = random_permutation(symnum);
00332                 for (uint i=0; i<symnum; i++) {
00333                         ELF_SYMBOL64 sym;
00334                         if (entropy[i] == 0) continue;
00335                         file->seek(h+entropy[i]*sizeof (ELF_SYMBOL64));
00336                         file->read(&sym, sizeof sym);
00337                         create_host_struct(&sym, ELF_SYMBOL64_struct, elf_shared->byte_order);
00338 
00339                         file->seek(sto+sym.st_name);
00340                         char *name = fgetstrz(file);
00341                         if (!name) continue;
00342 
00343                         switch (sym.st_shndx) {
00344                                 case ELF_SHN_UNDEF:
00345                                         break;
00346                                 case ELF_SHN_ABS:
00347                                         break;
00348                                 case ELF_SHN_COMMON:
00349                                         break;
00350                                 default: {
00351                                         // sym.st_shndx
00352                                         break;
00353                                 }
00354                         }
00355 
00356                         char *bind;
00357                         switch (ELF64_ST_BIND(sym.st_info)) {
00358                                 case ELF_STB_LOCAL:
00359                                         bind="local";
00360                                         break;
00361                                 case ELF_STB_GLOBAL:
00362                                         bind="global";
00363                                         break;
00364                                 case ELF_STB_WEAK:
00365                                         bind="weak";
00366                                         break;
00367                                 default:
00368                                         bind="?";
00369                                         break;
00370                         }
00371 
00372                         switch (ELF64_ST_TYPE(sym.st_info)) {
00373                                 case ELF_STT_NOTYPE:
00374                                 case ELF_STT_FUNC: {
00375                                         char *label = name;
00376                                         if (!getSymbolByName(label)) {
00377                                                 Address *address = createAddress64(sym.st_value);
00378 
00379                                                 char *demangled = cplus_demangle(label, DMGL_PARAMS | DMGL_ANSI);
00380 
00381                                                 make_valid_name(label, label);
00382 
00383                                                 ht_snprintf(elf_buffer, sizeof elf_buffer, "; function %s (%s)", (demangled) ? demangled : label, bind);
00384 
00385                                                 if (demangled) free(demangled);
00386 
00387                                                 addComment(address, 0, "");
00388                                                 addComment(address, 0, ";********************************************************");
00389                                                 addComment(address, 0, elf_buffer);
00390                                                 addComment(address, 0, ";********************************************************");
00391                                                 pushAddress(address, address);
00392                                                 assignSymbol(address, label, label_func);
00393                                                 
00394                                                 delete address;
00395                                         }
00396                                         break;
00397                                 }
00398                                 case ELF_STT_OBJECT: {
00399                                         char *label = name;
00400                                         if (!getSymbolByName(label)) {
00401                                                 Address *address = createAddress64(sym.st_value);
00402 
00403                                                 char *demangled = cplus_demangle(label, DMGL_PARAMS | DMGL_ANSI);
00404                                         
00405                                                 make_valid_name(label, label);
00406                                         
00407                                                 ht_snprintf(elf_buffer, sizeof elf_buffer, "; data object %s, size %d (%s)", (demangled) ? demangled : label, sym.st_size.lo, bind);
00408 
00409                                                 if (demangled) free(demangled);
00410 
00411                                                 addComment(address, 0, "");
00412                                                 addComment(address, 0, ";********************************************************");
00413                                                 addComment(address, 0, elf_buffer);
00414                                                 addComment(address, 0, ";********************************************************");
00415                                                 assignSymbol(address, label, label_data);
00416                                                 
00417                                                 delete address;
00418                                         }
00419                                         break;
00420                                 }
00421                                 case ELF_STT_SECTION:
00422                                 case ELF_STT_FILE:
00423                                         break;
00424                         }
00425                         free(name);
00426                 }
00427                 if (entropy) free(entropy);
00428         }
00429 }
00430 
00431 /*
00432  *
00433  */
00434 int ElfAnalyser::load(ht_object_stream *f)
00435 {
00436         GET_OBJECT(f, validarea);
00437         return Analyser::load(f);
00438 }
00439 
00440 /*
00441  *
00442  */
00443 void ElfAnalyser::done()
00444 {
00445         validarea->done();
00446         delete validarea;
00447         Analyser::done();
00448 }
00449 
00450 OBJECT_ID ElfAnalyser::object_id() const
00451 {
00452         return ATOM_ELF_ANALYSER;
00453 }
00454 
00455 /*
00456  *
00457  */
00458 uint ElfAnalyser::bufPtr(Address *Addr, byte *buf, int size)
00459 {
00460         FILEOFS ofs = addressToFileofs(Addr);
00461 /*     if (ofs == INVALID_FILE_OFS) {
00462                 int as = 1;
00463         }*/
00464         assert(ofs != INVALID_FILE_OFS);
00465         file->seek(ofs);
00466         return file->read(buf, size);
00467 }
00468 
00469 bool ElfAnalyser::convertAddressToELFAddress(Address *addr, ELFAddress *r)
00470 {
00471         if (addr->object_id()==ATOM_ADDRESS_FLAT_32) {
00472                 r->a32 = ((AddressFlat32*)addr)->addr;
00473                 return true;
00474         } else if (addr->object_id()==ATOM_ADDRESS_X86_FLAT_32) {
00475                 r->a32 = ((AddressX86Flat32*)addr)->addr;
00476                 return true;
00477         } else if (addr->object_id()==ATOM_ADDRESS_FLAT_64) {
00478                 r->a64.lo = ((AddressFlat64*)addr)->addr.lo;
00479                 r->a64.hi = ((AddressFlat64*)addr)->addr.hi;
00480                 return true;
00481         } else {
00482                 return false;
00483         }
00484 }
00485 
00486 Address *ElfAnalyser::createAddress()
00487 {
00488         switch (elf_shared->ident.e_ident[ELF_EI_CLASS]) {
00489                         case ELFCLASS32: {
00490                                 switch (elf_shared->header32.e_machine) {
00491                                         case ELF_EM_386:
00492                                                 return new AddressX86Flat32();
00493                                 }
00494                                 return new AddressFlat32();
00495                         }
00496                         case ELFCLASS64: {
00497 /*                              switch (elf_shared->header32.e_machine) {
00498                                         case ELF_EM_386:
00499                                                 return new AddressX86Flat32(0);
00500                                 }*/
00501                                 return new AddressFlat64();
00502                         }
00503         }
00504         return new AddressFlat32();
00505 }
00506 
00507 Address *ElfAnalyser::createAddress32(dword addr)
00508 {
00509         switch (elf_shared->header32.e_machine) {
00510                 case ELF_EM_386:
00511                         return new AddressX86Flat32(addr);
00512         }
00513         return new AddressFlat32(addr);
00514 }
00515 
00516 Address *ElfAnalyser::createAddress64(qword addr)
00517 {
00518         return new AddressFlat64(addr);
00519 }
00520 
00521 /*
00522  *
00523  */
00524 Assembler *ElfAnalyser::createAssembler()
00525 {
00526         switch (elf_shared->header32.e_machine) {
00527                 case ELF_EM_386:
00528                         Assembler *a = new x86asm(X86_OPSIZE32, X86_ADDRSIZE32);
00529                         a->init();
00530                         return a;
00531         }
00532         return NULL;
00533 }
00534 
00535 /*
00536  *
00537  */
00538 FILEOFS ElfAnalyser::addressToFileofs(Address *Addr)
00539 {
00540         if (validAddress(Addr, scinitialized)) {
00541                 dword ofs;
00542                 ELFAddress ea;
00543                 if (!convertAddressToELFAddress(Addr, &ea)) return INVALID_FILE_OFS;
00544                 if (!elf_addr_to_ofs(&elf_shared->sheaders, elf_shared->ident.e_ident[ELF_EI_CLASS], ea, &ofs)) return INVALID_FILE_OFS;
00545                 return ofs;
00546         } else {
00547                 return INVALID_FILE_OFS;
00548         }
00549 }
00550 
00551 /*
00552  *
00553  */
00554 
00555 char *ElfAnalyser::getSegmentNameByAddress(Address *Addr)
00556 {
00557         static char elf_sectionname[33];
00558         elf_section_headers *sections=&elf_shared->sheaders;
00559         int i;
00560         ELFAddress ea;
00561         if (!convertAddressToELFAddress(Addr, &ea)) return NULL;
00562         if (!elf_addr_to_section(sections, elf_shared->ident.e_ident[ELF_EI_CLASS], ea, &i)) return NULL;
00563         if (i == elf_shared->fake_undefined_shidx) {
00564                 strcpy(elf_sectionname, "$$HT_FAKE$$");
00565         } else {
00566                 strncpy(elf_sectionname, elf_shared->shnames[i], 32);
00567                 elf_sectionname[32] = 0;
00568         }
00569         return elf_sectionname;
00570 }
00571 
00572 /*
00573  *
00574  */
00575 const char *ElfAnalyser::getName()
00576 {
00577         return file->get_desc();
00578 }
00579 
00580 /*
00581  *
00582  */
00583 const char *ElfAnalyser::getType()
00584 {
00585         return "ELF/Analyser";
00586 }
00587 
00588 /*
00589  *
00590  */
00591 void ElfAnalyser::initCodeAnalyser()
00592 {
00593         Analyser::initCodeAnalyser();
00594 }
00595 
00596 /*
00597  *
00598  */
00599 void ElfAnalyser::initUnasm()
00600 {
00601         DPRINTF("elf_analy: ");
00602         int machine = 0;
00603         bool elf64 = false;
00604         switch (elf_shared->ident.e_ident[ELF_EI_CLASS]) {
00605                 case ELFCLASS32: machine = elf_shared->header32.e_machine; break;
00606                 case ELFCLASS64: machine = elf_shared->header64.e_machine; elf64 = true; break;
00607         }
00608         switch (machine) {
00609                 case ELF_EM_386: // Intel
00610                         DPRINTF("initing analy_x86_disassembler\n");
00611                         analy_disasm = new AnalyX86Disassembler();
00612                         ((AnalyX86Disassembler*)analy_disasm)->init(this, elf64 ? ANALYX86DISASSEMBLER_FLAGS_FLAT64 : 0);
00613                         break;
00614                 case ELF_EM_IA_64: // Intel ia64
00615                         if (elf_shared->ident.e_ident[ELF_EI_CLASS] != ELFCLASS64) {
00616                                 errorbox("Intel IA64 cant be used in a 32-Bit ELF.");
00617                         } else {
00618                                 analy_disasm = new AnalyIA64Disassembler();
00619                                 ((AnalyIA64Disassembler*)analy_disasm)->init(this);
00620                         }
00621                         break;
00622                 case ELF_EM_PPC: // PowerPC
00623                         if (elf_shared->ident.e_ident[ELF_EI_CLASS] != ELFCLASS32) {
00624                                 errorbox("Intel PowerPC cant be used in a 64-Bit ELF.");
00625                         } else {
00626                                 DPRINTF("initing analy_ppc_disassembler\n");
00627                                 analy_disasm = new AnalyPPCDisassembler();
00628                                 ((AnalyPPCDisassembler*)analy_disasm)->init(this);
00629                         }
00630                         break;
00631                 case ELF_EM_PPC64: // PowerPC64
00632                         if (elf_shared->ident.e_ident[ELF_EI_CLASS] != ELFCLASS64) {
00633                                 errorbox("Intel PowerPC64 cant be used in a 32-Bit ELF.");
00634                         } else {
00635                                 DPRINTF("initing analy_ppc_disassembler\n");
00636                                 analy_disasm = new AnalyPPCDisassembler();
00637                                 ((AnalyPPCDisassembler*)analy_disasm)->init(this);
00638                         }
00639                         break;
00640                 default:
00641                         DPRINTF("no apropriate disassembler for machine %04x\n", machine);
00642                         warnbox("No disassembler for unknown machine type %04x!", machine);
00643         }
00644 }
00645 
00646 /*
00647  *
00648  */
00649 void ElfAnalyser::log(const char *msg)
00650 {
00651         /*
00652          *      log() does to much traffic so dont log
00653          *   perhaps we reactivate this later
00654          *
00655          */
00656 /*      LOG(msg);*/
00657 }
00658 
00659 /*
00660  *
00661  */
00662 Address *ElfAnalyser::nextValid(Address *Addr)
00663 {
00664         return (Address *)validarea->findNext(Addr);
00665 }
00666 
00667 /*
00668  *
00669  */
00670 void ElfAnalyser::store(ht_object_stream *f)
00671 {
00672         PUT_OBJECT(f, validarea);
00673         Analyser::store(f);
00674 }
00675 
00676 /*
00677  *
00678  */
00679 int ElfAnalyser::queryConfig(int mode)
00680 {
00681         switch (mode) {
00682                 case Q_DO_ANALYSIS:
00683                 case Q_ENGAGE_CODE_ANALYSER:
00684                 case Q_ENGAGE_DATA_ANALYSER:
00685                         return true;
00686                 default:
00687                         return 0;
00688         }
00689 }
00690 
00691 /*
00692  *
00693  */
00694 Address *ElfAnalyser::fileofsToAddress(FILEOFS fileofs)
00695 {
00696         ELFAddress ea;
00697         if (elf_ofs_to_addr(&elf_shared->sheaders, elf_shared->ident.e_ident[ELF_EI_CLASS], fileofs, &ea)) {
00698                 switch (elf_shared->ident.e_ident[ELF_EI_CLASS]) {          
00699                         case ELFCLASS32: return createAddress32(ea.a32);
00700                         case ELFCLASS64: return createAddress64(ea.a64);
00701                 }
00702                 return new InvalidAddress();
00703         } else {
00704                 return new InvalidAddress();
00705         }
00706 }
00707 
00708 /*
00709  *
00710  */
00711 bool ElfAnalyser::validAddress(Address *Addr, tsectype action)
00712 {
00713         elf_section_headers *sections=&elf_shared->sheaders;
00714         int sec;
00715         byte cls = elf_shared->ident.e_ident[ELF_EI_CLASS];
00716         ELFAddress ea;
00717         if (!convertAddressToELFAddress(Addr, &ea)) return false;
00718         if (!elf_addr_to_section(sections, cls, ea, &sec)) return false;
00719         switch (cls) {
00720                 case ELFCLASS32: {
00721                         ELF_SECTION_HEADER32 *s=sections->sheaders32+sec;
00722                         switch (action) {
00723                                 case scvalid:
00724                                         return true;
00725                                 case scread:
00726                                         return true;
00727                                 case scwrite:
00728                                 case screadwrite:
00729                                         return s->sh_flags & ELF_SHF_WRITE;
00730                                 case sccode:
00731                                         return (s->sh_flags & ELF_SHF_EXECINSTR) && (s->sh_type==ELF_SHT_PROGBITS);
00732                                 case scinitialized:
00733                                         return s->sh_type==ELF_SHT_PROGBITS;
00734                         }
00735                         return false;
00736                 }
00737                 case ELFCLASS64: {
00738                         ELF_SECTION_HEADER64 *s=sections->sheaders64+sec;
00739                         switch (action) {
00740                                 case scvalid:
00741                                         return true;
00742                                 case scread:
00743                                         return true;
00744                                 case scwrite:
00745                                 case screadwrite:
00746                                         return s->sh_flags.lo & ELF_SHF_WRITE;
00747                                 case sccode:
00748                                         return (s->sh_flags.lo & ELF_SHF_EXECINSTR) && (s->sh_type==ELF_SHT_PROGBITS);
00749                                 case scinitialized:
00750                                         return s->sh_type==ELF_SHT_PROGBITS;
00751                         }
00752                         return false;
00753                 }
00754         }
00755         return false;
00756 }

Generated on Fri May 7 21:15:30 2004 by doxygen 1.3.5