SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

Diff markup

Differences between /sos/binfmt_elf32.c (Article 9) and /sos/binfmt_elf32.c (Article 7.5)


001 /* Copyright (C) 2005 David Decotigny             001 /* Copyright (C) 2005 David Decotigny
002                                                   002 
003    This program is free software; you can redi    003    This program is free software; you can redistribute it and/or
004    modify it under the terms of the GNU Genera    004    modify it under the terms of the GNU General Public License
005    as published by the Free Software Foundatio    005    as published by the Free Software Foundation; either version 2
006    of the License, or (at your option) any lat    006    of the License, or (at your option) any later version.
007                                                   007    
008    This program is distributed in the hope tha    008    This program is distributed in the hope that it will be useful,
009    but WITHOUT ANY WARRANTY; without even the     009    but WITHOUT ANY WARRANTY; without even the implied warranty of
010    MERCHANTABILITY or FITNESS FOR A PARTICULAR    010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
011    GNU General Public License for more details    011    GNU General Public License for more details.
012                                                   012    
013    You should have received a copy of the GNU     013    You should have received a copy of the GNU General Public License
014    along with this program; if not, write to t    014    along with this program; if not, write to the Free Software
015    Foundation, Inc., 59 Temple Place - Suite 3    015    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
016    USA.                                           016    USA. 
017 */                                                017 */
018                                                   018 
019 #include <sos/kmalloc.h>                          019 #include <sos/kmalloc.h>
020 #include <sos/assert.h>                           020 #include <sos/assert.h>
021 #include <sos/physmem.h>                          021 #include <sos/physmem.h>
022 #include <drivers/bochs.h>                        022 #include <drivers/bochs.h>
023 #include <hwcore/paging.h>                        023 #include <hwcore/paging.h>
024 #include <drivers/zero.h>                         024 #include <drivers/zero.h>
025                                                   025 
026 #include "binfmt_elf32.h"                         026 #include "binfmt_elf32.h"
027                                                   027 
028                                                   028 
029 /**                                               029 /**
030  * The "C" structure of a user program image i    030  * The "C" structure of a user program image in the kernel. Structures
031  * like this are created by the Makefile in th    031  * like this are created by the Makefile in the userland/ directory
032  */                                               032  */
033 struct userprog_entry                             033 struct userprog_entry
034 {                                                 034 {
035   const char *name;                               035   const char *name;
036   sos_vaddr_t bottom_vaddr;                       036   sos_vaddr_t bottom_vaddr;
037   sos_vaddr_t top_vaddr;                          037   sos_vaddr_t top_vaddr;
038 };                                                038 };
039                                                   039 
040                                                   040 
041 /**                                               041 /**
042  * Symbol marking the start of the userprogs t    042  * Symbol marking the start of the userprogs table, as setup by the
043  * ld script in the userland/ directory           043  * ld script in the userland/ directory
044  */                                               044  */
045 extern char _userprogs_table;                     045 extern char _userprogs_table;
046                                                   046 
047                                                   047 
048 /**                                               048 /**
049  * Structure of a mapped resource for an ELF32    049  * Structure of a mapped resource for an ELF32 program (ie a portion
050  * of the kernel space)                           050  * of the kernel space)
051  */                                               051  */
052 struct elf32_mapped_program                       052 struct elf32_mapped_program
053 {                                                 053 {
054   sos_vaddr_t vaddr;                              054   sos_vaddr_t vaddr;
055   sos_size_t  size;                               055   sos_size_t  size;
056   int ref_cnt;                                    056   int ref_cnt;
057                                                   057 
058   struct sos_umem_vmm_mapped_resource mr;         058   struct sos_umem_vmm_mapped_resource mr;
059 };                                                059 };
060                                                   060 
061                                                   061 
062 /** Called after the virtual region has been i    062 /** Called after the virtual region has been inserted inside its
063     address space */                              063     address space */
064 static void elf32prog_ref(struct sos_umem_vmm_    064 static void elf32prog_ref(struct sos_umem_vmm_vr * vr)
065 {                                                 065 {
066   struct elf32_mapped_program * elf32prog_reso    066   struct elf32_mapped_program * elf32prog_resource;
067   elf32prog_resource = (struct elf32_mapped_pr    067   elf32prog_resource = (struct elf32_mapped_program*) sos_umem_vmm_get_mapped_resource_of_vr(vr)->custom_data;
068                                                   068   
069   elf32prog_resource->ref_cnt ++;                 069   elf32prog_resource->ref_cnt ++;
070 }                                                 070 }
071                                                   071 
072                                                   072 
073 /** Called when the virtual region is removed     073 /** Called when the virtual region is removed from its address
074     space */                                      074     space */
075 static void elf32prog_unref(struct sos_umem_vm    075 static void elf32prog_unref(struct sos_umem_vmm_vr * vr)
076 {                                                 076 {
077   struct elf32_mapped_program * elf32prog_reso    077   struct elf32_mapped_program * elf32prog_resource;
078   elf32prog_resource                              078   elf32prog_resource
079     = (struct elf32_mapped_program*)              079     = (struct elf32_mapped_program*)
080       sos_umem_vmm_get_mapped_resource_of_vr(v    080       sos_umem_vmm_get_mapped_resource_of_vr(vr)->custom_data;
081                                                   081   
082   elf32prog_resource->ref_cnt --;                 082   elf32prog_resource->ref_cnt --;
083   SOS_ASSERT_FATAL(elf32prog_resource->ref_cnt    083   SOS_ASSERT_FATAL(elf32prog_resource->ref_cnt >= 0);
084                                                   084 
085   /* Free the resource if it becomes unused */    085   /* Free the resource if it becomes unused */
086   if (elf32prog_resource->ref_cnt == 0)           086   if (elf32prog_resource->ref_cnt == 0)
087     sos_kfree((sos_vaddr_t)elf32prog_resource)    087     sos_kfree((sos_vaddr_t)elf32prog_resource);
088 }                                                 088 }
089                                                   089 
090                                                   090 
091 /** Called when a legitimate page fault is occ    091 /** Called when a legitimate page fault is occuring in the VR */
092 static sos_ret_t elf32prog_page_in(struct sos_    092 static sos_ret_t elf32prog_page_in(struct sos_umem_vmm_vr * vr,
093                                    sos_uaddr_t    093                                    sos_uaddr_t uaddr,
094                                    sos_bool_t     094                                    sos_bool_t write_access)
095 {                                                 095 {
096   struct elf32_mapped_program * elf32prog_reso    096   struct elf32_mapped_program * elf32prog_resource;
097   sos_ret_t     retval = SOS_OK;                  097   sos_ret_t     retval = SOS_OK;
098   sos_paddr_t   ppage_paddr;                      098   sos_paddr_t   ppage_paddr;
099   sos_uaddr_t   upage_uaddr = SOS_PAGE_ALIGN_I    099   sos_uaddr_t   upage_uaddr = SOS_PAGE_ALIGN_INF(uaddr);
100   sos_uoffset_t offset_in_prog;                   100   sos_uoffset_t offset_in_prog;
101   sos_size_t    size_to_copy;                     101   sos_size_t    size_to_copy;
102   sos_ui32_t    access_rights = sos_umem_vmm_g    102   sos_ui32_t    access_rights = sos_umem_vmm_get_prot_of_vr(vr);
103                                                   103 
104   elf32prog_resource                              104   elf32prog_resource
105     = (struct elf32_mapped_program*)              105     = (struct elf32_mapped_program*)
106       sos_umem_vmm_get_mapped_resource_of_vr(v    106       sos_umem_vmm_get_mapped_resource_of_vr(vr)->custom_data;
107                                                   107 
108   /* Compute the offset in program of the page    108   /* Compute the offset in program of the page, and the size to copy
109      in user space */                             109      in user space */
110   offset_in_prog = upage_uaddr - sos_umem_vmm_    110   offset_in_prog = upage_uaddr - sos_umem_vmm_get_start_of_vr(vr)
111     + sos_umem_vmm_get_offset_in_resource(vr);    111     + sos_umem_vmm_get_offset_in_resource(vr);
112   size_to_copy = SOS_PAGE_SIZE;                   112   size_to_copy = SOS_PAGE_SIZE;
113   if (offset_in_prog + size_to_copy > elf32pro    113   if (offset_in_prog + size_to_copy > elf32prog_resource->size)
114     size_to_copy = elf32prog_resource->size -     114     size_to_copy = elf32prog_resource->size - offset_in_prog;
115                                                   115 
116   /* If the source page is also aligned, simpl << 
117      into user space */                        << 
118   if (SOS_IS_PAGE_ALIGNED(elf32prog_resource-> << 
119     {                                          << 
120       sos_vaddr_t kern_vaddr = elf32prog_resou << 
121                                                << 
122       ppage_paddr = sos_paging_get_paddr(kern_ << 
123                                                << 
124       /* Remap it in user space, in read-only  << 
125       retval = sos_paging_map(ppage_paddr,     << 
126                               upage_uaddr,     << 
127                               TRUE,            << 
128                               access_rights &  << 
129       SOS_ASSERT_FATAL(SOS_OK == retval);      << 
130     }                                          << 
131                                                << 
132   /* Otherwise we need to allocate a new page  << 
133   else                                         << 
134     {                                          << 
135       /* Allocate a new page that contains the    116       /* Allocate a new page that contains the code/data of the
136          program */                               117          program */
137       ppage_paddr = sos_physmem_ref_physpage_n    118       ppage_paddr = sos_physmem_ref_physpage_new(FALSE);
138       if (! ppage_paddr)                          119       if (! ppage_paddr)
139         return -SOS_ENOMEM;                       120         return -SOS_ENOMEM;
140                                                   121       
141       /* Map it in user space, in read/write m    122       /* Map it in user space, in read/write mode for the kernel to copy
142          the data in the page */                  123          the data in the page */
143       retval = sos_paging_map(ppage_paddr,        124       retval = sos_paging_map(ppage_paddr,
144                               upage_uaddr,        125                               upage_uaddr,
145                               TRUE,               126                               TRUE,
146                               access_rights |     127                               access_rights | SOS_VM_MAP_PROT_WRITE);
147       SOS_ASSERT_FATAL(SOS_OK == retval);         128       SOS_ASSERT_FATAL(SOS_OK == retval);
148       sos_physmem_unref_physpage(ppage_paddr);    129       sos_physmem_unref_physpage(ppage_paddr);
149                                                   130       
150       /* Copy the program in it */                131       /* Copy the program in it */
151       memcpy((void*)upage_uaddr,                  132       memcpy((void*)upage_uaddr,
152              (void*)elf32prog_resource->vaddr     133              (void*)elf32prog_resource->vaddr + offset_in_prog,
153              size_to_copy);                       134              size_to_copy);
154       if (size_to_copy < SOS_PAGE_SIZE)           135       if (size_to_copy < SOS_PAGE_SIZE)
155         memset((void*)(upage_uaddr + size_to_c    136         memset((void*)(upage_uaddr + size_to_copy), 0x0,
156                SOS_PAGE_SIZE - size_to_copy);     137                SOS_PAGE_SIZE - size_to_copy);
157                                                   138       
158       /* Change it read-only if needed */         139       /* Change it read-only if needed */
159       if (! (access_rights & SOS_VM_MAP_PROT_W    140       if (! (access_rights & SOS_VM_MAP_PROT_WRITE))
160         return sos_paging_set_prot(upage_uaddr    141         return sos_paging_set_prot(upage_uaddr,
161                                    access_righ    142                                    access_rights & ~SOS_VM_MAP_PROT_WRITE);
162     }                                          << 
163                                                   143    
164   return retval;                                  144   return retval;
165 }                                                 145 }
166                                                   146 
167                                                   147 
168 static struct sos_umem_vmm_vr_ops elf32prog_op    148 static struct sos_umem_vmm_vr_ops elf32prog_ops = (struct sos_umem_vmm_vr_ops)
169 {                                                 149 {
170   .ref     = elf32prog_ref,                       150   .ref     = elf32prog_ref,
171   .unref   = elf32prog_unref,                     151   .unref   = elf32prog_unref,
172   .page_in = elf32prog_page_in,                   152   .page_in = elf32prog_page_in,
173   .unmap   = NULL /* ignored */                   153   .unmap   = NULL /* ignored */
174 };                                                154 };
175                                                   155 
176                                                   156 
177 static sos_ret_t elf32prog_mmap(struct sos_ume    157 static sos_ret_t elf32prog_mmap(struct sos_umem_vmm_vr *vr)
178 {                                                 158 {
179   return sos_umem_vmm_set_ops_of_vr(vr, &elf32    159   return sos_umem_vmm_set_ops_of_vr(vr, &elf32prog_ops);
180 }                                                 160 }
181                                                   161 
182                                                   162 
183 /*                                                163 /*
184  * Local functions                                164  * Local functions
185  */                                               165  */
186                                                   166 
187                                                   167 
188 /**                                               168 /**
189  * Function to locate the given user program i    169  * Function to locate the given user program image in the kernel memory
190  */                                               170  */
191 static struct userprog_entry * lookup_userprog    171 static struct userprog_entry * lookup_userprog(const char *name);
192                                                   172 
193                                                   173 
194 sos_uaddr_t sos_binfmt_elf32_map(struct sos_um    174 sos_uaddr_t sos_binfmt_elf32_map(struct sos_umem_vmm_as * dest_as,
195                                  const char *     175                                  const char * progname)
196 {                                                 176 {
197   int i;                                          177   int i;
198                                                   178 
199   /**                                             179   /**
200    * Typedefs, constants and structure definit    180    * Typedefs, constants and structure definitions as given by the ELF
201    * standard specifications.                     181    * standard specifications.
202    */                                             182    */
203   typedef unsigned long  Elf32_Addr;              183   typedef unsigned long  Elf32_Addr;
204   typedef unsigned long  Elf32_Word;              184   typedef unsigned long  Elf32_Word;
205   typedef unsigned short Elf32_Half;              185   typedef unsigned short Elf32_Half;
206   typedef unsigned long  Elf32_Off;               186   typedef unsigned long  Elf32_Off;
207   typedef signed long    Elf32_Sword;             187   typedef signed long    Elf32_Sword;
208                                                   188   
209   /* Elf identification */                        189   /* Elf identification */
210                                                   190   
211 #define EI_NIDENT 16                              191 #define EI_NIDENT 16
212   typedef struct {                                192   typedef struct {
213     unsigned char       e_ident[EI_NIDENT];       193     unsigned char       e_ident[EI_NIDENT];
214     Elf32_Half          e_type;                   194     Elf32_Half          e_type;
215     Elf32_Half          e_machine;                195     Elf32_Half          e_machine;
216     Elf32_Word          e_version;                196     Elf32_Word          e_version;
217     Elf32_Addr          e_entry;                  197     Elf32_Addr          e_entry;
218     Elf32_Off           e_phoff;                  198     Elf32_Off           e_phoff;
219     Elf32_Off           e_shoff;                  199     Elf32_Off           e_shoff;
220     Elf32_Word          e_flags;                  200     Elf32_Word          e_flags;
221     Elf32_Half          e_ehsize;                 201     Elf32_Half          e_ehsize;
222     Elf32_Half          e_phentsize;              202     Elf32_Half          e_phentsize;
223     Elf32_Half          e_phnum;                  203     Elf32_Half          e_phnum;
224     Elf32_Half          e_shentsize;              204     Elf32_Half          e_shentsize;
225     Elf32_Half          e_shnum;                  205     Elf32_Half          e_shnum;
226     Elf32_Half          e_shstrndx;               206     Elf32_Half          e_shstrndx;
227   } __attribute__((packed)) Elf32_Ehdr_t;         207   } __attribute__((packed)) Elf32_Ehdr_t;
228                                                   208   
229 /* e_ident value */                               209 /* e_ident value */
230 #define ELFMAG0 0x7f                              210 #define ELFMAG0 0x7f
231 #define ELFMAG1 'E'                               211 #define ELFMAG1 'E'
232 #define ELFMAG2 'L'                               212 #define ELFMAG2 'L'
233 #define ELFMAG3 'F'                               213 #define ELFMAG3 'F'
234                                                   214 
235 /* e_ident offsets */                             215 /* e_ident offsets */
236 #define EI_MAG0         0                         216 #define EI_MAG0         0
237 #define EI_MAG1         1                         217 #define EI_MAG1         1
238 #define EI_MAG2         2                         218 #define EI_MAG2         2
239 #define EI_MAG3         3                         219 #define EI_MAG3         3
240 #define EI_CLASS        4                         220 #define EI_CLASS        4
241 #define EI_DATA         5                         221 #define EI_DATA         5
242 #define EI_VERSION      6                         222 #define EI_VERSION      6
243 #define EI_PAD          7                         223 #define EI_PAD          7
244                                                   224 
245 /* e_ident[EI_CLASS] */                           225 /* e_ident[EI_CLASS] */
246 #define ELFCLASSNONE    0                         226 #define ELFCLASSNONE    0
247 #define ELFCLASS32      1                         227 #define ELFCLASS32      1
248 #define ELFCLASS64      2                         228 #define ELFCLASS64      2
249                                                   229 
250 /* e_ident[EI_DATA] */                            230 /* e_ident[EI_DATA] */
251 #define ELFDATANONE     0                         231 #define ELFDATANONE     0
252 #define ELFDATA2LSB     1                         232 #define ELFDATA2LSB     1
253 #define ELFDATA2MSB     2                         233 #define ELFDATA2MSB     2
254                                                   234 
255 /* e_type */                                      235 /* e_type */
256 #define ET_NONE         0  /* No file type        236 #define ET_NONE         0  /* No file type       */
257 #define ET_REL          1  /* Relocatable file    237 #define ET_REL          1  /* Relocatable file   */
258 #define ET_EXEC         2  /* Executable file     238 #define ET_EXEC         2  /* Executable file    */
259 #define ET_DYN          3  /* Shared object fi    239 #define ET_DYN          3  /* Shared object file */
260 #define ET_CORE         4  /* Core file           240 #define ET_CORE         4  /* Core file          */
261 #define ET_LOPROC  0xff00  /* Processor-specif    241 #define ET_LOPROC  0xff00  /* Processor-specific */
262 #define ET_HIPROC  0xffff  /* Processor-specif    242 #define ET_HIPROC  0xffff  /* Processor-specific */
263                                                   243 
264 /* e_machine */                                   244 /* e_machine */
265 #define EM_NONE       0  /* No machine     */     245 #define EM_NONE       0  /* No machine     */
266 #define EM_M32        1  /* AT&T WE 32100  */     246 #define EM_M32        1  /* AT&T WE 32100  */
267 #define EM_SPARC      2  /* SPARC          */     247 #define EM_SPARC      2  /* SPARC          */
268 #define EM_386        3  /* Intel 80386    */     248 #define EM_386        3  /* Intel 80386    */
269 #define EM_68K        4  /* Motorola 68000 */     249 #define EM_68K        4  /* Motorola 68000 */
270 #define EM_88K        5  /* Motorola 88000 */     250 #define EM_88K        5  /* Motorola 88000 */
271 #define EM_860        7  /* Intel 80860    */     251 #define EM_860        7  /* Intel 80860    */
272 #define EM_MIPS       8  /* MIPS RS3000    */     252 #define EM_MIPS       8  /* MIPS RS3000    */
273                                                   253 
274 /* e_version */                                   254 /* e_version */
275 #define EV_NONE    0 /* invalid version */        255 #define EV_NONE    0 /* invalid version */
276 #define EV_CURRENT 1 /* current version */        256 #define EV_CURRENT 1 /* current version */
277                                                   257 
278   typedef struct {                                258   typedef struct {
279     Elf32_Word    p_type;                         259     Elf32_Word    p_type;
280     Elf32_Off     p_offset;                       260     Elf32_Off     p_offset;
281     Elf32_Addr    p_vaddr;                        261     Elf32_Addr    p_vaddr;
282     Elf32_Addr    p_paddr;                        262     Elf32_Addr    p_paddr;
283     Elf32_Word    p_filesz;                       263     Elf32_Word    p_filesz;
284     Elf32_Word    p_memsz;                        264     Elf32_Word    p_memsz;
285     Elf32_Word    p_flags;                        265     Elf32_Word    p_flags;
286     Elf32_Word    p_align;                        266     Elf32_Word    p_align;
287   } __attribute__((packed)) Elf32_Phdr_t;         267   } __attribute__((packed)) Elf32_Phdr_t;
288                                                   268 
289 /* Reserved segment types p_type */               269 /* Reserved segment types p_type */
290 #define PT_NULL    0                              270 #define PT_NULL    0
291 #define PT_LOAD    1                              271 #define PT_LOAD    1
292 #define PT_DYNAMIC 2                              272 #define PT_DYNAMIC 2
293 #define PT_INTERP  3                              273 #define PT_INTERP  3
294 #define PT_NOTE    4                              274 #define PT_NOTE    4
295 #define PT_SHLIB   5                              275 #define PT_SHLIB   5
296 #define PT_PHDR    6                              276 #define PT_PHDR    6
297 #define PT_LOPROC  0x70000000                     277 #define PT_LOPROC  0x70000000
298 #define PT_HIPROC  0x7fffffff                     278 #define PT_HIPROC  0x7fffffff
299                                                   279 
300 /* p_flags */                                     280 /* p_flags */
301 #define PF_X       1                              281 #define PF_X       1
302 #define PF_W       2                              282 #define PF_W       2
303 #define PF_R       4                              283 #define PF_R       4
304                                                   284 
305                                                   285 
306   Elf32_Ehdr_t *elf_hdr;                          286   Elf32_Ehdr_t *elf_hdr;
307   Elf32_Phdr_t *elf_phdrs;                        287   Elf32_Phdr_t *elf_phdrs;
308                                                   288 
309   struct elf32_mapped_program * mapped_prog;      289   struct elf32_mapped_program * mapped_prog;
310   struct userprog_entry * prog;                   290   struct userprog_entry * prog;
311   sos_uaddr_t prog_top_user_address = 0;          291   sos_uaddr_t prog_top_user_address = 0;
312                                                   292 
313   mapped_prog                                     293   mapped_prog
314     = (struct elf32_mapped_program*)              294     = (struct elf32_mapped_program*)
315       sos_kmalloc(sizeof(struct elf32_mapped_p    295       sos_kmalloc(sizeof(struct elf32_mapped_program), 0);
316   if (! mapped_prog)                              296   if (! mapped_prog)
317     return -SOS_ENOMEM;                           297     return -SOS_ENOMEM;
318                                                   298 
319   prog = lookup_userprog(progname);               299   prog = lookup_userprog(progname);
320   if (! prog)                                     300   if (! prog)
321     {                                             301     {
322       sos_kfree((sos_vaddr_t)mapped_prog);        302       sos_kfree((sos_vaddr_t)mapped_prog);
323       return 0;                                   303       return 0;
324     }                                             304     }
325                                                   305 
326   /* Initialize mapped resource */                306   /* Initialize mapped resource */
327   memset(mapped_prog, 0x0, sizeof(*mapped_prog    307   memset(mapped_prog, 0x0, sizeof(*mapped_prog));
328   mapped_prog->mr.custom_data = mapped_prog;      308   mapped_prog->mr.custom_data = mapped_prog;
329   mapped_prog->mr.mmap        = elf32prog_mmap    309   mapped_prog->mr.mmap        = elf32prog_mmap;
330   mapped_prog->mr.allowed_access_rights           310   mapped_prog->mr.allowed_access_rights
331     = SOS_VM_MAP_PROT_READ                        311     = SOS_VM_MAP_PROT_READ
332     | SOS_VM_MAP_PROT_WRITE                       312     | SOS_VM_MAP_PROT_WRITE
333     | SOS_VM_MAP_PROT_EXEC;                       313     | SOS_VM_MAP_PROT_EXEC;
334   mapped_prog->vaddr          = prog->bottom_v    314   mapped_prog->vaddr          = prog->bottom_vaddr;
335   mapped_prog->size           = prog->top_vadd    315   mapped_prog->size           = prog->top_vaddr - prog->bottom_vaddr;
336                                                   316   
337   elf_hdr = (Elf32_Ehdr_t*) prog->bottom_vaddr    317   elf_hdr = (Elf32_Ehdr_t*) prog->bottom_vaddr;
338                                                   318 
339   /* Make sure the image is large enough to co    319   /* Make sure the image is large enough to contain at least the ELF
340      header */                                    320      header */
341   if (prog->bottom_vaddr + sizeof(Elf32_Ehdr_t    321   if (prog->bottom_vaddr + sizeof(Elf32_Ehdr_t) > prog->top_vaddr)
342     {                                             322     {
343       sos_bochs_printf("ELF prog %s: incorrect    323       sos_bochs_printf("ELF prog %s: incorrect header\n", prog->name);
344       return 0;                                   324       return 0;
345     }                                             325     }
346                                                   326 
347   /* Macro to check expected values for some f    327   /* Macro to check expected values for some fields in the ELF header */
348 #define ELF_CHECK(hdr,field,expected_value) \     328 #define ELF_CHECK(hdr,field,expected_value) \
349   ({ if ((hdr)->field != (expected_value)) \      329   ({ if ((hdr)->field != (expected_value)) \
350      { \                                          330      { \
351        sos_bochs_printf("ELF prog %s: for %s,     331        sos_bochs_printf("ELF prog %s: for %s, expected %x, got %x\n", \
352                         prog->name, \             332                         prog->name, \
353                         #field, \                 333                         #field, \
354                         (unsigned)(expected_va    334                         (unsigned)(expected_value), \
355                         (unsigned)(hdr)->field    335                         (unsigned)(hdr)->field); \
356        return 0; \                                336        return 0; \
357      } \                                          337      } \
358   })                                              338   })
359                                                   339 
360   ELF_CHECK(elf_hdr, e_ident[EI_MAG0], ELFMAG0    340   ELF_CHECK(elf_hdr, e_ident[EI_MAG0], ELFMAG0);
361   ELF_CHECK(elf_hdr, e_ident[EI_MAG1], ELFMAG1    341   ELF_CHECK(elf_hdr, e_ident[EI_MAG1], ELFMAG1);
362   ELF_CHECK(elf_hdr, e_ident[EI_MAG2], ELFMAG2    342   ELF_CHECK(elf_hdr, e_ident[EI_MAG2], ELFMAG2);
363   ELF_CHECK(elf_hdr, e_ident[EI_MAG3], ELFMAG3    343   ELF_CHECK(elf_hdr, e_ident[EI_MAG3], ELFMAG3);
364   ELF_CHECK(elf_hdr, e_ident[EI_CLASS], ELFCLA    344   ELF_CHECK(elf_hdr, e_ident[EI_CLASS], ELFCLASS32);
365   ELF_CHECK(elf_hdr, e_ident[EI_DATA], ELFDATA    345   ELF_CHECK(elf_hdr, e_ident[EI_DATA], ELFDATA2LSB);
366   ELF_CHECK(elf_hdr, e_type, ET_EXEC);            346   ELF_CHECK(elf_hdr, e_type, ET_EXEC);
367   ELF_CHECK(elf_hdr, e_version, EV_CURRENT);      347   ELF_CHECK(elf_hdr, e_version, EV_CURRENT);
368                                                   348 
369   /* Get the begining of the program header ta    349   /* Get the begining of the program header table */
370   elf_phdrs = (Elf32_Phdr_t*) (prog->bottom_va    350   elf_phdrs = (Elf32_Phdr_t*) (prog->bottom_vaddr + elf_hdr->e_phoff);
371                                                   351 
372   /* Map the program segment in R/W mode. To m    352   /* Map the program segment in R/W mode. To make things clean, we
373      should iterate over the sections, not the    353      should iterate over the sections, not the program header */
374   for (i = 0 ; i < elf_hdr->e_phnum ; i++)        354   for (i = 0 ; i < elf_hdr->e_phnum ; i++)
375     {                                             355     {
376       sos_ui32_t prot_flags;                      356       sos_ui32_t prot_flags;
377       sos_uaddr_t uaddr;                          357       sos_uaddr_t uaddr;
378                                                   358 
379       /* Ignore the empty program headers that    359       /* Ignore the empty program headers that are not marked "LOAD" */
380       if (elf_phdrs[i].p_type != PT_LOAD)         360       if (elf_phdrs[i].p_type != PT_LOAD)
381         {                                         361         {
382           if (elf_phdrs[i].p_memsz != 0)          362           if (elf_phdrs[i].p_memsz != 0)
383             {                                     363             {
384               sos_display_fatal_error("ELF: no    364               sos_display_fatal_error("ELF: non-empty non-LOAD segments not supported yet");
385             }                                     365             }
386           continue;                               366           continue;
387         }                                         367         }
388                                                   368       
389       if (elf_phdrs[i].p_vaddr < SOS_PAGING_BA    369       if (elf_phdrs[i].p_vaddr < SOS_PAGING_BASE_USER_ADDRESS)
390         {                                         370         {
391           sos_display_fatal_error("User progra    371           sos_display_fatal_error("User program has an incorrect address");
392         }                                         372         }
393                                                   373 
394       prot_flags = 0;                             374       prot_flags = 0;
395       if (elf_phdrs[i].p_flags & SOS_VM_MAP_PR    375       if (elf_phdrs[i].p_flags & SOS_VM_MAP_PROT_READ)
396         prot_flags |= SOS_VM_MAP_PROT_READ;       376         prot_flags |= SOS_VM_MAP_PROT_READ;
397       if (elf_phdrs[i].p_flags & SOS_VM_MAP_PR    377       if (elf_phdrs[i].p_flags & SOS_VM_MAP_PROT_WRITE)
398         prot_flags |= SOS_VM_MAP_PROT_WRITE;      378         prot_flags |= SOS_VM_MAP_PROT_WRITE;
399       if (elf_phdrs[i].p_flags & SOS_VM_MAP_PR    379       if (elf_phdrs[i].p_flags & SOS_VM_MAP_PROT_EXEC)
400         prot_flags |= SOS_VM_MAP_PROT_EXEC;       380         prot_flags |= SOS_VM_MAP_PROT_EXEC;
401                                                   381 
402       uaddr = elf_phdrs[i].p_vaddr;               382       uaddr = elf_phdrs[i].p_vaddr;
403       SOS_ASSERT_FATAL(SOS_IS_PAGE_ALIGNED(uad    383       SOS_ASSERT_FATAL(SOS_IS_PAGE_ALIGNED(uaddr));
404                                                   384 
405       /* First of all: map the region of the p    385       /* First of all: map the region of the phdr which is also
406          covered by the file */                   386          covered by the file */
407       SOS_ASSERT_FATAL(SOS_OK                     387       SOS_ASSERT_FATAL(SOS_OK
408                        == sos_umem_vmm_map(des    388                        == sos_umem_vmm_map(dest_as, &uaddr,
409                                            SOS    389                                            SOS_PAGE_ALIGN_SUP(elf_phdrs[i].p_filesz),
410                                            pro    390                                            prot_flags,
411                                            /*     391                                            /* PRIVATE */ SOS_VR_MAP_FIXED,
412                                            & m    392                                            & mapped_prog->mr,
413                                            elf    393                                            elf_phdrs[i].p_offset));
414                                                   394 
415       /* Then map the remaining by a zero reso    395       /* Then map the remaining by a zero resource */
416       uaddr += SOS_PAGE_ALIGN_SUP(elf_phdrs[i]    396       uaddr += SOS_PAGE_ALIGN_SUP(elf_phdrs[i].p_filesz);
417       if (SOS_PAGE_ALIGN_SUP(elf_phdrs[i].p_fi    397       if (SOS_PAGE_ALIGN_SUP(elf_phdrs[i].p_filesz)
418           < SOS_PAGE_ALIGN_SUP(elf_phdrs[i].p_    398           < SOS_PAGE_ALIGN_SUP(elf_phdrs[i].p_memsz))
419         SOS_ASSERT_FATAL(SOS_OK                   399         SOS_ASSERT_FATAL(SOS_OK
420                          == sos_dev_zero_map(d    400                          == sos_dev_zero_map(dest_as, &uaddr,
421                                              S    401                                              SOS_PAGE_ALIGN_SUP(elf_phdrs[i].p_memsz)
422                                              -    402                                              - SOS_PAGE_ALIGN_SUP(elf_phdrs[i].p_filesz),
423                                              p    403                                              prot_flags,
424                                              /    404                                              /* PRIVATE */ SOS_VR_MAP_FIXED));
425                                                   405 
426       if (prog_top_user_address                   406       if (prog_top_user_address
427           < uaddr + SOS_PAGE_ALIGN_SUP(elf_phd    407           < uaddr + SOS_PAGE_ALIGN_SUP(elf_phdrs[i].p_memsz))
428         prog_top_user_address                     408         prog_top_user_address
429           = uaddr + SOS_PAGE_ALIGN_SUP(elf_phd    409           = uaddr + SOS_PAGE_ALIGN_SUP(elf_phdrs[i].p_memsz);
430     }                                             410     }
431                                                   411 
432   /* Now prepare the heap */                      412   /* Now prepare the heap */
433   sos_umem_vmm_init_heap(dest_as, prog_top_use    413   sos_umem_vmm_init_heap(dest_as, prog_top_user_address);
434                                                   414 
435   return elf_hdr->e_entry;                        415   return elf_hdr->e_entry;
436 }                                                 416 }
437                                                   417 
438                                                   418 
439 /**                                               419 /**
440  * Lookup a user program located inside the ke    420  * Lookup a user program located inside the kernel's image
441  */                                               421  */
442 static struct userprog_entry * lookup_userprog    422 static struct userprog_entry * lookup_userprog(const char *name)
443 {                                                 423 {
444   struct userprog_entry *prog;                    424   struct userprog_entry *prog;
445                                                   425 
446   if (! name)                                     426   if (! name)
447     return NULL;                                  427     return NULL;
448                                                   428 
449   /* Walk through the table of user program de    429   /* Walk through the table of user program description structures to
450      find the user program with the given name    430      find the user program with the given name */
451   for (prog = (struct userprog_entry*) & _user    431   for (prog = (struct userprog_entry*) & _userprogs_table ;
452        prog && (prog->name != NULL) ;             432        prog && (prog->name != NULL) ;
453        prog++)                                    433        prog++)
454     {                                             434     {
455       if (0 == strcmp(name, prog->name))          435       if (0 == strcmp(name, prog->name))
456         /* Found it ! */                          436         /* Found it ! */
457         return prog;                              437         return prog;
458     }                                             438     }
459                                                   439 
460   return NULL;                                    440   return NULL;
461 }                                                 441 }
                                                      

source navigation ] diff markup ] identifier search ] general search ]