summaryrefslogblamecommitdiffstats
path: root/elfreader.c
blob: eb0edf7a65e3c3ed7f778a272816f103770cc8d0 (plain) (tree)




























































































































































































































































































































































                                                                                
                      












































































































































































































































































































                                                                                        




                                             



                                                        

                                                                       






                                                 


                                                   


                                                  
                                                                          
 


                        


                                    
                                                                         



                            

                                  
         
















                                                                     






























                                                                  
#include "elfreader.h"


/******************************************************************************/
Elf_Ident* elf_ident(  FILE *f )
{
	Elf_Ident *ret = NULL;
	size_t read_bytes = 0;

	if ( f == NULL )
	{
		return NULL;
	}

	ret = malloc( sizeof(Elf_Ident) );
	if ( ret == NULL )
	{
		return NULL;
	}

	fseek( f, 0, SEEK_SET );
	read_bytes = fread( ret->ident, 1, EI_NIDENT, f );
	if ( read_bytes != EI_NIDENT )
	{
		free( ret );
		return NULL;
	}

	return ret;
}


/******************************************************************************/
int ident_check( Elf_Ident *ident )
{
	int ret=0;
	/* check if its elf file */
	if ( (ident->ident[EI_MAG0] != ELFMAG0) ||
	     (ident->ident[EI_MAG1] != ELFMAG1) ||
	     (ident->ident[EI_MAG2] != ELFMAG2) ||
	     (ident->ident[EI_MAG3] != ELFMAG3) )
	{
		printf("Elf header magic is wrong\n");
		ret = -1;
	}

	/* check file class */
	switch ( ident->ident[EI_CLASS] )
	{
	case ELFCLASS32:
	case ELFCLASS64:
		break;
	default:
		printf("EI_CLASS not supported\n");
		return -1;
	}

	return ret;
}


/******************************************************************************/
void ident_info( Elf_Ident *ident )
{
	printf("ELF IDENT:\n");
	printf("ELFCLASS  :0x%02x\n", ident->ident[EI_CLASS]);
	printf("ELFDATA   :0x%02x\n", ident->ident[EI_DATA]);
}


/******************************************************************************/
int elf_ehdr_32( Elf_Ehdr *ehdr, Elf32_Ehdr *ehdr32, int byteorder )
{
	if ( byteorder == ELF_MLSB )
	{
		/* working with MIPS on INTEL */
		elf_ehdr32_bele( ehdr32 );
		/* input was in MSB output now in LSB */
	} else if ( (byteorder == ELF_MMSB) || (byteorder == ELF_LLSB) )
	{
		/* no need to do something */
	} else 
	{
		/* is someone compile stuff on MIPS for Intel or so? */
		ERROR("Not yet implemented\n");
		/* Should be ok for now */
		exit(0);
	}

	ehdr->e_type      = ehdr32->e_type;
	ehdr->e_machine   = ehdr32->e_machine;
	ehdr->e_version   = ehdr32->e_version;
	ehdr->e_entry     = ehdr32->e_entry;
	ehdr->e_phoff     = ehdr32->e_phoff;
	ehdr->e_shoff     = ehdr32->e_shoff;
	ehdr->e_flags     = ehdr32->e_flags;
	ehdr->e_ehsize    = ehdr32->e_ehsize;
	ehdr->e_phentsize = ehdr32->e_phentsize;
	ehdr->e_phnum     = ehdr32->e_phnum;
	ehdr->e_shentsize = ehdr32->e_shentsize;
	ehdr->e_shnum     = ehdr32->e_shnum;
	ehdr->e_shstrndx  = ehdr32->e_shstrndx;

	return 0;
}


/******************************************************************************/
int elf_ehdr_64( Elf_Ehdr *ehdr, Elf64_Ehdr *ehdr64, int byteorder )
{
	ENL();

	ehdr->e_type      = ehdr64->e_type;
	ehdr->e_machine   = ehdr64->e_machine;
	ehdr->e_version   = ehdr64->e_version;
	ehdr->e_entry     = ehdr64->e_entry;
	ehdr->e_phoff     = ehdr64->e_phoff;
	ehdr->e_shoff     = ehdr64->e_shoff;
	ehdr->e_flags     = ehdr64->e_flags;
	ehdr->e_ehsize    = ehdr64->e_ehsize;
	ehdr->e_phentsize = ehdr64->e_phentsize;
	ehdr->e_phnum     = ehdr64->e_phnum;
	ehdr->e_shentsize = ehdr64->e_shentsize;
	ehdr->e_shnum     = ehdr64->e_shnum;
	ehdr->e_shstrndx  = ehdr64->e_shstrndx;

	return 0;
}


