#ifndef __VXBOOT_LOADER_H__ # define __VXBOOT_LOADER_H__ #include #include #include "vxBoot/hardware.h" #include "vxBoot/fs/smemfs.h" //--- // ELF struct definition //--- /* The ELF file header. This appears at the start of every ELF file. */ #define EI_NIDENT (16) typedef struct { uint8_t e_ident[EI_NIDENT]; /* Magic number and other info */ uint16_t e_type; /* Object file type */ uint16_t e_machine; /* Architecture */ uint32_t e_version; /* Object file version */ uint32_t e_entry; /* Entry point virtual address */ uint32_t e_phoff; /* Program header table file offset */ uint32_t e_shoff; /* Section header table file offset */ uint32_t e_flags; /* Processor-specific flags */ uint16_t e_ehsize; /* ELF header size in bytes */ uint16_t e_phentsize; /* Program header table entry size */ uint16_t e_phnum; /* Program header table entry count */ uint16_t e_shentsize; /* Section header table entry size */ uint16_t e_shnum; /* Section header table entry count */ uint16_t e_shstrndx; /* Section header string table index */ } Elf32_Ehdr; /* Fields in the e_ident array */ #define EI_MAG0 0 /* File identification byte 0 index */ #define EI_MAG1 1 /* File identification byte 1 index */ #define EI_MAG2 2 /* File identification byte 2 index */ #define EI_MAG3 3 /* File identification byte 3 index */ #define ELFMAG0 0x7f /* Magic number byte 0 */ #define ELFMAG1 'E' /* Magic number byte 1 */ #define ELFMAG2 'L' /* Magic number byte 2 */ #define ELFMAG3 'F' /* Magic number byte 3 */ /* class information */ #define EI_CLASS 4 /* File class byte index */ #define ELFCLASS32 1 /* 32-bit objects */ /* data encoding information */ #define EI_DATA 5 /* Data encoding byte index */ #define ELFDATA2MSB 2 /* 2's complement, big endian */ /* object file type */ #define ET_EXEC 2 /* Executable file */ #define ET_DYN 3 /* Shared object file */ /* architecture */ #define EM_SH 42 /* Hitachi SH */ /* ELF version */ #define EV_CURRENT 1 /* Current version */ /* Program segment header. */ typedef struct { uint32_t p_type; /* Segment type */ uint32_t p_offset; /* Segment file offset */ uint32_t p_vaddr; /* Segment virtual address */ uint32_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 */ } Elf32_Phdr; /* Section header */ typedef struct { uint32_t sh_name; /* Section name (string tbl index) */ uint32_t sh_type; /* Section type */ uint32_t sh_flags; /* Section flags */ uint32_t sh_addr; /* Section virtual addr at execution */ uint32_t sh_offset; /* Section file offset */ uint32_t sh_size; /* Section size in bytes */ uint32_t sh_link; /* Link to another section */ uint32_t sh_info; /* Additional section information */ uint32_t sh_addralign; /* Section alignment */ uint32_t sh_entsize; /* Entry size if section holds table */ } Elf32_Shdr; /* Legal values for sh_type (section type). */ #define SHT_NULL 0 /* Section header table entry unused */ #define SHT_PROGBITS 1 /* Program data */ #define SHT_SYMTAB 2 /* Symbol table */ #define SHT_STRTAB 3 /* String table */ #define SHT_RELA 4 /* Relocation entries with addends */ #define SHT_HASH 5 /* Symbol hash table */ #define SHT_DYNAMIC 6 /* Dynamic linking information */ #define SHT_NOTE 7 /* Notes */ #define SHT_NOBITS 8 /* Program space with no data (bss) */ #define SHT_REL 9 /* Relocation entries, no addends */ #define SHT_SHLIB 10 /* Reserved */ #define SHT_DYNSYM 11 /* Dynamic linker symbol table */ #define SHT_INIT_ARRAY 14 /* Array of constructors */ #define SHT_FINI_ARRAY 15 /* Array of destructors */ #define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ #define SHT_GROUP 17 /* Section group */ #define SHT_SYMTAB_SHNDX 18 /* Extended section indices */ #define SHT_NUM 19 /* Number of defined types. */ /* Relocation table entry with addend (in section of type SHT_RELA). */ typedef struct { uint32_t r_offset; /* Address */ uint32_t r_info; /* Relocation type and symbol index */ int32_t r_addend; /* Addend */ } Elf32_Rela; /* How to extract and insert information held in the r_info field. */ #define ELF32_R_SYM(val) ((val) >> 8) #define ELF32_R_TYPE(val) ((val) & 0xff) #define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff)) /* SH relocs. */ #define R_SH_NONE 0 #define R_SH_DIR32 1 #define R_SH_REL32 2 #define R_SH_DIR8WPN 3 #define R_SH_IND12W 4 #define R_SH_DIR8WPL 5 #define R_SH_DIR8WPZ 6 #define R_SH_DIR8BP 7 #define R_SH_DIR8W 8 #define R_SH_DIR8L 9 #define R_SH_SWITCH16 25 #define R_SH_SWITCH32 26 #define R_SH_USES 27 #define R_SH_COUNT 28 #define R_SH_ALIGN 29 #define R_SH_CODE 30 #define R_SH_DATA 31 #define R_SH_LABEL 32 #define R_SH_SWITCH8 33 #define R_SH_GNU_VTINHERIT 34 #define R_SH_GNU_VTENTRY 35 #define R_SH_TLS_GD_32 144 #define R_SH_TLS_LD_32 145 #define R_SH_TLS_LDO_32 146 #define R_SH_TLS_IE_32 147 #define R_SH_TLS_LE_32 148 #define R_SH_TLS_DTPMOD32 149 #define R_SH_TLS_DTPOFF32 150 #define R_SH_TLS_TPOFF32 151 #define R_SH_GOT32 160 #define R_SH_PLT32 161 #define R_SH_COPY 162 #define R_SH_GLOB_DAT 163 #define R_SH_JMP_SLOT 164 #define R_SH_RELATIVE 165 #define R_SH_GOTOFF 166 #define R_SH_GOTPC 167 /* Keep this the last entry. */ #define R_SH_NUM 256 /* Symbol table entry. */ typedef struct { uint32_t st_name; /* Symbol name (string tbl index) */ uint32_t st_value; /* Symbol value */ uint32_t st_size; /* Symbol size */ unsigned char st_info; /* Symbol type and binding */ unsigned char st_other; /* Symbol visibility */ uint16_t st_shndx; /* Section index */ } Elf32_Sym; //--- // Loader API //--- /* kernel loading information */ struct kernel { /* kernel entry */ uintptr_t entry; /* memory information */ struct { struct { void *start; size_t size; struct { uintptr_t vmin; uintptr_t vmax; } elf; } program; } memory; /* hardware information */ struct hwinfo hardware; /* file information */ struct smemfs_inode const *inode; /* ELF information */ struct { Elf32_Ehdr hdr; Elf32_Shdr *shdr; Elf32_Phdr *phdr; struct { Elf32_Sym *tab; int nb; } sym; char * shstrtab; char * strtab; uintptr_t * got; int got_nb; } elf; }; /* internal kernel image list */ struct ldimg { struct smemfs_inode * inode; struct ldimg *next; }; /* loader_scan() : scan the storage memory and try to find ELF PIE file */ extern int loader_scan(void); /* loader_kernel_img_get() : get the image ID information */ extern struct ldimg *loader_kernel_img_get(int id); /* loader_kernel_img_count() : count the number of kernel image found */ extern int loader_kernel_img_count(void); /* loader() : try to load a ELF PIE file */ #define LOADER_DEFAULT 0 #define LOADER_DUMP 1 #define LOADER_TRACE 2 #define LOADER_INFO 3 #define LOADER_CHECK 4 extern int loader(struct smemfs_inode const * restrict const inode, int mode); //--- // Error ldpers //--- struct ld_error_db { const int id; const char *strerror; }; extern int loader_error( struct ld_error_db const * const db, char const * restrict const prefix, int const errnum ); //--- // ELF Header ldpers //--- enum { ld_header_valid = 0, ld_header_size_error = -1, ld_header_magic_error = -2, ld_header_class_error = -3, ld_header_indent_error = -4, ld_header_type_error = -5, ld_header_machine_error = -6, ld_header_version_error = -7, }; /* loader_header_get() : get / check ELF header information */ extern int loader_header_get( struct smemfs_inode const * restrict const inode, Elf32_Ehdr *header ); /* loader_header_check() : load and check the file header validity */ extern int loader_header_check(struct kernel * const kernel); /* loader_header_error() : display error message */ extern int loader_header_error(int errnum); //--- // ELF image ldpers //--- /* returned value */ enum { ld_image_success = 0, ld_image_size_error = -1, ld_image_type_error = -2, ld_image_mem_error = -3, ld_image_mem_not_available = -4, }; /* loader_image_load() : try to load the entier image data */ extern int loader_image_load(struct kernel * const kernel); /* loader_image_error() : Display error message */ extern int loader_image_error(int const errnum); //--- // Relocs helpers //--- /* loader_got_patch() : Try to patch the GOT section */ extern int loader_got_patch(struct kernel * const kernel); /* loader_rela_patch() : Try to patch the RELA section */ extern int loader_rela_patch(struct kernel * const kernel); #endif /*__VXBOOT_LOADER_H__*/