Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields   Globals   Related Pages  

elf32.c File Reference

ELF32 file format loader. More...

#include <const.h>
#include <errno.h>
#include <arch/mem.h>
#include <kernel/console.h>
#include <kernel/fat.h>
#include <kernel/kernel_map.h>
#include <kernel/keyboard.h>
#include <kernel/kmalloc.h>
#include <kernel/elf32.h>

Go to the source code of this file.

Functions

int elf32_check (elf32_hdr_t *f)
 Check if a file has a valid elf32 header.
Parameters:
f  The file header.
Returns:
  • 0 if success;
  • -ENOEXEC if f is not a valid ELF32 header.


uint32_t elf32_copy_sections (elf32_hdr_t *f)
 Copy the ELF32 sections at the right locations in memory.
Parameters:
f  The buffer where the ELF32 file is located.
Returns:
  • the entry point address on success;
  • NULL if an error occurs.


int elf32_load_file (char *file_name, void *file_buffer)
 Load an ELF32 file into a buffer.
Parameters:
file_name  The name of the file to be loaded.
file_buffer  The buffer where the file will be loaded.
Returns:
  • 0 on success;
  • -ENOENT if the file doesn't exist;
  • -ENOEXEC if the file is not a valid ELF32 file.


int elf32_exec (void *f, int argc, char **argv)
 Execute a file.


Detailed Description

ELF32 file format loader.

Author:
Andrea Righi <drizzt@inwind.it>
Date:
Last update:
2003-01-24 Andrea Righi: Skip NULL sections when copying them to memory.
Note:
Copyright (©) 2003 Andrea Righi

Definition in file elf32.c.


Function Documentation

int elf32_check elf32_hdr_t   f
 

Check if a file has a valid elf32 header.

Parameters:
f  The file header.
Returns:
  • 0 if success;
  • -ENOEXEC if f is not a valid ELF32 header.

Definition at line 30 of file elf32.c.

00031 {
00032 // Check if "f" is a valid ELF32 header                                 //
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         // Magic number check                                           //
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         // Class check                                                  //
00054         if ( f->e_ident[EI_CLASS] != ELF_CLASS32 )
00055                 return( -ENOEXEC );
00056 
00057         // Data encoding check                                          //
00058         if ( f->e_ident[EI_DATA] != ELF_DATA2LSB )
00059                 return( -ENOEXEC );
00060 
00061         // Check OK!                                                    //
00062         return(0);
00063 }

uint32_t elf32_copy_sections elf32_hdr_t   f
 

Copy the ELF32 sections at the right locations in memory.

Parameters:
f  The buffer where the ELF32 file is located.
Returns:
  • the entry point address on success;
  • NULL if an error occurs.

Definition at line 71 of file elf32.c.

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                 // Skip NULL sections.
00095                 if( (sec->sh_addr==NULL) || (sec->sh_offset==NULL) )
00096                         return;
00097 
00098                 // Copy this section into the current address space.
00099                 memcpy( (void *)(sec->sh_addr),
00100                         (void *)((uint32_t)f + sec->sh_offset),
00101                         sec->sh_size );
00102         }
00103 
00104         // Check if it is a valid ELF32 file                            //
00105         if ( elf32_check(f)<0 )
00106                 return(NULL);
00107 
00108         // Get the section informations                                 //
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         // First of all check if the sections are not in the user space
00117         // boundaries.
00118         // ----- User Sections          (4KB - 1GB)
00119         // ----- User Heap              (1GB - 2GB)
00120         // ----- User Stack             (2GB - 3GB)
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         // Copy the sections in memory                                  //
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 }

int elf32_exec void *    f,
int    argc,
char **    argv
 

Execute a file.

Definition at line 164 of file elf32.c.

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 }

int elf32_load_file char *    file_name,
void *    file_buffer
 

Load an ELF32 file into a buffer.

Parameters:
file_name  The name of the file to be loaded.
file_buffer  The buffer where the file will be loaded.
Returns:
  • 0 on success;
  • -ENOENT if the file doesn't exist;
  • -ENOEXEC if the file is not a valid ELF32 file.

Definition at line 147 of file elf32.c.

00148 {
00149         // Load the file into the buffer                                //
00150         // TODO: replace with:
00151         //      int fread(void *buf, size_t size, size_t count, FILE *stream);
00152         if ( !(load_file(file_name, file_buffer)) )
00153                 return( -ENOENT );
00154 
00155         // Check if it is a valid ELF file                              //
00156         if ( elf32_check((elf32_hdr_t *)file_buffer) < 0 )
00157                 return( -ENOEXEC );
00158 
00159         // The ELF32 file is successfully loaded                        //
00160         return(0);
00161 }


Generated on Fri Feb 20 15:32:17 2004 for Minirighi by doxygen1.2.18