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 #ifndef _ELF_READER_
00035 #define _ELF_READER_
00036
00037 #include <elf.h>
00038 #include <vector>
00039 #include "workaround.h"
00040 #include "messg.h"
00041
00042
00043
00044
00045 #define _BSS_SEC ".bss"
00046 #define _COMMENT_SEC ".comment"
00047 #define _DATA_SEC ".data"
00048 #define _DATA1_SEC ".data1"
00049 #define _DEBUG_SEC ".debug"
00050 #define _STRTAB_SEC ".strtab"
00051 #define _SYMTAB_SEC ".symtab"
00052 #define _TEXT_SEC ".text"
00053 #define _RODATA_SEC ".rodata"
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 #if 1 // endian handling
00067 #define NDN(A) A
00068 #endif
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 class ELFHdr;
00082 class ProgHdr;
00083 class ProgHdrTable;
00084 class SecHdr;
00085 class SecHdrTable;
00086 class ElfSymbol;
00087 class ElfSymtab;
00088 class ELF_object;
00089
00090
00091
00092
00093
00094
00095 class ELFHdr
00096 {
00097
00098 friend class SecHdrTable;
00099 friend class ProgHdrTable;
00100
00101 public:
00102 Elf32_Ehdr* _startAddr;
00103 unsigned char _eimag[EI_NIDENT];
00104
00105 public:
00106 ELFHdr(Elf32_Ehdr* address);
00107
00108
00109 unsigned char* e_ident_EI_MAG(void) { return NDN(_eimag); };
00110 unsigned char e_ident_EI_CLASS(void) { return NDN(_startAddr->e_ident[EI_CLASS]); };
00111 unsigned char e_ident_EI_DATA(void) { return NDN(_startAddr->e_ident[EI_DATA]); };
00112 unsigned char e_ident_EI_VERSION(void) { return NDN(_startAddr->e_ident[EI_VERSION]); };
00113 Elf32_Half e_type(void) { return NDN(_startAddr->e_type); };
00114 Elf32_Half e_machine(void) { return NDN(_startAddr->e_machine); };
00115 Elf32_Word e_version(void) { return NDN(_startAddr->e_version); };
00116 Elf32_Addr e_entry(void) { return NDN(_startAddr->e_entry); };
00117 Elf32_Off e_phoff(void) { return NDN(_startAddr->e_phoff); };
00118 Elf32_Off e_shoff(void) { return NDN(_startAddr->e_shoff); };
00119 Elf32_Word e_flags(void) { return NDN(_startAddr->e_flags); };
00120 Elf32_Half e_ehsize(void) { return NDN(_startAddr->e_ehsize); };
00121 Elf32_Half e_phentsize(void) { return NDN(_startAddr->e_phentsize); };
00122 Elf32_Half e_phnum(void) { return NDN(_startAddr->e_phnum); };
00123 Elf32_Half e_shentsize(void) { return NDN(_startAddr->e_shentsize); };
00124 Elf32_Half e_shnum(void) { return NDN(_startAddr->e_shnum); };
00125 Elf32_Half e_shstrndx(void) { return NDN(_startAddr->e_shstrndx); };
00126
00127
00128 void Print(FILE* stream = stdout);
00129
00130
00131 };
00132
00133 class ProgHdr
00134 {
00135
00136 friend class ProgHdrTable;
00137
00138 public:
00139 Elf32_Phdr* _startAddr;
00140 ProgHdrTable* _progHdrTable;
00141
00142 public:
00143 ProgHdr(unsigned char* address,ProgHdrTable* pht);
00144
00145
00146 Elf32_Word p_type(void) { return NDN(_startAddr->p_type); };
00147 Elf32_Off p_offset(void) { return NDN(_startAddr->p_offset); };
00148 Elf32_Addr p_vaddr(void) { return NDN(_startAddr->p_vaddr); };
00149 Elf32_Addr p_paddr(void) { return NDN(_startAddr->p_paddr); };
00150 Elf32_Word p_filesz(void) { return NDN(_startAddr->p_filesz); };
00151 Elf32_Word p_memsz(void) { return NDN(_startAddr->p_memsz); };
00152 Elf32_Word p_flags(void) { return NDN(_startAddr->p_flags); };
00153 Elf32_Word p_align(void) { return NDN(_startAddr->p_align); };
00154
00155 public:
00156 const unsigned char* decode_p_type(void);
00157 const unsigned char* decode_p_flags(void);
00158
00159 BOOL is_loadable(void) { return (p_type() == PT_LOAD); };
00160 BOOL is_ldExec(void) {
00161
00162 return (is_loadable() &&
00163 (p_flags() % 2));
00164 };
00165 BOOL is_ldReadWrite(void) {
00166
00167 return (is_loadable() &&
00168 ((PF_R | PF_W) == (p_flags() & (PF_R | PF_W)))
00169 );
00170 };
00171
00172 BOOL is_ldReadOnly(void) {
00173
00174 return (is_loadable() &&
00175 ((p_flags()&PF_R) && ((p_flags()&PF_W)==0) && ((p_flags()&PF_X)==0))
00176 );
00177 };
00178
00179 void Print(FILE* stream = stdout);
00180
00181 };
00182
00183
00184 class ProgHdrTable
00185 {
00186
00187 friend class ProgHdr;
00188 public:
00189 unsigned char* _fileStartAddr;
00190 ProgHdr* _progHdrs;
00191 Elf32_Half _numEntries;
00192 UINT _numExecSeg;
00193 std::vector<INT> _execSegNdx;
00194 std::vector<INT> _BssSegNdx;
00195 UINT _numBssSeg;
00196 UINT _numRWSeg;
00197 std::vector<INT> _RWSegNdx;
00198 std::vector<INT> _RSegNdx;
00199 UINT _numRSeg;
00200 INT _ReginfoNdx;
00201
00202 private:
00203 void _print_one(FILE* stream,ProgHdr* phdr,UINT phNum);
00204
00205 public:
00206 ProgHdrTable(unsigned char* address,ELFHdr* eh);
00207
00208 public:
00209 ProgHdr* getPHdrByIndex(UINT phNum);
00210 Elf32_Off textSegPAddr(INT);
00211 Elf32_Off textSegVAddr(INT);
00212 Elf32_Off textSegFAddr(INT);
00213 Elf32_Word textSegFSize(INT);
00214 Elf32_Word textSegMSize(INT);
00215 Elf32_Off dataSegPAddr(INT);
00216 Elf32_Off dataSegVAddr(INT);
00217 Elf32_Off dataSegFAddr(INT);
00218 Elf32_Word dataSegFSize(INT);
00219 Elf32_Word dataSegMSize(INT);
00220 Elf32_Off rodataSegPAddr(INT);
00221 Elf32_Off rodataSegVAddr(INT);
00222 Elf32_Off rodataSegFAddr(INT);
00223 Elf32_Word rodataSegFSize(INT);
00224 Elf32_Word rodataSegMSize(INT);
00225 Elf32_Off bssSegVAddr(INT);
00226 Elf32_Off bssSegFAddr(INT);
00227 Elf32_Word bssSegMSize(INT);
00228 ProgHdr* begin(void) { return _progHdrs; };
00229 ProgHdr* end(void) { return &_progHdrs[_numEntries]; };
00230 INT32 Reginfo_bias(void);
00231 INT32 numExecSeg(void) { return _execSegNdx.size(); }
00232 INT32 numRSeg(void) { return _RSegNdx.size(); }
00233 INT32 numRWSeg(void) { return _RWSegNdx.size(); }
00234 INT32 numBssSeg(void) { return _BssSegNdx.size(); }
00235
00236 void Print(FILE* stream = stdout,INT phNum = -1);
00237
00238 };
00239
00240
00241 class SecHdr
00242 {
00243
00244 private:
00245 Elf32_Shdr* _startAddr;
00246 SecHdrTable* _secHdrTable;
00247
00248 public:
00249 SecHdr(unsigned char* address,SecHdrTable* sht);
00250
00251 public:
00252 Elf32_Word sh_name(void) { return NDN(_startAddr->sh_name); };
00253 Elf32_Word sh_type(void) { return NDN(_startAddr->sh_type); };
00254 Elf32_Word sh_flags(void) { return NDN(_startAddr->sh_flags); };
00255 Elf32_Addr sh_addr(void) { return NDN(_startAddr->sh_addr); };
00256 Elf32_Off sh_offset(void) { return NDN(_startAddr->sh_offset); };
00257 Elf32_Word sh_size(void) { return NDN(_startAddr->sh_size); };
00258 Elf32_Word sh_link(void) { return NDN(_startAddr->sh_link); };
00259 Elf32_Word sh_info(void) { return NDN(_startAddr->sh_info); };
00260 Elf32_Word sh_addralign(void) { return NDN(_startAddr->sh_addralign); };
00261 Elf32_Word sh_entsize(void) { return NDN(_startAddr->sh_entsize); };
00262
00263 public:
00264 const unsigned char* decode_sh_type(void);
00265 unsigned char* secName(void);
00266
00267 };
00268
00269 class SecHdrTable
00270 {
00271
00272 friend class SecHdr;
00273
00274 public:
00275 unsigned char* _fileStartAddr;
00276 SecHdr* _secHdrs;
00277 Elf32_Half _numEntries;
00278 Elf32_Half _shstrndx;
00279
00280 private:
00281 void _print_one(FILE* stream,SecHdr* shdr,UINT secNum);
00282
00283 public:
00284 SecHdrTable(unsigned char* address,ELFHdr* eh);
00285
00286 public:
00287 SecHdr* SecTab(void) { return _secHdrs; }
00288 INT SecNum(void) { return _numEntries; }
00289 SecHdr* getSHdrByName(char* secName);
00290 SecHdr* getSHdrByIndex(UINT secNum);
00291
00292 SecHdr* begin(void) { return _secHdrs; };
00293 SecHdr* end(void){ return &_secHdrs[_numEntries]; };
00294
00295 void Print(FILE* stream = stdout,INT secNum = -1);
00296
00297 };
00298
00299 class ElfSymbol
00300 {
00301
00302 friend class ElfSymtab;
00303
00304 public:
00305 Elf32_Sym* _startAddr;
00306 ElfSymtab* _symtab;
00307
00308 public:
00309 ElfSymbol(unsigned char* address, ElfSymtab* st);
00310
00311 public:
00312 Elf32_Word st_name(void) { return NDN(_startAddr->st_name); };
00313 Elf32_Addr st_value(void) { return NDN(_startAddr->st_value); };
00314 Elf32_Half st_shndx(void) { return NDN(_startAddr->st_shndx); };
00315 Elf32_Word st_size(void) { return NDN(_startAddr->st_size); };
00316 unsigned char st_info(void) { return NDN(_startAddr->st_info); };
00317 unsigned char st_other(void) { return NDN(_startAddr->st_other); };
00318 BOOL st_is_code(void) { return (ELF32_ST_TYPE(NDN(_startAddr->st_info)) == STT_FUNC); }
00319 BOOL st_is_data(void) { return ((ELF32_ST_TYPE(NDN(_startAddr->st_info)) == STT_OBJECT) || (ELF32_ST_TYPE(NDN(_startAddr->st_info)) == STT_TLS)) ; }
00320 BOOL st_is_bss(void) { return (ELF32_ST_TYPE(NDN(_startAddr->st_info)) == STT_COMMON); }
00321 BOOL st_is_weak(void) { return (ELF32_ST_BIND(_startAddr->st_info)) == STB_WEAK; }
00322
00323 public:
00324 char* symName(void);
00325 const unsigned char* decode_st_type(void);
00326 const unsigned char* decode_st_bind(void);
00327 const unsigned char* decode_sec_index(void);
00328 char* symNameIsSpecial(ElfSymtab*);
00329 BOOL symNameIsSpecial(void) { return this->st_shndx() == 0; }
00330
00331 };
00332
00333 class ElfSymtab
00334 {
00335
00336 friend class ElfSymbol;
00337
00338 public:
00339 unsigned char* _fileStartAddr;
00340 SecHdrTable* _shdrs;
00341 ElfSymbol* _symbols;
00342 Elf32_Half _numEntries;
00343 Elf32_Half _sizeOfEntry;
00344
00345 private:
00346 void _print_one(FILE* stream, ElfSymbol* sym, UINT symNum);
00347
00348 public:
00349 ElfSymtab(unsigned char* address, SecHdrTable* sh);
00350
00351 ElfSymbol* getSymByName(char* symName);
00352 ElfSymbol* getSymByIndex(UINT symNum);
00353 ElfSymbol* begin(void) { return _symbols; };
00354 ElfSymbol* end(void) { return &_symbols[_numEntries]; }
00355 ElfSymbol* Entry(INT i) { return &_symbols[i]; }
00356 INT Size(void) { return (INT)_numEntries; }
00357 void Print(FILE* stream = stdout,INT symNum = -1);
00358
00359 #ifdef _SL1_VERSION_CHECK
00360 void setSymVersionNumber(UINT version);
00361 #endif
00362
00363
00364
00365 };
00366
00367 #define FILE_NAME_MAX 256
00368 class ELF_object
00369 {
00370
00371 public:
00372 ELFHdr* _elfHeader;
00373 SecHdrTable* _secHdrs;
00374 ElfSymtab* _symTable;
00375 ProgHdrTable* _progHdrs;
00376 BOOL _is32bit;
00377 char _elfFileName[ FILE_NAME_MAX ];
00378
00379 public:
00380 ELF_object(char* elf_file);
00381
00382 public:
00383 char *getFileName( void ) { return _elfFileName;}
00384 SecHdrTable* SecHdrTab(void) { return _secHdrs; }
00385 BOOL Is32Bit(void) { return _is32bit; }
00386 void PrintEHdr(FILE* stream = stdout);
00387 void PrintSHdr(FILE* stream = stdout);
00388 void PrintPHdr(FILE* stream = stdout);
00389 void PrintSymtab(FILE* stream = stdout);
00390
00391 public:
00392 Elf32_Off textSecFAddr(void) {
00393 return (Elf32_Off)(_secHdrs->getSHdrByName(_TEXT_SEC)->sh_offset()
00394 + _elfHeader);
00395 };
00396
00397 Elf32_Word textSecFSize(void) {
00398 return (_secHdrs->getSHdrByName(_TEXT_SEC)->sh_size());
00399 };
00400
00401 Elf32_Addr textSecVAddr(void) {
00402 return _secHdrs->getSHdrByName(_TEXT_SEC)->sh_addr();
00403 };
00404
00405 Elf32_Addr EntryPt(void) { return _elfHeader->e_entry(); }
00406 ElfSymtab* Table(void) { return _symTable; }
00407 Elf32_Off textSegPAddr(INT);
00408 Elf32_Off textSegVAddr(INT);
00409 Elf32_Off textSegFAddr(INT);
00410 Elf32_Word textSegFSize(INT);
00411 Elf32_Word textSegMSize(INT);
00412 Elf32_Off dataSegPAddr(INT);
00413 Elf32_Off dataSegVAddr(INT);
00414 Elf32_Off dataSegFAddr(INT);
00415 Elf32_Word dataSegFSize(INT);
00416 Elf32_Word dataSegMSize(INT);
00417 Elf32_Off rodataSegPAddr(INT);
00418 Elf32_Off rodataSegVAddr(INT);
00419 Elf32_Off rodataSegFAddr(INT);
00420 Elf32_Word rodataSegFSize(INT);
00421 Elf32_Word rodataSegMSize(INT);
00422 Elf32_Off bssSegVAddr(INT);
00423 Elf32_Off bssSegFAddr(INT);
00424 Elf32_Word bssSegMSize(INT);
00425 ProgHdrTable* progHdrs(void) { return _progHdrs; }
00426 #ifdef _SL1_VERSION_CHECK
00427 void setSymVersionNumber(void);
00428 #endif
00429
00430 };
00431
00432
00433 #endif // _ELF_READER_
00434