26 #ifndef CONFIG_FILESYSTEM_SUPPORT
27 #error "Filesystem support required for Elf loader"
48 #define __KSYMTAB_ADDR ((va_t *)&_SW_KSYMTAB)
53 *entry_func,
u32 symindex,
const char *strtab,
62 if(
sw_strcmp((
char *)(strtab + index), entry_func) == 0){
91 sw_printf(
"Unable to unmap secure memory of elf loader\n");
107 static int load_into_memory(
void *file_map ,
Elf32_Shdr * sec_header)
112 int shnum = elf_header->
e_shnum,i;
115 for(i = 1; i < shnum ; i++){
118 (
void*)tmp_shdr[i].sh_addr,
119 tmp_shdr[i].sh_size);
124 prev_addr += tmp_shdr[i].
sh_size;
150 const char *symname,
int n)
188 *entry_func,
u32 symindex,
const char *strtab,
197 if(
sw_strcmp((
char *)(strtab + index), entry_func) == 0){
236 static int apply_relocations(
void *file_map ,
Elf32_Shdr *sec_header ,
const
247 u32 symbol_addr,sym_index = symindex;
248 s32 offset,loc_to_rel;
254 va_t * sym_tab_start = (
va_t *)&_SW_KSYMTAB;
255 va_t * sym_tab_end = (
va_t *)&_SW_KSYMTAB_END;
256 u32 n = ((
u32)sym_tab_end -
266 if(offset < 0 || offset >
268 sw_printf(
"Invalid offset inside the symbol table\n");
276 symname = str_tab + sym->
st_name;
280 if( (rel[i].r_offset < 0 || rel[i].r_offset >
282 sw_printf(
"Invalid offset of %s\n", symname);
308 symbol_addr = get_undefined_symbol_addr(
310 if(symbol_addr == -1){
317 offset = (*(
u32 *) loc_to_rel &
319 if(offset & 0x02000000)
320 offset -= 0x04000000;
323 offset += symbol_addr -
341 *(
u32 *)loc_to_rel &= 0xff000000;
343 |= offset & 0x00ffffff;
352 offset = (*(
u32 *) loc_to_rel &
355 if(offset & 0x02000000)
356 offset -= 0x04000000;
361 offset <= 0xfe000000 ||
362 offset >= 0x02000000) {
371 *(
u32 *)loc_to_rel &= 0xff000000;
372 *(
u32 *)loc_to_rel |= offset &
389 status = fix_entry_point(sec_header, tmp_sym ,entry_func ,
390 sym_index, str_tab, conf);
392 sw_printf(
"Unable to fix entry_point\n");
396 status = fix_process_func(sec_header, tmp_sym
398 sym_index, str_tab, conf);
401 sw_printf(
"Unable to fix process_func\n");
404 elf_header = file_map;
430 static int relocate_elf_loader(
int fp,
Elf32_Ehdr *elf_header,
434 u32 offset, len, num_bytes,sh_off,sh_num,i,symindex,strindex,relindex;
435 char *str_tab =
NULL;
436 int status,ret =
OTZ_OK,fl = 0;
461 num_bytes =
file_read(fp,(
char *)tmp,len);
467 tmp = (
char *)tmp + num_bytes;
477 sec_header = (
Elf32_Shdr *)((
char *)tmp + sh_off);
478 tmp_shdr = sec_header;
482 for(i = 1; i < sh_num ; i++){
495 str_tab = ((
char *)tmp + tmp_shdr[strindex].sh_offset);
498 for(i = 1;i < sh_num ; i++){
499 if(tmp_shdr[i].sh_type ==
SHT_REL){
501 status = apply_relocations(file_map, sec_header ,
502 str_tab, symindex, relindex, conf,&fl);
511 status = load_into_memory(file_map,sec_header);
513 sw_printf(
"Unable to load into memory\n");
536 static int init_map_loader(
sa_config_t *psa_config)
560 static int validate_elf_header(
int fp ,
Elf32_Ehdr *elf_header)
562 int num_bytes,rel = 0;
584 sw_printf(
"Not in Little Endian format\n");
590 sw_printf(
"Not using the current version of ELF\n");
605 sw_printf(
"Unsupported process architecture\n");
611 sw_printf(
"Not using the current version of the ELF file\n");
632 int ph_num,num_bytes,num_of_segments,num_of_loadable_segments = 0;
638 if(phdr_table ==
NULL){
643 num_bytes =
file_read(fp,(
char *)phdr_table,
645 if (num_bytes != (ph_num *
sizeof(
Elf32_Phdr))){
646 sw_printf(
"Reading Programheader table from ELF file failed\n");
650 tmp_phdr = phdr_table;
652 for(num_of_segments = 0;num_of_segments < elf_header->
e_phnum;
655 num_of_loadable_segments++;
660 *phdr_tab = phdr_table;
661 return num_of_loadable_segments;
683 u32 num_bytes = 0,va_offset,status;
686 u32 offset,leftover_size, num_of_loadable_segments = 0;
688 char *leftover_data =
NULL;
691 ret = init_map_loader(conf);
705 rel = validate_elf_header(fp,&elf_header);
706 tmp_ehdr = &elf_header;
708 status = relocate_elf_loader(fp,tmp_ehdr,conf);
712 if(status == -1 || status == 0)
726 &elf_header,&phdr_table);
727 if(num_of_loadable_segments == -1){
731 tmp_phdr = phdr_table;
733 flag =
sw_malloc(num_of_loadable_segments *
sizeof(
u32) );
739 sw_memset(flag,0x0,num_of_loadable_segments *
sizeof(
u32));
740 for(num_of_segments = 0;num_of_segments < elf_header.
e_phnum;
742 if(tmp_phdr->p_type ==
PT_LOAD)
746 if(tmp_phdr->p_filesz == tmp_phdr->p_memsz)
750 va_offset = tmp_phdr->p_vaddr;
752 offset = tmp_phdr->p_offset;
756 num_bytes =
file_read(fp,((
char *)base_va
759 if(num_bytes != tmp_phdr->p_filesz){
768 else if (tmp_phdr->p_filesz < tmp_phdr->p_memsz){
770 va_offset = tmp_phdr->p_vaddr;
771 offset = tmp_phdr->p_offset;
775 num_bytes =
file_read(fp,((
char *)base_va +
778 if(num_bytes != tmp_phdr->p_filesz){
783 leftover_size = (tmp_phdr->p_memsz -
784 tmp_phdr->p_filesz + 1);
787 tmp_phdr->p_filesz+ 1);
788 sw_memset(leftover_data,0x0,(tmp_phdr->p_memsz -
789 tmp_phdr->p_filesz + 1));
790 sw_memcpy(base_va,leftover_data,leftover_size);
812 tmp_phdr = phdr_table;
813 for(num_of_segments = 0,num_of_loadable_segments = 0;
814 num_of_segments < elf_header.
e_phnum;
816 if(tmp_phdr->p_type ==
PT_LOAD){
817 if(!flag[num_of_loadable_segments]){
823 num_of_loadable_segments++;