00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include <sys/mman.h>
00046 #include <sys/stat.h>
00047 #include <sys/types.h>
00048 #include <stdlib.h>
00049 #include <string.h>
00050 #include <fcntl.h>
00051 #include <stdio.h>
00052 #include <unistd.h>
00053
00054 #include "elf_reader.h"
00055 #define EM_MIPS_RS4_BE 10 // from osprey/linux/include/elf_stuff.h
00056
00057
00058
00059
00060
00061
00062
00063
00064 #if defined NO_MESSG
00065 #define FmtAssert(A,B) ;
00066 #define ErrMsg(A,B) ;
00067 #define FatalMsg(A,B) ;
00068 #endif
00069
00070
00072
00073
00074
00075
00077
00078 ELF_object::ELF_object(char* elf_file) : _elfHeader(NULL),
00079 _secHdrs(NULL),
00080 _symTable(NULL),
00081 _progHdrs(NULL)
00082 {
00083 size_t fd;
00084
00085 struct stat filestat;
00086 unsigned char* mmap_ptr;
00087
00088 if(elf_file) {
00089 #ifdef _SL1_VERSION_CHECK
00090 if ( ((UINT)-1 == (fd = open(elf_file, O_RDWR, 0664))) ||
00091 #else
00092 if ( ((UINT)-1 == (fd = open(elf_file, O_RDONLY, 0664))) ||
00093 #endif
00094 (-1 == fstat(fd,&filestat)))
00095 {
00096 close(fd);
00097 throw(STRING("Object file open error\n"));
00098 }
00099 }
00100
00101 if (MAP_FAILED == (mmap_ptr = (unsigned char*) mmap(0,
00102 filestat.st_size,
00103 #ifdef _SL1_VERSION_CHECK
00104 PROT_READ | PROT_WRITE,
00105 #else
00106 PROT_READ,
00107 #endif
00108
00109 MAP_SHARED,
00110 fd,
00111 0)))
00112 {
00113 close(fd);
00114 throw(STRING("Map error\n"));
00115 }
00116
00117
00118 _elfHeader = new ELFHdr((Elf32_Ehdr*)mmap_ptr);
00119 if(_elfHeader==NULL)
00120 {
00121 close(fd);
00122 throw(STRING("Failure in construction of ELFHdr\n"));
00123 }
00124
00125 if ((_elfHeader->e_ident_EI_CLASS() == ELFCLASS64)) {
00126 #include "elf_reader64.h"
00127 _is32bit = FALSE;
00128
00129 if ((_elfHeader->e_machine() != EM_X86_64) && (_elfHeader->e_machine() != EM_IA_64)) {
00130 close(fd);
00131 throw(STRING("Bad elf64 file, not supported arch"));
00132 }
00133
00134 }
00135 else {
00136 _is32bit = TRUE;
00137
00138 INT m = (INT)_elfHeader->e_machine();
00139 if ((m != EM_MIPS) && (m != EM_386) && (m != EM_MIPS_RS4_BE))
00140 {
00141 close(fd);
00142 throw(STRING("Bad elf file (non-Mips/Pac object file)\n"));
00143
00144
00145 }
00146
00147 if (_elfHeader->e_ident_EI_DATA() != ELFDATA2LSB ) {
00148 close(fd);
00149 throw(STRING("Incorrect endianness\n"));
00150 }
00151
00152
00153 _secHdrs = new SecHdrTable(mmap_ptr,_elfHeader);
00154
00155 if(_secHdrs==NULL) {
00156 close(fd);
00157 throw(STRING("Failure in construction of SecHdrTable\n"));
00158 }
00159
00160
00161 if (_elfHeader->e_phoff() != 0) {
00162 _progHdrs = new ProgHdrTable(mmap_ptr,_elfHeader);
00163 }
00164
00165
00166 _symTable = new ElfSymtab(mmap_ptr,_secHdrs);
00167
00168 if(_symTable==NULL) {
00169 close(fd);
00170 throw(STRING("Failure in construction of ElfSymtab\n"));
00171 }
00172
00173 }
00174 close(fd);
00175
00176 strcpy( _elfFileName, elf_file );
00177 }
00178
00179
00180 #ifdef _SL1_VERSION_CHECK
00181 void
00182 ELF_object::setSymVersionNumber(void)
00183 {
00184 if(_symTable == NULL)
00185 throw(STRING("Illegal reference to ElfSymbol Table\n"));
00186
00187 _symTable->setSymVersionNumber(_elfHeader->e_flags());
00188 }
00189 #endif
00190
00191
00192 Elf32_Off
00193 ELF_object::textSegPAddr (INT i)
00194 {
00195 return _progHdrs->textSegPAddr(i);
00196 }
00197
00198 Elf32_Off ELF_object::textSegVAddr(INT i)
00199 {
00200 return _progHdrs->textSegVAddr(i);
00201 }
00202
00203 Elf32_Off ELF_object::textSegFAddr(INT i)
00204 {
00205 return _progHdrs->textSegFAddr(i);
00206 }
00207
00208 Elf32_Off
00209 ELF_object::dataSegPAddr (INT i)
00210 {
00211 return _progHdrs->dataSegPAddr(i);
00212 }
00213
00214 Elf32_Off ELF_object::dataSegVAddr(INT i)
00215 {
00216 return _progHdrs->dataSegVAddr(i);
00217 }
00218
00219 Elf32_Off ELF_object::dataSegFAddr(INT i)
00220 {
00221 return _progHdrs->dataSegFAddr(i);
00222 }
00223
00224 Elf32_Off ELF_object::rodataSegPAddr(INT i)
00225 {
00226 return _progHdrs->rodataSegPAddr(i);
00227 }
00228
00229 Elf32_Off ELF_object::rodataSegVAddr(INT i)
00230 {
00231 return _progHdrs->rodataSegVAddr(i);
00232 }
00233
00234 Elf32_Off ELF_object::rodataSegFAddr(INT i)
00235 {
00236 return _progHdrs->rodataSegFAddr(i);
00237 }
00238
00239 Elf32_Off ELF_object::bssSegVAddr(INT i)
00240 {
00241 return _progHdrs->bssSegVAddr(i);
00242 }
00243
00244 Elf32_Off ELF_object::bssSegFAddr(INT i)
00245 {
00246 if (_progHdrs)
00247 return _progHdrs->bssSegFAddr(i);
00248 else {
00249 SimFatal((0), ("Impossible: Invalid prog headers for bss segment\n"));
00250 return (UINT)-1;
00251 }
00252 }
00253
00254 Elf32_Word ELF_object::textSegFSize(INT i)
00255 {
00256 if (_progHdrs)
00257 return _progHdrs->textSegFSize(i);
00258 else
00259 return 0;
00260 }
00261
00262 Elf32_Word ELF_object::textSegMSize(INT i)
00263 {
00264 return _progHdrs->textSegMSize(i);
00265 }
00266
00267 Elf32_Word ELF_object::dataSegFSize(INT i)
00268 {
00269 if (_progHdrs)
00270 return _progHdrs->dataSegFSize(i);
00271 else
00272 return 0;
00273 }
00274
00275 Elf32_Word ELF_object::dataSegMSize(INT i)
00276 {
00277 if (_progHdrs)
00278 return _progHdrs->dataSegMSize(i);
00279 else
00280 return 0;
00281 }
00282
00283 Elf32_Word ELF_object::rodataSegFSize(INT i)
00284 {
00285 return _progHdrs->rodataSegFSize(i);
00286 }
00287
00288 Elf32_Word ELF_object::rodataSegMSize(INT i)
00289 {
00290 if(_progHdrs)
00291 return _progHdrs->rodataSegMSize(i);
00292 else
00293 return 0;
00294 }
00295
00296 Elf32_Word ELF_object::bssSegMSize(INT i)
00297 {
00298 if (_progHdrs)
00299 return _progHdrs->bssSegMSize(i);
00300 else
00301 return 0;
00302 }
00303
00304 void ELF_object::PrintEHdr(FILE* stream)
00305 {
00306 _elfHeader->Print(stream);
00307 }
00308
00309 void ELF_object::PrintSHdr(FILE* stream)
00310 {
00311 _secHdrs->Print(stream);
00312 }
00313
00314 void ELF_object::PrintPHdr(FILE* stream)
00315 {
00316 if(_progHdrs)
00317 _progHdrs->Print(stream);
00318 }
00319
00320 void ELF_object::PrintSymtab(FILE* stream)
00321 {
00322 _symTable->Print(stream);
00323 }
00324
00325
00327
00328
00329
00330
00332
00333 ProgHdr::ProgHdr(unsigned char* address,ProgHdrTable* pht) :
00334 _startAddr((Elf32_Phdr*)address),_progHdrTable(pht) {}
00335
00336 const unsigned char* ProgHdr::decode_p_type(void)
00337 {
00338 static const char* unknown= "*UNKNOWN*";
00339
00340 static const char* ptypeLabels[] = {
00341 "NULL",
00342 "LOAD",
00343 "DYNAMIC",
00344 "INTERP",
00345 "NOTE",
00346 "SHLIB",
00347 "PHDR",
00348 "*ILLEGAL*"
00349 };
00350
00351 INT pt = this->p_type();
00352
00353 if(!(pt <= PT_PHDR||pt == PT_LOPROC||pt == PT_HIPROC))
00354 throw(STRING("Illegal ST_TYPE value\n"));
00355
00356 if (pt >= PT_NULL&&pt <= PT_PHDR)
00357 {
00358 return (const unsigned char*)ptypeLabels[pt];
00359 }
00360 else
00361 {
00362 return (const unsigned char*)unknown;
00363 }
00364 }
00365
00366 const unsigned char* ProgHdr::decode_p_flags(void)
00367 {
00368 static const char* unknown= "*UNKNOWN*";
00369
00370 static const char* pflagsLabels[] = {
00371 "NONE",
00372 " E",
00373 " W ",
00374 " WE",
00375 "R ",
00376 "R E",
00377 "RW ",
00378 "RWE",
00379 "*ILLEGAL*"
00380 };
00381
00382 INT pf = this->p_flags();
00383
00384 if (pf > 0 && pf <= (PF_X|PF_W|PF_R))
00385 {
00386 return (const unsigned char*)pflagsLabels[pf];
00387 }
00388 else
00389 {
00390 return (const unsigned char*)unknown;
00391 }
00392 }
00393
00394
00395
00396 ProgHdrTable::ProgHdrTable(unsigned char* address,ELFHdr* eh)
00397 : _fileStartAddr(address),
00398 _progHdrs(NULL),
00399 _numEntries(eh->e_phnum()),
00400 _numExecSeg(0),
00401 _numBssSeg(0),
00402 _numRWSeg(0),
00403 _numRSeg(0),
00404 _ReginfoNdx(-1)
00405
00406 {
00407
00408 if(!(_fileStartAddr == (unsigned char*)eh->_startAddr))
00409 throw(STRING("Illegal Section Header Table address\n"));
00410
00411 _progHdrs = (ProgHdr*)malloc((sizeof(ProgHdr) * _numEntries));
00412
00413 if(!(_progHdrs != NULL))
00414 throw(STRING("Failed to allocate memory for Program Headers\n"));
00415
00416 unsigned char* tmp_phdr_ptr = address + eh->e_phoff();
00417
00418 _execSegNdx.clear();
00419 _RWSegNdx.clear();
00420 _RSegNdx.clear();
00421 _BssSegNdx.clear();
00422 for (INT i=0; i < _numEntries; i++) {
00423 _progHdrs[i] = ProgHdr(tmp_phdr_ptr,this);
00424
00425 if (_progHdrs[i].p_type() == PT_MIPS_REGINFO) {
00426 _ReginfoNdx = i;
00427 }
00428
00429 if(!(&(_progHdrs[i]) != NULL))
00430 throw(STRING("Failure in construction of ProgHdr\n"));
00431
00432 tmp_phdr_ptr += sizeof(Elf32_Phdr);
00433
00434
00435 if (_progHdrs[i].is_ldExec()) {
00436 _execSegNdx.push_back(i);
00437 _numExecSeg++;
00438 }
00439 if (_progHdrs[i].is_ldReadWrite() && !(_progHdrs[i].is_ldExec())) {
00440
00441 if (_progHdrs[i].p_filesz() == 0) {
00442 _BssSegNdx.push_back(i);
00443 ++_numBssSeg;
00444 }
00445 else {
00446 _RWSegNdx.push_back(i);
00447 ++_numRWSeg;
00448 }
00449 }
00450 if (_progHdrs[i].is_ldReadOnly()) {
00451 _RSegNdx.push_back(i);
00452 ++_numRSeg;
00453 }
00454 }
00455
00456 #if 0
00457
00458 if(!(_numRWSeg <= 1))
00459 throw(STRING("Unexpected number of loadable exec segments"));
00460 #endif
00461 }
00462
00463 ProgHdr* ProgHdrTable::getPHdrByIndex(UINT phNum)
00464 {
00465
00466 if(!(phNum < _numEntries))
00467 throw(STRING("Illegal Program Header number requested\n"));
00468
00469 return &_progHdrs[phNum];
00470 }
00471
00472
00473 INT32 ProgHdrTable::Reginfo_bias(void)
00474 {
00475 if (_ReginfoNdx >= 0) {
00476 for (UINT i = 0; i < _numExecSeg; i++) {
00477 INT ndx = _execSegNdx[i];
00478 if (_progHdrs[_ReginfoNdx].p_offset() > _progHdrs[ndx].p_offset()) {
00479 if ((_progHdrs[_ReginfoNdx].p_offset()+_progHdrs[ndx].p_filesz()) >
00480 _progHdrs[_ReginfoNdx].p_offset()) {
00481
00482 return((_progHdrs[_ReginfoNdx].p_offset() + _progHdrs[_ReginfoNdx].p_filesz() + 0xf) & ~0xf);
00483 }
00484 }
00485 }
00486 }
00487 return 0;
00488 }
00489
00490 Elf32_Off ProgHdrTable::textSegPAddr (INT i)
00491 {
00492 if (_ReginfoNdx >= 0) {
00493 return (_progHdrs[_execSegNdx[i]].p_paddr() + Reginfo_bias());
00494 }
00495 return _progHdrs[_execSegNdx[i]].p_paddr();
00496 }
00497
00498 Elf32_Off ProgHdrTable::textSegVAddr(INT i)
00499 {
00500 if (_ReginfoNdx >= 0) {
00501 return(_progHdrs[_execSegNdx[i]].p_vaddr() + Reginfo_bias());
00502 }
00503 return _progHdrs[_execSegNdx[i]].p_vaddr();
00504 }
00505
00506 Elf32_Off ProgHdrTable::textSegFAddr(INT i)
00507 {
00508 if (_ReginfoNdx >= 0) {
00509 return( _progHdrs[_execSegNdx[i]].p_offset() + (Elf32_Off)_fileStartAddr + Reginfo_bias());
00510 }
00511 return _progHdrs[_execSegNdx[i]].p_offset() + (Elf32_Off)_fileStartAddr;
00512 }
00513
00514 Elf32_Off ProgHdrTable::textSegFSize(INT i)
00515 {
00516 if (_ReginfoNdx >= 0) {
00517 return _progHdrs[_execSegNdx[i]].p_filesz() + Reginfo_bias();
00518 }
00519 return _progHdrs[_execSegNdx[i]].p_filesz();
00520 }
00521
00522 Elf32_Off ProgHdrTable::textSegMSize(INT i)
00523 {
00524 if (_ReginfoNdx >= 0) {
00525 return _progHdrs[_execSegNdx[i]].p_memsz() + Reginfo_bias();
00526 }
00527 return _progHdrs[_execSegNdx[i]].p_memsz();
00528 }
00529
00530 Elf32_Off ProgHdrTable::dataSegPAddr(INT i)
00531 {
00532 return _progHdrs[_RWSegNdx[i]].p_paddr();
00533 }
00534
00535 Elf32_Off ProgHdrTable::dataSegVAddr(INT i)
00536 {
00537 return _progHdrs[_RWSegNdx[i]].p_vaddr();
00538 }
00539
00540 Elf32_Off ProgHdrTable::dataSegFAddr(INT i)
00541 {
00542 return _progHdrs[_RWSegNdx[i]].p_offset() + (Elf32_Off)_fileStartAddr;
00543 }
00544
00545 Elf32_Off ProgHdrTable::dataSegFSize(INT i)
00546 {
00547 if (_numRWSeg == 0) return 0;
00548 return _progHdrs[_RWSegNdx[i]].p_filesz();
00549 }
00550
00551 Elf32_Off ProgHdrTable::dataSegMSize(INT i)
00552 {
00553 if (_numRWSeg == 0) return 0;
00554 return _progHdrs[_RWSegNdx[i]].p_memsz();
00555 }
00556
00557 Elf32_Off ProgHdrTable::rodataSegPAddr(INT i)
00558 {
00559 return _progHdrs[_RSegNdx[i]].p_paddr();
00560 }
00561
00562
00563 Elf32_Off ProgHdrTable::rodataSegVAddr(INT i)
00564 {
00565 return _progHdrs[_RSegNdx[i]].p_vaddr();
00566 }
00567
00568 Elf32_Off ProgHdrTable::rodataSegFAddr(INT i)
00569 {
00570 return _progHdrs[_RSegNdx[i]].p_offset() + (Elf32_Off)_fileStartAddr;
00571 }
00572
00573 Elf32_Off ProgHdrTable::rodataSegFSize(INT i)
00574 {
00575 if (_numRSeg == 0) return 0;
00576 if (_progHdrs)
00577 return _progHdrs[_RSegNdx[i]].p_filesz();
00578 else
00579 return 0;
00580 }
00581
00582 Elf32_Off ProgHdrTable::rodataSegMSize(INT i)
00583 {
00584 if (_numRSeg == 0) return 0;
00585 if (_progHdrs)
00586 return _progHdrs[_RSegNdx[i]].p_memsz();
00587 else
00588 return 0;
00589 }
00590
00591 Elf32_Off ProgHdrTable::bssSegVAddr(INT i)
00592 {
00593 if (_numBssSeg == 0) return (UINT)-1;
00594 return _progHdrs[_BssSegNdx[i]].p_vaddr();
00595 }
00596
00597 Elf32_Off ProgHdrTable::bssSegFAddr(INT i)
00598 {
00599 if (_numBssSeg == 0) return (UINT)-1;
00600 return _progHdrs[_BssSegNdx[i]].p_offset() + (Elf32_Off)_fileStartAddr;
00601 }
00602
00603 Elf32_Off ProgHdrTable::bssSegMSize(INT i)
00604 {
00605 if (_numBssSeg == 0) return 0;
00606 return _progHdrs[_BssSegNdx[i]].p_memsz();
00607 }
00608
00609 void ProgHdrTable::Print(FILE* stream, INT phNum)
00610 {
00611
00612
00613
00614
00615 ProgHdr* phdr = NULL;
00616
00617
00618 fprintf(stream,"\n== PROGRAM HEADERS ==\n");
00619 fprintf(stream,"Number of loadable exec segments: %i\n",_numExecSeg);
00620 fprintf(stream,"Number of loadable read-write segments: %i\n\n",_numRWSeg);
00621
00622 fprintf(stream,"Num Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n");
00623
00624 if (phNum > -1)
00625 {
00626
00627 if(!(phNum < _numEntries))
00628 throw(STRING("Program Header index requested is out of range\n"));
00629
00630 phdr = getPHdrByIndex(phNum);
00631
00632 if(phdr==NULL)
00633 throw(STRING("Request program header cannot be found\n"));
00634
00635 _print_one(stream,phdr,phNum);
00636
00637 }
00638 else if (-1 == phNum)
00639 {
00640 for (phdr = begin(),phNum = 0; phdr != end(); phdr++,phNum++)
00641 {
00642 _print_one(stream,phdr,phNum);
00643 }
00644
00645 }
00646 else
00647 {
00648 throw(STRING("Unexpected Section Header index\n"));
00649 }
00650 }
00651
00652 void ProgHdrTable::_print_one(FILE* stream,ProgHdr* phdr,UINT phNum)
00653 {
00654 fprintf(stream,"%3u ",phNum);
00655 fprintf(stream,"%-12s ",phdr->decode_p_type());
00656 fprintf(stream,"%-8x ",phdr->p_offset());
00657 fprintf(stream,"%-10x ",phdr->p_vaddr());
00658 fprintf(stream,"%-10x ",phdr->p_paddr());
00659 fprintf(stream,"%-7x ",phdr->p_filesz());
00660 fprintf(stream,"%-7x ",phdr->p_memsz());
00661 fprintf(stream,"%-3s ",phdr->decode_p_flags());
00662 fprintf(stream,"%-5x\n",phdr->p_align());
00663 }
00664
00666
00667
00668
00670
00671
00672 ELFHdr::ELFHdr(Elf32_Ehdr* address) : _startAddr(address)
00673 {
00674
00675 if(!(((_eimag[0] = _startAddr->e_ident[EI_MAG0]) == ELFMAG0)))
00676 throw(STRING("Illegal ELF object, illegal ELFMAG0\n"));
00677 if(!((_eimag[1] = _startAddr->e_ident[EI_MAG1]) == ELFMAG1))
00678 throw(STRING("Illegal ELF object, illegal ELFMAG1\n"));
00679 if(!((_eimag[2] = _startAddr->e_ident[EI_MAG2]) == ELFMAG2))
00680 throw(STRING("Illegal ELF object, illegal ELFMAG2\n"));
00681 if(!((_eimag[3] = _startAddr->e_ident[EI_MAG3]) == ELFMAG3))
00682 throw(STRING("Illegal ELF object, illegal ELFMAG3\n"));
00683 _eimag[4] = '\0';
00684 }
00685
00686
00687 void ELFHdr::Print(FILE* stream)
00688 {
00689 fprintf(stream,"\n== ELF HEADER ==\n");
00690 fprintf(stream,"file starts at %p\n",_startAddr);
00691 fprintf(stream,"%-14s %-10s","Magic:",e_ident_EI_MAG());
00692 fprintf(stream,"%-14s %-10i","EI_CLASS:",e_ident_EI_CLASS());
00693 fprintf(stream,"%-14s %-10i","EI_DATA:",e_ident_EI_DATA());
00694 fprintf(stream,"%-14s %-10i\n","EI_VERSION:",e_ident_EI_VERSION());
00695
00696 fprintf(stream,"%-14s %-10hi","e_type:",e_type());
00697 fprintf(stream,"%-14s %-10hi","e_machine:",e_machine());
00698 fprintf(stream,"%-14s %-10i","e_version:",e_version());
00699 fprintf(stream,"%-14s %-10p\n","e_entry:",e_entry());
00700
00701 fprintf(stream,"%-14s %-10p","e_phoff:",e_phoff());
00702 fprintf(stream,"%-14s %-10p","e_shoff:",e_shoff());
00703 fprintf(stream,"%-14s %-10i","e_flags:",e_flags());
00704 fprintf(stream,"%-14s %-10i\n","e_ehsize:",e_ehsize());
00705
00706 fprintf(stream,"%-14s %-10i","e_phentsize:",e_phentsize());
00707 fprintf(stream,"%-14s %-10i","e_phnum:",e_phnum());
00708 fprintf(stream,"%-14s %-10i","e_shentsize:",e_shentsize());
00709 fprintf(stream,"%-14s %-10i\n","e_shnum:",e_shnum());
00710
00711 fprintf(stream,"%-14s %-10i\n","e_shstrndx:",e_shstrndx());
00712
00713 }
00714
00715
00717
00718
00719
00721
00722 SecHdr::SecHdr(unsigned char* address,SecHdrTable* sht)
00723 :_startAddr((Elf32_Shdr*)address),
00724 _secHdrTable(sht)
00725 {
00726
00727 if(_startAddr==NULL)
00728 throw(STRING("Illegal Section Header address\n"));
00729 if(_secHdrTable==NULL)
00730 throw(STRING("Illegal Section Header Table pointer\n"));
00731 }
00732
00733 unsigned char* SecHdr::secName(void)
00734 {
00735 if(_secHdrTable==NULL)
00736 throw(STRING("Illegal reference to Section Header Table\n"));
00737 if(!((_secHdrTable->_shstrndx > 0)
00738 && (_secHdrTable->_shstrndx < _secHdrTable->_numEntries)))
00739 throw(STRING("Illegal value of shstrndx\n"));
00740
00741 return ((_secHdrTable->_secHdrs[_secHdrTable->_shstrndx]).sh_offset()
00742 + _secHdrTable->_fileStartAddr
00743 + this->sh_name());
00744 }
00745
00746 const unsigned char* SecHdr::decode_sh_type(void)
00747 {
00748 static const char* unknown= "*UNKNOWN*";
00749
00750 static const char* shtypeLabels[] = {
00751 "NULL",
00752 "PROGBITS",
00753 "SYMTAB",
00754 "STRTAB",
00755 "RELA",
00756 "HASH",
00757 "DYNAMIC",
00758 "NOTE",
00759 "NOBITS",
00760 "REL",
00761 "SHLIB",
00762 "DYNSYM",
00763 "*ILLEGAL*",
00764 "*ILLEGAL*",
00765 "INIT_ARR",
00766 "FINI_ARR",
00767 "PREINIT_ARR",
00768 "SHT_GRP",
00769 "SYMTAB_SNDX",
00770 "NUM"
00771 };
00772
00773 if (this->sh_type() >= SHT_NULL && this->sh_type() <= SHT_NUM)
00774 {
00775 return (const unsigned char*)shtypeLabels[this->sh_type()];
00776 }
00777 else
00778 {
00779 return (const unsigned char*)unknown;
00780
00781 }
00782 }
00783
00785
00786
00787
00789
00790 SecHdrTable::SecHdrTable(unsigned char* address,ELFHdr* eh)
00791 : _fileStartAddr(address),
00792 _secHdrs(NULL),
00793 _numEntries(eh->e_shnum()),
00794 _shstrndx(eh->e_shstrndx())
00795 {
00796 if(!(_fileStartAddr == (unsigned char*)eh->_startAddr))
00797 throw(STRING("Illegal Section Header Table address\n"));
00798 if(!((_shstrndx > 0 && _shstrndx < _numEntries) || _shstrndx == SHN_UNDEF))
00799 throw(STRING("Illegal value of shstrndx\n"));
00800
00801 _secHdrs = (SecHdr*)malloc((sizeof(SecHdr) * _numEntries));
00802
00803 if(_secHdrs==NULL)
00804 throw(STRING("Failed to allocate memory for section headers\n"));
00805
00806 unsigned char* tmp_shdr_ptr = address + eh->e_shoff();
00807
00808 for (INT i=0; i < _numEntries; i++)
00809 {
00810 _secHdrs[i] = SecHdr(tmp_shdr_ptr,this);
00811 if(!(&(_secHdrs[i]) != NULL))
00812 throw(STRING("Failure in construction of SecHdr\n"));
00813 tmp_shdr_ptr += sizeof(Elf32_Shdr);
00814 }
00815
00816 }
00817
00818 SecHdr* SecHdrTable::getSHdrByIndex(UINT secNum)
00819 {
00820 if(!(secNum < _numEntries))
00821 throw(STRING("Illegal Section Header number requested\n"));
00822 return &_secHdrs[secNum];
00823
00824 }
00825
00826
00827 SecHdr* SecHdrTable::getSHdrByName(char* secName)
00828 {
00829
00830 for (SecHdr* shdr = begin(); shdr != end(); shdr++)
00831 {
00832 if (0 == strcmp(secName,(const char*)shdr->secName()))
00833 {
00834 return shdr;
00835 }
00836 }
00837
00838 return NULL;
00839 }
00840
00841
00842 void SecHdrTable::_print_one(FILE* stream,SecHdr* shdr,UINT secNum)
00843 {
00844 fprintf(stream," [%3u] ",secNum);
00845 fprintf(stream,"%-17s ",shdr->secName());
00846 fprintf(stream,"%-15s ",shdr->decode_sh_type());
00847 fprintf(stream,"%-8x ",shdr->sh_addr());
00848 fprintf(stream,"%-6x ",shdr->sh_offset());
00849 fprintf(stream,"%-6x ",shdr->sh_size());
00850 fprintf(stream,"%-2x ",shdr->sh_entsize());
00851 fprintf(stream,"%-3i ",shdr->sh_flags());
00852 fprintf(stream,"%-2i ",shdr->sh_link());
00853 fprintf(stream,"%-3i ",shdr->sh_info());
00854 fprintf(stream,"%-2i\n",shdr->sh_addralign());
00855 }
00856
00857
00858 void SecHdrTable::Print(FILE* stream,INT secNum)
00859 {
00860
00861
00862
00863 SecHdr* shdr = NULL;
00864
00865
00866 fprintf(stream,"\n== SECTION HEADERS ==\n");
00867 fprintf(stream," [ndx] Name Type Addr Off Size ES Flg Lk Inf Al\n");
00868
00869
00870 if (secNum > -1)
00871 {
00872
00873 if(!(secNum < _numEntries))
00874 throw(STRING("Section Header index requested is out of range\n"));
00875 shdr = getSHdrByIndex(secNum);
00876 if(shdr==NULL)
00877 throw(STRING("Request section cannot be found\n"));
00878 _print_one(stream,shdr,secNum);
00879 }
00880 else if (-1 == secNum)
00881 {
00882 for (shdr = begin(),secNum = 0; shdr != end(); shdr++,secNum++)
00883 {
00884 _print_one(stream,shdr,secNum);
00885 }
00886 }
00887 else
00888 {
00889 throw(STRING("Unexpected Section Header index\n"));
00890 }
00891 }
00892
00894
00895
00896
00897
00899
00900 ElfSymbol::ElfSymbol(unsigned char* address, ElfSymtab* st)
00901 :_startAddr((Elf32_Sym*)address),
00902 _symtab(st)
00903 { }
00904
00905 char* ElfSymbol::symNameIsSpecial(ElfSymtab* symtab)
00906 {
00907 if ((this->st_shndx() > 0) && (this->st_shndx() < SHN_LORESERVE))
00908 {
00909 if (ELF32_ST_TYPE(this->st_info()) == STT_SECTION)
00910 {
00911 return (char *)symtab->_shdrs->getSHdrByIndex(this->st_shndx())->secName();
00912 }
00913 }
00914 return (char *)0;
00915 }
00916
00917 char* ElfSymbol::symName(void)
00918 {
00919 if(_symtab==NULL)
00920 throw(STRING("Illegal reference to ElfSymbol Table\n"));
00921 if(_symtab->_shdrs==NULL)
00922 throw(STRING("Illegal reference to Section Header Table\n"));
00923 if(_symtab->_shdrs->getSHdrByName(_STRTAB_SEC)==NULL)
00924 throw(STRING("Requested Section Header cannot be found\n"));
00925
00926 return (char* )(_symtab->_shdrs->getSHdrByName(_STRTAB_SEC)->sh_offset()
00927 + _symtab->_fileStartAddr
00928 + this->st_name());
00929 }
00930
00931 const unsigned char* ElfSymbol::decode_sec_index(void)
00932 {
00933 switch(this->st_shndx())
00934 {
00935 case SHN_UNDEF:
00936 return (const unsigned char*)"UNDEF";
00937 case SHN_LOPROC:
00938 return (const unsigned char*)"LOPROC";
00939 case SHN_HIPROC:
00940 return (const unsigned char*)"HIPROC";
00941 case SHN_ABS:
00942 return (const unsigned char*)"ABS";
00943 case SHN_COMMON:
00944 return (const unsigned char*)"COMMON";
00945 case SHN_HIRESERVE:
00946 return (const unsigned char*)"HIRESERVE";
00947 default:
00948 return (const unsigned char*)"*ILLEGAL*";
00949 }
00950 }
00951
00952 const unsigned char* ElfSymbol::decode_st_type(void)
00953 {
00954 static const char* sttypeLabels[] = {
00955 "NOTYPE",
00956 "OBJECT",
00957 "FUNC",
00958 "SECTION",
00959 "FILE",
00960 "*ILLEGAL*",
00961 "*ILLEGAL*",
00962 "*ILLEGAL*",
00963 "*ILLEGAL*",
00964 "*ILLEGAL*",
00965 "*ILLEGAL*",
00966 "*ILLEGAL*",
00967 "*ILLEGAL*",
00968 "LOPROC",
00969 "*ILLEGAL*",
00970 "HIPROC"
00971 };
00972 INT stt = ELF32_ST_TYPE(this->st_info());
00973 if(!(stt <= STT_HIPROC))
00974 throw(STRING("Illegal ST_TYPE value\n"));
00975 return (const unsigned char*)sttypeLabels[stt];
00976 }
00977
00978 const unsigned char* ElfSymbol::decode_st_bind(void)
00979 {
00980 static const char* stbindLabels[] = {
00981 "LOCAL",
00982 "GLOBAL",
00983 "WEAK",
00984 "*ILLEGAL*",
00985 "*ILLEGAL*",
00986 "*ILLEGAL*",
00987 "*ILLEGAL*",
00988 "*ILLEGAL*",
00989 "*ILLEGAL*",
00990 "*ILLEGAL*",
00991 "*ILLEGAL*",
00992 "*ILLEGAL*",
00993 "*ILLEGAL*",
00994 "LOPROC",
00995 "*ILLEGAL*",
00996 "HIPROC"
00997 };
00998 INT stb = ELF32_ST_BIND(this->st_info());
00999 if(!(stb <= STB_HIPROC))
01000 throw(STRING("Illegal ST_BIND value\n"));
01001 return (const unsigned char*)stbindLabels[stb];
01002 }
01003
01004
01006
01007
01008
01009
01011
01012
01013 ElfSymtab::ElfSymtab(unsigned char* address,SecHdrTable* sh)
01014 :_fileStartAddr(address),
01015 _shdrs(sh),
01016 _symbols(NULL),
01017 _numEntries((sh->getSHdrByName(_SYMTAB_SEC)->sh_size())/
01018 (sh->getSHdrByName(_SYMTAB_SEC)->sh_entsize())),
01019 _sizeOfEntry(sh->getSHdrByName(_SYMTAB_SEC)->sh_entsize())
01020 {
01021 if(!(_sizeOfEntry == sizeof(Elf32_Sym)))
01022 throw(STRING("Illegal Symbol Table Entry Size\n"));
01023
01024 _symbols = (ElfSymbol*)malloc((sizeof(ElfSymbol) * _numEntries));
01025 if(_symbols==NULL)
01026 throw(STRING("Failed to allocate memory for ElfSymbols\n"));
01027
01028 unsigned char* tmp_sym_ptr = address + sh->getSHdrByName(_SYMTAB_SEC)->sh_offset();
01029
01030 if(sh->getSHdrByName(_STRTAB_SEC)==NULL)
01031 throw(STRING("Requested Section Header cannot be found\n"));
01032
01033 for (INT i =0; i < _numEntries; i++)
01034 {
01035 _symbols[i] = ElfSymbol(tmp_sym_ptr,this);
01036 tmp_sym_ptr += sizeof(Elf32_Sym);
01037 }
01038 }
01039
01040 void ElfSymtab::_print_one(FILE* stream, ElfSymbol* sym,UINT symNum)
01041 {
01042 fprintf(stream," %3u:",symNum);
01043 fprintf(stream," %8x",sym->st_value());
01044 fprintf(stream," %5u",sym->st_size());
01045 fprintf(stream," %7s",sym->decode_st_type());
01046 fprintf(stream," %6s",sym->decode_st_bind());
01047 (sym->st_shndx() > 0 && sym->st_shndx() < SHN_LORESERVE) ?
01048 fprintf(stream," %10i",sym->st_shndx()) :
01049 fprintf(stream," %10s",sym->decode_sec_index());
01050
01051
01052 (sym->st_shndx() > 0 && sym->st_shndx() < SHN_LORESERVE) ?
01053 fprintf(stream," %10s", _shdrs->getSHdrByIndex(sym->st_shndx())->secName()):
01054 fprintf(stream," %10s","*special*");
01055
01056 fprintf(stream," %s\n",sym->symName());
01057
01058 }
01059
01060 void ElfSymtab::Print(FILE* stream,INT symNum)
01061 {
01062
01063
01064
01065
01066
01067 ElfSymbol* sym = NULL;
01068
01069
01070 fprintf(stream,"\n== SYMBOL TABLE ==\n");
01071 fprintf(stream," Num: Value Size Type Bind Ndx Section Name\n");
01072
01073 if (symNum > -1)
01074 {
01075 if(!(symNum < _numEntries))
01076 throw(STRING("Section Header index requested is out of range\n"));
01077 sym = getSymByIndex(symNum);
01078 _print_one(stream,sym,symNum);
01079 }
01080 else if (-1 == symNum)
01081 {
01082 for (sym = begin(),symNum = 0; sym != end(); sym++,symNum++)
01083 {
01084 _print_one(stream,sym,symNum);
01085 }
01086 }
01087 else
01088 {
01089 throw(STRING("Unexpected ElfSymbol Table index\n"));
01090 }
01091 }
01092
01093 ElfSymbol* ElfSymtab::getSymByIndex(UINT symNum)
01094 {
01095 if(!(symNum < _numEntries))
01096 throw(STRING("Illegal ElfSymbol Table index requested\n"));
01097 return &_symbols[symNum];
01098 }
01099
01100 ElfSymbol* ElfSymtab::getSymByName(char* symName)
01101 {
01102 ElfSymbol* sym;
01103 for(sym = begin(); sym != end(); sym++)
01104 {
01105 if(strcmp(sym->symName(), symName)==0)
01106 return sym;
01107 }
01108
01109 return (ElfSymbol *)NULL;
01110 }
01111
01112 #ifdef _SL1_VERSION_CHECK
01113 void ElfSymtab::setSymVersionNumber(UINT version)
01114 {
01115 ElfSymbol* symbol = getSymByName("__version_number");
01116 if(symbol == NULL)
01117 return;
01118
01119 SecHdr * secHdr = _shdrs->getSHdrByIndex(symbol->st_shndx());
01120 UINT fileoffset = symbol->st_value() - secHdr->sh_addr() + (UINT)_fileStartAddr + secHdr->sh_offset();
01121 printf("fileoffset = %x %x %x\n", fileoffset, symbol->st_value(), secHdr->sh_addr());
01122 printf("e_flags = %x\n", version);
01123 *(UINT *)fileoffset = version;
01124 }
01125 #endif