Rename addrspace to process.
[pintos-anon] / src / userprog / process.c
1 #include "userprog/process.h"
2 #include <debug.h>
3 #include <inttypes.h>
4 #include <round.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include "userprog/gdt.h"
8 #include "userprog/pagedir.h"
9 #include "userprog/tss.h"
10 #include "filesys/directory.h"
11 #include "filesys/file.h"
12 #include "filesys/filesys.h"
13 #include "threads/flags.h"
14 #include "threads/init.h"
15 #include "threads/interrupt.h"
16 #include "threads/mmu.h"
17 #include "threads/palloc.h"
18 #include "threads/thread.h"
19
20 static thread_func execute_thread NO_RETURN;
21 static bool load (const char *cmdline, void (**eip) (void), void **esp);
22
23 /* Starts a new thread running a user program loaded from
24    FILENAME.  The new thread may be scheduled before
25    process_execute() returns.*/
26 tid_t
27 process_execute (const char *filename) 
28 {
29   char *fn_copy;
30   tid_t tid;
31
32   /* Make a copy of FILENAME.
33      Otherwise there's a race between the caller and load(). */
34   fn_copy = palloc_get (0);
35   if (fn_copy == NULL)
36     return TID_ERROR;
37   strlcpy (fn_copy, filename, PGSIZE);
38
39   /* Create a new thread to execute FILENAME. */
40   tid = thread_create (filename, PRI_DEFAULT, execute_thread, fn_copy);
41   if (tid == TID_ERROR)
42     palloc_free (fn_copy); 
43   return tid;
44 }
45
46 /* A thread function that loads a user process and starts it
47    running. */
48 static void
49 execute_thread (void *filename_)
50 {
51   char *filename = filename_;
52   struct intr_frame if_;
53   bool success;
54
55   /* Initialize interrupt frame and load executable. */
56   memset (&if_, 0, sizeof if_);
57   if_.es = SEL_UDSEG;
58   if_.ds = SEL_UDSEG;
59   if_.cs = SEL_UCSEG;
60   if_.eflags = FLAG_IF | FLAG_MBS;
61   if_.ss = SEL_UDSEG;
62   success = load (filename, &if_.eip, &if_.esp);
63
64   /* If load failed, quit. */
65   palloc_free (filename);
66   if (!success) 
67     thread_exit ();
68
69   /* Switch page tables. */
70   process_activate ();
71
72   /* Start the user process by simulating a return from an
73      interrupt, implemented by intr_exit (in
74      threads/intr-stubs.pl).  Because intr_exit takes all of its
75      arguments on the stack in the form of a `struct intr_frame',
76      we just point the stack pointer (%esp) to our stack frame
77      and jump to it. */
78   asm ("mov %0, %%esp\n"
79        "jmp intr_exit\n"
80        : /* no outputs */
81        : "g" (&if_));
82   NOT_REACHED ();
83 }
84
85 /* Destroys the user address space in T and frees all of its
86    resources. */
87 void
88 process_destroy (struct thread *t)
89 {
90   ASSERT (t != thread_current ());
91
92   if (t->pagedir != NULL) 
93     {
94       pagedir_destroy (t->pagedir);
95       t->pagedir = NULL; 
96     }
97 }
98
99 /* Sets up the CPU for running user code in the current
100    thread. */
101 void
102 process_activate (void)
103 {
104   struct thread *t = thread_current ();
105
106   /* Activate T's page tables. */
107   pagedir_activate (t->pagedir);
108
109   /* Set T's kernel stack for use in processing interrupts. */
110   tss_set_esp0 ((uint8_t *) t + PGSIZE);
111 }
112 \f
113 /* We load ELF binaries.  The following definitions are taken
114    from the ELF specification, [ELF1], more-or-less verbatim.  */
115
116 /* ELF types.  See [ELF1] 1-2. */
117 typedef uint32_t Elf32_Word, Elf32_Addr, Elf32_Off;
118 typedef uint16_t Elf32_Half;
119
120 /* For use with ELF types in printf(). */
121 #define PE32Wx PRIx32   /* Print Elf32_Word in hexadecimal. */
122 #define PE32Ax PRIx32   /* Print Elf32_Addr in hexadecimal. */
123 #define PE32Ox PRIx32   /* Print Elf32_Off in hexadecimal. */
124 #define PE32Hx PRIx16   /* Print Elf32_Half in hexadecimal. */
125
126 /* Executable header.  See [ELF1] 1-4 to 1-8.
127    This appears at the very beginning of an ELF binary. */
128 struct Elf32_Ehdr
129   {
130     unsigned char e_ident[16];
131     Elf32_Half    e_type;
132     Elf32_Half    e_machine;
133     Elf32_Word    e_version;
134     Elf32_Addr    e_entry;
135     Elf32_Off     e_phoff;
136     Elf32_Off     e_shoff;
137     Elf32_Word    e_flags;
138     Elf32_Half    e_ehsize;
139     Elf32_Half    e_phentsize;
140     Elf32_Half    e_phnum;
141     Elf32_Half    e_shentsize;
142     Elf32_Half    e_shnum;
143     Elf32_Half    e_shstrndx;
144   };
145
146 /* Program header.  See [ELF1] 2-2 to 2-4.
147    There are e_phnum of these, starting at file offset e_phoff
148    (see [ELF1] 1-6). */
149 struct Elf32_Phdr
150   {
151     Elf32_Word p_type;
152     Elf32_Off  p_offset;
153     Elf32_Addr p_vaddr;
154     Elf32_Addr p_paddr;
155     Elf32_Word p_filesz;
156     Elf32_Word p_memsz;
157     Elf32_Word p_flags;
158     Elf32_Word p_align;
159   };
160
161 /* Values for p_type.  See [ELF1] 2-3. */
162 #define PT_NULL    0            /* Ignore. */
163 #define PT_LOAD    1            /* Loadable segment. */
164 #define PT_DYNAMIC 2            /* Dynamic linking info. */
165 #define PT_INTERP  3            /* Name of dynamic loader. */
166 #define PT_NOTE    4            /* Auxiliary info. */
167 #define PT_SHLIB   5            /* Reserved. */
168 #define PT_PHDR    6            /* Program header table. */
169 #define PT_STACK   0x6474e551   /* Stack segment. */
170
171 /* Flags for p_flags.  See [ELF3] 2-3 and 2-4. */
172 #define PF_X 1          /* Executable. */
173 #define PF_W 2          /* Writable. */
174 #define PF_R 4          /* Readable. */
175
176 static bool load_segment (struct file *, const struct Elf32_Phdr *);
177 static bool setup_stack (void **esp);
178
179 /* Aborts loading an executable, with an error message. */
180 #define LOAD_ERROR(MSG)                                         \
181         do {                                                    \
182                 printf ("load: %s: ", filename);      \
183                 printf MSG;                                     \
184                 printf ("\n");                                  \
185                 goto done;                                     \
186         } while (0)
187
188 /* Loads an ELF executable from FILENAME into the current thread.
189    Stores the executable's entry point into *EIP
190    and its initial stack pointer into *ESP.
191    Returns true if successful, false otherwise. */
192 bool
193 load (const char *filename, void (**eip) (void), void **esp) 
194 {
195   struct thread *t = thread_current ();
196   struct Elf32_Ehdr ehdr;
197   struct file *file = NULL;
198   off_t file_ofs;
199   bool success = false;
200   int i;
201
202   /* Allocate page directory. */
203   t->pagedir = pagedir_create ();
204   if (t->pagedir == NULL)
205     LOAD_ERROR (("page directory allocation failed"));
206
207   /* Open executable file. */
208   file = filesys_open (filename);
209   if (file == NULL)
210     LOAD_ERROR (("open failed"));
211
212   /* Read and verify executable header. */
213   if (file_read (file, &ehdr, sizeof ehdr) != sizeof ehdr) 
214     LOAD_ERROR (("error reading executable header"));
215   if (memcmp (ehdr.e_ident, "\177ELF\1\1\1", 7) != 0)
216     LOAD_ERROR (("file is not ELF"));
217   if (ehdr.e_type != 2)
218     LOAD_ERROR (("ELF file is not an executable"));
219   if (ehdr.e_machine != 3)
220     LOAD_ERROR (("ELF executable is not x86"));
221   if (ehdr.e_version != 1)
222     LOAD_ERROR (("ELF executable hasunknown version %d",
223                  (int) ehdr.e_version));
224   if (ehdr.e_phentsize != sizeof (struct Elf32_Phdr))
225     LOAD_ERROR (("bad ELF program header size"));
226   if (ehdr.e_phnum > 1024)
227     LOAD_ERROR (("too many ELF program headers"));
228
229   /* Read program headers. */
230   file_ofs = ehdr.e_phoff;
231   for (i = 0; i < ehdr.e_phnum; i++) 
232     {
233       struct Elf32_Phdr phdr;
234
235       file_seek (file, file_ofs);
236       if (file_read (file, &phdr, sizeof phdr) != sizeof phdr)
237         LOAD_ERROR (("error reading program header"));
238       file_ofs += sizeof phdr;
239       switch (phdr.p_type) 
240         {
241         case PT_NULL:
242         case PT_NOTE:
243         case PT_PHDR:
244         case PT_STACK:
245           /* Ignore this segment. */
246           break;
247         case PT_DYNAMIC:
248         case PT_INTERP:
249         case PT_SHLIB:
250           /* Reject the executable. */
251           LOAD_ERROR (("unsupported ELF segment type %d\n", phdr.p_type));
252           break;
253         default:
254           printf ("unknown ELF segment type %08x\n", phdr.p_type);
255           break;
256         case PT_LOAD:
257           if (!load_segment (file, &phdr))
258             goto done;
259           break;
260         }
261     }
262
263   /* Set up stack. */
264   if (!setup_stack (esp))
265     goto done;
266
267   /* Start address. */
268   *eip = (void (*) (void)) ehdr.e_entry;
269
270   success = true;
271
272  done:
273   /* We arrive here whether the load is successful or not. */
274   file_close (file);
275   return success;
276 }
277 \f
278 /* load() helpers. */
279
280 static bool install_page (void *upage, void *kpage);
281
282 /* Loads the segment described by PHDR from FILE into user
283    address space.  Return true if successful, false otherwise. */
284 static bool
285 load_segment (struct file *file, const struct Elf32_Phdr *phdr) 
286 {
287   void *start, *end;  /* Page-rounded segment start and end. */
288   uint8_t *upage;     /* Iterator from start to end. */
289   off_t filesz_left;  /* Bytes left of file data (as opposed to
290                          zero-initialized bytes). */
291
292   /* Is this a read-only segment?  Not currently used, so it's
293      commented out.  You'll want to use it when implementing VM
294      to decide whether to page the segment from its executable or
295      from swap. */
296   //bool read_only = (phdr->p_flags & PF_W) == 0;
297
298   ASSERT (file != NULL);
299   ASSERT (phdr != NULL);
300   ASSERT (phdr->p_type == PT_LOAD);
301
302   /* [ELF1] 2-2 says that p_offset and p_vaddr must be congruent
303      modulo PGSIZE. */
304   if (phdr->p_offset % PGSIZE != phdr->p_vaddr % PGSIZE) 
305     {
306       printf ("%#08"PE32Ox" and %#08"PE32Ax" not congruent modulo %#x\n",
307               phdr->p_offset, phdr->p_vaddr, (unsigned) PGSIZE);
308       return false; 
309     }
310
311   /* [ELF1] 2-3 says that p_memsz must be at least as big as
312      p_filesz. */
313   if (phdr->p_memsz < phdr->p_filesz) 
314     {
315       printf ("p_memsz (%08"PE32Wx") < p_filesz (%08"PE32Wx")\n",
316               phdr->p_memsz, phdr->p_filesz);
317       return false; 
318     }
319
320   /* Validate virtual memory region to be mapped.
321      The region must both start and end within the user address
322      space range starting at 0 and ending at PHYS_BASE (typically
323      3 GB == 0xc0000000). */
324   start = pg_round_down ((void *) phdr->p_vaddr);
325   end = pg_round_up ((void *) (phdr->p_vaddr + phdr->p_memsz));
326   if (start >= PHYS_BASE || end >= PHYS_BASE || end < start) 
327     {
328       printf ("bad virtual region %08lx...%08lx\n",
329               (unsigned long) start, (unsigned long) end);
330       return false; 
331     }
332
333   /* Load the segment page-by-page into memory. */
334   filesz_left = phdr->p_filesz + (phdr->p_vaddr & PGMASK);
335   file_seek (file, ROUND_DOWN (phdr->p_offset, PGSIZE));
336   for (upage = start; upage < (uint8_t *) end; upage += PGSIZE) 
337     {
338       /* We want to read min(PGSIZE, filesz_left) bytes from the
339          file into the page and zero the rest. */
340       size_t read_bytes = filesz_left >= PGSIZE ? PGSIZE : filesz_left;
341       size_t zero_bytes = PGSIZE - read_bytes;
342       uint8_t *kpage = palloc_get (PAL_USER);
343       if (kpage == NULL)
344         return false;
345
346       /* Do the reading and zeroing. */
347       if (file_read (file, kpage, read_bytes) != (int) read_bytes) 
348         {
349           palloc_free (kpage);
350           return false; 
351         }
352       memset (kpage + read_bytes, 0, zero_bytes);
353       filesz_left -= read_bytes;
354
355       /* Add the page to the process's address space. */
356       if (!install_page (upage, kpage)) 
357         {
358           palloc_free (kpage);
359           return false; 
360         }
361     }
362
363   return true;
364 }
365
366 /* Create a minimal stack by mapping a zeroed page at the top of
367    user virtual memory. */
368 static bool
369 setup_stack (void **esp) 
370 {
371   uint8_t *kpage;
372   bool success = false;
373
374   kpage = palloc_get (PAL_USER | PAL_ZERO);
375   if (kpage != NULL) 
376     {
377       success = install_page (((uint8_t *) PHYS_BASE) - PGSIZE, kpage);
378       if (success)
379         *esp = PHYS_BASE;
380       else
381         palloc_free (kpage);
382     }
383   else
384     printf ("failed to allocate process stack\n");
385
386   return success;
387 }
388
389 /* Adds a mapping from user virtual address UPAGE to kernel
390    virtual address KPAGE to the page table.  Fails if UPAGE is
391    already mapped or if memory allocation fails. */
392 static bool
393 install_page (void *upage, void *kpage)
394 {
395   struct thread *t = thread_current ();
396
397   /* Verify that there's not already a page at that virtual
398      address, then map our page there. */
399   return (pagedir_get_page (t->pagedir, upage) == NULL
400           && pagedir_set_page (t->pagedir, upage, kpage, true));
401 }