Ignore:
File:
1 edited

Legend:

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

    r1e00216 r1ea99cc  
    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:
    158161        case PT_PHDR:
    159         case PT_NOTE:
    160162                break;
    161163        case PT_LOAD:
    162164                return load_segment(entry, elf, as);
     165                break;
    163166        case PT_DYNAMIC:
    164167        case PT_INTERP:
    165                 // FIXME
    166                 /*
    167                 char *interp = (char *) elf + entry->p_offset;
    168                 if (memcmp((uintptr_t) interp, (uintptr_t) ELF_INTERP_ZSTR,
     168                interp = (char *)elf + entry->p_offset;
     169                /* DO NOT COMMIT ME */
     170                /*if (memcmp((uintptr_t)interp, (uintptr_t)ELF_INTERP_ZSTR,
    169171                    ELF_INTERP_ZLEN) != 0) {
    170172                        return EE_UNSUPPORTED;
    171                 } */
    172                 if ((flags & ELD_F_LOADER) == 0)
     173                }*/
     174                if ((flags & ELD_F_LOADER) == 0) {
    173175                        return EE_LOADER;
     176                }
    174177                break;
    175178        case PT_SHLIB:
     179        case PT_NOTE:
    176180        case PT_LOPROC:
    177181        case PT_HIPROC:
    178182        default:
    179183                return EE_UNSUPPORTED;
     184                break;
    180185        }
    181186        return EE_OK;
     
    185190 *
    186191 * @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.
     192 * @param elf ELF header.
     193 * @param as Address space into wich the ELF is being loaded.
    189194 *
    190195 * @return EE_OK on success, error code otherwise.
    191  *
    192196 */
    193197int load_segment(elf_segment_header_t *entry, elf_header_t *elf, as_t *as)
    194198{
     199        as_area_t *a;
     200        int flags = 0;
    195201        mem_backend_data_t backend_data;
     202        uintptr_t base;
     203        size_t mem_sz;
     204       
    196205        backend_data.elf = elf;
    197206        backend_data.segment = entry;
    198        
     207
    199208        if (entry->p_align > 1) {
    200209                if ((entry->p_offset % entry->p_align) !=
    201                     (entry->p_vaddr % entry->p_align))
     210                    (entry->p_vaddr % entry->p_align)) {
    202211                        return EE_INVALID;
    203         }
    204        
    205         unsigned int flags = 0;
    206        
     212                }
     213        }
     214
    207215        if (entry->p_flags & PF_X)
    208216                flags |= AS_AREA_EXEC;
    209        
    210217        if (entry->p_flags & PF_W)
    211218                flags |= AS_AREA_WRITE;
    212        
    213219        if (entry->p_flags & PF_R)
    214220                flags |= AS_AREA_READ;
    215        
    216221        flags |= AS_AREA_CACHEABLE;
    217        
    218         /*
     222
     223        /* 
    219224         * Align vaddr down, inserting a little "gap" at the beginning.
    220225         * Adjust area size, so that its end remains in place.
    221          *
    222226         */
    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,
     227        base = ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE);
     228        mem_sz = entry->p_memsz + (entry->p_vaddr - base);
     229
     230        a = as_area_create(as, flags, mem_sz, base,
    227231            AS_AREA_ATTR_NONE, &elf_backend, &backend_data);
    228         if (!area)
     232        if (!a)
    229233                return EE_MEMORY;
    230234       
    231235        /*
    232236         * The segment will be mapped on demand by elf_page_fault().
    233          *
    234237         */
    235        
     238
    236239        return EE_OK;
    237240}
     
    240243 *
    241244 * @param entry Segment header.
    242  * @param elf   ELF header.
    243  * @param as    Address space into wich the ELF is being loaded.
     245 * @param elf ELF header.
     246 * @param as Address space into wich the ELF is being loaded.
    244247 *
    245248 * @return EE_OK on success, error code otherwise.
    246  *
    247249 */
    248250static int section_header(elf_section_header_t *entry, elf_header_t *elf,
Note: See TracChangeset for help on using the changeset viewer.