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