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.5) and /sos/binfmt_elf32.c (Article 9)


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    116   /* If the source page is also aligned, simply remap the kernel area
117      into user space */                           117      into user space */
118   if (SOS_IS_PAGE_ALIGNED(elf32prog_resource->    118   if (SOS_IS_PAGE_ALIGNED(elf32prog_resource->vaddr + offset_in_prog))
119     {                                             119     {
120       sos_vaddr_t kern_vaddr = elf32prog_resou    120       sos_vaddr_t kern_vaddr = elf32prog_resource->vaddr + offset_in_prog;
121                                                   121 
122       ppage_paddr = sos_paging_get_paddr(kern_    122       ppage_paddr = sos_paging_get_paddr(kern_vaddr);
123                                                   123 
124       /* Remap it in user space, in read-only     124       /* Remap it in user space, in read-only mode (to force COW) */
125       retval = sos_paging_map(ppage_paddr,        125       retval = sos_paging_map(ppage_paddr,
126                               upage_uaddr,        126                               upage_uaddr,
127                               TRUE,               127                               TRUE,
128                               access_rights &     128                               access_rights & ~SOS_VM_MAP_PROT_WRITE);
129       SOS_ASSERT_FATAL(SOS_OK == retval);         129       SOS_ASSERT_FATAL(SOS_OK == retval);
130     }                                             130     }
131                                                   131 
132   /* Otherwise we need to allocate a new page     132   /* Otherwise we need to allocate a new page */
133   else                                            133   else
134     {                                             134     {
135       /* Allocate a new page that contains the    135       /* Allocate a new page that contains the code/data of the
136          program */                               136          program */
137       ppage_paddr = sos_physmem_ref_physpage_n    137       ppage_paddr = sos_physmem_ref_physpage_new(FALSE);
138       if (! ppage_paddr)                          138       if (! ppage_paddr)
139         return -SOS_ENOMEM;                       139         return -SOS_ENOMEM;
140                                                   140       
141       /* Map it in user space, in read/write m    141       /* Map it in user space, in read/write mode for the kernel to copy
142          the data in the page */                  142          the data in the page */
143       retval = sos_paging_map(ppage_paddr,        143       retval = sos_paging_map(ppage_paddr,
144                               upage_uaddr,        144                               upage_uaddr,
145                               TRUE,               145                               TRUE,
146                               access_rights |     146                               access_rights | SOS_VM_MAP_PROT_WRITE);
147       SOS_ASSERT_FATAL(SOS_OK == retval);         147       SOS_ASSERT_FATAL(SOS_OK == retval);
148       sos_physmem_unref_physpage(ppage_paddr);    148       sos_physmem_unref_physpage(ppage_paddr);
149                                                   149       
150       /* Copy the program in it */                150       /* Copy the program in it */
151       memcpy((void*)upage_uaddr,                  151       memcpy((void*)upage_uaddr,
152              (void*)(elf32prog_resource->vaddr !! 152              (void*)elf32prog_resource->vaddr + offset_in_prog,
153              size_to_copy);                       153              size_to_copy);
154       if (size_to_copy < SOS_PAGE_SIZE)           154       if (size_to_copy < SOS_PAGE_SIZE)
155         memset((void*)(upage_uaddr + size_to_c    155         memset((void*)(upage_uaddr + size_to_copy), 0x0,
156                SOS_PAGE_SIZE - size_to_copy);     156                SOS_PAGE_SIZE - size_to_copy);
157                                                   157       
158       /* Change it read-only if needed */         158       /* Change it read-only if needed */
159       if (! (access_rights & SOS_VM_MAP_PROT_W    159       if (! (access_rights & SOS_VM_MAP_PROT_WRITE))
160         return sos_paging_set_prot(upage_uaddr    160         return sos_paging_set_prot(upage_uaddr,
161                                    access_righ    161                                    access_rights & ~SOS_VM_MAP_PROT_WRITE);
162     }                                             162     }
163                                                   163    
164   return retval;                                  164   return retval;
165 }                                                 165 }
166                                                   166 
167                                                   167 
168 static struct sos_umem_vmm_vr_ops elf32prog_op    168 static struct sos_umem_vmm_vr_ops elf32prog_ops = (struct sos_umem_vmm_vr_ops)
169 {                                                 169 {
170   .ref     = elf32prog_ref,                       170   .ref     = elf32prog_ref,
171   .unref   = elf32prog_unref,                     171   .unref   = elf32prog_unref,
172   .page_in = elf32prog_page_in,                   172   .page_in = elf32prog_page_in,
173   .unmap   = NULL /* ignored */                   173   .unmap   = NULL /* ignored */
174 };                                                174 };
175                                                   175 
176                                                   176 
177 static sos_ret_t elf32prog_mmap(struct sos_ume    177 static sos_ret_t elf32prog_mmap(struct sos_umem_vmm_vr *vr)
178 {                                                 178 {
179   return sos_umem_vmm_set_ops_of_vr(vr, &elf32    179   return sos_umem_vmm_set_ops_of_vr(vr, &elf32prog_ops);
180 }                                                 180 }
181                                                   181 
182                                                   182 
183 /*                                                183 /*
184  * Local functions                                184  * Local functions
185  */                                               185  */
186                                                   186 
187                                                   187 
188 /**                                               188 /**
189  * Function to locate the given user program i    189  * Function to locate the given user program image in the kernel memory
190  */                                               190  */
191 static struct userprog_entry * lookup_userprog    191 static struct userprog_entry * lookup_userprog(const char *name);
192                                                   192 
193                                                   193 
194 sos_uaddr_t sos_binfmt_elf32_map(struct sos_um    194 sos_uaddr_t sos_binfmt_elf32_map(struct sos_umem_vmm_as * dest_as,
195                                  const char *     195                                  const char * progname)
196 {                                                 196 {
197   int i;                                          197   int i;
198                                                   198 
199   /**                                             199   /**
200    * Typedefs, constants and structure definit    200    * Typedefs, constants and structure definitions as given by the ELF
201    * standard specifications.                     201    * standard specifications.
202    */                                             202    */
203   typedef unsigned long  Elf32_Addr;              203   typedef unsigned long  Elf32_Addr;
204   typedef unsigned long  Elf32_Word;              204   typedef unsigned long  Elf32_Word;
205   typedef unsigned short Elf32_Half;              205   typedef unsigned short Elf32_Half;
206   typedef unsigned long  Elf32_Off;               206   typedef unsigned long  Elf32_Off;
207   typedef signed long    Elf32_Sword;             207   typedef signed long    Elf32_Sword;
208                                                   208   
209   /* Elf identification */                        209   /* Elf identification */
210                                                   210   
211 #define EI_NIDENT 16                              211 #define EI_NIDENT 16
212   typedef struct {                                212   typedef struct {
213     unsigned char       e_ident[EI_NIDENT];       213     unsigned char       e_ident[EI_NIDENT];
214     Elf32_Half          e_type;                   214     Elf32_Half          e_type;
215     Elf32_Half          e_machine;                215     Elf32_Half          e_machine;
216     Elf32_Word          e_version;                216     Elf32_Word          e_version;
217     Elf32_Addr          e_entry;                  217     Elf32_Addr          e_entry;
218     Elf32_Off           e_phoff;                  218     Elf32_Off           e_phoff;
219     Elf32_Off           e_shoff;                  219     Elf32_Off           e_shoff;
220     Elf32_Word          e_flags;                  220     Elf32_Word          e_flags;
221     Elf32_Half          e_ehsize;                 221     Elf32_Half          e_ehsize;
222     Elf32_Half          e_phentsize;              222     Elf32_Half          e_phentsize;
223     Elf32_Half          e_phnum;                  223     Elf32_Half          e_phnum;
224     Elf32_Half          e_shentsize;              224     Elf32_Half          e_shentsize;
225     Elf32_Half          e_shnum;                  225     Elf32_Half          e_shnum;
226     Elf32_Half          e_shstrndx;               226     Elf32_Half          e_shstrndx;
227   } __attribute__((packed)) Elf32_Ehdr_t;         227   } __attribute__((packed)) Elf32_Ehdr_t;
228                                                   228   
229 /* e_ident value */                               229 /* e_ident value */
230 #define ELFMAG0 0x7f                              230 #define ELFMAG0 0x7f
231 #define ELFMAG1 'E'                               231 #define ELFMAG1 'E'
232 #define ELFMAG2 'L'                               232 #define ELFMAG2 'L'
233 #define ELFMAG3 'F'                               233 #define ELFMAG3 'F'
234                                                   234 
235 /* e_ident offsets */                             235 /* e_ident offsets */
236 #define EI_MAG0         0                         236 #define EI_MAG0         0
237 #define EI_MAG1         1                         237 #define EI_MAG1         1
238 #define EI_MAG2         2                         238 #define EI_MAG2         2
239 #define EI_MAG3         3                         239 #define EI_MAG3         3
240 #define EI_CLASS        4                         240 #define EI_CLASS        4
241 #define EI_DATA         5                         241 #define EI_DATA         5
242 #define EI_VERSION      6                         242 #define EI_VERSION      6
243 #define EI_PAD          7                         243 #define EI_PAD          7
244                                                   244 
245 /* e_ident[EI_CLASS] */                           245 /* e_ident[EI_CLASS] */
246 #define ELFCLASSNONE    0                         246 #define ELFCLASSNONE    0
247 #define ELFCLASS32      1                         247 #define ELFCLASS32      1
248 #define ELFCLASS64      2                         248 #define ELFCLASS64      2
249                                                   249 
250 /* e_ident[EI_DATA] */                            250 /* e_ident[EI_DATA] */
251 #define ELFDATANONE     0                         251 #define ELFDATANONE     0
252 #define ELFDATA2LSB     1                         252 #define ELFDATA2LSB     1
253 #define ELFDATA2MSB     2                         253 #define ELFDATA2MSB     2
254                                                   254 
255 /* e_type */                                      255 /* e_type */
256 #define ET_NONE         0  /* No file type        256 #define ET_NONE         0  /* No file type       */
257 #define ET_REL          1  /* Relocatable file    257 #define ET_REL          1  /* Relocatable file   */
258 #define ET_EXEC         2  /* Executable file     258 #define ET_EXEC         2  /* Executable file    */
259 #define ET_DYN          3  /* Shared object fi    259 #define ET_DYN          3  /* Shared object file */
260 #define ET_CORE         4  /* Core file           260 #define ET_CORE         4  /* Core file          */
261 #define ET_LOPROC  0xff00  /* Processor-specif    261 #define ET_LOPROC  0xff00  /* Processor-specific */
262 #define ET_HIPROC  0xffff  /* Processor-specif    262 #define ET_HIPROC  0xffff  /* Processor-specific */
263                                                   263 
264 /* e_machine */                                   264 /* e_machine */
265 #define EM_NONE       0  /* No machine     */     265 #define EM_NONE       0  /* No machine     */
266 #define EM_M32        1  /* AT&T WE 32100  */     266 #define EM_M32        1  /* AT&T WE 32100  */
267 #define EM_SPARC      2  /* SPARC          */     267 #define EM_SPARC      2  /* SPARC          */
268 #define EM_386        3  /* Intel 80386    */     268 #define EM_386        3  /* Intel 80386    */
269 #define EM_68K        4  /* Motorola 68000 */     269 #define EM_68K        4  /* Motorola 68000 */
270 #define EM_88K        5  /* Motorola 88000 */     270 #define EM_88K        5  /* Motorola 88000 */
271 #define EM_860        7  /* Intel 80860    */     271 #define EM_860        7  /* Intel 80860    */
272 #define EM_MIPS       8  /* MIPS RS3000    */     272 #define EM_MIPS       8  /* MIPS RS3000    */
273                                                   273 
274 /* e_version */                                   274 /* e_version */
275 #define EV_NONE    0 /* invalid version */        275 #define EV_NONE    0 /* invalid version */
276 #define EV_CURRENT 1 /* current version */        276 #define EV_CURRENT 1 /* current version */
277                                                   277 
278   typedef struct {                                278   typedef struct {
279     Elf32_Word    p_type;                         279     Elf32_Word    p_type;
280     Elf32_Off     p_offset;                       280     Elf32_Off     p_offset;
281     Elf32_Addr    p_vaddr;                        281     Elf32_Addr    p_vaddr;
282     Elf32_Addr    p_paddr;                        282     Elf32_Addr    p_paddr;
283     Elf32_Word    p_filesz;                       283     Elf32_Word    p_filesz;
284     Elf32_Word    p_memsz;                        284     Elf32_Word    p_memsz;
285     Elf32_Word    p_flags;                        285     Elf32_Word    p_flags;
286     Elf32_Word    p_align;                        286     Elf32_Word    p_align;
287   } __attribute__((packed)) Elf32_Phdr_t;         287   } __attribute__((packed)) Elf32_Phdr_t;
288                                                   288 
289 /* Reserved segment types p_type */               289 /* Reserved segment types p_type */
290 #define PT_NULL    0                              290 #define PT_NULL    0
291 #define PT_LOAD    1                              291 #define PT_LOAD    1
292 #define PT_DYNAMIC 2                              292 #define PT_DYNAMIC 2
293 #define PT_INTERP  3                              293 #define PT_INTERP  3
294 #define PT_NOTE    4                              294 #define PT_NOTE    4
295 #define PT_SHLIB   5                              295 #define PT_SHLIB   5
296 #define PT_PHDR    6                              296 #define PT_PHDR    6
297 #define PT_LOPROC  0x70000000                     297 #define PT_LOPROC  0x70000000
298 #define PT_HIPROC  0x7fffffff                     298 #define PT_HIPROC  0x7fffffff
299                                                   299 
300 /* p_flags */                                     300 /* p_flags */
301 #define PF_X       1                              301 #define PF_X       1
302 #define PF_W       2                              302 #define PF_W       2
303 #define PF_R       4                              303 #define PF_R       4
304                                                   304 
305                                                   305 
306   Elf32_Ehdr_t *elf_hdr;                          306   Elf32_Ehdr_t *elf_hdr;
307   Elf32_Phdr_t *elf_phdrs;                        307   Elf32_Phdr_t *elf_phdrs;
308                                                   308 
309   struct elf32_mapped_program * mapped_prog;      309   struct elf32_mapped_program * mapped_prog;
310   struct userprog_entry * prog;                   310   struct userprog_entry * prog;
311   sos_uaddr_t prog_top_user_address = 0;          311   sos_uaddr_t prog_top_user_address = 0;
312                                                   312 
313   mapped_prog                                     313   mapped_prog
314     = (struct elf32_mapped_program*)              314     = (struct elf32_mapped_program*)
315       sos_kmalloc(sizeof(struct elf32_mapped_p    315       sos_kmalloc(sizeof(struct elf32_mapped_program), 0);
316   if (! mapped_prog)                              316   if (! mapped_prog)
317     return -SOS_ENOMEM;                           317     return -SOS_ENOMEM;
318                                                   318 
319   prog = lookup_userprog(progname);               319   prog = lookup_userprog(progname);
320   if (! prog)                                     320   if (! prog)
321     {                                             321     {
322       sos_kfree((sos_vaddr_t)mapped_prog);        322       sos_kfree((sos_vaddr_t)mapped_prog);
323       return 0;                                   323       return 0;
324     }                                             324     }
325                                                   325 
326   /* Initialize mapped resource */                326   /* Initialize mapped resource */
327   memset(mapped_prog, 0x0, sizeof(*mapped_prog    327   memset(mapped_prog, 0x0, sizeof(*mapped_prog));
328   mapped_prog->mr.custom_data = mapped_prog;      328   mapped_prog->mr.custom_data = mapped_prog;
329   mapped_prog->mr.mmap        = elf32prog_mmap    329   mapped_prog->mr.mmap        = elf32prog_mmap;
330   mapped_prog->mr.allowed_access_rights           330   mapped_prog->mr.allowed_access_rights
331     = SOS_VM_MAP_PROT_READ                        331     = SOS_VM_MAP_PROT_READ
332     | SOS_VM_MAP_PROT_WRITE                       332     | SOS_VM_MAP_PROT_WRITE
333     | SOS_VM_MAP_PROT_EXEC;                       333     | SOS_VM_MAP_PROT_EXEC;
334   mapped_prog->vaddr          = prog->bottom_v    334   mapped_prog->vaddr          = prog->bottom_vaddr;
335   mapped_prog->size           = prog->top_vadd    335   mapped_prog->size           = prog->top_vaddr - prog->bottom_vaddr;
336                                                   336   
337   elf_hdr = (Elf32_Ehdr_t*) prog->bottom_vaddr    337   elf_hdr = (Elf32_Ehdr_t*) prog->bottom_vaddr;
338                                                   338 
339   /* Make sure the image is large enough to co    339   /* Make sure the image is large enough to contain at least the ELF
340      header */                                    340      header */
341   if (prog->bottom_vaddr + sizeof(Elf32_Ehdr_t    341   if (prog->bottom_vaddr + sizeof(Elf32_Ehdr_t) > prog->top_vaddr)
342     {                                             342     {
343       sos_bochs_printf("ELF prog %s: incorrect    343       sos_bochs_printf("ELF prog %s: incorrect header\n", prog->name);
344       return 0;                                   344       return 0;
345     }                                             345     }
346                                                   346 
347   /* Macro to check expected values for some f    347   /* Macro to check expected values for some fields in the ELF header */
348 #define ELF_CHECK(hdr,field,expected_value) \     348 #define ELF_CHECK(hdr,field,expected_value) \
349   ({ if ((hdr)->field != (expected_value)) \      349   ({ if ((hdr)->field != (expected_value)) \
350      { \                                          350      { \
351        sos_bochs_printf("ELF prog %s: for %s,     351        sos_bochs_printf("ELF prog %s: for %s, expected %x, got %x\n", \
352                         prog->name, \             352                         prog->name, \
353                         #field, \                 353                         #field, \
354                         (unsigned)(expected_va    354                         (unsigned)(expected_value), \
355                         (unsigned)(hdr)->field    355                         (unsigned)(hdr)->field); \
356        return 0; \                                356        return 0; \
357      } \                                          357      } \
358   })                                              358   })
359                                                   359 
360   ELF_CHECK(elf_hdr, e_ident[EI_MAG0], ELFMAG0    360   ELF_CHECK(elf_hdr, e_ident[EI_MAG0], ELFMAG0);
361   ELF_CHECK(elf_hdr, e_ident[EI_MAG1], ELFMAG1    361   ELF_CHECK(elf_hdr, e_ident[EI_MAG1], ELFMAG1);
362   ELF_CHECK(elf_hdr, e_ident[EI_MAG2], ELFMAG2    362   ELF_CHECK(elf_hdr, e_ident[EI_MAG2], ELFMAG2);
363   ELF_CHECK(elf_hdr, e_ident[EI_MAG3], ELFMAG3    363   ELF_CHECK(elf_hdr, e_ident[EI_MAG3], ELFMAG3);
364   ELF_CHECK(elf_hdr, e_ident[EI_CLASS], ELFCLA    364   ELF_CHECK(elf_hdr, e_ident[EI_CLASS], ELFCLASS32);
365   ELF_CHECK(elf_hdr, e_ident[EI_DATA], ELFDATA    365   ELF_CHECK(elf_hdr, e_ident[EI_DATA], ELFDATA2LSB);
366   ELF_CHECK(elf_hdr, e_type, ET_EXEC);            366   ELF_CHECK(elf_hdr, e_type, ET_EXEC);
367   ELF_CHECK(elf_hdr, e_version, EV_CURRENT);      367   ELF_CHECK(elf_hdr, e_version, EV_CURRENT);
368                                                   368 
369   /* Get the begining of the program header ta    369   /* Get the begining of the program header table */
370   elf_phdrs = (Elf32_Phdr_t*) (prog->bottom_va    370   elf_phdrs = (Elf32_Phdr_t*) (prog->bottom_vaddr + elf_hdr->e_phoff);
371                                                   371 
372   /* Map the program segment in R/W mode. To m    372   /* Map the program segment in R/W mode. To make things clean, we
373      should iterate over the sections, not the    373      should iterate over the sections, not the program header */
374   for (i = 0 ; i < elf_hdr->e_phnum ; i++)        374   for (i = 0 ; i < elf_hdr->e_phnum ; i++)
375     {                                             375     {
376       sos_ui32_t prot_flags;                      376       sos_ui32_t prot_flags;
377       sos_uaddr_t uaddr;                          377       sos_uaddr_t uaddr;
378                                                   378 
379       /* Ignore the empty program headers that    379       /* Ignore the empty program headers that are not marked "LOAD" */
380       if (elf_phdrs[i].p_type != PT_LOAD)         380       if (elf_phdrs[i].p_type != PT_LOAD)
381         {                                         381         {
382           if (elf_phdrs[i].p_memsz != 0)          382           if (elf_phdrs[i].p_memsz != 0)
383             {                                     383             {
384               sos_display_fatal_error("ELF: no    384               sos_display_fatal_error("ELF: non-empty non-LOAD segments not supported yet");
385             }                                     385             }
386           continue;                               386           continue;
387         }                                         387         }
388                                                   388       
389       if (elf_phdrs[i].p_vaddr < SOS_PAGING_BA    389       if (elf_phdrs[i].p_vaddr < SOS_PAGING_BASE_USER_ADDRESS)
390         {                                         390         {
391           sos_display_fatal_error("User progra    391           sos_display_fatal_error("User program has an incorrect address");
392         }                                         392         }
393                                                   393 
394       prot_flags = 0;                             394       prot_flags = 0;
395       if (elf_phdrs[i].p_flags & SOS_VM_MAP_PR    395       if (elf_phdrs[i].p_flags & SOS_VM_MAP_PROT_READ)
396         prot_flags |= SOS_VM_MAP_PROT_READ;       396         prot_flags |= SOS_VM_MAP_PROT_READ;
397       if (elf_phdrs[i].p_flags & SOS_VM_MAP_PR    397       if (elf_phdrs[i].p_flags & SOS_VM_MAP_PROT_WRITE)
398         prot_flags |= SOS_VM_MAP_PROT_WRITE;      398         prot_flags |= SOS_VM_MAP_PROT_WRITE;
399       if (elf_phdrs[i].p_flags & SOS_VM_MAP_PR    399       if (elf_phdrs[i].p_flags & SOS_VM_MAP_PROT_EXEC)
400         prot_flags |= SOS_VM_MAP_PROT_EXEC;       400         prot_flags |= SOS_VM_MAP_PROT_EXEC;
401                                                   401 
402       uaddr = elf_phdrs[i].p_vaddr;               402       uaddr = elf_phdrs[i].p_vaddr;
403       SOS_ASSERT_FATAL(SOS_IS_PAGE_ALIGNED(uad    403       SOS_ASSERT_FATAL(SOS_IS_PAGE_ALIGNED(uaddr));
404                                                   404 
405       /* First of all: map the region of the p    405       /* First of all: map the region of the phdr which is also
406          covered by the file */                   406          covered by the file */
407       SOS_ASSERT_FATAL(SOS_OK                     407       SOS_ASSERT_FATAL(SOS_OK
408                        == sos_umem_vmm_map(des    408                        == sos_umem_vmm_map(dest_as, &uaddr,
409                                            SOS    409                                            SOS_PAGE_ALIGN_SUP(elf_phdrs[i].p_filesz),
410                                            pro    410                                            prot_flags,
411                                            /*     411                                            /* PRIVATE */ SOS_VR_MAP_FIXED,
412                                            & m    412                                            & mapped_prog->mr,
413                                            elf    413                                            elf_phdrs[i].p_offset));
414                                                   414 
415       /* Then map the remaining by a zero reso    415       /* Then map the remaining by a zero resource */
416       uaddr += SOS_PAGE_ALIGN_SUP(elf_phdrs[i]    416       uaddr += SOS_PAGE_ALIGN_SUP(elf_phdrs[i].p_filesz);
417       if (SOS_PAGE_ALIGN_SUP(elf_phdrs[i].p_fi    417       if (SOS_PAGE_ALIGN_SUP(elf_phdrs[i].p_filesz)
418           < SOS_PAGE_ALIGN_SUP(elf_phdrs[i].p_    418           < SOS_PAGE_ALIGN_SUP(elf_phdrs[i].p_memsz))
419         SOS_ASSERT_FATAL(SOS_OK                   419         SOS_ASSERT_FATAL(SOS_OK
420                          == sos_dev_zero_map(d    420                          == sos_dev_zero_map(dest_as, &uaddr,
421                                              S    421                                              SOS_PAGE_ALIGN_SUP(elf_phdrs[i].p_memsz)
422                                              -    422                                              - SOS_PAGE_ALIGN_SUP(elf_phdrs[i].p_filesz),
423                                              p    423                                              prot_flags,
424                                              /    424                                              /* PRIVATE */ SOS_VR_MAP_FIXED));
425                                                   425 
426       if (prog_top_user_address                   426       if (prog_top_user_address
427           < uaddr + SOS_PAGE_ALIGN_SUP(elf_phd    427           < uaddr + SOS_PAGE_ALIGN_SUP(elf_phdrs[i].p_memsz))
428         prog_top_user_address                     428         prog_top_user_address
429           = uaddr + SOS_PAGE_ALIGN_SUP(elf_phd    429           = uaddr + SOS_PAGE_ALIGN_SUP(elf_phdrs[i].p_memsz);
430     }                                             430     }
431                                                   431 
432   /* Now prepare the heap */                      432   /* Now prepare the heap */
433   sos_umem_vmm_init_heap(dest_as, prog_top_use    433   sos_umem_vmm_init_heap(dest_as, prog_top_user_address);
434                                                   434 
435   return elf_hdr->e_entry;                        435   return elf_hdr->e_entry;
436 }                                                 436 }
437                                                   437 
438                                                   438 
439 /**                                               439 /**
440  * Lookup a user program located inside the ke    440  * Lookup a user program located inside the kernel's image
441  */                                               441  */
442 static struct userprog_entry * lookup_userprog    442 static struct userprog_entry * lookup_userprog(const char *name)
443 {                                                 443 {
444   struct userprog_entry *prog;                    444   struct userprog_entry *prog;
445                                                   445 
446   if (! name)                                     446   if (! name)
447     return NULL;                                  447     return NULL;
448                                                   448 
449   /* Walk through the table of user program de    449   /* Walk through the table of user program description structures to
450      find the user program with the given name    450      find the user program with the given name */
451   for (prog = (struct userprog_entry*) & _user    451   for (prog = (struct userprog_entry*) & _userprogs_table ;
452        prog && (prog->name != NULL) ;             452        prog && (prog->name != NULL) ;
453        prog++)                                    453        prog++)
454     {                                             454     {
455       if (0 == strcmp(name, prog->name))          455       if (0 == strcmp(name, prog->name))
456         /* Found it ! */                          456         /* Found it ! */
457         return prog;                              457         return prog;
458     }                                             458     }
459                                                   459 
460   return NULL;                                    460   return NULL;
461 }                                                 461 }
                                                      

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