Changeset 78a95d6f in mainline


Ignore:
Timestamp:
2006-03-13T16:05:43Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6d9c49a
Parents:
0967877
Message:

Support for loading segments containing .bss section.

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • arch/ia32/include/boot/boot.h

    r0967877 r78a95d6f  
    3030#define __ia32_BOOT_H__
    3131
    32 #define BOOT_OFFSET                     0x108000
     32#define BOOT_OFFSET             0x108000
    3333#define AP_BOOT_OFFSET          0x8000
    3434#define BOOT_STACK_SIZE 0x400
  • arch/ia32/src/asm.S

    r0967877 r78a95d6f  
    2929## very low and hardware-level functions
    3030
    31 #  Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word
     31# Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word
    3232# and 1 means interrupt with error word
    3333#define ERROR_WORD_INTERRUPT_LIST 0x00027D00
  • generic/include/elf.h

    r0967877 r78a95d6f  
    245245
    246246/*
     247 * ELF segment header.
     248 * Segments headers are also known as program headers.
     249 */
     250struct elf32_segment_header {
     251        elf_word p_type;
     252        elf32_off p_offset;
     253        elf32_addr p_vaddr;
     254        elf32_addr p_paddr;
     255        elf_word p_filesz;
     256        elf_word p_memsz;
     257        elf_word p_flags;
     258        elf_word p_align;
     259};
     260struct elf64_segment_header {
     261        elf_word p_type;
     262        elf_word p_flags;
     263        elf64_off p_offset;
     264        elf64_addr p_vaddr;
     265        elf64_addr p_paddr;
     266        elf_xword p_filesz;
     267        elf_xword p_memsz;
     268        elf_xword p_align;
     269};
     270
     271/*
    247272 * ELF section header
    248273 */
     
    292317};
    293318
    294 /*
    295  * ELF program header entry
    296  */
    297 struct elf32_ph_entry {
    298         elf_word p_type;
    299         elf32_off p_offset;
    300         elf32_addr p_vaddr;
    301         elf32_addr p_paddr;
    302         elf_word p_filesz;
    303         elf_word p_memsz;
    304         elf_word p_flags;
    305         elf_word p_align;
    306 };
    307 struct elf64_ph_entry {
    308         elf_word p_type;
    309         elf_word p_flags;
    310         elf64_off p_offset;
    311         elf64_addr p_vaddr;
    312         elf64_addr p_paddr;
    313         elf_xword p_filesz;
    314         elf_xword p_memsz;
    315         elf_xword p_align;
    316 };
    317 
    318319#ifdef __32_BITS__
    319320typedef struct elf32_header elf_header_t;
     321typedef struct elf32_segment_header elf_segment_header_t;
    320322typedef struct elf32_section_header elf_section_header_t;
    321323typedef struct elf32_symbol elf_symbol_t;
    322 typedef struct elf32_ph_entry elf_ph_entry_t;
    323324#endif
    324325#ifdef __64_BITS__
    325326typedef struct elf64_header elf_header_t;
     327typedef struct elf64_segment_header elf_segment_header_t;
    326328typedef struct elf64_section_header elf_section_header_t;
    327329typedef struct elf64_symbol elf_symbol_t;
    328 typedef struct elf64_ph_entry elf_ph_entry_t;
    329330#endif
    330331
  • generic/src/lib/elf.c

    r0967877 r78a95d6f  
    3333#include <mm/as.h>
    3434#include <mm/frame.h>
     35#include <mm/slab.h>
    3536#include <print.h>
    3637#include <align.h>
     38#include <memstr.h>
     39#include <macros.h>
    3740
    3841static char *error_codes[] = {
     
    4548};
    4649
    47 static int program_header_entry(elf_header_t *header, elf_ph_entry_t *entry, as_t *as);
    48 static int load_segment(elf_header_t *header, elf_ph_entry_t *entry, as_t *as);
     50static int segment_header(elf_segment_header_t *entry, elf_header_t *elf, as_t *as);
     51static int section_header(elf_section_header_t *entry, elf_header_t *elf, as_t *as);
     52static int load_segment(elf_segment_header_t *entry, elf_header_t *elf, as_t *as);
    4953
    5054/** ELF loader
     
    7175        }
    7276
    73         if (header->e_phentsize != sizeof(elf_ph_entry_t))
     77        if (header->e_phentsize != sizeof(elf_segment_header_t))
     78                return EE_INCOMPATIBLE;
     79
     80        if (header->e_shentsize != sizeof(elf_section_header_t))
    7481                return EE_INCOMPATIBLE;
    7582
     
    7885                return EE_UNSUPPORTED;
    7986
    80         /* Walk through all program header entries and process them. */
     87        /* Walk through all segment headers and process them. */
    8188        for (i = 0; i < header->e_phnum; i++) {
    82                 rc = program_header_entry(header, &((elf_ph_entry_t *)(((__u8 *) header) + header->e_phoff))[i], as);
     89                rc = segment_header(&((elf_segment_header_t *)(((__u8 *) header) + header->e_phoff))[i], header, as);
    8390                if (rc != EE_OK)
    8491                        return rc;
    8592        }
    8693
     94        /* Inspect all section headers and proccess them. */
     95        for (i = 0; i < header->e_shnum; i++) {
     96                rc = section_header(&((elf_section_header_t *)(((__u8 *) header) + header->e_shoff))[i], header, as);
     97                if (rc != EE_OK)
     98                        return rc;
     99        }
     100
    87101        return EE_OK;
    88102}
     
    101115}
    102116
    103 /** Process program header entry.
    104  *
    105  * @param entry Program header entry.
     117/** Process segment header.
     118 *
     119 * @param entry Segment header.
     120 * @param elf ELF header.
    106121 * @param as Address space into wich the ELF is being loaded.
    107122 *
    108123 * @return EE_OK on success, error code otherwise.
    109124 */
    110 static int program_header_entry(elf_header_t *header, elf_ph_entry_t *entry, as_t *as)
     125static int segment_header(elf_segment_header_t *entry, elf_header_t *elf, as_t *as)
    111126{
    112127        switch (entry->p_type) {
     
    115130                break;
    116131            case PT_LOAD:
    117                 return load_segment(header, entry, as);
     132                return load_segment(entry, elf, as);
    118133                break;
    119134            case PT_DYNAMIC:
     
    133148 *
    134149 * @param entry Program header entry describing segment to be loaded.
     150 * @param elf ELF header.
    135151 * @parma as Address space into wich the ELF is being loaded.
    136152 *
    137153 * @return EE_OK on success, error code otherwise.
    138154 */
    139 int load_segment(elf_header_t *header, elf_ph_entry_t *entry, as_t *as)
     155int load_segment(elf_segment_header_t *entry, elf_header_t *elf, as_t *as)
    140156{
    141157        as_area_t *a;
    142158        int i, type = 0;
     159        size_t segment_size;
     160        __u8 *segment;
    143161
    144162        if (entry->p_align > 1) {
     
    162180        }
    163181
     182        /*
     183         * Check if the virtual address starts on page boundary.
     184         */
     185        if (ALIGN_UP(entry->p_vaddr, PAGE_SIZE) != entry->p_vaddr)
     186                return EE_UNSUPPORTED;
     187
     188        /*
     189         * Copying the segment out is certainly necessary for segments with p_filesz < p_memsz
     190         * because of the effect of .bss-like sections. For security reasons, it looks like a
     191         * good idea to copy the segment anyway.
     192         */
     193        segment_size = ALIGN_UP(max(entry->p_filesz, entry->p_memsz), PAGE_SIZE);
     194        segment = malloc(segment_size, 0);
     195        if (entry->p_filesz < entry->p_memsz)
     196                memsetb((__address) (segment + entry->p_filesz), segment_size - entry->p_filesz, 0);
     197        memcpy(segment, (void *) (((__address) elf) + entry->p_offset), entry->p_filesz);
     198
    164199        a = as_area_create(as, AS_AREA_TEXT, SIZE2FRAMES(entry->p_memsz), entry->p_vaddr);
    165200        if (!a)
     
    167202       
    168203        for (i = 0; i < SIZE2FRAMES(entry->p_filesz); i++) {
    169                 as_set_mapping(as, entry->p_vaddr + i*PAGE_SIZE, KA2PA(((__address) header) + entry->p_offset + i*PAGE_SIZE));
    170         }
    171        
    172         return EE_OK;
    173 }
     204                as_set_mapping(as, entry->p_vaddr + i*PAGE_SIZE, KA2PA(((__address) segment) + i*PAGE_SIZE));
     205        }
     206       
     207        return EE_OK;
     208}
     209
     210/** Process section header.
     211 *
     212 * @param entry Segment header.
     213 * @param elf ELF header.
     214 * @param as Address space into wich the ELF is being loaded.
     215 *
     216 * @return EE_OK on success, error code otherwise.
     217 */
     218static int section_header(elf_section_header_t *entry, elf_header_t *elf, as_t *as)
     219{
     220        switch (entry->sh_type) {
     221            default:
     222                break;
     223        }
     224       
     225        return EE_OK;
     226}
Note: See TracChangeset for help on using the changeset viewer.