- /* Load the segment page-by-page into memory. */
- filesz_left = phdr->p_filesz + (phdr->p_vaddr & PGMASK);
- file_seek (file, ROUND_DOWN (phdr->p_offset, PGSIZE));
- for (upage = start; upage < (uint8_t *) end; upage += PGSIZE)
+/* Loads a segment starting at offset OFS in FILE at address
+ UPAGE. In total, READ_BYTES + ZERO_BYTES bytes of virtual
+ memory are initialized, as follows:
+
+ - READ_BYTES bytes at UPAGE must be read from FILE
+ starting at offset OFS.
+
+ - ZERO_BYTES bytes at UPAGE + READ_BYTES must be zeroed.
+
+ The pages initialized by this function must be writable by the
+ user process if WRITABLE is true, read-only otherwise.
+
+ Return true if successful, false if a memory allocation error
+ or disk read error occurs. */
+static bool
+load_segment (struct file *file, off_t ofs, uint8_t *upage,
+ uint32_t read_bytes, uint32_t zero_bytes, bool writable)
+{
+ ASSERT ((read_bytes + zero_bytes) % PGSIZE == 0);
+ ASSERT (pg_ofs (upage) == 0);
+ ASSERT (ofs % PGSIZE == 0);
+
+ file_seek (file, ofs);
+ while (read_bytes > 0 || zero_bytes > 0)