dbgsrv/coredumpserver/test/elfdump/elfdump.cpp
changeset 0 c6b0df440bee
equal deleted inserted replaced
-1:000000000000 0:c6b0df440bee
       
     1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <stdio.h>
       
    17 #include <string.h>
       
    18 #include <stdlib.h>
       
    19 #include <symbianelfdefs.h>
       
    20 #include <sys/stat.h>
       
    21 #include <time.h>
       
    22 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
       
    23 #include <iostream>
       
    24 #include <iomanip>
       
    25 using namespace std;
       
    26 #else //(!__MSVCDOTNET__ && !__TOOLS2__)
       
    27 #include <iostream.h>
       
    28 #include <iomanip.h>
       
    29 #endif //__MSVCDOTNET__
       
    30 
       
    31 #define ADDR(rtype, p, o) (rtype *)(((char *)p) + o)
       
    32 
       
    33 bool ignoreSomeSections;
       
    34 void hexdump_data(unsigned char *data,int aSize,int j)
       
    35 {
       
    36 	int i=0;
       
    37 	int p=0;
       
    38 
       
    39 	while (i<aSize)
       
    40 		{
       
    41 		int count=0;
       
    42 		if(p==0)
       
    43 		{
       
    44 			printf("\t0x%08x:\t\t\t",j);
       
    45 		} // offset into section
       
    46 
       
    47 		while (i<aSize && count<4)
       
    48 			{
       
    49 			printf("%02X", *data);		// print 4 lots of %08x for the data expresed as 32-bit word
       
    50 			data++;
       
    51 			i++;
       
    52 			count++;
       
    53 			j++;
       
    54 			}
       
    55 
       
    56 		printf("  ");
       
    57 		p++;
       
    58 		if (p==4)
       
    59 			{
       
    60 			data=data-16;
       
    61 			for (int i=0;i<16;i++)			//print 16 bytes of memory interpreted
       
    62 				{							//as ASCII characters with all non-printing
       
    63 				if (*data>32 && *data <127)	//characters converted to dots
       
    64 					{
       
    65 					printf("%1c",*data);
       
    66 					}
       
    67 				else
       
    68 					{
       
    69 					printf(".");
       
    70 					}
       
    71 					data++;
       
    72 				}
       
    73 			p=0;
       
    74 			printf("\n ");
       
    75 			}
       
    76 		}
       
    77 		//printf("\n");
       
    78 	}
       
    79 void hexdump(unsigned char* data, int aSize, int offset)
       
    80 	//  print hex dump of relevant sections
       
    81 	{
       
    82 	int i=0;
       
    83 	int p=0;
       
    84 	while (i<aSize)
       
    85 		{
       
    86 		int count=0;
       
    87 		if(p==0){printf("\t%06x   ",offset);} // offset into section
       
    88 		while (i<aSize && count<4)
       
    89 			{
       
    90 			printf("%02X", *data);		// print 4 lots of %08x for the data expresed as 32-bit word
       
    91 			data++;
       
    92 			i++;
       
    93 			count++;
       
    94 			offset++;
       
    95 			}
       
    96 
       
    97 		printf("  ");
       
    98 		p++;
       
    99 		if (p==4)
       
   100 			{
       
   101 			data=data-16;
       
   102 			for (int i=0;i<16;i++)			//print 16 bytes of memory interpreted
       
   103 				{							//as ASCII characters with all non-printing
       
   104 				if (*data>32 && *data <127)	//characters converted to dots
       
   105 					{
       
   106 					printf("%1c",*data);
       
   107 					}
       
   108 				else
       
   109 					{
       
   110 					printf(".");
       
   111 					}
       
   112 					data++;
       
   113 				}
       
   114 			p=0;
       
   115 			printf(" \n ");
       
   116 			}
       
   117 		}
       
   118 		printf(" \n\n ");
       
   119 	}
       
   120 
       
   121 void print_directive(unsigned char* data, int size)
       
   122 	// print formatted text of directive section
       
   123 	{
       
   124 	printf ("\t");
       
   125 
       
   126 	for (int i=0; i<size; i++)
       
   127 		{
       
   128 		if ((char)data[i]>31 && (char)data[i]<127)
       
   129 			{
       
   130 			printf ("%c", (char)data[i]);
       
   131 			}
       
   132 
       
   133 		if ((char)data[i]=='\n')
       
   134 			{
       
   135 			printf ("\n\t");
       
   136 			}
       
   137 		}
       
   138 
       
   139 	printf ("\n");
       
   140 	}
       
   141 
       
   142 void print_reloc(Elf32_Ehdr* eh, Elf32_Sym* symT, unsigned char* strtab)
       
   143 	// print relocation section
       
   144 	{
       
   145 	Elf32_Shdr* shdr = ADDR(Elf32_Shdr, eh, eh->e_shoff);
       
   146 	for (int j=0;j< eh->e_shnum;j++)
       
   147 		{
       
   148 		char* sname = ADDR(char, eh, shdr[eh->e_shstrndx].sh_offset);
       
   149 		if ( (shdr[j].sh_type==9) &&
       
   150 		     ( (!ignoreSomeSections) ||
       
   151 		       (strncmp(".rel.debug_", &sname[shdr[j].sh_name], 11))
       
   152 		     )
       
   153 		   )
       
   154 			{
       
   155 			unsigned char* data = ADDR(unsigned char, eh, shdr[j].sh_offset);
       
   156 			int noOfReloc=shdr[j].sh_size / shdr[j].sh_entsize;
       
   157 			printf("\n\n\n\t\t\t%s\n", &sname[shdr[j].sh_name]);
       
   158 			Elf32_Rel* rl=(Elf32_Rel*)data;				// pointer to relocation section
       
   159 			for (int i=0;i<noOfReloc;i++)
       
   160 				{
       
   161 				unsigned char* symbolName = strtab;		// pointer to firest element of string											// table which holds symbol names
       
   162 				Elf32_Sym*  sym = symT;					// pointer to symbol table
       
   163 				int symTIndx= ELF32_R_SYM(rl->r_info);		// symbol Tableindex
       
   164 				sym=sym+symTIndx;
       
   165 				symbolName=symbolName+sym->st_name;		// index into string table section
       
   166 															// with symbol names
       
   167 				printf("\t0x%08x \t", rl->r_offset);		// prints offset into relocation section
       
   168 				printf("%d", symTIndx);					// symbol table index
       
   169 				printf("\t%s\n",symbolName);				// symbol name
       
   170 				rl++;
       
   171 				}
       
   172 			}
       
   173 		}
       
   174 	}
       
   175 
       
   176 void print_GlSymbols(Elf32_Ehdr* eh, Elf32_Sym* symT, unsigned char* strtab)
       
   177 	// print global symbols from Symbol Table
       
   178 	{
       
   179 	Elf32_Shdr* shdr = ADDR(Elf32_Shdr, eh, eh->e_shoff);
       
   180 	char* sname = ADDR(char, eh, shdr[eh->e_shstrndx].sh_offset);
       
   181 	for (int i=0;i< eh->e_shnum;i++)
       
   182 		{
       
   183 		if (!strcmp(".symtab", &sname[shdr[i].sh_name]))
       
   184 			{
       
   185 		  	int noOfSym=shdr[i].sh_size / shdr[i].sh_entsize; 	// number of symbols
       
   186 		  	const char *symName =(const char *)strtab;
       
   187 		  	int count = 1;
       
   188 		  	printf("Global symbols:\n");
       
   189 		  	printf("=================\n\n");
       
   190 		  	for (int l=0;l< noOfSym ;l++)
       
   191 				{
       
   192 				symT=symT+1;
       
   193 				if( ELF32_ST_BIND(symT->st_info) == 1)			// searching for global symbols
       
   194 			 		{
       
   195 			  		symName = symName + symT->st_name;			// index into string table section
       
   196 			 		printf("%d	",count);
       
   197 			  		printf(symName);
       
   198 			  		printf("\n");
       
   199 			  		symName = symName - symT->st_name;			// back to pointing to first byte of string table
       
   200 			  		count++;
       
   201 					}
       
   202 
       
   203 				}
       
   204 			}
       
   205 		}
       
   206 	}
       
   207 
       
   208 void print_elf_header(Elf32_Ehdr* eh)
       
   209 	{
       
   210 	// print elf header
       
   211 	if (eh->e_version==1)
       
   212 		printf("\tHeader version: EV_CURRENT (Current version)\n");
       
   213 	else
       
   214 		printf("\tInvalid version: EV_NONE (Invalid version)\n");
       
   215 
       
   216 	printf("\tFile Type\t\t\t:");
       
   217 	if (eh->e_type==0)
       
   218 		printf("ET_NONE (No file type) (0)\n");
       
   219 	else if (eh->e_type==1)
       
   220 		printf("ET_REL (Relocatable object) (1)\n");
       
   221 	else if (eh->e_type==2)
       
   222 		printf("ET_EXEC (Executable file) (2)\n");
       
   223 	else if (eh->e_type==3)
       
   224 		printf("ET_DYN (Shared object file) (3)\n");
       
   225 	else if (eh->e_type==4)
       
   226 		printf("ET_CORE (Core File) (4)\n");
       
   227 	else if (eh->e_type==65280)
       
   228 		printf("ET_LOPROC (Precessor Specific) (ff00)\n");
       
   229 	else
       
   230 		printf("ET_HIPROC (Precessor Specific) (ffff)\n");
       
   231 
       
   232 	if (eh->e_machine==40)
       
   233 		printf("\tMachine\t\t\t\t:EM_ARM (ARM)\n");
       
   234 	else
       
   235 		printf("\tERROR:\tUnexpected machine\n");
       
   236 
       
   237 	if(eh->e_ident[EI_DATA] == ELFDATA2LSB)
       
   238 		printf("\tData Encoding\t\t\t:ELFDATA2LSB\n");
       
   239 	else if(eh->e_ident[EI_DATA] == ELFDATA2MSB)
       
   240 		printf("\tData Encoding\t\t\t:ELFDATA2MSB\n");
       
   241 
       
   242 	printf("\tEntry offset (in SHF_ENTRYSECT section):0x%08x \n",eh->e_entry);
       
   243 	printf("\tProgram header entries\t\t:%d\n",eh->e_phnum);
       
   244 	printf("\tSection header entries\t\t:%d\n",eh->e_shnum);
       
   245 	printf("\tProgram header offset\t\t:%d",eh->e_phoff);
       
   246 	printf("  bytes (0x%08X",eh->e_phoff);
       
   247 	printf(")\n");
       
   248 	printf("\tSection header offset\t\t:%d",eh->e_shoff);
       
   249 	printf("  bytes (0x%08X",eh->e_shoff);
       
   250 	printf(")\n");
       
   251 
       
   252 	printf("\tProgram header entry size\t:%d",eh->e_phentsize);
       
   253 	printf("  bytes (0x%02X",eh->e_phentsize);
       
   254 	printf(")\n");
       
   255 	printf("\tSection header entry size\t:%d",eh->e_shentsize);
       
   256 	printf("  bytes (0x%02X",eh->e_shentsize);
       
   257 	printf(")\n");
       
   258 	printf("\tSection header string table index: %d \n", eh->e_shstrndx);
       
   259 	printf("\tHeader size\t\t\t:%d", eh->e_ehsize);
       
   260 	printf("  bytes (0x%02X",eh->e_ehsize);
       
   261 	printf(")\n");
       
   262 	}
       
   263 
       
   264 void print_sect_header(char* sname, Elf32_Shdr* shdr, int count)
       
   265 	// print section header names
       
   266 	{
       
   267 	static const char* KtypeName[]={"0","SHT_PROGBITS (1)","SHT_SYMTAB (2)","SHT_STRTAB (3)",
       
   268 								  "SHT_RELA (4)","5",	"SHT_DINAMIC (6)","7","8","SHT_REL (9)",
       
   269 								  "10","SHT_DINSYM (11)"};
       
   270 
       
   271 	printf("\n\n\tName\t\t:%1s\n ",&sname[shdr[count].sh_name]);
       
   272 	printf("\tType\t\t: %s\n",  KtypeName[shdr[count].sh_type]);
       
   273 	printf("\tAddr\t\t: 0x%08X\n",shdr[count].sh_addr);
       
   274 	printf("\tSize\t\t: %1d", shdr[count].sh_size);
       
   275 	printf("  bytes (0x%X",shdr[count].sh_size);
       
   276 	printf(")\n");
       
   277 	printf("\tEntry Size\t: %1d\n",shdr[count].sh_entsize);
       
   278 	printf("\tAligment\t: %1d\n\n\n",shdr[count].sh_addralign);
       
   279 	}
       
   280 
       
   281 unsigned char* findSymbolStringT(Elf32_Ehdr* eh)
       
   282 	//calculate and return pointer to the first byte of string table(the one with symbol names)
       
   283 	{
       
   284 	Elf32_Shdr* shdr = ADDR(Elf32_Shdr, eh, eh->e_shoff);
       
   285 	char* sname = ADDR(char, eh, shdr[eh->e_shstrndx].sh_offset);
       
   286 	for (int i=0;i < eh->e_shnum; i++)
       
   287 		{
       
   288 		if (!strcmp(".strtab", &sname[shdr[i].sh_name]))
       
   289 			{
       
   290 			unsigned char* data = ADDR(unsigned char, eh, shdr[i].sh_offset);
       
   291 			return data;	//pointer to the first byte of string table section
       
   292 			}
       
   293 		}
       
   294 	return NULL;	//if not found
       
   295 	}
       
   296 
       
   297 Elf32_Sym* findSymbolT(Elf32_Ehdr* eh)
       
   298 	//calculate and return pointer to the first element of symbol table
       
   299 	{
       
   300 	Elf32_Shdr* shdr = ADDR(Elf32_Shdr, eh, eh->e_shoff);
       
   301 	for (int i=0;i < eh->e_shnum;i++)
       
   302 		{
       
   303 		if (shdr[i].sh_type==2)
       
   304 			{
       
   305 			unsigned char* data = ADDR(unsigned char, eh, shdr[i].sh_offset);
       
   306 			Elf32_Sym* sym=(Elf32_Sym*)data;
       
   307 			return sym;		//pointer to the first element of symbol table.
       
   308 			}
       
   309 		}
       
   310 	return NULL; // if not found
       
   311 	}
       
   312 
       
   313 void print_Summary(Elf32_Ehdr* eh)
       
   314 	{
       
   315 	//print section names
       
   316 	Elf32_Shdr* shdr = ADDR(Elf32_Shdr, eh, eh->e_shoff);
       
   317 	char* sname = ADDR(char, eh, shdr[eh->e_shstrndx].sh_offset);
       
   318 	printf("\nSummary: \n");
       
   319 	printf("==========\n");
       
   320 	for (int i=0;i< eh->e_shnum;i++)
       
   321 		{
       
   322 		printf(&sname[shdr[i].sh_name]);
       
   323 		printf("\n");
       
   324 		}
       
   325 	}
       
   326 
       
   327 bool printAll;
       
   328 /*char  *ctime( const time_t *date)
       
   329 {
       
   330 
       
   331 }*/
       
   332 
       
   333 enum TCrashType { ECrashException, ECrashKill };
       
   334 
       
   335 enum TExcType
       
   336 	{
       
   337 	EExcGeneral=0,
       
   338 	EExcIntegerDivideByZero=1,
       
   339 	EExcSingleStep=2,
       
   340 	EExcBreakPoint=3,
       
   341 	EExcIntegerOverflow=4,
       
   342 	EExcBoundsCheck=5,
       
   343 	EExcInvalidOpCode=6,
       
   344 	EExcDoubleFault=7,
       
   345 	EExcStackFault=8,
       
   346 	EExcAccessViolation=9,
       
   347 	EExcPrivInstruction=10,
       
   348 	EExcAlignment=11,
       
   349 	EExcPageFault=12,
       
   350 	EExcFloatDenormal=13,
       
   351 	EExcFloatDivideByZero=14,
       
   352 	EExcFloatInexactResult=15,
       
   353 	EExcFloatInvalidOperation=16,
       
   354 	EExcFloatOverflow=17,
       
   355 	EExcFloatStackCheck=18,
       
   356 	EExcFloatUnderflow=19,
       
   357 	EExcAbort=20,
       
   358 	EExcKill=21,
       
   359 	EExcUserInterrupt=22,
       
   360 	EExcDataAbort=23,
       
   361 	EExcCodeAbort=24,
       
   362 	EExcMaxNumber=25,
       
   363 	EExcInvalidVector=26,
       
   364 	};
       
   365 
       
   366 char * TExcTypeNames[EExcInvalidVector+1] =
       
   367 	{
       
   368 	"EExcGeneral",
       
   369 	"EExcIntegerDivideByZero",
       
   370 	"EExcSingleStep",
       
   371 	"EExcBreakPoint",
       
   372 	"EExcIntegerOverflow",
       
   373 	"EExcBoundsCheck",
       
   374 	"EExcInvalidOpCode",
       
   375 	"EExcDoubleFault",
       
   376 	"EExcStackFault",
       
   377 	"EExcAccessViolation",
       
   378 	"EExcPrivInstruction",
       
   379 	"EExcAlignment",
       
   380 	"EExcPageFault",
       
   381 	"EExcFloatDenormal",
       
   382 	"EExcFloatDivideByZero",
       
   383 	"EExcFloatInexactResult",
       
   384 	"EExcFloatInvalidOperation",
       
   385 	"EExcFloatOverflow",
       
   386 	"EExcFloatStackCheck",
       
   387 	"EExcFloatUnderflow",
       
   388 	"EExcAbort",
       
   389 	"EExcKill",
       
   390 	"EExcUserInterrupt",
       
   391 	"EExcDataAbort",
       
   392 	"EExcCodeAbort",
       
   393 	"EExcMaxNumber",
       
   394 	"EExcInvalidVector"
       
   395 	};
       
   396 
       
   397 void print_symbian_info(Sym32_syminfod *syminfod)
       
   398 {
       
   399 
       
   400 	//printf("\tDate and time of the crash\t:=0x%X",syminfod->sd_date_time );
       
   401 	const time_t unix_time = 62168256000LL;//from 0AD to 1970 in seconds = 365*1971*86 400
       
   402 	//printf("\traw Date =0x%X\n", (syminfod->sd_date_time[1]<<32+syminfod->sd_date_time[0])/*/1000000*/ );
       
   403     time_t date = syminfod->sd_date_time/1000000; //convert to seconds
       
   404     date -= unix_time; //convert to unix time
       
   405 	printf("\tDate and time of the crash\t: %s\n", ctime(&date));
       
   406 
       
   407 	if( SYM32_EXECID_SIZE != sizeof(Sym32_execid) )
       
   408 		{
       
   409 		printf("\tWarning! : Expected Size of EXECUTABLE ID %d is different from sizeof operator %d\n\n",
       
   410 			SYM32_EXECID_SIZE, sizeof(Sym32_execid) );
       
   411 		}
       
   412 
       
   413 	printf("\tExecutable Crc32 (first 1kb)\t:0x%X\n",syminfod->sd_execid.exec_crc );
       
   414 
       
   415 	if( ECrashException == syminfod->sd_exit_type )
       
   416 		{
       
   417 		printf("\tHardware Exception\t\t:%d\n",syminfod->sd_exit_reason);
       
   418 		//printf("\tException Type\t\t\t:%s\n", TExcTypeNames[syminfod->sd_exit_reason] );
       
   419 		}
       
   420 	else if ( ECrashKill == syminfod->sd_exit_type )
       
   421 		{
       
   422 		printf("\tExit Type\t\t\t:%d",syminfod->sd_exit_reason);
       
   423 		switch(syminfod->sd_exit_reason)
       
   424 			{
       
   425 			case 0:printf(":EExitKill\n");		break;
       
   426 			case 1:printf(":EExitTerminate\n");	break;
       
   427 			case 2:printf(":EExitPanic\n");		break;
       
   428 			case 3:printf(":EExitPending\n");	break;
       
   429 			default:printf(":Unknown\n");			break;
       
   430 			}
       
   431 		}
       
   432 	else
       
   433 		{
       
   434 		printf("\t\tUnknown Crash Type\n" );
       
   435 		}
       
   436 
       
   437 	printf("\tCrashed Thread Id\t\t:0x%X\n",syminfod->sd_thread_id);
       
   438 	printf("\tOwning process\t\t\t:0x%X\n",syminfod->sd_proc_id);
       
   439 }
       
   440 
       
   441 void print_lockdata_info(Sym32_lockdata* lockdata)
       
   442 	{
       
   443 	printf("\n\n\tNum locks\t\t\t:%d\n", lockdata->lk_lock_count);
       
   444 	printf("\tmutex thread wait count\t\t:%d\n",lockdata->lk_mutex_thread_wait_count);
       
   445 	printf("\tmutex thread held count\t\t:%d\n",lockdata->lk_mutex_held_count);
       
   446 	}
       
   447 
       
   448 void print_thread_info(Sym32_thrdinfod *thrdinfod)
       
   449 {
       
   450 
       
   451 	//printf("\tIndex into the CORE.SYMBIAN.STR note segment defining");
       
   452 	//printf(" the name of the thread or ESYM_STR_UNDEF :%d\n",thrdinfod->td_name);
       
   453 	printf("\tThread ID\t\t\t:0x%X\n",thrdinfod->td_id);
       
   454 	printf("\tOwning process\t\t\t:0x%X\n",thrdinfod->td_owning_process);
       
   455 	printf("\tThread Priority\t\t\t:%d\n",thrdinfod->td_priority);
       
   456 	printf("\tSupervisor Stack Pointer\t:0x%08X\n",thrdinfod->td_svc_sp);
       
   457 	printf("\tSupervisor Stack Address\t:0x%08X\n",thrdinfod->td_svc_stack);
       
   458 	printf("\tSupervisor Stack Size\t\t:%u",thrdinfod->td_svc_stacksz);
       
   459 	printf("  bytes (0x%08X",thrdinfod->td_svc_stacksz);
       
   460 	printf(")\n");
       
   461     printf("\tUser Stack Address\t\t:0x%08X\n",thrdinfod->td_usr_stack);
       
   462     printf("\tUser Stack Size\t\t\t:%u",thrdinfod->td_usr_stacksz);
       
   463 	printf("  bytes (0x%08X)\n",thrdinfod->td_usr_stacksz);
       
   464     printf("\tHeap base Address\t\t:0x%08X\n",thrdinfod->td_heap_add);
       
   465     printf("\tHeap Size\t\t\t:%u",thrdinfod->td_heap_sz);
       
   466 	printf("  bytes (0x%08X)\n",thrdinfod->td_heap_sz);
       
   467 }
       
   468 
       
   469 void print_process_info(Sym32_procinfod *procinfod)
       
   470 {
       
   471 
       
   472 	//printf("\t\t\tIndex into the CORE.SYMBIAN.STR note segment defining");
       
   473 	//printf(" the name of the process or ESYM_STR_UNDEF:%d\n",procinfod->pd_name);
       
   474 	printf("\tProcess ID\t\t\t:0x%X\n",procinfod->pd_id);
       
   475 	printf("\tProcess Priority\t\t:%d\n",procinfod->pd_priority);
       
   476 
       
   477 }
       
   478 
       
   479 void print_executable_info(Sym32_execinfod *execinfod)
       
   480 {
       
   481 
       
   482 	printf("\tExecutable ID\t\t\t:0x%08X\n",execinfod->ed_execid.exec_id);
       
   483 	printf("\tExecutable Crc32 (first 1kb)\t:0x%X\n",execinfod->ed_execid.exec_crc );
       
   484 
       
   485 	if(execinfod->ed_XIP == 1)
       
   486 	{
       
   487 		printf("\tXIP ROM\t\t\t\t:TRUE\n");
       
   488     }
       
   489     else if(execinfod->ed_XIP == 0)
       
   490     {
       
   491 	     printf("\tXIP ROM\t\t\t\t:FALSE\n");
       
   492     }
       
   493 
       
   494 	printf("\tSize of executable code segment\t\t\t:%d",execinfod->ed_codesize);
       
   495 	printf("  bytes (0x%08X)\n",execinfod->ed_codesize);
       
   496 
       
   497 	printf("\tExecution address of the code segment\t\t:0x%08X\n",execinfod->ed_coderunaddr);
       
   498 
       
   499 	printf("\tBuild address of the code segment\t\t:0x%08X\n",execinfod->ed_codeloadaddr);
       
   500 
       
   501 	printf("\tSize of the executable read only data segment\t:%d",execinfod->ed_rodatasize);
       
   502 	printf("  bytes (0x%08X)\n",execinfod->ed_rodatasize);
       
   503 
       
   504 	printf("\tExecution address of the read only data segment\t:0x%08X\n",execinfod->ed_rodatarunaddr);
       
   505 
       
   506     printf("\tBuild address of the read only data segment\t:0x%08X\n",execinfod->ed_rodataloadaddr);
       
   507 
       
   508     printf("\tSize of the executable data segment\t\t:%d", execinfod->ed_datasize);
       
   509 	printf("  bytes (0x%08X)\n",execinfod->ed_datasize);
       
   510 
       
   511     printf("\tExecution address of the data segment\t\t:0x%08X\n",execinfod->ed_datarunaddr);
       
   512 
       
   513     printf("\tBuild address of the data segment\t\t:0x%08X\n",execinfod->ed_dataloadaddr);
       
   514 }
       
   515 
       
   516 //void print_register_info(Sym32_reginfod *reginfod,unsigned int nreg,Sym32_regdatad *regdatad,char *array,unsigned int elenum)
       
   517 void print_register_info( Sym32_reginfod *reginfod, Elf32_Ehdr* eh, char *array )
       
   518 {
       
   519 	printf("\tVersion of the register data info descriptor\t:%s\n",&array[reginfod->rid_version]);
       
   520 	printf("\tThread ID\t\t\t:0x%X\n",reginfod->rid_thread_id);
       
   521 	printf("\tNumber of registers\t\t:%d\n",reginfod->rid_num_registers);
       
   522 
       
   523 	printf("\tRegister Class\t\t\t:%d",reginfod->rid_class);
       
   524 	switch( reginfod->rid_class )
       
   525 		{
       
   526 		case ESYM_REG_CORE:
       
   527 			printf( " : ESYM_REG_CORE\n" );
       
   528 			break;
       
   529 		case ESYM_REG_COPRO:
       
   530 			printf( " : ESYM_REG_COPRO\n" );
       
   531 			break;
       
   532 		default:
       
   533 			printf( " : Unknown Register Class\n" );
       
   534 		}
       
   535 
       
   536 	printf("\tRegister Representation\t\t:%d",reginfod->rid_repre );
       
   537 	switch( reginfod->rid_repre )
       
   538 		{
       
   539 		case ESYM_REG_8:
       
   540 			printf( " : ESYM_REG_8\n" );
       
   541 			break;
       
   542 		case ESYM_REG_16:
       
   543 			printf( " : ESYM_REG_16\n" );
       
   544 			break;
       
   545 		case ESYM_REG_32:
       
   546 			printf( " : ESYM_REG_32\n" );
       
   547 			break;
       
   548 		case ESYM_REG_64:
       
   549 			printf( " : ESYM_REG_64\n" );
       
   550 			break;
       
   551 		default:
       
   552 			printf( "\n" );
       
   553 		}
       
   554 
       
   555 	printf( "\n" );
       
   556 
       
   557 	Sym32_regdatad *regdatad = ADDR(Sym32_regdatad, reginfod, sizeof (Sym32_reginfod) );
       
   558 
       
   559 	for( unsigned int i = 0; i < reginfod->rid_num_registers; i++ )
       
   560 	{
       
   561 		printf("\tRegister ID\t\t\t:0x%X ", regdatad->rd_id);
       
   562 
       
   563 		if( ESYM_REG_CORE == reginfod->rid_class )
       
   564 		{
       
   565 			switch(regdatad->rd_id)
       
   566 			{
       
   567 				case 0x00000000: printf("ARM REGISTER R0\n"); break;
       
   568 				case 0x00000100: printf("ARM REGISTER R1\n"); break;
       
   569 				case 0x00000200: printf("ARM REGISTER R2\n"); break;
       
   570 				case 0x00000300: printf("ARM REGISTER R3\n"); break;
       
   571 				case 0x00000400: printf("ARM REGISTER R4\n"); break;
       
   572 				case 0x00000500: printf("ARM REGISTER R5\n"); break;
       
   573 				case 0x00000600: printf("ARM REGISTER R6\n"); break;
       
   574 				case 0x00000700: printf("ARM REGISTER R7\n"); break;
       
   575 				case 0x00000800: printf("ARM REGISTER R8\n"); break;
       
   576 				case 0x00000900: printf("ARM REGISTER R9\n"); break;
       
   577 				case 0x00000a00: printf("ARM REGISTER R10\n"); break;
       
   578 				case 0x00000b00: printf("ARM REGISTER R11\n"); break;
       
   579 				case 0x00000c00: printf("ARM REGISTER R12\n"); break;
       
   580 				case 0x00000d00: printf("ARM REGISTER R13\n"); break;
       
   581 				case 0x00000e00: printf("ARM REGISTER R14\n"); break;
       
   582 				case 0x00000f00: printf("ARM REGISTER R15\n"); break;
       
   583 				case 0x00001000: printf("ARM REGISTER CPSR\n"); break;
       
   584 				case 0x00001100: printf("ARM REGISTER R13_SVC\n"); break;
       
   585 				case 0x00001200: printf("ARM REGISTER R14_SVC\n"); break;
       
   586 				case 0x00001300: printf("ARM REGISTER SPSR_SVC\n"); break;
       
   587 				case 0x00001400: printf("ARM REGISTER R13_ABT\n"); break;
       
   588 				case 0x00001500: printf("ARM REGISTER R14_ABT\n"); break;
       
   589 				case 0x00001600: printf("ARM REGISTER SPSR_ABT\n"); break;
       
   590 				case 0x00001700: printf("ARM REGISTER R13_UND\n"); break;
       
   591 				case 0x00001800: printf("ARM REGISTER R14_UND\n"); break;
       
   592 				case 0x00001900: printf("ARM REGISTER SPSR_UND\n"); break;
       
   593 				case 0x00001a00: printf("ARM REGISTER R13_IRQ\n"); break;
       
   594 				case 0x00001b00: printf("ARM REGISTER R14_IRQ\n"); break;
       
   595 				case 0x00001c00: printf("ARM REGISTER SPSR_IRQ\n"); break;
       
   596 				case 0x00001d00: printf("ARM REGISTER R8_FIQ\n"); break;
       
   597 				case 0x00001e00: printf("ARM REGISTER R9_FIQ\n"); break;
       
   598 				case 0x00001f00: printf("ARM REGISTER R10_FIQ\n"); break;
       
   599 				case 0x00002000: printf("ARM REGISTER R11_FIQ\n"); break;
       
   600 				case 0x00002100: printf("ARM REGISTER R12_FIQ\n"); break;
       
   601 				case 0x00002200: printf("ARM REGISTER R13_FIQ\n"); break;
       
   602 				case 0x00002300: printf("ARM REGISTER R14_FIQ\n"); break;
       
   603 				case 0x00002400: printf("ARM REGISTER SPSR_FIQ\n"); break;
       
   604 				default:printf("Unknown Core Register\n"); break;
       
   605 			} // switch
       
   606 		} // if CORE
       
   607 		else
       
   608 		{
       
   609 			printf("\n\tRegister SubId\t\t\t:0x%X\n",regdatad->rd_sub_id);
       
   610 		}
       
   611 
       
   612 		switch( reginfod->rid_repre )
       
   613 		{
       
   614 		case ESYM_REG_8:
       
   615 			Elf32_Byte * val8;
       
   616 			val8 = ADDR( Elf32_Byte, eh, regdatad->rd_data );
       
   617 			printf( "\tESYM_REG_8 Value\t\t:0x%02X\n", *val8 );
       
   618 			break;
       
   619 		case ESYM_REG_16:
       
   620 			Elf32_Half * val16;
       
   621 			val16 = ADDR( Elf32_Half, eh, regdatad->rd_data );
       
   622 			printf( "\tESYM_REG_16 Value\t\t:0x%04X\n", *val16 );
       
   623 			break;
       
   624 		case ESYM_REG_32:
       
   625 			Elf32_Word * val32;
       
   626 			val32 = ADDR( Elf32_Word, eh, regdatad->rd_data );
       
   627 			printf( "\tESYM_REG_32 Value\t\t:0x%08X\n", *val32 );
       
   628 			break;
       
   629 
       
   630 		case ESYM_REG_64:
       
   631 			// We need to split the printing of a 64 bit number since the
       
   632 			// printf is not working correctly for this size.
       
   633 			Elf32_Word * val64_0;
       
   634 			Elf32_Word * val64_1;
       
   635 			val64_0 = ADDR( Elf32_Word, eh, regdatad->rd_data );
       
   636 			val64_1 = ADDR( Elf32_Word, eh, regdatad->rd_data + 4 );
       
   637 			printf( "\tESYM_REG_64 Value\t\t:0x%X%X\n", *val64_1, *val64_0 );
       
   638 			break;
       
   639 
       
   640 		default:
       
   641 			printf( "\n" );
       
   642 		}
       
   643 
       
   644 		regdatad++;
       
   645 	} // for
       
   646  }
       
   647 
       
   648 void print_trace_info( Sym32_tracedata *aTraceData, Elf32_Ehdr* aElfHdr, char *aArray)
       
   649 	{
       
   650 	printf("\tVersion of the trace data info descriptor\t:%s\n", &aArray[aTraceData->tr_version]);
       
   651 	printf("\tSize of trace buffer\t\t:%d bytes\n", aTraceData->tr_size);
       
   652 
       
   653 	if(aTraceData->tr_data == 0)
       
   654 		{
       
   655 		printf("\tNo trace data present\n");
       
   656 		}
       
   657 	else
       
   658 		{
       
   659 		unsigned char* data = ADDR(unsigned char, aElfHdr, aTraceData->tr_data);
       
   660 		printf("\tTrace Data starts at\t\t:0x%X\n", data);
       
   661 		}
       
   662 	}
       
   663 void print_variant_data(const Sym32_variant_spec_data* aVarData, const Elf32_Ehdr* aElfHeader)
       
   664 	{
       
   665 	printf("\n\n\tVariant data size\t\t:0x%X\n", aVarData->es_size);
       
   666 
       
   667 	unsigned char* data = ADDR(unsigned char, aElfHeader, aVarData->es_data);
       
   668 	hexdump_data(data, aVarData->es_size, 0);
       
   669 	printf("\n");
       
   670 	}
       
   671 
       
   672 void print_rom_info(const Sym32_rombuild* aRomInfo)
       
   673 	{
       
   674 	printf("\tROM Major Version\t\t:%hd\n", aRomInfo->rom_major_version);
       
   675 	printf("\tROM Minor Version\t\t:%hd\n",aRomInfo->rom_minor_version);
       
   676 	printf("\tROM Build Number\t\t:%hd\n",aRomInfo->rom_build);
       
   677 
       
   678 	const time_t unix_time = 62168256000LL;//from 0AD to 1970 in seconds = 365*1971*86 400
       
   679 	time_t date = aRomInfo->rom_time/1000000; //convert to seconds
       
   680 	date -= unix_time; //convert to unix time
       
   681 	printf("\tDate and time of the ROM Build\t:%s", ctime(&date));
       
   682 	}
       
   683 
       
   684 int do_elf_file(char* buffer, char* name)
       
   685 	{
       
   686 	Elf32_Ehdr* eh=(Elf32_Ehdr *)buffer;	//elf header
       
   687 	if (eh->e_ident[EI_MAG0] !=0x7f || eh->e_ident[EI_MAG1] != 0x45 || eh->e_ident[EI_MAG2] !=0x4c || eh->e_ident[EI_MAG3] != 0x46)
       
   688 		{
       
   689 		// EI_MAG0 to EI_MAG3 - A files' first 4 bytes hold a 'magic number', identifying the file as an ELF object file.
       
   690 		printf("Error: %s is not a valid ELF file", name);
       
   691 		return 1;
       
   692 		}
       
   693 	if (eh->e_ident[EI_DATA] == 2)
       
   694 		{
       
   695 		// ELF Header size should be 52 bytes or converted into Big-Endian system 13312
       
   696 		if (eh->e_ehsize != 13312)
       
   697 			{
       
   698 			printf("\tERROR:\tELF Header contains invalid file type\n");
       
   699 			exit(1);
       
   700 			}
       
   701 		// e_ident[EI_DATA] specifies the data encoding of the processor-specific data in the object file.
       
   702 		printf("\tERROR:\tData encoding ELFDATA2MSB (Big-Endian) not supported\n");
       
   703 		exit(1);
       
   704 		}
       
   705 	if (eh->e_ehsize != 52)
       
   706 		{
       
   707 		// ELF Header size should be 52 bytes
       
   708 		printf("\tERROR:\tELF Header contains invalid file type\n");
       
   709 		exit(1);
       
   710 		}
       
   711 
       
   712 	printf("\n\nELF HEADER INFORMATION\n");
       
   713 	print_elf_header(eh);									// print Elf Header
       
   714 	int phnum = eh->e_phnum;
       
   715 	int phoff =eh->e_phoff;
       
   716 	Elf32_Phdr* phdr = ADDR(Elf32_Phdr,eh,phoff);
       
   717 
       
   718 	//segments start here
       
   719 	char *array = NULL;
       
   720 	for(int j = 0; j < phnum; j++)
       
   721 		{
       
   722 		if(phdr[j].p_type == PT_NOTE)
       
   723 			{
       
   724 			Sym32_dhdr *dhdr = ADDR(Sym32_dhdr, eh, phdr[j].p_offset);
       
   725 			if(dhdr->d_type == ESYM_NOTE_STR)
       
   726 				{
       
   727 				array = (char*)dhdr + sizeof(Sym32_dhdr);
       
   728 				}
       
   729 			}
       
   730 		}
       
   731 
       
   732 	for(int i = 0; i < phnum; i++)
       
   733 		{
       
   734 		unsigned int data = phdr[i].p_offset;
       
   735 
       
   736 		if( SYM32_DESCHDR_SIZE != sizeof(Sym32_dhdr) )
       
   737 			{
       
   738 			printf("\n\tWarning! : Expected Size of SYM32_DESCHDR_SIZE %d is different from sizeof(Sym32_dhdr) %d\n\n",
       
   739 				 SYM32_DESCHDR_SIZE, sizeof(Sym32_dhdr) );
       
   740 			}
       
   741 
       
   742 		Sym32_dhdr *dhdr = ADDR(Sym32_dhdr,eh,data);
       
   743 		printf("\nPROGRAM HEADER ENTRY  %d INFORMATION \n",i);
       
   744 		printf("\tHeader offset\t\t\t:%d",phdr[i].p_offset);
       
   745 		printf("  bytes (0x%08X",phdr[i].p_offset);
       
   746 		printf(")\n");
       
   747 		printf("\tVirtual address\t\t\t:0x%08X\n",phdr[i].p_vaddr);
       
   748 
       
   749 		printf("\tSize of mapping from the file\t:0x%X (%d bytes)\n",phdr[i].p_filesz, phdr[i].p_filesz);
       
   750 		printf("\tSize of mapping in memory\t:0x%X (%d bytes)\n",phdr[i].p_memsz, phdr[i].p_memsz);
       
   751 
       
   752 		unsigned int  flag = phdr[i].p_flags;
       
   753 		switch(flag)
       
   754 			{
       
   755 			case 1 :
       
   756 				printf("\tFlag\t\t\t\t:PF_X : (1) \n");
       
   757 				break;
       
   758 			case 2 :
       
   759 				printf("\tFlag\t\t\t\t:PF_W: (2) \n");
       
   760 				break;
       
   761 			case 4 :
       
   762 				printf("\tFlag\t\t\t\t:PF_R : (4) \n");
       
   763 				break;
       
   764 			case 5:
       
   765 				printf("\tFlag\t\t\t\t:PF_X|PF_R : (5)\n");
       
   766 				break;
       
   767 			case 6:
       
   768 				printf("\tFlag\t\t\t\t:PF_W|PF_R : (6)\n");
       
   769 				break;
       
   770 			}
       
   771 
       
   772 		printf("\tAlignment to word boundary      :%d \n",phdr[i].p_align);
       
   773 
       
   774 		if(phdr[i].p_type == PT_LOAD)
       
   775 			{
       
   776 			printf("\tLOADABLE CODE/DATA SEGMENT\n"); //load
       
   777 			unsigned char* data = ADDR(unsigned char, eh, phdr[i].p_offset);
       
   778 			const int scope = 128;
       
   779 			//printf("\tDatasegment starts from here:%p, size:%d\n",data, phdr[i].p_memsz);
       
   780 			if(phdr[i].p_filesz == 0) continue;
       
   781 			if(phdr[i].p_filesz < 2*scope)
       
   782 				hexdump_data(data,phdr[i].p_memsz,phdr[i].p_vaddr);
       
   783 			else
       
   784 				{
       
   785 				hexdump_data(data,scope,phdr[i].p_vaddr);
       
   786 				printf("\t...\n");
       
   787 				hexdump_data(data+phdr[i].p_filesz-scope,scope,phdr[i].p_vaddr+phdr[i].p_filesz-scope);
       
   788 				}
       
   789 			if(phdr[i].p_filesz%16) printf("\n");
       
   790 			}
       
   791 		else if(phdr[i].p_type == PT_NOTE)
       
   792 			{
       
   793 			printf("\tName of the descriptor\t\t:%s\n",&array[dhdr->d_name]);
       
   794 			printf("\tSize of single descriptor element:%d \n",dhdr->d_descrsz);
       
   795 			printf("\tVersion string\t\t\t:%s\n",&array[dhdr->d_version]);
       
   796 			printf("\tNumber of descriptor elements\t:%d\n",dhdr->d_elemnum);
       
   797 			printf("\tSegment type\t\t\t:");
       
   798 
       
   799 			if( dhdr->d_type == ESYM_NOTE_SYM )
       
   800 				{
       
   801 				printf("SYMBIAN INFO SEGMENT\n\n");
       
   802 
       
   803 				if( sizeof(Sym32_syminfod) != dhdr->d_descrsz )
       
   804 					{
       
   805 					printf("\tWarning! : sizeof(Sym32_syminfod) %d is different from descriptor size %d\n\n",
       
   806 						 sizeof(Sym32_syminfod), dhdr->d_descrsz );
       
   807 					}
       
   808 
       
   809 				if( SYM32_SYMINFO_SIZE != dhdr->d_descrsz )
       
   810 					{
       
   811 					printf("\tWarning! : Expected Size of SYMBIAN INFO SEGMENT %d is different from descriptor size %d\n\n",
       
   812 						 SYM32_SYMINFO_SIZE, dhdr->d_descrsz );
       
   813 					}
       
   814 
       
   815 				Sym32_syminfod *syminfod = ADDR(Sym32_syminfod,eh,data+sizeof(Sym32_dhdr));
       
   816 				if( syminfod->sd_exit_cat > 0 )
       
   817 					{
       
   818 					printf("\tCrash reason\t\t\t:%s\n",&array[syminfod->sd_exit_cat]);
       
   819 					}
       
   820 				print_symbian_info(syminfod);
       
   821 				}
       
   822 			else if( dhdr->d_type == ESYM_NOTE_THRD)
       
   823 				{
       
   824 				printf("THREAD INFO SEGMENT\n\n");
       
   825 
       
   826 				if( sizeof(Sym32_thrdinfod) != dhdr->d_descrsz )
       
   827 					{
       
   828 					printf("\tWarning! : sizeof(Sym32_thrdinfod) %d is different from descriptor size %d\n\n",
       
   829 						sizeof(Sym32_thrdinfod), dhdr->d_descrsz );
       
   830 					}
       
   831 
       
   832 				if( SYM32_THRINFO_SIZE!= dhdr->d_descrsz )
       
   833 					{
       
   834 					printf("\tWarning! : Expected Size of THREAD INFO SEGMENT %d is different from descriptor size %d\n\n",
       
   835 						 SYM32_THRINFO_SIZE, dhdr->d_descrsz );
       
   836 					}
       
   837 
       
   838 				Sym32_thrdinfod *thrdinfod = ADDR(Sym32_thrdinfod,eh,data+sizeof(Sym32_dhdr));
       
   839 				for(int thrIdx = 0; thrIdx < dhdr->d_elemnum; thrIdx++ )
       
   840 					{
       
   841 					printf("\tThread Name\t\t\t:%s\n",&array[thrdinfod->td_name]);
       
   842 					print_thread_info(thrdinfod);
       
   843 					thrdinfod ++;
       
   844 					}
       
   845 				}
       
   846 			else if(dhdr->d_type == ESYM_NOTE_PROC )
       
   847 				{
       
   848 				printf("PROCESS INFO SEGMENT\n\n");
       
   849 
       
   850 				if( sizeof(Sym32_procinfod) != dhdr->d_descrsz )
       
   851 					{
       
   852 					printf("\tWarning! :  sizeof(Sym32_procinfod) %d is different from descriptor size %d\n\n",
       
   853 						sizeof(Sym32_procinfod), dhdr->d_descrsz );
       
   854 					}
       
   855 
       
   856 				if( SYM32_PROCINFO_SIZE != dhdr->d_descrsz )
       
   857 					{
       
   858 					printf("\tWarning! : Expected Size of PROCESS INFO SEGMENT %d is different from descriptor size %d\n\n",
       
   859 						 SYM32_PROCINFO_SIZE, dhdr->d_descrsz );
       
   860 					}
       
   861 
       
   862 				Sym32_procinfod *procinfod = ADDR(Sym32_procinfod,eh,data+sizeof(Sym32_dhdr));
       
   863 
       
   864 				for(int procIdx = 0; procIdx < dhdr->d_elemnum; procIdx ++ )
       
   865 					{
       
   866 					printf("\tProcess Name\t\t\t:%s\n",&array[procinfod->pd_name]);
       
   867 					print_process_info(procinfod);
       
   868 					procinfod ++;
       
   869 					printf("\n");
       
   870 					}
       
   871 				}
       
   872 			else if(dhdr->d_type == ESYM_NOTE_EXEC)
       
   873 				{
       
   874 				printf("EXECUTABLE INFO SEGMENT\n\n");
       
   875 
       
   876 				if( sizeof(Sym32_execinfod) != dhdr->d_descrsz )
       
   877 					{
       
   878 					printf("\tWarning! : sizeof(Sym32_execinfod) %d is different from descriptor size %d\n\n",
       
   879 						sizeof(Sym32_execinfod), dhdr->d_descrsz );
       
   880 					}
       
   881 
       
   882 				if( SYM32_EXECINFO_SIZE != dhdr->d_descrsz )
       
   883 					{
       
   884 					printf("\tWarning! : Expected Size of EXECUTABLE INFO SEGMENT %d is different from descriptor size %d\n\n",
       
   885 						 SYM32_EXECINFO_SIZE, dhdr->d_descrsz );
       
   886 					}
       
   887 
       
   888 				Sym32_execinfod *execinfod = ADDR(Sym32_execinfod,eh,data+sizeof(Sym32_dhdr));
       
   889 				for(int i = 0; i < dhdr->d_elemnum; i++)
       
   890 					{
       
   891 					if(i) printf("\n");
       
   892 					printf("\tCrashed Executable Name\t\t:%s\n",&array[execinfod->ed_name]);
       
   893 					print_executable_info(execinfod);
       
   894 					execinfod++;
       
   895 					}
       
   896 				}
       
   897 			else if(dhdr->d_type == ESYM_NOTE_REG)
       
   898 				{
       
   899 				printf("REGISTER INFO SEGMENT\n\n");
       
   900 
       
   901 				if( SYM32_REGINFO_SIZE != sizeof(Sym32_reginfod) )
       
   902 					{
       
   903 					printf("\tWarning! : Expected Size of REGISTER INFO SEGMENT %d is different from sizeof operator %d\n\n",
       
   904 						SYM32_REGINFO_SIZE, sizeof(Sym32_reginfod) );
       
   905 					}
       
   906 
       
   907 				if( SYM32_REGDATA_SIZE != sizeof(Sym32_regdatad) )
       
   908 					{
       
   909 					printf("\tWarning! : Expected Size of REGISTER INFO DATA SEGMENT %d is different from sizeof operator %d\n\n",
       
   910 						SYM32_REGDATA_SIZE, sizeof(Sym32_regdatad) );
       
   911 					}
       
   912 
       
   913 				Sym32_reginfod *reginfod = ADDR(Sym32_reginfod,eh,data+sizeof(Sym32_dhdr));
       
   914 
       
   915 				for( int regInfoD = 0; regInfoD < dhdr->d_elemnum; regInfoD++ )
       
   916 					{
       
   917 					print_register_info(reginfod, eh, array);
       
   918 					reginfod ++;
       
   919 					}
       
   920 
       
   921 				}
       
   922 			else if(dhdr->d_type == ESYM_NOTE_TRACE)
       
   923 				{
       
   924 				printf("TRACE INFO SEGMENT\n\n");
       
   925 
       
   926 				if( SYM32_TRACEDATA_SIZE != sizeof(Sym32_tracedata) )
       
   927 					{
       
   928 					printf("\tWarning! : Expected Size of TRACE INFO SEGMENT %d is different from sizeof operator %d\n\n",
       
   929 							SYM32_TRACEDATA_SIZE, sizeof(Sym32_tracedata) );
       
   930 					}
       
   931 
       
   932 				Sym32_tracedata *traceInfo = ADDR(Sym32_tracedata, eh, data+sizeof(Sym32_dhdr));
       
   933 
       
   934 				for( int cnt = 0; cnt < dhdr->d_elemnum; cnt++ )
       
   935 					{
       
   936 					print_trace_info(traceInfo, eh, array);
       
   937 					traceInfo++;
       
   938 					}
       
   939 				}
       
   940 			else if(dhdr->d_type == ESYM_NOTE_ROMBUILD)
       
   941 				{
       
   942 				printf("ROM BUILD INFO SEGMENT\n\n");
       
   943 
       
   944 				if( SYM32_ROMBUILD_SIZE != sizeof(Sym32_rombuild) )
       
   945 					{
       
   946 					printf("\tWarning! : Expected Size of ROM BUILD INFO SEGMENT %d is different from sizeof operator %d\n\n",
       
   947 							SYM32_ROMBUILD_SIZE, sizeof(Sym32_rombuild) );
       
   948 					}
       
   949 
       
   950 				Sym32_rombuild *romInf = ADDR(Sym32_rombuild, eh, data+sizeof(Sym32_dhdr));
       
   951 
       
   952 				for( int cnt = 0; cnt < dhdr->d_elemnum; cnt++ )
       
   953 					{
       
   954 					print_rom_info(romInf);
       
   955 					romInf++;
       
   956 					}
       
   957 				}
       
   958 			else if(dhdr->d_type == ESYM_NOTE_VARIANT_DATA)
       
   959 				{
       
   960 				printf("VARIANT SPECIFIC DATA SEGMENT");
       
   961 
       
   962 				Sym32_variant_spec_data* varData = ADDR(Sym32_variant_spec_data,eh,data+sizeof(Sym32_dhdr));
       
   963 				if(SYM32_VARIANT_SPEC_DATA_SIZE != sizeof(Sym32_variant_spec_data))
       
   964 					{
       
   965 					printf("\tWarning! : Expected Size of VARIANT SPECIFIC DATA SEGMENT %d is different from sizeof operator %d\n\n",
       
   966 						SYM32_VARIANT_SPEC_DATA_SIZE, sizeof(Sym32_variant_spec_data));
       
   967 					}
       
   968 	
       
   969 				if(sizeof(Sym32_variant_spec_data) != dhdr->d_descrsz )
       
   970 					{
       
   971 					printf("\tWarning! :  sizeof(Sym32_variant_spec_data) %d is different from descriptor size %d\n\n",
       
   972 						sizeof(Sym32_variant_spec_data), dhdr->d_descrsz );
       
   973 					}
       
   974 
       
   975 				print_variant_data(varData, eh);
       
   976 
       
   977 				}
       
   978 			else if(dhdr->d_type == ESYM_NOTE_LOCKDATA)
       
   979 				{
       
   980 				printf("LOCK DATA SEGMENT");
       
   981 
       
   982 				Sym32_lockdata* lockdata = ADDR(Sym32_lockdata,eh,data+sizeof(Sym32_dhdr));
       
   983 				if( SYM32_LOCKDATA_SIZE != sizeof(Sym32_lockdata))
       
   984 					{
       
   985 					printf("\tWarning! : Expected Size of LOCK DATA SEGMENT %d is different from sizeof operator %d\n\n",
       
   986 					SYM32_LOCKDATA_SIZE, sizeof(Sym32_lockdata) );
       
   987 					}
       
   988 
       
   989 				if( sizeof(Sym32_lockdata) != dhdr->d_descrsz )
       
   990 					{
       
   991 					printf("\tWarning! :  sizeof(Sym32_lockdata) %d is different from descriptor size %d\n\n",
       
   992 						sizeof(Sym32_lockdata), dhdr->d_descrsz );
       
   993 					}
       
   994 
       
   995 				print_lockdata_info(lockdata);
       
   996 				}	
       
   997 			else if(dhdr->d_type == ESYM_NOTE_STR)
       
   998 				{
       
   999 				printf("STRING INFO SEGMENT\n\n");
       
  1000 				char *temp=array+dhdr->d_descrsz;
       
  1001 				printf("\t");
       
  1002 				while(array<=temp)
       
  1003 					{
       
  1004 					printf("%c",*array);
       
  1005 					array++;
       
  1006 					}
       
  1007 				}
       
  1008 			}
       
  1009 		else
       
  1010 			{
       
  1011 		 	//printf("\t other p_types\n"); //unknown
       
  1012 		 	continue;
       
  1013 			}
       
  1014 		}
       
  1015 
       
  1016 	//sections start here
       
  1017 	int shoff = eh->e_shoff;							    // offset of section header table
       
  1018 	Elf32_Shdr* shdr = ADDR(Elf32_Shdr, eh, shoff);			// calculating pointer to Secton Header Table
       
  1019 															// Elf32_Shdr * shdr = (Elf32_Shdr *)(buffer+shoff);
       
  1020 	int shnum = eh->e_shnum;							    // number of section headers
       
  1021 	int shstrndx = eh->e_shstrndx;
       
  1022 	int snameoffset = shdr[shstrndx].sh_offset;				// offset in file of sections' names
       
  1023 	char* sname = ADDR(char, eh, snameoffset);				// pointer to String Table which holds section names
       
  1024 															// char * sname = (char *)(buffer+snameoffset);
       
  1025 
       
  1026 	Elf32_Sym* symT= findSymbolT(eh);	// pointer to Symbol table
       
  1027 	if (symT==NULL)
       
  1028 		{
       
  1029 		printf("\nSymbol table not found\n");
       
  1030 		}
       
  1031 
       
  1032 	unsigned char* strtab=findSymbolStringT(eh);	// pointer to String table which holds symbol names
       
  1033 	if (strtab==NULL)
       
  1034 		{
       
  1035 		printf("\nString table holding symbol names not found\n");
       
  1036 		}
       
  1037 
       
  1038 	print_reloc(eh,symT, strtab);	// print relocation info showing symbol names and
       
  1039 					        // and the name of section in which the relocaton occurs.
       
  1040 	for(int k = 0; k < shnum; k++)
       
  1041 		{
       
  1042 		unsigned char* data = ADDR(unsigned char, eh, shdr[k].sh_offset);	//pointer to the first byte in the section
       
  1043 															//unsigned char * data = (unsigned char * )(buffer+shdr[k].sh_offset);
       
  1044 		int size = shdr[k].sh_size;	// section size in bytes
       
  1045 
       
  1046 		//print directive section
       
  1047 		if (!strcmp(".directive", &sname[shdr[k].sh_name]))
       
  1048 			{
       
  1049 			print_sect_header(sname, shdr, k);
       
  1050 			print_directive(data,size);
       
  1051 			}
       
  1052 
       
  1053 		if (!strcmp(".symtab", &sname[shdr[k].sh_name]))
       
  1054 			{
       
  1055 			 print_sect_header(sname, shdr, k);
       
  1056 			 // print global symbols
       
  1057 			 print_GlSymbols(eh,symT, strtab);
       
  1058 			}
       
  1059 
       
  1060 		//print relevant section header names
       
  1061  		//print hex dump of relevant sections
       
  1062 		if (shdr[k].sh_type==1 || shdr[k].sh_type==4 || shdr[k].sh_type==6 ||
       
  1063 			shdr[k].sh_type==9 || shdr[k].sh_type==11)
       
  1064 			{
       
  1065 			if (strcmp(".comment", &sname[shdr[k].sh_name])&&
       
  1066 				strcmp(".line", &sname[shdr[k].sh_name])   &&
       
  1067 				strcmp(".hash", &sname[shdr[k].sh_name])   &&
       
  1068 				strcmp(".note", &sname[shdr[k].sh_name])   &&
       
  1069 				strcmp(".directive", &sname[shdr[k].sh_name]) &&
       
  1070 				strncmp(".debug",&sname[shdr[k].sh_name] ,6))
       
  1071 				{
       
  1072 				if (!((ignoreSomeSections) &&
       
  1073 					(strncmp(".rel.debug_", &sname[shdr[k].sh_name], 11)==0)))
       
  1074 					{
       
  1075 					print_sect_header(sname, shdr, k);
       
  1076 					hexdump(data,size,k);
       
  1077 					}
       
  1078 				}
       
  1079 			}
       
  1080 		if (printAll)		// displays extra information
       
  1081 			{
       
  1082 			if(k!=0)
       
  1083 			 	{
       
  1084 				print_sect_header(sname, shdr, k);
       
  1085 				hexdump(data,size,k);
       
  1086 				}
       
  1087 			}
       
  1088 		}
       
  1089 	print_Summary(eh);	// print section names
       
  1090 	return 0;
       
  1091 }
       
  1092 
       
  1093 int read_ar_element_header(char* ptr)
       
  1094 	{
       
  1095 	int length = strtol(ptr+48,0,10);
       
  1096 
       
  1097 	if (strncmp(ptr+58, "\x60\x0A", 2) != 0)
       
  1098 		{
       
  1099 		return -1;
       
  1100 		}
       
  1101 	return length;
       
  1102 	}
       
  1103 
       
  1104 int main(int argc, char* argv[])
       
  1105 	{
       
  1106 	char* arg;
       
  1107 	int numberOfOptions=2;
       
  1108 	printAll=0;
       
  1109 	ignoreSomeSections=0;
       
  1110 	if (argc<2)
       
  1111 		{
       
  1112 		printf("File not specified");
       
  1113 		exit(1);
       
  1114 		}
       
  1115 	else if (argc>numberOfOptions+2)
       
  1116 		{
       
  1117 		printf("Too many arguments");
       
  1118 		exit(1);
       
  1119 		}
       
  1120 	else
       
  1121 		{
       
  1122 		for (int i=1;i<=argc-2;i++)
       
  1123 			{
       
  1124 			if ( strcmp("-i", argv[i]) ==0 )
       
  1125 				{
       
  1126 				ignoreSomeSections=1;
       
  1127 				}
       
  1128 			else if ( strcmp("-a", argv[i]) ==0 )
       
  1129 				{
       
  1130 				printAll=1;
       
  1131 				}
       
  1132 			}
       
  1133 		arg=argv[argc-1];
       
  1134 		}
       
  1135 
       
  1136 	struct stat results;
       
  1137 	stat(arg, &results);
       
  1138 	FILE *elffile;
       
  1139 	if((elffile  = fopen(arg, "rb" )) == NULL)
       
  1140 		{
       
  1141 		cout << "Error opening file " << arg;
       
  1142 		exit (1);
       
  1143 		}
       
  1144 
       
  1145 	char* buffer=new  char [results.st_size];//allocating enough memory
       
  1146 	fread( buffer, sizeof( char ), results.st_size, elffile);
       
  1147 	fclose(elffile);
       
  1148 
       
  1149 	if (strncmp(buffer, "!<arch>\x0A", 8) != 0)
       
  1150 		{
       
  1151 		// plain ELF file
       
  1152 		if (do_elf_file(buffer, arg) != 0)
       
  1153 			{
       
  1154 			return 1;
       
  1155 			}
       
  1156 		return 0;
       
  1157 		}
       
  1158 
       
  1159 	// library file
       
  1160 	char* nextfile = buffer;
       
  1161 	int remainder = results.st_size;
       
  1162 
       
  1163 #define ADVANCE(n)	nextfile+=(n); remainder-=(n);
       
  1164 
       
  1165 	ADVANCE(8);
       
  1166 
       
  1167 	while (remainder > 0)
       
  1168 		{
       
  1169 		int element_length = read_ar_element_header(nextfile);
       
  1170 		ADVANCE(60);
       
  1171 
       
  1172 		if (element_length < 0 || element_length > remainder)
       
  1173 			{
       
  1174 			cout << "Error: archive file corrupt";
       
  1175 			return 1;
       
  1176 			}
       
  1177 
       
  1178 		if (strncmp(nextfile, "\x7F\x45\x4C\x46",4) == 0)
       
  1179 			{
       
  1180 			if (do_elf_file(nextfile, "archive_element") != 0)
       
  1181 				{
       
  1182 				return 1;
       
  1183 				}
       
  1184 			}
       
  1185 		element_length += element_length&1;	// round up to a multiple of 2
       
  1186 		ADVANCE(element_length);
       
  1187 		}
       
  1188 
       
  1189 	return 0;
       
  1190 	}