00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <const.h>
00012 #include <errno.h>
00013
00014 #include <arch/mem.h>
00015
00016 #include <kernel/console.h>
00017 #include <kernel/fat.h>
00018 #include <kernel/kernel_map.h>
00019 #include <kernel/keyboard.h>
00020 #include <kernel/kmalloc.h>
00021
00022 #include <kernel/elf32.h>
00023
00024
00025
00026
00027
00028
00029
00030 int elf32_check(elf32_hdr_t *f)
00031 {
00032
00033 #ifdef ELF32_DEBUG
00034 kprintf("\n\rFile header:");
00035 kprintf("\n\rmagic[]=%c%c%c%c class=%u data=%u",
00036 f->e_ident[EI_MAG0],
00037 f->e_ident[EI_MAG1],
00038 f->e_ident[EI_MAG2],
00039 f->e_ident[EI_MAG3],
00040 f->e_ident[EI_CLASS],
00041 f->e_ident[EI_DATA]
00042 );
00043 #endif
00044
00045 if (
00046 (f->e_ident[EI_MAG0] != ELF_MAG0) ||
00047 (f->e_ident[EI_MAG1] != ELF_MAG1) ||
00048 (f->e_ident[EI_MAG2] != ELF_MAG2) ||
00049 (f->e_ident[EI_MAG3] != ELF_MAG3)
00050 )
00051 return( -ENOEXEC );
00052
00053
00054 if ( f->e_ident[EI_CLASS] != ELF_CLASS32 )
00055 return( -ENOEXEC );
00056
00057
00058 if ( f->e_ident[EI_DATA] != ELF_DATA2LSB )
00059 return( -ENOEXEC );
00060
00061
00062 return(0);
00063 }
00064
00065
00066
00067
00068
00069
00070
00071 uint32_t elf32_copy_sections(elf32_hdr_t *f)
00072 {
00073 elf32_shdr_t *sec;
00074 int sec_num;
00075 int sec_entsize;
00076 int i;
00077
00078 void copy_section(elf32_shdr_t *sec)
00079 {
00080 #ifdef ELF32_DEBUG
00081 kprintf("\n\rsh_name = %#010x", sec->sh_name);
00082 kprintf("\n\rsh_type = %#010x", sec->sh_type);
00083 kprintf("\n\rsh_flags = %#010x", sec->sh_flags);
00084 kprintf("\n\rsh_addr = %#010x", sec->sh_addr);
00085 kprintf("\n\rsh_offset = %#010x", sec->sh_offset);
00086 kprintf("\n\rsh_size = %#010x", sec->sh_size);
00087 kprintf("\n\rsh_link = %#010x", sec->sh_link);
00088 kprintf("\n\rsh_info = %#010x", sec->sh_info);
00089 kprintf("\n\rsh_addralign = %#010x", sec->sh_addralign);
00090 kprintf("\n\rsh_entsize = %#010x", sec->sh_entsize);
00091 kprintf("\n\r");
00092 #endif
00093
00094
00095 if( (sec->sh_addr==NULL) || (sec->sh_offset==NULL) )
00096 return;
00097
00098
00099 memcpy( (void *)(sec->sh_addr),
00100 (void *)((uint32_t)f + sec->sh_offset),
00101 sec->sh_size );
00102 }
00103
00104
00105 if ( elf32_check(f)<0 )
00106 return(NULL);
00107
00108
00109 sec_num = f->e_shnum;
00110 sec_entsize = f->e_shentsize;
00111 #ifdef ELF32_DEBUG
00112 kprintf("\n\rEntry point @ %#010x", f->e_entry);
00113 kprintf("\n\rsec_num=%#010x, sec_entsize=%#010x\n\r", sec_num, sec_entsize);
00114 #endif
00115
00116
00117
00118
00119
00120
00121 sec = (elf32_shdr_t *)((uint32_t)f->e_shoff + (uint32_t)f);
00122 for (i=0; i<sec_num; i++)
00123 {
00124 if ( (sec->sh_addr >= K_VIR_START) || (sec->sh_addr + sec->sh_size) >= K_VIR_START )
00125 return( NULL );
00126 (uint32_t)sec += sec_entsize;
00127 }
00128
00129
00130 sec = (elf32_shdr_t *)((uint32_t)f->e_shoff + (uint32_t)f);
00131 for (i=0; i<sec_num; i++)
00132 {
00133 copy_section( sec );
00134 (uint32_t)sec += sec_entsize;
00135 }
00136 return( f->e_entry );
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 int elf32_load_file(char *file_name, void *file_buffer)
00148 {
00149
00150
00151
00152 if ( !(load_file(file_name, file_buffer)) )
00153 return( -ENOENT );
00154
00155
00156 if ( elf32_check((elf32_hdr_t *)file_buffer) < 0 )
00157 return( -ENOEXEC );
00158
00159
00160 return(0);
00161 }
00162
00163
00164 int elf32_exec(void *f, int argc, char **argv)
00165 {
00166 int (*entry)(int argc, char **argv) = (int(*)(int argc, char **argv))(((elf32_hdr_t *)f)->e_entry);
00167 return( entry(argc, argv) );
00168 }