Ignore:
File:
1 edited

Legend:

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

    rd99c1d2 rda1bafb  
    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 *entry, elf_header_t *elf,
    60     as_t *as, int flags);
    61 static int section_header(elf_section_header_t *entry, elf_header_t *elf,
    62     as_t *as);
    63 static int load_segment(elf_segment_header_t *entry, elf_header_t *elf,
    64     as_t *as);
     59static int segment_header(elf_segment_header_t *, elf_header_t *, as_t *,
     60    unsigned int);
     61static int section_header(elf_section_header_t *, elf_header_t *, as_t *);
     62static int load_segment(elf_segment_header_t *, elf_header_t *, as_t *);
    6563
    6664/** ELF loader
    6765 *
    6866 * @param header Pointer to ELF header in memory
    69  * @param as Created and properly mapped address space
    70  * @param flags A combination of ELD_F_*
     67 * @param as     Created and properly mapped address space
     68 * @param flags  A combination of ELD_F_*
     69 *
    7170 * @return EE_OK on success
    72  */
    73 unsigned int elf_load(elf_header_t *header, as_t * as, int flags)
    74 {
    75         int i, rc;
    76 
     71 *
     72 */
     73unsigned int elf_load(elf_header_t *header, as_t *as, unsigned int flags)
     74{
    7775        /* Identify ELF */
    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) {
     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))
    8280                return EE_INVALID;
    83         }
    8481       
    8582        /* Identify ELF compatibility */
    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) {
     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))
    9188                return EE_INCOMPATIBLE;
    92         }
    93 
     89       
    9490        if (header->e_phentsize != sizeof(elf_segment_header_t))
    9591                return EE_INCOMPATIBLE;
    96 
     92       
    9793        if (header->e_shentsize != sizeof(elf_section_header_t))
    9894                return EE_INCOMPATIBLE;
    99 
     95       
    10096        /* Check if the object type is supported. */
    10197        if (header->e_type != ET_EXEC)
    10298                return EE_UNSUPPORTED;
    103 
     99       
    104100        /* Check if the ELF image starts on a page boundary */
    105         if (ALIGN_UP((uintptr_t)header, PAGE_SIZE) != (uintptr_t)header)
     101        if (ALIGN_UP((uintptr_t) header, PAGE_SIZE) != (uintptr_t) header)
    106102                return EE_UNSUPPORTED;
    107 
     103       
    108104        /* Walk through all segment headers and process them. */
     105        elf_half i;
    109106        for (i = 0; i < header->e_phnum; i++) {
    110                 elf_segment_header_t *seghdr;
    111 
    112                 seghdr = &((elf_segment_header_t *)(((uint8_t *) header) +
     107                elf_segment_header_t *seghdr =
     108                    &((elf_segment_header_t *)(((uint8_t *) header) +
    113109                    header->e_phoff))[i];
    114                 rc = segment_header(seghdr, header, as, flags);
     110               
     111                int rc = segment_header(seghdr, header, as, flags);
    115112                if (rc != EE_OK)
    116113                        return rc;
    117114        }
    118 
     115       
    119116        /* Inspect all section headers and proccess them. */
    120117        for (i = 0; i < header->e_shnum; i++) {
    121                 elf_section_header_t *sechdr;
    122 
    123                 sechdr = &((elf_section_header_t *)(((uint8_t *) header) +
     118                elf_section_header_t *sechdr =
     119                    &((elf_section_header_t *)(((uint8_t *) header) +
    124120                    header->e_shoff))[i];
    125                 rc = section_header(sechdr, header, as);
     121               
     122                int rc = section_header(sechdr, header, as);
    126123                if (rc != EE_OK)
    127124                        return rc;
    128125        }
    129 
     126       
    130127        return EE_OK;
    131128}
     
    136133 *
    137134 * @return NULL terminated description of error.
     135 *
    138136 */
    139137const char *elf_error(unsigned int rc)
    140138{
    141139        ASSERT(rc < sizeof(error_codes) / sizeof(char *));
    142 
     140       
    143141        return error_codes[rc];
    144142}
     
    147145 *
    148146 * @param entry Segment header.
    149  * @param elf ELF header.
    150  * @param as Address space into wich the ELF is being loaded.
     147 * @param elf   ELF header.
     148 * @param as    Address space into wich the ELF is being loaded.
    151149 *
    152150 * @return EE_OK on success, error code otherwise.
     151 *
    153152 */
    154153static int segment_header(elf_segment_header_t *entry, elf_header_t *elf,
    155     as_t *as, int flags)
     154    as_t *as, unsigned int flags)
    156155{
    157156        switch (entry->p_type) {
     
    170169                        return EE_UNSUPPORTED;
    171170                } */
    172                 if ((flags & ELD_F_LOADER) == 0) {
     171                if ((flags & ELD_F_LOADER) == 0)
    173172                        return EE_LOADER;
    174                 }
    175173                break;
    176174        case PT_SHLIB:
     
    187185 *
    188186 * @param entry Program header entry describing segment to be loaded.
    189  * @param elf ELF header.
    190  * @param as Address space into wich the ELF is being loaded.
     187 * @param elf   ELF header.
     188 * @param as    Address space into wich the ELF is being loaded.
    191189 *
    192190 * @return EE_OK on success, error code otherwise.
     191 *
    193192 */
    194193int load_segment(elf_segment_header_t *entry, elf_header_t *elf, as_t *as)
    195194{
    196         as_area_t *a;
    197         int flags = 0;
    198195        mem_backend_data_t backend_data;
    199         uintptr_t base;
    200         size_t mem_sz;
    201        
    202196        backend_data.elf = elf;
    203197        backend_data.segment = entry;
    204 
     198       
    205199        if (entry->p_align > 1) {
    206200                if ((entry->p_offset % entry->p_align) !=
    207                     (entry->p_vaddr % entry->p_align)) {
     201                    (entry->p_vaddr % entry->p_align))
    208202                        return EE_INVALID;
    209                 }
    210         }
    211 
     203        }
     204       
     205        unsigned int flags = 0;
     206       
    212207        if (entry->p_flags & PF_X)
    213208                flags |= AS_AREA_EXEC;
     209       
    214210        if (entry->p_flags & PF_W)
    215211                flags |= AS_AREA_WRITE;
     212       
    216213        if (entry->p_flags & PF_R)
    217214                flags |= AS_AREA_READ;
     215       
    218216        flags |= AS_AREA_CACHEABLE;
    219 
    220         /* 
     217       
     218        /*
    221219         * Align vaddr down, inserting a little "gap" at the beginning.
    222220         * Adjust area size, so that its end remains in place.
     221         *
    223222         */
    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,
     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,
    228227            AS_AREA_ATTR_NONE, &elf_backend, &backend_data);
    229         if (!a)
     228        if (!area)
    230229                return EE_MEMORY;
    231230       
    232231        /*
    233232         * 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 *
    246247 */
    247248static int section_header(elf_section_header_t *entry, elf_header_t *elf,
Note: See TracChangeset for help on using the changeset viewer.