/[nova]/nova/kern/objfmt-elf.c
ViewVC logotype

Diff of /nova/kern/objfmt-elf.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1.1.1 by jrydberg, Tue Feb 12 19:28:44 2002 UTC revision 1.2 by jrydberg, Wed Mar 27 23:21:54 2002 UTC
# Line 1  Line 1 
1  /* ELF object format functions.  /* ELF object format functions.
2     Copyright 1999, 2000, 2001 Johan Rydberg, jrydberg@opencores.org.     Copyright 1999, 2000, 2001, 2002 Johan Rydberg, jrydberg@opencores.org.
3    
4  This program is free software; you can redistribute it and/or modify  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by  it under the terms of the GNU General Public License as published by
# Line 16  along with this program; if not, write t Line 16  along with this program; if not, write t
16  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17    
18  #include <rtmk/rtmk.h>  #include <rtmk/rtmk.h>
19  #include <rtmk/thread-status.h>  #include <rtmk/thread-state.h>
20    
21  #include <errno.h>  #include <errno.h>
22  #include <stdlib.h>  #include <stdlib.h>
# Line 28  Foundation, Inc., 59 Temple Place - Suit Line 28  Foundation, Inc., 59 Temple Place - Suit
28  #include "objfmt.h"  #include "objfmt.h"
29  #include "objfmt-elf.h"  #include "objfmt-elf.h"
30  #include "io-uio.h"  #include "io-uio.h"
31    #include "pager.h"
32    #include "nova-intern.h"
33    
34    #ifdef __i386__
35    # define THREAD_STATE_STRUCTURE thread_state_i386_cpu
36    # define PC     eip
37    # define SP     uesp
38    #endif
39    
40  /* ??? */  /* ??? */
41    
# Line 35  static int Line 43  static int
43  machine_init_thread (rtmk_port_t thread_name, vm_offset_t pc,  machine_init_thread (rtmk_port_t thread_name, vm_offset_t pc,
44                       vm_offset_t sp)                       vm_offset_t sp)
45  {  {
46    thread_state_i386_t ts;    struct thread_state_i386_cpu ts;
47    kern_return_t kr;    kern_return_t kr;
48    int count;    int count;
49    
50    count = sizeof ts;    count = sizeof ts;
51    kr = thread_get_status (thread_name, THREAD_STATUS_FLAVOR_CPU_STATE,    kr = thread_state_get (thread_name, THREAD_STATE_FLAVOR_I386_CPU,
52                            (thread_status_t *) &ts, &count);                           (char *) &ts, &count);
53    if (kr)    if (kr)
54      return kr;      return kr;
55        
# Line 49  machine_init_thread (rtmk_port_t thread_ Line 57  machine_init_thread (rtmk_port_t thread_
57    ts.eip  = (unsigned int) pc;    ts.eip  = (unsigned int) pc;
58    
59    count = sizeof ts;    count = sizeof ts;
60    kr = thread_set_status (thread_name, THREAD_STATUS_FLAVOR_CPU_STATE,    kr = thread_state_set (thread_name, THREAD_STATE_FLAVOR_I386_CPU,
61                            (thread_status_t *) &ts, count);                           (char *) &ts, count);
62    return kr;    return kr;
63  }  }
64    
# Line 135  elf_identify (void *buf, size_t size) Line 143  elf_identify (void *buf, size_t size)
143    return 0;    return 0;
144  }  }
145    
146    /* Load or allocate a section.  */
147    static int
148    load_section (void *section, rtmk_port_t filemap,
149                  rtmk_port_t task)
150    {
151      Elf32_Phdr *ph = section;
152      vm_address_t addr = 0;
153      vm_offset_t filepos = 0;
154      vm_size_t filesz = 0, memsz = 0;
155      vm_prot_t vm_prot;
156      int anywhere, err;
157    
158      vm_prot = VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXEC;
159    
160      addr = ph->p_vaddr & ~(ph->p_align - 1);
161      memsz = ph->p_vaddr + ph->p_memsz - addr;
162      filepos = ph->p_offset & ~(ph->p_align - 1);
163      filesz = ph->p_offset + ph->p_filesz - filepos;
164    
165      if ((ph->p_flags & PF_R) == 0)
166        vm_prot &= ~VM_PROT_READ;
167      if ((ph->p_flags & PF_W) == 0)
168        vm_prot &= ~VM_PROT_WRITE;
169      if ((ph->p_flags & PF_X) == 0)
170        vm_prot &= ~VM_PROT_EXEC;
171      anywhere = 0;
172    
173      if (memsz == 0)
174        /* This section is empty; ignore it.  */
175        return 0;
176    
177      if (filesz != 0)
178        {
179          vm_address_t mapstart = vm_round_page (addr);
180    
181          if (mapstart - addr < filesz)
182            {
183              /* MAPSTART is the first page that starts inside the section.
184                 Map all the pages that start inside the section.  */
185    
186              /* Map the data into the task directly from the file.  */
187              err = vm_map (task, &mapstart, filesz - (mapstart - addr),
188                            anywhere, filemap, filepos + (mapstart - addr),
189                            0, vm_prot,
190                            VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXEC,
191                            VM_INHERIT_COPY);
192              if (err)
193                return err;
194            }
195          
196          if (mapstart > addr)
197            {
198              assert (0);
199            }
200        }
201    
202      if (memsz != 0)
203        {
204          /* SEC_ALLOC: Allocate zero-filled memory for the section.  */
205          vm_address_t mapstart = vm_round_page (addr + filesz);
206    
207          if (mapstart - addr < memsz)
208            {
209              /* MAPSTART is the first page that starts inside the section.
210                 Allocate all the pages that start inside the section.  */
211              err = vm_map (task, &mapstart, memsz - (mapstart - addr),
212                            anywhere, RTMK_PORT_NULL, 0, 0,
213                            vm_prot, VM_PROT_ALL, VM_INHERIT_COPY);
214              if (err)
215                return err;
216            }
217    
218          if (mapstart > addr)
219            {
220            }
221        }  
222      return 0;
223    }
224    
225    
226  static int  static int
227  elf_load (struct proc *p, struct vnode *vp, void *buf,  elf_load (struct proc *p, struct vnode *vp, void *buf,
228            int nargv, char **argv, int nenvp, char **envp)            int nargv, char **argv, int nenvp, char **envp)
229  {  {
230    Elf32_Ehdr *elf_hdr = (Elf32_Ehdr *) buf;    Elf32_Ehdr *elf_hdr = (Elf32_Ehdr *) buf;
231    Elf32_Phdr *phdr, *ph;    Elf32_Phdr *phdr, *ph;
232      vm_offset_t stack_top;
233      struct pager *pager;
234    size_t phsize;    size_t phsize;
235    int err, i;    int err, i;
   vm_offset_t stack_top;  
236    
237    struct io_iovec iovec;    struct io_iovec iovec;
238    struct io_uio uio;    struct io_uio uio;
# Line 158  elf_load (struct proc *p, struct vnode * Line 247  elf_load (struct proc *p, struct vnode *
247                 phsize, &iovec, 1, p);                 phsize, &iovec, 1, p);
248    err = VOP_READ (vp, &uio, 0);    err = VOP_READ (vp, &uio, 0);
249    if (err)    if (err)
250      return err;      {
251          trace_printf ("no read");
252          return err;
253        }
254    
255    /* Load program sections.  */    /* Load program sections.  */
   
