Ignore:
File:
1 edited

Legend:

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

    rda1bafb rd99c1d2  
    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
     
    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  *
    136138 */
    137139const char *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    as_t *as, int flags)
    155156{
    156157        switch (entry->p_type) {
     
    169170                        return EE_UNSUPPORTED;
    170171                } */
    171                 if ((flags & ELD_F_LOADER) == 0)
     172                if ((flags & ELD_F_LOADER) == 0) {
    172173                        return EE_LOADER;
     174                }
    173175                break;
    174176        case PT_SHLIB:
     
    185187 *
    186188 * @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.
     189 * @param elf ELF header.
     190 * @param as Address space into wich the ELF is being loaded.
    189191 *
    190192 * @return EE_OK on success, error code otherwise.
    191  *
    192193 */
    193194int load_segment(elf_segment_header_t *entry, elf_header_t *elf, as_t *as)
    194195{
     196        as_area_t *a;
     197        int flags = 0;
    195198        mem_backend_data_t backend_data;
     199        uintptr_t base;
     200        size_t mem_sz;
     201       
    196202        backend_data.elf = elf;
    197203        backend_data.segment = entry;
    198        
     204
    199205        if (entry->p_align > 1) {
    200206                if ((entry->p_offset % entry->p_align) !=
    201                     (entry->p_vaddr % entry->p_align))
     207                    (entry->p_vaddr % entry->p_align)) {
    202208                        return EE_INVALID;
    203         }
    204        
    205         unsigned int flags = 0;
    206        
     209                }
     210        }
     211
    207212        if (entry->p_flags & PF_X)
    208213                flags |= AS_AREA_EXEC;
    209        
    210214        if (entry->p_flags & PF_W)
    211215                flags |= AS_AREA_WRITE;
    212        
    213216        if (entry->p_flags & PF_R)
    214217                flags |= AS_AREA_READ;
    215        
    216218        flags |= AS_AREA_CACHEABLE;
    217        
    218         /*
     219
     220        /* 
    219221         * Align vaddr down, inserting a little "gap" at the beginning.
    220222         * Adjust area size, so that its end remains in place.
    221          *
    222223         */
    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,
     224        base = ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE);
     225        mem_sz = entry->p_memsz + (entry->p_vaddr - base);
     226
     227        a = as_area_create(as, flags, mem_sz, base,
    227228            AS_AREA_ATTR_NONE, &elf_backend, &backend_data);
    228         if (!area)
     229        if (!a)
    229230                return EE_MEMORY;
    230231       
    231232        /*
    232233         * The segment will be mapped on demand by elf_page_fault().
    233          *
    234234         */
    235        
     235
    236236        return EE_OK;
    237237}
     
    240240 *
    241241 * @param entry Segment header.
    242  * @param elf   ELF header.
    243  * @param as    Address space into wich the ELF is being loaded.
     242 * @param elf ELF header.
     243 * @param as Address space into wich the ELF is being loaded.
    244244 *
    245245 * @return EE_OK on success, error code otherwise.
    246  *
    247246 */
    248247static int section_header(elf_section_header_t *entry, elf_header_t *elf,
Note: See TracChangeset for help on using the changeset viewer.