Subversion Repositories HelenOS-historic

Rev

Rev 973 | Rev 1048 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 973 Rev 1026
Line 153... Line 153...
153
 * @return EE_OK on success, error code otherwise.
153
 * @return EE_OK on success, error code otherwise.
154
 */
154
 */
155
int load_segment(elf_segment_header_t *entry, elf_header_t *elf, as_t *as)
155
int load_segment(elf_segment_header_t *entry, elf_header_t *elf, as_t *as)
156
{
156
{
157
    as_area_t *a;
157
    as_area_t *a;
158
    int i, type = 0;
158
    int i, flags = 0;
159
    size_t segment_size;
159
    size_t segment_size;
160
    __u8 *segment;
160
    __u8 *segment;
161
 
161
 
162
    if (entry->p_align > 1) {
162
    if (entry->p_align > 1) {
163
        if ((entry->p_offset % entry->p_align) != (entry->p_vaddr % entry->p_align)) {
163
        if ((entry->p_offset % entry->p_align) != (entry->p_vaddr % entry->p_align)) {
Line 169... Line 169...
169
     * Check if the segment doesn't interfere with kernel address space.
169
     * Check if the segment doesn't interfere with kernel address space.
170
     */
170
     */
171
    if (entry->p_vaddr + ALIGN_UP(entry->p_memsz, PAGE_SIZE) >= USER_ADDRESS_SPACE_END)
171
    if (entry->p_vaddr + ALIGN_UP(entry->p_memsz, PAGE_SIZE) >= USER_ADDRESS_SPACE_END)
172
        return EE_MEMORY;
172
        return EE_MEMORY;
173
   
173
   
174
    if (entry->p_flags & PF_X) {
174
    if (entry->p_flags & PF_X)
175
        type = AS_AREA_TEXT;
175
        flags |= AS_AREA_EXEC;
176
    } else if (entry->p_flags & PF_W) {
176
    if (entry->p_flags & PF_W)
177
        type = AS_AREA_DATA;
177
        flags |= AS_AREA_WRITE;
178
    } else {
178
    if (entry->p_flags & PF_R)
179
        return EE_UNSUPPORTED;
179
        flags |= AS_AREA_READ;
180
    }
-
 
181
 
180
 
182
    /*
181
    /*
183
     * Check if the virtual address starts on page boundary.
182
     * Check if the virtual address starts on page boundary.
184
     */
183
     */
185
    if (ALIGN_UP(entry->p_vaddr, PAGE_SIZE) != entry->p_vaddr)
184
    if (ALIGN_UP(entry->p_vaddr, PAGE_SIZE) != entry->p_vaddr)
Line 192... Line 191...
192
        memsetb((__address) (segment + entry->p_filesz), segment_size - entry->p_filesz, 0);
191
        memsetb((__address) (segment + entry->p_filesz), segment_size - entry->p_filesz, 0);
193
        memcpy(segment, (void *) (((__address) elf) + entry->p_offset), entry->p_filesz);
192
        memcpy(segment, (void *) (((__address) elf) + entry->p_offset), entry->p_filesz);
194
    } else /* Map identically original data */
193
    } else /* Map identically original data */
195
        segment = ((void *) elf) + entry->p_offset;
194
        segment = ((void *) elf) + entry->p_offset;
196
 
195
 
197
    a = as_area_create(as, type, SIZE2FRAMES(entry->p_memsz), entry->p_vaddr);
196
    a = as_area_create(as, flags, SIZE2FRAMES(entry->p_memsz), entry->p_vaddr);
198
    if (!a)
197
    if (!a)
199
        return EE_IRRECOVERABLE;
198
        return EE_IRRECOVERABLE;
200
   
199
   
201
    for (i = 0; i < SIZE2FRAMES(entry->p_filesz); i++) {
200
    for (i = 0; i < SIZE2FRAMES(entry->p_filesz); i++) {
202
        as_set_mapping(as, entry->p_vaddr + i*PAGE_SIZE, KA2PA(((__address) segment) + i*PAGE_SIZE));
201
        as_set_mapping(as, entry->p_vaddr + i*PAGE_SIZE, KA2PA(((__address) segment) + i*PAGE_SIZE));