256    for (i = 0; i < elf_hdr->e_phnum; i++)    for (i = 0; i < elf_hdr->e_phnum; i++)
257      {      {
258        ph = (Elf32_Phdr *) ((vm_offset_t) phdr + i * elf_hdr->e_phentsize);        ph = (Elf32_Phdr *) ((vm_offset_t) phdr + i * elf_hdr->e_phentsize);
259        if (ph->p_type == PT_LOAD)        if (ph->p_type != PT_LOAD)
260          {          continue;
           vm_prot_t protection = 0;  
           vm_offset_t alloc_offset;  
           vm_size_t vsize;  
   
           if (ph->p_flags & PF_R)  
             protection |= VM_PROT_READ;  
           if (ph->p_flags & PF_W)  
             protection |= VM_PROT_WRITE;  
           if (ph->p_flags & PF_X)  
             protection |= VM_PROT_EXEC;  
             
           io_iov_init (&iovec, (void *) ph->p_vaddr, ph->p_filesz);  
           io_uio_init (&uio, IO_UIO_WRITE, IO_UIO_USERSPACE,  
                        ph->p_offset, ph->p_filesz, &iovec, 1, p);  
261    
262            vsize = vm_round_page (ph->p_memsz + (ph->p_vaddr & VM_PAGE_MASK));        pager = pager_create (vp, VM_PROT_ALL, 0);
263            alloc_offset = vm_trunc_page (ph->p_vaddr);        if (! pager)
264            return ENOMEM;
265          port_insert_right (task_self (), pager_get_right (pager),
266                             pager_get_right (pager), RTMK_MSG_TYPE_MAKE_SEND);
267    
268            err = vm_allocate (p->p_task, vsize, &alloc_offset, 0);        load_section (ph, pager_get_right (pager), p->p_task);
           if (err)  
             return err;  
   
           err = VOP_READ (vp, &uio, 0);  
           if (err)  
             return err;  
         }  
269      }      }
270    
271    /* Allocate stack for the thread.  */    /* Allocate stack for the thread.  */
272    p->p_stksize = 16 * VM_PAGE_SIZE;    p->p_stksize = 16 * VM_PAGE_SIZE;
273    p->p_stkbase = (VM_USER_MAX_ADDRESS - VM_USER_MIN_ADDRESS) - p->p_stksize;    p->p_stkbase = (VM_USER_MAX_ADDRESS - VM_USER_MIN_ADDRESS) - p->p_stksize;
274        
275    err = vm_allocate (p->p_task, p->p_stksize, &p->p_stkbase, 0);    err = vm_allocate (p->p_task, &p->p_stkbase, p->p_stksize, 0);
276    if (err)    if (err)
277      return err;      return err;
278        

Legend:
Removed from v.1.1.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26