Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/lib/elf.c

    rda1bafb r439d036  
    2828 */
    2929
    30 /** @addtogroup generic
     30/** @addtogroup generic 
    3131 * @{
    3232 */
     
    3434/**
    3535 * @file
    36  * @brief Kernel ELF loader.
     36 * @brief       Kernel ELF loader.
    3737 */
    3838
    3939#include <lib/elf.h>
    4040#include <debug.h>
    41 #include <typedefs.h>
     41#include <arch/types.h>
    4242#include <mm/as.h>
    4343#include <mm/frame.h>
     
    4848#include <arch.h>
    4949
    50 static const char *error_codes[] = {
     50static char *error_codes[] = {
    5151        "no error",
    5252        "invalid image",
     
    5757};
    5858
    59 static int segment_header(elf_segment_header_t *, elf_header_t *, as_t *,
    60     unsigned int);
    61 static int section_header(elf_section_header_t *, elf_header_t *, as_t *);
    62 static int load_segment(elf_segment_header_t *, elf_header_t *, as_t *);
     59static int segment_header(elf_segment_header_t *entry, elf_header_t *elf,
     60    as_t *as, int flags);
     61static int section_header(elf_section_header_t *entry, elf_header_t *elf,
     62    as_t *as);
     63static int load_segment(elf_segment_header_t *entry, elf_header_t *elf,
     64    as_t *as);
    6365
    6466/** ELF loader
    6567 *
    6668 * @param header Pointer to ELF header in memory
    67  * @param as     Created and properly mapped address space
    68  * @param flags  A combination of ELD_F_*
    69  *
     69 * @param as Created and properly mapped address space
     70 * @param flags A combination of ELD_F_*
    7071 * @return EE_OK on success
    71  *
    72  */
    73 unsigned int elf_load(elf_header_t *header, as_t *as, unsigned int flags)
    74 {
     72 */
     73unsigned int elf_load(elf_header_t *header, as_t * as, int flags)
     74{
     75        int i, rc;
     76
    7577        /* Identify ELF */
    76         if ((header->e_ident[EI_MAG0] != ELFMAG0) ||
    77             (header->e_ident[EI_MAG1] != ELFMAG1) ||
    78             (header->e_ident[EI_MAG2] != ELFMAG2) ||
    79             (header->e_ident[EI_MAG3] != ELFMAG3))
     78        if (header->e_ident[EI_MAG0] != ELFMAG0 ||
     79            header->e_ident[EI_MAG1] != ELFMAG1 ||
     80            header->e_ident[EI_MAG2] != ELFMAG2 ||
     81            header->e_ident[EI_MAG3] != ELFMAG3) {
    8082                return EE_INVALID;
     83        }
    8184       
    8285        /* Identify ELF compatibility */
    83         if ((header->e_ident[EI_DATA] != ELF_DATA_ENCODING) ||
    84             (header->e_machine != ELF_MACHINE) ||
    85             (header->e_ident[EI_VERSION] != EV_CURRENT) ||
    86             (header->e_version != EV_CURRENT) ||
    87             (header->e_ident[EI_CLASS] != ELF_CLASS))
     86        if (header->e_ident[EI_DATA] != ELF_DATA_ENCODING ||
     87            header->e_machine != ELF_MACHINE ||
     88            header->e_ident[EI_VERSION] != EV_CURRENT ||
     89            header->e_version != EV_CURRENT ||
     90            header->e_ident[EI_CLASS] != ELF_CLASS) {
    8891                return EE_INCOMPATIBLE;
    89        
     92        }
     93
    9094        if (header->e_phentsize != sizeof(elf_segment_header_t))
    9195                return EE_INCOMPATIBLE;
    92        
     96
    9397        if (header->e_shentsize != sizeof(elf_section_header_t))
    9498                return EE_INCOMPATIBLE;
    95        
     99
    96100        /* Check if the object type is supported. */
    97101        if (header->e_type != ET_EXEC)
    98102                return EE_UNSUPPORTED;
    99        
     103
    100104        /* Check if the ELF image starts on a page boundary */
    101         if (ALIGN_UP((uintptr_t) header, PAGE_SIZE) != (uintptr_t) header)
     105        if (ALIGN_UP((uintptr_t)header, PAGE_SIZE) != (uintptr_t)header)
    102106                return EE_UNSUPPORTED;
    103        
     107
    104108        /* Walk through all segment headers and process them. */
    105         elf_half i;
    106109        for (i = 0; i < header->e_phnum; i++) {
    107                 elf_segment_header_t *seghdr =
    108                     &((elf_segment_header_t *)(((uint8_t *) header) +
     110                elf_segment_header_t *seghdr;
     111
     112                seghdr = &((elf_segment_header_t *)(((uint8_t *) header) +
    109113                    header->e_phoff))[i];
    110                
    111                 int rc = segment_header(seghdr, header, as, flags);
     114                rc = segment_header(seghdr, header, as, flags);
    112115                if (rc != EE_OK)
    113116                        return rc;
    114117        }
    115        
     118
    116119        /* Inspect all section headers and proccess them. */
    117120        for (i = 0; i < header->e_shnum; i++) {
    118                 elf_section_header_t *sechdr =
    119                     &((elf_section_header_t *)(((uint8_t *) header) +
     121                elf_section_header_t *sechdr;
     122
     123                sechdr = &((elf_section_header_t *)(((uint8_t *) header) +
    120124                    header->e_shoff))[i];
    121                
    122                 int rc = section_header(sechdr, header, as);
     125                rc = section_header(sechdr, header, as);
    123126                if (rc != EE_OK)
    124127                        return rc;
    125128        }
    126        
     129
    127130        return EE_OK;
    128131}
     
    133136 *
    134137 * @return NULL terminated description of error.
    135  *
    136  */
    137 const char *elf_error(unsigned int rc)
     138 */
     139char *elf_error(unsigned int rc)
    138140{
    139141        ASSERT(rc < sizeof(error_codes) / sizeof(char *));
    140        
     142
    141143        return error_codes[rc];
    142144}
     
    145147 *
    146148 * @param entry Segment header.
    147  * @param elf   ELF header.
    148  * @param as    Address space into wich the ELF is being loaded.
     149 * @param elf ELF header.
     150 * @param as Address space into wich the ELF is being loaded.
    149151 *
    150152 * @return EE_OK on success, error code otherwise.
    151  *
    152153 */
    153154static int segment_header(elf_segment_header_t *entry, elf_header_t *elf,
    154     as_t *as, unsigned int flags)
    155 {
     155    as_t *as, int flags)
     156{
     157        char *interp;
     158
    156159        switch (entry->p_type) {
    157160        case PT_NULL:
     
    162165        case PT_DYNAMIC:
    163166        case PT_INTERP:
    164                 // FIXME
    165                 /*
    166                 char *interp = (char *) elf + entry->p_offset;
    167                 if (memcmp((uintptr_t) interp, (uintptr_t) ELF_INTERP_ZSTR,
     167                interp = (char *)elf + entry->p_offset;
     168                /* FIXME */
     169                /*if (memcmp((uintptr_t)interp, (uintptr_t)ELF_INTERP_ZSTR,
    168170                    ELF_INTERP_ZLEN) != 0) {
    169171                        return EE_UNSUPPORTED;
    170                 } */
    171                 if ((flags & ELD_F_LOADER) == 0)
     172                }*/
     173                if ((flags & ELD_F_LOADER) == 0) {
    172174                        return EE_LOADER;
     175                }
    173176                break;
    174177        case PT_SHLIB:
     
    185188 *
    186189 * @param entry Program header entry describing segment to be loaded.
    187  * @param elf   ELF header.
    188  * @param as    Address space into wich the ELF is being loaded.
     190 * @param elf ELF header.
     191 * @param as Address space into wich the ELF is being loaded.
    189192 *
    190193 * @return EE_OK on success, error code otherwise.
    191  *
    192194 */
    193195int load_segment(elf_segment_header_t *entry, elf_header_t *elf, as_t *as)
    194196{
     197        as_area_t *a;
     198        int flags = 0;
    195199        mem_backend_data_t backend_data;
     200        uintptr_t base;
     201        size_t mem_sz;
     202       
    196203        backend_data.elf = elf;
    197204        backend_data.segment = entry;
    198        
     205
    199206        if (entry->p_align > 1) {
    200207                if ((entry->p_offset % entry->p_align) !=
    201                     (entry->p_vaddr % entry->p_align))
     208                    (entry->p_vaddr % entry->p_align)) {
    202209                        return EE_INVALID;
    203         }
    204        
    205         unsigned int flags = 0;
    206        
     210                }
     211        }
     212
    207213        if (entry->p_flags & PF_X)
    208214                flags |= AS_AREA_EXEC;
    209        
    210215        if (entry->p_flags & PF_W)
    211216                flags |= AS_AREA_WRITE;
    212        
    213217        if (entry->p_flags & PF_R)
    214218                flags |= AS_AREA_READ;
    215        
    216219        flags |= AS_AREA_CACHEABLE;
    217        
    218         /*
     220
     221        /* 
    219222         * Align vaddr down, inserting a little "gap" at the beginning.
    220223         * Adjust area size, so that its end remains in place.
    221          *
    222224         */
    223         uintptr_t base = ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE);
    224         size_t mem_sz = entry->p_memsz + (entry->p_vaddr - base);
    225        
    226         as_area_t *area = as_area_create(as, flags, mem_sz, base,
     225        base = ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE);
     226        mem_sz = entry->p_memsz + (entry->p_vaddr - base);
     227
     228        a = as_area_create(as, flags, mem_sz, base,
    227229            AS_AREA_ATTR_NONE, &elf_backend, &backend_data);
    228         if (!area)
     230        if (!a)
    229231                return EE_MEMORY;
    230232       
    231233        /*
    232234         * The segment will be mapped on demand by elf_page_fault().
    233          *
    234235         */
    235        
     236
    236237        return EE_OK;
    237238}
     
    240241 *
    241242 * @param entry Segment header.
    242  * @param elf   ELF header.
    243  * @param as    Address space into wich the ELF is being loaded.
     243 * @param elf ELF header.
     244 * @param as Address space into wich the ELF is being loaded.
    244245 *
    245246 * @return EE_OK on success, error code otherwise.
    246  *
    247247 */
    248248static int section_header(elf_section_header_t *entry, elf_header_t *elf,
Note: See TracChangeset for help on using the changeset viewer.