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