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

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