rem: image->regions[regcount].vmstart = _ROUNDOWN(pheader->p_vaddr, B_PAGE_SIZE); image->regions[regcount].vmsize = _ROUNDUP (pheader->p_filesz + (pheader->p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE);
add: image->regions[regcount].vmstart = PAGE_BASE(pheader->p_vaddr); image->regions[regcount].vmsize = TO_PAGE_SIZE(pheader->p_filesz + PAGE_OFFSET(pheader->p_vaddr));
context: parse_program_headers(image_t *image, char *buff, int phnum, int phentsize){	struct Elf32_Phdr *pheader;	int regcount;	int i;	regcount = 0;	for (i = 0; i < phnum; i++) {		pheader = (struct Elf32_Phdr *)(buff + i * phentsize);		switch (pheader->p_type) {			case PT_NULL:				/* NOP header */				break;			case PT_LOAD:				if (pheader->p_memsz == pheader->p_filesz) {					/*					 * everything in one area					 */					image->regions[regcount].start = pheader->p_vaddr;					image->regions[regcount].size = pheader->p_memsz;					image->regions[regcount].vmstart = _ROUNDOWN(pheader->p_vaddr, B_PAGE_SIZE);					image->regions[regcount].vmsize = _ROUNDUP(pheader->p_memsz +						(pheader->p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE);					image->regions[regcount].fdstart = pheader->p_offset;					image->regions[regcount].fdsize = pheader->p_filesz;					image->regions[regcount].delta = 0;					image->regions[regcount].flags = 0;					if (pheader->p_flags & PF_WRITE) {						// this is a writable segment						image->regions[regcount].flags |= RFLAG_RW;					}				} else {					/*					 * may require splitting					 */					unsigned A = pheader->p_vaddr + pheader->p_memsz;					unsigned B = pheader->p_vaddr + pheader->p_filesz - 1;					A = PAGE_BASE(A);					B = PAGE_BASE(B);					image->regions[regcount].start = pheader->p_vaddr;					image->regions[regcount].size = pheader->p_filesz;					image->regions[regcount].vmstart = _ROUNDOWN(pheader->p_vaddr, B_PAGE_SIZE);					image->regions[regcount].vmsize = _ROUNDUP (pheader->p_filesz +						(pheader->p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE);					image->regions[regcount].fdstart = pheader->p_offset;					image->regions[regcount].fdsize = pheader->p_filesz;					image->regions[regcount].delta = 0;					image->regions[regcount].flags = 0;					if (pheader->p_flags & PF_WRITE) {						// this is a writable segment						image->regions[regcount].flags |= RFLAG_RW;					}					if (A != B) {						/*						 * yeah, it requires splitting						 */						regcount += 1;						image->regions[regcount].start = pheader->p_vaddr;						image->regions[regcount].size = pheader->p_memsz - pheader->p_filesz;						image->regions[regcount].vmstart = image->regions[regcount-1].vmstart + image->regions[regcount-1].vmsize;						image->regions[regcount].vmsize = _ROUNDUP(pheader->p_memsz								+ (pheader->p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE)							- image->regions[regcount-1].vmsize;						image->regions[regcount].fdstart = 0;						image->regions[regcount].fdsize = 0;						image->regions[regcount].delta = 0;						image->regions[regcount].flags = RFLAG_ANON;						if (pheader->p_flags & PF_WRITE) {							// this is a writable segment							image->regions[regcount].flags |= RFLAG_RW;						}					}				}				regcount += 1;				break;			case PT_DYNAMIC:				image->dynamic_ptr = pheader->p_vaddr;				break;			case PT_INTERP:				/* should check here for appropiate interpreter */				break;			case PT_NOTE:				/* unsupported */				break;			case PT_SHLIB:				/* undefined semantics */				break;			case PT_PHDR:				/* we don't use it */				break;			default:				FATAL(true, "unhandled pheader type 0x%lx\n", pheader[i].p_type);				break;		}	}}