effd25f1ea1460a2cd27722fb49be0b90c7ff4b2
[pintos-anon] / src / userprog / addrspace.c
1 #include "addrspace.h"
2
3 /* We load ELF binaries.  The following definitions are taken
4    from the ELF specification more-or-less literally. */
5
6 /* ELF types. */
7 typedef uint32_t Elf32_Word, Elf32_Addr, Elf32_Off;
8 typedef uint16_t Elf32_Half;
9
10 /* Executable header.
11    This appears at the very beginning of an ELF binary. */
12 struct Elf32_Ehdr
13   {
14     unsigned char e_ident[16];
15     Elf32_Half    e_type;
16     Elf32_Half    e_machine;
17     Elf32_Word    e_version;
18     Elf32_Addr    e_entry;
19     Elf32_Off     e_phoff;
20     Elf32_Off     e_shoff;
21     Elf32_Word    e_flags;
22     Elf32_Half    e_ehsize;
23     Elf32_Half    e_phentsize;
24     Elf32_Half    e_phnum;
25     Elf32_Half    e_shentsize;
26     Elf32_Half    e_shnum;
27     Elf32_Half    e_shstrndx;
28   };
29
30 /* Program header.
31    There are e_phnum of these, starting at file offset e_phoff. */
32 struct Elf32_Phdr
33   {
34     Elf32_Word p_type;
35     Elf32_Off  p_offset;
36     Elf32_Addr p_vaddr;
37     Elf32_Addr p_paddr;
38     Elf32_Word p_filesz;
39     Elf32_Word p_memsz;
40     Elf32_Word p_flags;
41     Elf32_Word p_align;
42   };
43
44 /* Values for p_type in struct Elf32_Phdr. */
45 #define PT_NULL    0    /* Ignore this program header. */
46 #define PT_LOAD    1    /* Loadable segment. */
47 #define PT_DYNAMIC 2    /* Dynamic linking info. */
48 #define PT_INTERP  3    /* Name of dynamic loader. */
49 #define PT_NOTE    4    /* Auxiliary info. */
50 #define PT_SHLIB   5    /* Reserved. */
51 #define PT_PHDR    6    /* Program header table. */
52
53 #define LOAD_ERROR(MSG)                                         \
54         do {                                                    \
55                 printk ("addrspace_load: %s: ", filename);      \
56                 printk MSG;                                     \
57                 printk ("\n");                                  \
58                 goto error;                                     \
59         } while (0)
60
61 bool
62 addrspace_load (struct addrspace *as, const char *filename) 
63 {
64   Elf32_Ehdr ehdr;
65   struct file *file;
66
67   file = filesys_open (filename);
68   if (file == NULL)
69     LOAD_ERROR (("open failed"));
70
71   /* Read and verify executable header. */
72   if (file_read (file, &ehdr, sizeof ehdr) != sizeof ehdr) 
73     LOAD_ERROR (("error reading executable header"));
74   if (memcmp (ehdr.e_ident, "\x7fELF\1\1\1", 7) != 0)
75     LOAD_ERROR (("not an ELF file"));
76   if (ehdr.e_type != 2)
77     LOAD_ERROR (("not an executable"));
78   if (ehdr.e_machine != 3)
79     LOAD_ERROR (("not an x86 binary"));
80   if (ehdr.e_version != 1)
81     LOAD_ERROR (("unknown ELF version %d", (int) ehdr.e_version));
82   if (ehdr.e_phentsize != sizeof (struct Elf32_Phdr))
83     LOAD_ERROR (("bad program header size", (int) ehdr.e_phentsize));
84   if (ehdr.e_phnum > 1024)
85     LOAD_ERROR (("too many program headers"));
86
87   /* Read program headers. */
88
89   as->page_dir = create_page_dir ();
90   list_init (&as->vmas);
91
92   
93   
94
95 }