328 lines
8.5 KiB
C
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__*/
|