summaryrefslogblamecommitdiffstats
path: root/elfreader.h
blob: 06a5747959c9be80e0c79ab5c46389f8c14507a0 (plain) (tree)

























































































































































                                                                                                  
                                                                           


                                                                   
#ifndef __ELFREADER_H
#define __ELFREADER_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <elf.h>

#include "debug.h"
#include "assert.h"

#define SWP16(X) (((X)&0x00FF)<<8)|(((X)&0xFF00)>>8)
#define SWP32(X) ((((X)&0x00FF)<<24)|(((X)&0xFF00)<<8)|(((X)&0xFF0000)>>8)|(((X)&0xFF000000)>>24))


#define ELF_TYPE_UNKNOWN 0
#define ELF_TYPE_32      1
#define ELF_TYPE_64      2

/* if you add header on Intel(LE) on MIPS(be) arch
   then you going to have troubles. Lets prepare for this troubles
 */
#define ELF_ENONE 0
#define ELF_LLSB  1
#define ELF_LMSB  2
#define ELF_MLSB  3
#define ELF_MMSB  4

typedef struct Elf_Ident {
	unsigned char ident[EI_NIDENT];
} Elf_Ident;


/*
++++++++++++++++++++++++++++++++++++
+  Type  +   ELF32   +    ELF64    +
++++++++++++++++++++++++++++++++++++
+Half	 +  uint16_t  +  uint16_t  +
+Word    +  uint32_t  +  uint32_t  +
+Sword   +  int32_t   +  int32_t   +
+Xword   +  uint64_t  +  uint64_t  +
+Sxword  +  int64_t   +  int64_t   +
+Addr    +  uint32_t  +  uint64_t  +
+Off     +  uint32_t  +  uint64_t  +
+Section +  uint16_t  +  uint16_t  +
+Versym  +  uint16_t  +  uint16_t  +
++++++++++++++++++++++++++++++++++++
*/


typedef struct Elf_Ehdr {
	int		type;	/* to distinguish 32 or its 64 bits */
	int		byteorder;

	/* generic elf header information */
	uint16_t	e_type;			
	uint16_t	e_machine;		
	uint32_t	e_version;		
	uint64_t	e_entry;		
	uint64_t	e_phoff;		
	uint64_t	e_shoff;		
	uint32_t	e_flags;		
	uint16_t	e_ehsize;		
	uint16_t	e_phentsize;		
	uint16_t	e_phnum;		
	uint16_t	e_shentsize;		
	uint16_t	e_shnum;		
	uint16_t	e_shstrndx;		
} Elf_Ehdr;


typedef struct Elf_Phdr {
	int		type;
	uint32_t 	offset;			/* Offset in file */
	int		byteorder;
	
	/* generic progeam heaer information */
	uint32_t	p_type;			/* Segment type */
	uint64_t	p_offset;		/* Segment file offset */
	uint64_t	p_vaddr;		/* Segment virtual address */
	uint64_t	p_paddr;		/* Segment physical address */
	uint32_t	p_filesz;		/* Segment size in file */
	uint32_t	p_memsz;		/* Segment size in memory */
	uint32_t	p_flags;		/* Segment flags */
	uint32_t	p_align;		/* Segment alignment */
} Elf_Phdr;


typedef struct Elf_Shdr {
	int		type;
	uint32_t	offset;			/* Offset inside file */
	int		byteorder;
	
	/* generic section header information  */
	uint32_t	sh_name;		/* Section name (string tbl index) */
	uint32_t	sh_type;		/* Section type */
	uint64_t	sh_flags;		/* Section flags */
	uint64_t	sh_addr;		/* Section virtual addr at execution */
	uint64_t	sh_offset;		/* Section file offset */
	uint64_t	sh_size;		/* Section size in bytes */
	uint32_t	sh_link;		/* Link to another section */
	uint32_t	sh_info;		/* Additional section information */
	uint64_t	sh_addralign;		/* Section alignment */
	uint64_t	sh_entsize;
} Elf_Shdr;

typedef struct Elf_Shdr_strtab {
	long     offset;
	int      sz_tab;
	uint8_t *strtab;
} Elf_Shdr_strtab;

Elf_Ident* elf_ident(  FILE *f );
int ident_check( Elf_Ident *ident );
void ident_info( Elf_Ident *ident );

/* 
All headers can have different types or different offsets inside structure 
should we write each function 2 times for 32/64? or just one generic function
and type convos in between?
*/
/* ehdr := mapping ehdr32 */
int elf_ehdr_32( Elf_Ehdr *ehdr,     Elf32_Ehdr *ehdr32, int byteorder );
/* ehdr := mapping ehdr64 */
int elf_ehdr_64( Elf_Ehdr *ehdr,     Elf64_Ehdr *ehdr64, int byteorder );
/* ehdr32 := mapping ehdr */
int elf_32_ehdr( Elf32_Ehdr *ehdr32, Elf_Ehdr *ehdr );
/* ehdr64 := mapping ehdr */
int elf_64_ehdr( Elf64_Ehdr *ehdr64, Elf_Ehdr *ehdr );
int elf_ehdr32_bele( Elf32_Ehdr *ehdr32 );
int elf_ehdr32_lebe( Elf32_Ehdr *ehdr32 );
int elf_ehdr2mem( Elf_Ident *ident, Elf_Ehdr *ehdr, uint8_t *buf, int size );
Elf_Ehdr*    elf_header( FILE *f, Elf_Ident *ident, int sysorder );
void header_info( Elf_Ehdr *ehdr );


int elf_phdr_32( Elf_Phdr *phdr,     Elf32_Phdr *phdr32 );
int elf_phdr_64( Elf_Phdr *phdr,     Elf64_Phdr *phdr64 );
int elf_32_phdr( Elf32_Phdr *phdr32, Elf_Phdr   *phdr );
int elf_64_phdr( Elf64_Phdr *phdr64, Elf_Phdr   *phdr );
Elf_Phdr*   elf_phdr(    FILE *f, Elf_Ehdr  *ehdr  );


int elf_shdr_32( Elf_Shdr *shdr, Elf32_Shdr *shdr32 );
int elf_shdr_64( Elf_Shdr *shdr, Elf64_Shdr *shdr64 );
int elf_32_shdr( Elf32_Shdr *shdr32, Elf_Shdr *shdr );
int elf_64_shdr( Elf64_Shdr *shdr64, Elf_Shdr *shdr );
int elf_shdr64_lebe( Elf64_Shdr *shdr64 );
int elf_shdr32_lebe( Elf32_Shdr *shdr32 );
int elf_shdr2mem( Elf_Shdr *shdr, uint8_t *buf, int size, int offset );
Elf_Shdr**  elf_shdr( FILE *f, Elf_Ehdr  *ehdr  );
void section_info( Elf_Shdr* shdr, Elf_Shdr_strtab *strtab );

/* Search for strtab section */
Elf_Shdr_strtab* strtab_search( FILE *f, Elf_Ehdr *ehdr, Elf_Shdr **shdr );
unsigned char* strtab_name( Elf_Shdr_strtab *strtab, long offset );

#endif