#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