vxBoot/include/vxBoot/loader.h

328 lines
8.5 KiB
C

#ifndef __VXBOOT_LOADER_H__
# define __VXBOOT_LOADER_H__
#include <stddef.h>
#include <stdint.h>
#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__*/