/******************************************************************************/
int elf_32_ehdr( Elf32_Ehdr *ehdr32, Elf_Ehdr *ehdr )
{

	ehdr32->e_type      = ehdr->e_type;
	ehdr32->e_machine   = ehdr->e_machine;
	ehdr32->e_version   = ehdr->e_version;
	ehdr32->e_entry     = ehdr->e_entry;
	ehdr32->e_phoff     = ehdr->e_phoff;
	ehdr32->e_shoff     = ehdr->e_shoff;
	ehdr32->e_flags     = ehdr->e_flags;
	ehdr32->e_ehsize    = ehdr->e_ehsize;
	ehdr32->e_phentsize = ehdr->e_phentsize;
	ehdr32->e_phnum     = ehdr->e_phnum;
	ehdr32->e_shentsize = ehdr->e_shentsize;
	ehdr32->e_shnum     = ehdr->e_shnum;
	ehdr32->e_shstrndx  = ehdr->e_shstrndx;

	if ( ehdr->byteorder == ELF_MLSB )
	{
		elf_ehdr32_bele( ehdr32 );
	} else if ( (ehdr->byteorder == ELF_MMSB) || 
	  	  (  ehdr->byteorder == ELF_LLSB))
	{
	/* No need to do anything */
	} else
	{
		ERROR("Note implemtented\n");
	}


	return 0;
}


/******************************************************************************/
int elf_64_ehdr( Elf64_Ehdr *ehdr64, Elf_Ehdr *ehdr )
{
	ehdr64->e_type      = ehdr->e_type;
	ehdr64->e_machine   = ehdr->e_machine;
	ehdr64->e_version   = ehdr->e_version;
	ehdr64->e_entry     = ehdr->e_entry;
	ehdr64->e_phoff     = ehdr->e_phoff;
	ehdr64->e_shoff     = ehdr->e_shoff;
	ehdr64->e_flags     = ehdr->e_flags;
	ehdr64->e_ehsize    = ehdr->e_ehsize;
	ehdr64->e_phentsize = ehdr->e_phentsize;
	ehdr64->e_phnum     = ehdr->e_phnum;
	ehdr64->e_shentsize = ehdr->e_shentsize;
	ehdr64->e_shnum     = ehdr->e_shnum;
	ehdr64->e_shstrndx  = ehdr->e_shstrndx;

	return 0;
}

/******************************************************************************/
int elf_ehdr32_bele( Elf32_Ehdr *ehdr32 )
{
	int ret = 0;

	ehdr32->e_type      = SWP16(ehdr32->e_type);
	ehdr32->e_machine   = SWP16(ehdr32->e_machine);
	ehdr32->e_version   = SWP32(ehdr32->e_version);
	ehdr32->e_entry     = SWP32(ehdr32->e_entry);
	ehdr32->e_phoff     = SWP32(ehdr32->e_phoff );
	ehdr32->e_shoff     = SWP32(ehdr32->e_shoff);
	ehdr32->e_flags     = SWP32(ehdr32->e_flags);
	ehdr32->e_ehsize    = SWP16(ehdr32->e_ehsize);
	ehdr32->e_phentsize = SWP16(ehdr32->e_phentsize);
	ehdr32->e_phnum     = SWP16(ehdr32->e_phnum);
	ehdr32->e_shentsize = SWP16(ehdr32->e_shentsize);
	ehdr32->e_shnum     = SWP16(ehdr32->e_shnum);
	ehdr32->e_shstrndx  = SWP16(ehdr32->e_shstrndx);

	return ret;
}

/******************************************************************************/
int elf_ehdr32_lebe( Elf32_Ehdr *ehdr32 )
{
	int ret = 0;
	uint16_t u16;

	PNL();
	/*
	ehdr32->e_type      = SWP16(ehdr32->e_type);
	ehdr32->e_machine   = SWP16(ehdr32->e_machine);
	ehdr32->e_version   = SWP32(ehdr32->e_version);
	ehdr32->e_entry     = SWP32(ehdr32->e_entry);
	ehdr32->e_phoff     = SWP32(ehdr32->e_phoff );
	ehdr32->e_shoff     = SWP32(ehdr32->e_shoff);
	ehdr32->e_flags     = SWP32(ehdr32->e_flags);
	ehdr32->e_ehsize    = SWP16(ehdr32->e_ehsize);
	ehdr32->e_phentsize = SWP16(ehdr32->e_phentsize);
	ehdr32->e_phnum     = SWP16(ehdr32->e_phnum);
	ehdr32->e_shentsize = SWP16(ehdr32->e_shentsize);
	ehdr32->e_shnum     = SWP16(ehdr32->e_shnum);
	ehdr32->e_shstrndx  = SWP16(ehdr32->e_shstrndx);
	*/
	return ret;
}


/******************************************************************************/
int elf_ehdr2mem( Elf_Ident *ident, Elf_Ehdr *ehdr, uint8_t *buf, int size )
{
	int ret = 0;

	int i,j;
	uint8_t *head = NULL;
	int     sz_head = -1;

	if ( ehdr->type == ELF_TYPE_32 )
	{
		sz_head = sizeof(Elf32_Ehdr);
		head = malloc( sz_head );
		elf_32_ehdr( (Elf32_Ehdr *)head, ehdr );
	} else if ( ehdr->type == ELF_TYPE_64 )
	{
		sz_head = sizeof(Elf64_Ehdr);
		head = malloc( sz_head );
		elf_64_ehdr( (Elf64_Ehdr *)head, ehdr );
	} else
	{
		printf("Unknown ELF header type\n");
		return -1;
	}

	memcpy( head, ident->ident, EI_NIDENT);

	for (i=0,j=0; (i<size)&&(j<