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)); |