Changeset 1cc2974 in mainline for kernel/generic/src/mm/backend_elf.c
- Timestamp:
- 2008-05-26T18:56:34Z (17 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 5a55ae6
- Parents:
- fa832eb
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/mm/backend_elf.c
rfa832eb r1cc2974 80 80 elf_segment_header_t *entry = area->backend_data.segment; 81 81 btree_node_t *leaf; 82 uintptr_t base, frame ;82 uintptr_t base, frame, page, start_anon; 83 83 index_t i; 84 84 bool dirty = false; … … 87 87 return AS_PF_FAULT; 88 88 89 ASSERT((addr >= entry->p_vaddr) &&89 ASSERT((addr >= ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE)) && 90 90 (addr < entry->p_vaddr + entry->p_memsz)); 91 i = (addr - entry->p_vaddr) >> PAGE_WIDTH; 92 base = (uintptr_t) (((void *) elf) + entry->p_offset); 93 ASSERT(ALIGN_UP(base, FRAME_SIZE) == base); 91 i = (addr - ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE)) >> PAGE_WIDTH; 92 base = (uintptr_t) 93 (((void *) elf) + ALIGN_DOWN(entry->p_offset, PAGE_SIZE)); 94 95 /* Virtual address of faulting page*/ 96 page = ALIGN_DOWN(addr, PAGE_SIZE); 97 98 /* Virtual address of the end of initialized part of segment */ 99 start_anon = entry->p_vaddr + entry->p_filesz; 94 100 95 101 if (area->sh_info) { … … 99 105 * The address space area is shared. 100 106 */ 101 107 102 108 mutex_lock(&area->sh_info->lock); 103 109 frame = (uintptr_t) btree_search(&area->sh_info->pagemap, 104 ALIGN_DOWN(addr, PAGE_SIZE)- area->base, &leaf);110 page - area->base, &leaf); 105 111 if (!frame) { 106 112 unsigned int i; … … 111 117 112 118 for (i = 0; i < leaf->keys; i++) { 113 if (leaf->key[i] == 114 ALIGN_DOWN(addr, PAGE_SIZE)) { 119 if (leaf->key[i] == page) { 115 120 found = true; 116 121 break; … … 122 127 page_mapping_insert(AS, addr, frame, 123 128 as_area_get_flags(area)); 124 if (!used_space_insert(area, 125 ALIGN_DOWN(addr, PAGE_SIZE), 1)) 129 if (!used_space_insert(area, page, 1)) 126 130 panic("Could not insert used space.\n"); 127 131 mutex_unlock(&area->sh_info->lock); … … 129 133 } 130 134 } 131 135 132 136 /* 133 137 * The area is either not shared or the pagemap does not contain the 134 138 * mapping. 135 139 */ 136 137 if (ALIGN_DOWN(addr, PAGE_SIZE) + PAGE_SIZE < 138 entry->p_vaddr + entry->p_filesz) { 140 if (page >= entry->p_vaddr && page + PAGE_SIZE <= start_anon) { 139 141 /* 140 142 * Initialized portion of the segment. The memory is backed … … 150 152 (void *) (base + i * FRAME_SIZE), FRAME_SIZE); 151 153 dirty = true; 152 153 if (area->sh_info) {154 frame_reference_add(ADDR2PFN(frame));155 btree_insert(&area->sh_info->pagemap,156 ALIGN_DOWN(addr, PAGE_SIZE) - area->base,157 (void *) frame, leaf);158 }159 160 154 } else { 161 frame = KA2PA(base + i *FRAME_SIZE);155 frame = KA2PA(base + i * FRAME_SIZE); 162 156 } 163 } else if (ALIGN_DOWN(addr, PAGE_SIZE) >= 164 ALIGN_UP(entry->p_vaddr + entry->p_filesz, PAGE_SIZE)) { 157 } else if (page >= start_anon) { 165 158 /* 166 159 * This is the uninitialized portion of the segment. … … 172 165 memsetb(PA2KA(frame), FRAME_SIZE, 0); 173 166 dirty = true; 174 175 if (area->sh_info) {176 frame_reference_add(ADDR2PFN(frame));177 btree_insert(&area->sh_info->pagemap,178 ALIGN_DOWN(addr, PAGE_SIZE) - area->base,179 (void *) frame, leaf);180 }181 182 167 } else { 183 size_t size;168 size_t pad_lo, pad_hi; 184 169 /* 185 170 * The mixed case. 186 * The lower part is backed by the ELF image and 187 * the upper part is anonymous memory. 171 * 172 * The middle part is backed by the ELF image and 173 * the lower and upper parts are anonymous memory. 174 * (The segment can be and often is shorter than 1 page). 188 175 */ 189 size = entry->p_filesz - (i<<PAGE_WIDTH); 176 if (page < entry->p_vaddr) 177 pad_lo = entry->p_vaddr - page; 178 else 179 pad_lo = 0; 180 181 if (start_anon < page + PAGE_SIZE) 182 pad_hi = page + PAGE_SIZE - start_anon; 183 else 184 pad_hi = 0; 185 190 186 frame = (uintptr_t)frame_alloc(ONE_FRAME, 0); 191 memsetb(PA2KA(frame) + size, FRAME_SIZE - size, 0); 192 memcpy((void *) PA2KA(frame), (void *) (base + i * FRAME_SIZE), 193 size); 187 memcpy((void *) (PA2KA(frame) + pad_lo), 188 (void *) (base + i * FRAME_SIZE + pad_lo), 189 FRAME_SIZE - pad_lo - pad_hi); 190 memsetb(PA2KA(frame), pad_lo, 0); 191 memsetb(PA2KA(frame) + FRAME_SIZE - pad_hi, pad_hi, 0); 194 192 dirty = true; 195 196 if (area->sh_info) { 197 frame_reference_add(ADDR2PFN(frame)); 198 btree_insert(&area->sh_info->pagemap, 199 ALIGN_DOWN(addr, PAGE_SIZE) - area->base, 200 (void *) frame, leaf); 201 } 202 203 } 204 193 } 194 195 if (dirty && area->sh_info) { 196 frame_reference_add(ADDR2PFN(frame)); 197 btree_insert(&area->sh_info->pagemap, page - area->base, 198 (void *) frame, leaf); 199 } 200 205 201 if (area->sh_info) 206 202 mutex_unlock(&area->sh_info->lock); 207 203 208 204 page_mapping_insert(AS, addr, frame, as_area_get_flags(area)); 209 if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1))205 if (!used_space_insert(area, page, 1)) 210 206 panic("Could not insert used space.\n"); 211 207 … … 226 222 elf_header_t *elf = area->backend_data.elf; 227 223 elf_segment_header_t *entry = area->backend_data.segment; 228 uintptr_t base ;224 uintptr_t base, start_anon; 229 225 index_t i; 230 231 ASSERT((page >= entry->p_vaddr) &&226 227 ASSERT((page >= ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE)) && 232 228 (page < entry->p_vaddr + entry->p_memsz)); 233 i = (page - entry->p_vaddr) >> PAGE_WIDTH;234 base = (uintptr_t) (((void *) elf) + entry->p_offset);235 ASSERT(ALIGN_UP(base, FRAME_SIZE) == base);236 237 if (page + PAGE_SIZE < 238 ALIGN_UP(entry->p_vaddr + entry->p_filesz, PAGE_SIZE)) {229 i = (page - ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE)) >> PAGE_WIDTH; 230 base = (uintptr_t) (((void *) elf) + 231 ALIGN_DOWN(entry->p_offset, FRAME_SIZE)); 232 start_anon = entry->p_vaddr + entry->p_filesz; 233 234 if (page >= entry->p_vaddr && page + PAGE_SIZE <= start_anon) { 239 235 if (entry->p_flags & PF_W) { 240 236 /* … … 305 301 */ 306 302 if (!(area->flags & AS_AREA_WRITE)) 307 if (base + count * PAGE_SIZE <= start_anon) 303 if (base >= entry->p_vaddr && 304 base + count * PAGE_SIZE <= start_anon) 308 305 continue; 309 306 … … 316 313 */ 317 314 if (!(area->flags & AS_AREA_WRITE)) 318 if (base + (j + 1) * PAGE_SIZE <= 315 if (base >= entry->p_vaddr && 316 base + (j + 1) * PAGE_SIZE <= 319 317 start_anon) 320 318 continue;
Note:
See TracChangeset
for help on using the changeset viewer.