1 /* $NetBSD: compat_exec.c,v 1.16 2009/08/13 03:53:13 matt Exp $ */
4 * Copyright (c) 1993, 1994 Christopher G. Demetriou
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Christopher G. Demetriou.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: compat_exec.c,v 1.16 2009/08/13 03:53:13 matt Exp $");
37 #include "opt_execfmt.h"
40 #include <sys/param.h>
41 #include <sys/systm.h>
43 #include <sys/vnode.h>
45 #include <sys/resourcevar.h>
48 #include <sys/exec_aout.h>
51 * exec_aout_prep_oldzmagic():
52 * Prepare the vmcmds to build a vmspace for an old ZMAGIC
53 * binary. [386BSD/BSDI/4.4BSD/NetBSD0.8]
55 * Cloned from exec_aout_prep_zmagic() in kern/exec_aout.c; a more verbose
56 * description of operation is there.
57 * There were copies of this in the mac68k, hp300, and i386 ports.
60 exec_aout_prep_oldzmagic(struct lwp
*l
, struct exec_package
*epp
)
62 struct exec
*execp
= epp
->ep_hdr
;
66 epp
->ep_tsize
= execp
->a_text
;
67 epp
->ep_daddr
= epp
->ep_taddr
+ execp
->a_text
;
68 epp
->ep_dsize
= execp
->a_data
+ execp
->a_bss
;
69 epp
->ep_entry
= execp
->a_entry
;
71 error
= vn_marktext(epp
->ep_vp
);
75 /* set up command for text segment */
76 NEW_VMCMD(&epp
->ep_vmcmds
, vmcmd_map_pagedvn
, execp
->a_text
,
77 epp
->ep_taddr
, epp
->ep_vp
, PAGE_SIZE
, /* XXX CLBYTES? */
78 VM_PROT_READ
|VM_PROT_EXECUTE
);
80 /* set up command for data segment */
81 NEW_VMCMD(&epp
->ep_vmcmds
, vmcmd_map_pagedvn
, execp
->a_data
,
82 epp
->ep_daddr
, epp
->ep_vp
,
83 execp
->a_text
+ PAGE_SIZE
, /* XXX CLBYTES? */
84 VM_PROT_READ
|VM_PROT_WRITE
|VM_PROT_EXECUTE
);
86 /* set up command for bss segment */
88 NEW_VMCMD(&epp
->ep_vmcmds
, vmcmd_map_zero
, execp
->a_bss
,
89 epp
->ep_daddr
+ execp
->a_data
, NULLVP
, 0,
90 VM_PROT_READ
|VM_PROT_WRITE
|VM_PROT_EXECUTE
);
92 return (*epp
->ep_esch
->es_setup_stack
)(l
, epp
);
97 * exec_aout_prep_oldnmagic():
98 * Prepare the vmcmds to build a vmspace for an old NMAGIC
101 * Cloned from exec_aout_prep_nmagic() in kern/exec_aout.c; with text starting
103 * XXX: There must be a better way to share this code.
106 exec_aout_prep_oldnmagic(struct lwp
*l
, struct exec_package
*epp
)
108 struct exec
*execp
= epp
->ep_hdr
;
112 epp
->ep_tsize
= execp
->a_text
;
113 epp
->ep_daddr
= roundup(epp
->ep_taddr
+ execp
->a_text
, AOUT_LDPGSZ
);
114 epp
->ep_dsize
= execp
->a_data
+ execp
->a_bss
;
115 epp
->ep_entry
= execp
->a_entry
;
117 /* set up command for text segment */
118 NEW_VMCMD(&epp
->ep_vmcmds
, vmcmd_map_readvn
, execp
->a_text
,
119 epp
->ep_taddr
, epp
->ep_vp
, sizeof(struct exec
),
120 VM_PROT_READ
|VM_PROT_EXECUTE
);
122 /* set up command for data segment */
123 NEW_VMCMD(&epp
->ep_vmcmds
, vmcmd_map_readvn
, execp
->a_data
,
124 epp
->ep_daddr
, epp
->ep_vp
, execp
->a_text
+ sizeof(struct exec
),
125 VM_PROT_READ
|VM_PROT_WRITE
|VM_PROT_EXECUTE
);
127 /* set up command for bss segment */
128 baddr
= roundup(epp
->ep_daddr
+ execp
->a_data
, PAGE_SIZE
);
129 bsize
= epp
->ep_daddr
+ epp
->ep_dsize
- baddr
;
131 NEW_VMCMD(&epp
->ep_vmcmds
, vmcmd_map_zero
, bsize
, baddr
,
132 NULLVP
, 0, VM_PROT_READ
|VM_PROT_WRITE
|VM_PROT_EXECUTE
);
134 return (*epp
->ep_esch
->es_setup_stack
)(l
, epp
);
139 * exec_aout_prep_oldomagic():
140 * Prepare the vmcmds to build a vmspace for an old OMAGIC
143 * Cloned from exec_aout_prep_omagic() in kern/exec_aout.c; with text starting
145 * XXX: There must be a better way to share this code.
148 exec_aout_prep_oldomagic(struct lwp
*l
, struct exec_package
*epp
)
150 struct exec
*execp
= epp
->ep_hdr
;
151 long dsize
, bsize
, baddr
;
154 epp
->ep_tsize
= execp
->a_text
;
155 epp
->ep_daddr
= epp
->ep_taddr
+ execp
->a_text
;
156 epp
->ep_dsize
= execp
->a_data
+ execp
->a_bss
;
157 epp
->ep_entry
= execp
->a_entry
;
159 /* set up command for text and data segments */
160 NEW_VMCMD(&epp
->ep_vmcmds
, vmcmd_map_readvn
,
161 execp
->a_text
+ execp
->a_data
, epp
->ep_taddr
, epp
->ep_vp
,
162 sizeof(struct exec
), VM_PROT_READ
|VM_PROT_WRITE
|VM_PROT_EXECUTE
);
164 /* set up command for bss segment */
165 baddr
= roundup(epp
->ep_daddr
+ execp
->a_data
, PAGE_SIZE
);
166 bsize
= epp
->ep_daddr
+ epp
->ep_dsize
- baddr
;
168 NEW_VMCMD(&epp
->ep_vmcmds
, vmcmd_map_zero
, bsize
, baddr
,
169 NULLVP
, 0, VM_PROT_READ
|VM_PROT_WRITE
|VM_PROT_EXECUTE
);
172 * Make sure (# of pages) mapped above equals (vm_tsize + vm_dsize);
173 * obreak(2) relies on this fact. Both `vm_tsize' and `vm_dsize' are
174 * computed (in execve(2)) by rounding *up* `ep_tsize' and `ep_dsize'
175 * respectively to page boundaries.
176 * Compensate `ep_dsize' for the amount of data covered by the last
179 dsize
= epp
->ep_dsize
+ execp
->a_text
- roundup(execp
->a_text
,
181 epp
->ep_dsize
= (dsize
> 0) ? dsize
: 0;
182 return (*epp
->ep_esch
->es_setup_stack
)(l
, epp
);
184 #endif /* EXEC_AOUT */