Changeset 156


Ignore:
Timestamp:
Jul 7, 2017, 1:40:30 PM (7 years ago)
Author:
max@…
Message:

style

Location:
trunk/kernel/libk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/libk/elf.c

    r23 r156  
    3333#include <syscalls.h>
    3434
    35 
    3635///////////////////////////////////////////////////////////////////
    3736// This static function checks the .elf header.
     
    4140static bool_t elf_isValidHeader(Elf32_Ehdr *header)
    4241{
    43         if((header->e_ident[EI_CLASS] == ELFCLASS32) 
    44            && (header->e_ident[EI_DATA] == ELFDATA2LSB) 
     42        if((header->e_ident[EI_CLASS] == ELFCLASS32)
     43           && (header->e_ident[EI_DATA] == ELFDATA2LSB)
    4544           && (header->e_ident[EI_VERSION] == EV_CURRENT)
    4645           && (header->e_ident[EI_OSABI] == ELFOSABI_NONE)
    47            && ((header->e_machine == EM_MIPS) || 
     46           && ((header->e_machine == EM_MIPS) ||
    4847               (header->e_machine == EM_MIPS_RS3_LE) ||
    4948               (header->e_machine == EM_386))
    50            && (header->e_type == ET_EXEC))          return true;
    51    
     49           && (header->e_type == ET_EXEC))
     50                return true;
     51
    5252        if( header->e_ident[EI_CLASS] != ELFCLASS32 )
    53     printk("\n[ERROR] in %s : Elf is not 32-Binary\n", __FUNCTION__ );
     53                printk("\n[ERROR] in %s : Elf is not 32-Binary\n", __FUNCTION__ );
    5454
    5555        if( header->e_ident[EI_DATA] != ELFDATA2LSB )
    56     printk("\n[ERROR] in %s : Elf is not 2's complement, little endian\n", __FUNCTION__ );
    57 
    58         if( header->e_ident[EI_VERSION] != EV_CURRENT ) 
    59     printk("\n[ERROR] in %s : Elf is not in Current Version\n", __FUNCTION__);
     56                printk("\n[ERROR] in %s : Elf is not 2's complement, little endian\n", __FUNCTION__ );
     57
     58        if( header->e_ident[EI_VERSION] != EV_CURRENT )
     59                printk("\n[ERROR] in %s : Elf is not in Current Version\n", __FUNCTION__);
    6060
    6161        if( header->e_ident[EI_OSABI] != ELFOSABI_NONE )
    62     printk("\n[ERROR] in %s : Unexpected Elf ABI, need UNIX System V ABI\n", __FUNCTION__ );
    63 
    64         if( (header->e_machine == EM_MIPS) || 
    65                 (header->e_machine == EM_MIPS_RS3_LE) ||
    66         (header->e_machine == EM_386) )
    67         printk("\n[ERROR] in %s : unexpected core / accept only MIPS or 80386\n", __FUNCTION__ );
     62                printk("\n[ERROR] in %s : Unexpected Elf ABI, need UNIX System V ABI\n", __FUNCTION__ );
     63
     64        if( (header->e_machine == EM_MIPS) ||
     65            (header->e_machine == EM_MIPS_RS3_LE) ||
     66            (header->e_machine == EM_386) )
     67                printk("\n[ERROR] in %s : unexpected core / accept only MIPS or 80386\n", __FUNCTION__ );
    6868
    6969        if( header->e_type == ET_EXEC )
    70         printk("\n[ERROR] in %s : Elf is not executable binary\n", __FUNCTION__ );
     70                printk("\n[ERROR] in %s : Elf is not executable binary\n", __FUNCTION__ );
    7171
    7272        return false;
     
    7474
    7575///////////////////////////////////////////////////////////////////////////////////////
    76 // This function load the .elf header in the buffer allocated by the caller.
     76// This function loads the .elf header in the buffer allocated by the caller.
    7777// @ file   : extended pointer on the remote file descriptor.
    7878// @ buffer : pointer on buffer allocated by the caller.
     
    8282                                void   * buffer,
    8383                                uint32_t size )
    84 { 
    85     uint32_t  count;
    86 
    87     // load .elf header
     84{
     85        uint32_t  count;
     86
     87        // load .elf header
    8888        count = vfs_move( true ,
    89                       file_xp,
    90                       buffer,
    91                       size );
     89                          file_xp,
     90                          buffer,
     91                          size );
    9292
    9393        if( count != size )
     
    9797        }
    9898
    99     Elf32_Ehdr * header = (Elf32_Ehdr *)buffer;
    100    
     99        Elf32_Ehdr * header = (Elf32_Ehdr *)buffer;
     100
    101101        if( (header->e_ident[EI_MAG0] != ELFMAG0) ||
    102102            (header->e_ident[EI_MAG1] != ELFMAG1) ||
     
    114114        }
    115115        return 0;
    116 }  // end elf_header_read()
     116}
    117117
    118118///////////////////////////////////////////////////////////////////////////////////////
     
    124124///////////////////////////////////////////////////////////////////////////////////////
    125125static error_t elf_segments_load( xptr_t       file_xp,
    126                                                   void       * segs_base,
     126                                  void       * segs_base,
    127127                                  uint32_t     nb_segs,
    128                                                   process_t  * process )
     128                                  process_t  * process )
    129129{
    130130        error_t      error;
    131131        uint32_t     index;
    132132        uint32_t     file_size;
    133     uint32_t     mem_size;
     133        uint32_t     mem_size;
    134134        intptr_t     start;
    135135        uint32_t     type;
    136136        uint32_t     flags;
    137137        uint32_t     offset;
    138     vseg_t     * vseg;
    139 
    140     Elf32_Phdr * seg_ptr = (Elf32_Phdr *)segs_base;
    141 
    142     // loop on segments
    143         for( index = 0 ; index < nb_segs ; index++ , seg_ptr++ )
    144         {   
    145                 if( seg_ptr->p_type != PT_LOAD) continue;
    146    
    147         // get segment attributes
     138        vseg_t     * vseg;
     139
     140        Elf32_Phdr * seg_ptr = (Elf32_Phdr *)segs_base;
     141
     142        // loop on segments
     143        for( index = 0 ; index < nb_segs ; index++ , seg_ptr++ )
     144        {
     145                if( seg_ptr->p_type != PT_LOAD)
     146                        continue;
     147
     148                // get segment attributes
    148149                start     = seg_ptr->p_vaddr;
    149         offset    = seg_ptr->p_offset;
    150         file_size = seg_ptr->p_filesz;
    151         mem_size  = seg_ptr->p_memsz;
    152         flags     = seg_ptr->p_flags;
    153 
    154         // check alignment
     150                offset    = seg_ptr->p_offset;
     151                file_size = seg_ptr->p_filesz;
     152                mem_size  = seg_ptr->p_memsz;
     153                flags     = seg_ptr->p_flags;
     154
     155                // check alignment
    155156                if( start & CONFIG_PPM_PAGE_MASK )
    156157                {
     
    159160                }
    160161
    161         // check size
    162         if( file_size != mem_size )
     162                // check size
     163                if( file_size != mem_size )
    163164                {
    164165                        printk("\n[WARNING] in %s : base = %x / mem_size = %x / file_size = %x\n",
     
    166167                }
    167168
    168         // set seek on segment base in file
     169                // set seek on segment base in file
    169170                error = vfs_lseek( file_xp,
    170                            offset,
    171                            SEEK_SET,
    172                            NULL );
     171                                   offset,
     172                                   SEEK_SET,
     173                                   NULL );
    173174
    174175                if( error )
     
    180181                if( flags & PF_X ) // found CODE segment
    181182                {
    182             type                       = VSEG_TYPE_CODE;
     183                        type                       = VSEG_TYPE_CODE;
    183184                        process->vmm.code_vpn_base = start >> CONFIG_PPM_PAGE_SHIFT;
    184185
    185186                        elf_dmsg("\n[INFO] %s found CODE vseg / base = %x / size = %x\n",
    186                      __FUNCTION__ , start , mem_size );
    187                 }
    188                 else                   // found DATA segment
    189                 {
    190             type                       = VSEG_TYPE_DATA;
     187                                 __FUNCTION__ , start , mem_size );
     188                }
     189                else               // found DATA segment
     190                {
     191                        type                       = VSEG_TYPE_DATA;
    191192                        process->vmm.data_vpn_base = start >> CONFIG_PPM_PAGE_SHIFT;
    192193
    193194                        elf_dmsg("\n[INFO] %s found DATA vseg / base = %x / size = %x\n",
    194                      __FUNCTION__, start , mem_size );
    195                 }
    196 
    197         // register vseg in VMM
    198                 vseg = (vseg_t *)vmm_create_vseg( process, 
    199                                                               start,
    200                                                               mem_size,
    201                                                               type );
     195                                 __FUNCTION__, start , mem_size );
     196                }
     197
     198                // register vseg in VMM
     199                vseg = (vseg_t *)vmm_create_vseg( process,
     200                                                  start,
     201                                                  mem_size,
     202                                                  type );
    202203                if( vseg == NULL )
    203204                {
     
    211212
    212213        return 0;
    213 } // end elf_load_segments()
     214}
    214215
    215216///////////////////////////////////////////////
     
    217218                          process_t * process)
    218219{
    219     char         path_copy[CONFIG_VFS_MAX_PATH_LENGTH];
     220        char         path_copy[CONFIG_VFS_MAX_PATH_LENGTH];
    220221        kmem_req_t   req;              // kmem request for program header
    221222        uint32_t     length;           // actual path length
    222223        Elf32_Ehdr   header;           // local buffer for .elf header
    223224        void       * segs_base;        // pointer on buffer for segment descriptors array
    224     uint32_t     segs_size;        // size of buffer for segment descriptors array 
     225        uint32_t     segs_size;        // size of buffer for segment descriptors array
    225226        xptr_t       file_xp;          // extended pointer on created file descriptor
    226     uint32_t     file_id;          // file descriptor index (unused)
    227     uint32_t     count;            // bytes counter
     227        uint32_t     file_id;          // file descriptor index (unused)
     228        uint32_t     count;            // bytes counter
    228229        error_t      error;
    229230
    230     // get path length from user space
     231        // get path length from user space
    231232        length = hal_strlen_from_uspace( pathname );
    232233
    233     if( length >= CONFIG_VFS_MAX_PATH_LENGTH )
    234     {
    235         printk("\n[ERROR] in %s : pathname length too long\n", __FUNCTION__ );
    236         return -1;
    237     }
    238 
    239     // make a local copy for pathname
    240     hal_copy_from_uspace( path_copy , pathname , length+1 );
    241 
    242     // open file
    243     file_xp = XPTR_NULL;  // avoid GCC warning
    244     file_id = -1;
    245 
    246         error = vfs_open( process->vfs_cwd_xp, 
    247                       path_copy,
    248                       O_RDONLY,
    249                       0,
    250                       &file_xp,
    251                       &file_id );
     234        if( length >= CONFIG_VFS_MAX_PATH_LENGTH )
     235        {
     236                printk("\n[ERROR] in %s : pathname length too long\n", __FUNCTION__ );
     237                return -1;
     238        }
     239
     240        // make a local copy for pathname
     241        hal_copy_from_uspace( path_copy , pathname , length+1 );
     242
     243        // open file
     244        file_xp = XPTR_NULL;  // avoid GCC warning
     245        file_id = -1;
     246
     247        error = vfs_open( process->vfs_cwd_xp,
     248                          path_copy,
     249                          O_RDONLY,
     250                          0,
     251                          &file_xp,
     252                          &file_id );
    252253        if( error )
    253254        {
    254255                printk("\n[ERROR] in %s : failed to open executable file %s\n",
    255                __FUNCTION__ , path_copy );
    256                 return -1;
    257         }
    258 
    259     // load header in local buffer
    260         error = elf_header_read( file_xp , 
    261                              &header,
    262                              sizeof(Elf32_Ehdr) );
    263         if( error ) 
    264     {
    265         vfs_close( file_xp , file_id );
    266         return -1;
    267     }
     256                       __FUNCTION__ , path_copy );
     257                return -1;
     258        }
     259
     260        // load header in local buffer
     261        error = elf_header_read( file_xp ,
     262                                 &header,
     263                                 sizeof(Elf32_Ehdr) );
     264        if( error )
     265        {
     266                vfs_close( file_xp , file_id );
     267                return -1;
     268        }
    268269
    269270        elf_dmsg("\n[INFO] %s loaded elf header for %s\n", __FUNCTION__ , path_copy );
     
    272273        {
    273274                printk("\n[ERROR] in %s : no segments found\n", __FUNCTION__ );
    274         vfs_close( file_xp , file_id );
    275                 return -1;
    276         }
    277 
    278     // compute buffer size for segment descriptors array
     275                vfs_close( file_xp , file_id );
     276                return -1;
     277        }
     278
     279        // compute buffer size for segment descriptors array
    279280        segs_size = sizeof(Elf32_Phdr) * header.e_phnum;
    280  
    281     // allocate memory for segment descriptors array
     281
     282        // allocate memory for segment descriptors array
    282283        req.type  = KMEM_GENERIC;
    283284        req.size  = segs_size;
     
    286287
    287288        if( segs_base == NULL )
    288     {
     289        {
    289290                printk("\n[ERROR] in %s : no memory for segment descriptors\n", __FUNCTION__ );
    290         vfs_close( file_xp , file_id );
    291         return -1;
    292     }
    293 
    294     // set seek pointer in file descriptor to access segment descriptors array
     291                vfs_close( file_xp , file_id );
     292                return -1;
     293        }
     294
     295        // set seek pointer in file descriptor to access segment descriptors array
    295296        error = vfs_lseek( file_xp , header.e_phoff, SEEK_SET , NULL );
    296297
     
    298299        {
    299300                printk("\n[ERROR] in %s : cannot seek for descriptors array\n", __FUNCTION__ );
    300         vfs_close( file_xp , file_id );
    301             req.ptr = segs_base;
    302             kmem_free( &req );
    303                 return -1;
    304         }
    305 
    306     // load seg descriptors array to local buffer
     301                vfs_close( file_xp , file_id );
     302                req.ptr = segs_base;
     303                kmem_free( &req );
     304                return -1;
     305        }
     306
     307        // load seg descriptors array to local buffer
    307308        count = vfs_move( true,
    308                       file_xp,
    309                       segs_base,
    310                       segs_size );
     309                          file_xp,
     310                          segs_base,
     311                          segs_size );
    311312
    312313        if( count != segs_size )
    313314        {
    314315                printk("\n[ERROR] in %s : cannot read segments descriptors\n", __FUNCTION__ );
    315         vfs_close( file_xp , file_id );
    316             req.ptr = segs_base;
    317             kmem_free( &req );
     316                vfs_close( file_xp , file_id );
     317                req.ptr = segs_base;
     318                kmem_free( &req );
    318319                return -1;
    319320        }
     
    321322        elf_dmsg("\n[INFO] %s loaded segments descriptors for %s \n", __FUNCTION__ , path_copy );
    322323
    323     // register loadable segments in process VMM
    324         error = elf_segments_load( file_xp, 
    325                                segs_base,
    326                                header.e_phnum,
    327                                process );
     324        // register loadable segments in process VMM
     325        error = elf_segments_load( file_xp,
     326                                   segs_base,
     327                                   header.e_phnum,
     328                                   process );
    328329        if( error )
    329     {
    330         vfs_close( file_xp , file_id );
    331             req.ptr = segs_base;
    332             kmem_free( &req );
    333                 return -1;
    334     }
    335 
    336     // register process entry point in VMM
     330        {
     331                vfs_close( file_xp , file_id );
     332                req.ptr = segs_base;
     333                kmem_free( &req );
     334                return -1;
     335        }
     336
     337        // register process entry point in VMM
    337338        process->vmm.entry_point = (intptr_t)header.e_entry;
    338339
    339     // register extended pointer on .elf file descriptor
    340     process->vfs_bin_xp = file_xp;
    341 
    342     // release allocated memory for program header
     340        // register extended pointer on .elf file descriptor
     341        process->vfs_bin_xp = file_xp;
     342
     343        // release allocated memory for program header
    343344        req.ptr = segs_base;
    344345        kmem_free(&req);
    345346
    346         elf_dmsg("\n[INFO] %s successfully completed / entry point = %x for %s]\n", 
     347        elf_dmsg("\n[INFO] %s successfully completed / entry point = %x for %s]\n",
    347348                 __FUNCTION__, (uint32_t) header.e_entry , path_copy );
    348349
    349350        return 0;
    350 }  // end elf_load_process()
    351 
     351}
     352
  • trunk/kernel/libk/elf.h

    r1 r156  
    7171        Elf32_Half      e_shnum;            /* Section header table entry count */
    7272        Elf32_Half      e_shstrndx;         /* Section header string table index */
    73 } 
     73}
    7474Elf32_Ehdr;
    7575
     
    150150        Elf32_Word      p_flags;        /* Segment flags */
    151151        Elf32_Word      p_align;    /* Segment alignment */
    152 } 
     152}
    153153Elf32_Phdr;
    154154
     
    187187
    188188/****************************************************************************************
    189  * This function register in VMM the CODE and DATA vsegs defined in the .elf file.
     189 * This function registers in VMM the CODE and DATA vsegs defined in the .elf file.
    190190 * The segments are not loaded in memory.
    191  * It register also the process entry point in VMM.
     191 * It also registers the process entry point in VMM.
    192192 ****************************************************************************************
    193193 * @ pathname : .elf file pathname (in user space => must use hal_uspace API).
     
    197197                          process_t * process);
    198198
    199 
    200199#endif  /* elf.h */
Note: See TracChangeset for help on using the changeset viewer.