Annotation of sys/compat/sunos/sunos_exec.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: sunos_exec.c,v 1.18 2005/12/30 19:46:55 miod Exp $ */
2: /* $NetBSD: sunos_exec.c,v 1.11 1996/05/05 12:01:47 briggs Exp $ */
3:
4: /*
5: * Copyright (c) 1993 Theo de Raadt
6: * All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: *
17: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27: */
28:
29: #include <sys/param.h>
30: #include <sys/systm.h>
31: #include <sys/filedesc.h>
32: #include <sys/kernel.h>
33: #include <sys/proc.h>
34: #include <sys/mount.h>
35: #include <sys/malloc.h>
36: #include <sys/namei.h>
37: #include <sys/signalvar.h>
38: #include <sys/vnode.h>
39: #include <sys/file.h>
40: #include <sys/exec.h>
41: #include <sys/resourcevar.h>
42: #include <sys/wait.h>
43:
44: #include <sys/mman.h>
45: #include <uvm/uvm_extern.h>
46:
47: #include <machine/cpu.h>
48: #include <machine/reg.h>
49: #include <machine/exec.h>
50:
51: #include <compat/sunos/sunos.h>
52: #include <compat/sunos/sunos_exec.h>
53: #include <compat/sunos/sunos_syscall.h>
54:
55: #ifdef __sparc__
56: #define sunos_exec_aout_prep_zmagic exec_aout_prep_zmagic
57: #define sunos_exec_aout_prep_nmagic exec_aout_prep_nmagic
58: #define sunos_exec_aout_prep_omagic exec_aout_prep_omagic
59: #endif
60:
61: int sunos_exec_aout_makecmds(struct proc *, struct exec_package *);
62: int sunos_exec_aout_prep_zmagic(struct proc *, struct exec_package *);
63: int sunos_exec_aout_prep_nmagic(struct proc *, struct exec_package *);
64: int sunos_exec_aout_prep_omagic(struct proc *, struct exec_package *);
65:
66: extern int nsunos_sysent;
67: extern struct sysent sunos_sysent[];
68: #ifdef SYSCALL_DEBUG
69: extern char *sunos_syscallnames[];
70: #endif
71: extern char sigcode[], esigcode[];
72: const char sunos_emul_path[] = "/emul/sunos";
73:
74: struct emul emul_sunos = {
75: "sunos",
76: NULL,
77: #ifdef __sparc__
78: sendsig,
79: #else
80: sunos_sendsig,
81: #endif
82: SUNOS_SYS_syscall,
83: SUNOS_SYS_MAXSYSCALL,
84: sunos_sysent,
85: #ifdef SYSCALL_DEBUG
86: sunos_syscallnames,
87: #else
88: NULL,
89: #endif
90: 0,
91: copyargs,
92: setregs,
93: NULL,
94: sigcode,
95: esigcode,
96: };
97:
98: int
99: sunos_exec_aout_makecmds(p, epp)
100: struct proc *p;
101: struct exec_package *epp;
102: {
103: struct sunos_exec *sunmag = epp->ep_hdr;
104: int error = ENOEXEC;
105:
106: if (epp->ep_hdrvalid < sizeof(struct sunos_exec))
107: return (ENOEXEC);
108:
109: if(sunmag->a_machtype != SUNOS_M_NATIVE)
110: return (ENOEXEC);
111:
112: switch (sunmag->a_magic) {
113: case ZMAGIC:
114: error = sunos_exec_aout_prep_zmagic(p, epp);
115: break;
116: case NMAGIC:
117: error = sunos_exec_aout_prep_nmagic(p, epp);
118: break;
119: case OMAGIC:
120: error = sunos_exec_aout_prep_omagic(p, epp);
121: break;
122: }
123: if (error==0)
124: epp->ep_emul = &emul_sunos;
125: return error;
126: }
127:
128: /*
129: * the code below is only needed for sun3 emulation.
130: */
131: #ifndef __sparc__
132:
133: /* suns keep data seg aligned to SEGSIZ because of sun custom mmu */
134: #define SEGSIZ 0x20000
135: #define SUNOS_N_TXTADDR(x,m) __LDPGSZ
136: #define SUNOS_N_DATADDR(x,m) (((m)==OMAGIC) ? \
137: (SUNOS_N_TXTADDR(x,m) + (x).a_text) : \
138: (SEGSIZ + ((SUNOS_N_TXTADDR(x,m) + (x).a_text - 1) & ~(SEGSIZ-1))))
139: #define SUNOS_N_BSSADDR(x,m) (SUNOS_N_DATADDR(x,m)+(x).a_data)
140:
141: #define SUNOS_N_TXTOFF(x,m) ((m)==ZMAGIC ? 0 : sizeof (struct exec))
142: #define SUNOS_N_DATOFF(x,m) (SUNOS_N_TXTOFF(x,m) + (x).a_text)
143:
144: /*
145: * sunos_exec_aout_prep_zmagic(): Prepare a SunOS ZMAGIC binary's exec package
146: *
147: * First, set of the various offsets/lengths in the exec package.
148: *
149: * Then, mark the text image busy (so it can be demand paged) or error
150: * out if this is not possible. Finally, set up vmcmds for the
151: * text, data, bss, and stack segments.
152: */
153: int
154: sunos_exec_aout_prep_zmagic(p, epp)
155: struct proc *p;
156: struct exec_package *epp;
157: {
158: struct exec *execp = epp->ep_hdr;
159:
160: epp->ep_taddr = SUNOS_N_TXTADDR(*execp, ZMAGIC);
161: epp->ep_tsize = execp->a_text;
162: epp->ep_daddr = SUNOS_N_DATADDR(*execp, ZMAGIC);
163: epp->ep_dsize = execp->a_data + execp->a_bss;
164: epp->ep_entry = execp->a_entry;
165:
166: /*
167: * check if vnode is in open for writing, because we want to
168: * demand-page out of it. if it is, don't do it, for various
169: * reasons
170: */
171: if ((execp->a_text != 0 || execp->a_data != 0) &&
172: epp->ep_vp->v_writecount != 0) {
173: #ifdef DIAGNOSTIC
174: if (epp->ep_vp->v_flag & VTEXT)
175: panic("exec: a VTEXT vnode has writecount != 0");
176: #endif
177: return ETXTBSY;
178: }
179: vn_marktext(epp->ep_vp);
180:
181: /* set up command for text segment */
182: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, execp->a_text,
183: epp->ep_taddr, epp->ep_vp, SUNOS_N_TXTOFF(*execp, ZMAGIC),
184: VM_PROT_READ|VM_PROT_EXECUTE);
185:
186: /* set up command for data segment */
187: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, execp->a_data,
188: epp->ep_daddr, epp->ep_vp, SUNOS_N_DATOFF(*execp, ZMAGIC),
189: VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
190:
191: /* set up command for bss segment */
192: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, execp->a_bss,
193: epp->ep_daddr + execp->a_data, NULLVP, 0,
194: VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
195:
196: return exec_setup_stack(p, epp);
197: }
198:
199: /*
200: * sunos_exec_aout_prep_nmagic(): Prepare a SunOS NMAGIC binary's exec package
201: */
202: int
203: sunos_exec_aout_prep_nmagic(p, epp)
204: struct proc *p;
205: struct exec_package *epp;
206: {
207: struct exec *execp = epp->ep_hdr;
208: long bsize, baddr;
209:
210: epp->ep_taddr = SUNOS_N_TXTADDR(*execp, NMAGIC);
211: epp->ep_tsize = execp->a_text;
212: epp->ep_daddr = SUNOS_N_DATADDR(*execp, NMAGIC);
213: epp->ep_dsize = execp->a_data + execp->a_bss;
214: epp->ep_entry = execp->a_entry;
215:
216: /* set up command for text segment */
217: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, execp->a_text,
218: epp->ep_taddr, epp->ep_vp, SUNOS_N_TXTOFF(*execp, NMAGIC),
219: VM_PROT_READ|VM_PROT_EXECUTE);
220:
221: /* set up command for data segment */
222: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, execp->a_data,
223: epp->ep_daddr, epp->ep_vp, SUNOS_N_DATOFF(*execp, NMAGIC),
224: VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
225:
226: /* set up command for bss segment */
227: baddr = round_page(epp->ep_daddr + execp->a_data);
228: bsize = epp->ep_daddr + epp->ep_dsize - baddr;
229: if (bsize > 0)
230: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, bsize, baddr,
231: NULLVP, 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
232:
233: return exec_setup_stack(p, epp);
234: }
235:
236: /*
237: * sunos_exec_aout_prep_omagic(): Prepare a SunOS OMAGIC binary's exec package
238: */
239: int
240: sunos_exec_aout_prep_omagic(p, epp)
241: struct proc *p;
242: struct exec_package *epp;
243: {
244: struct exec *execp = epp->ep_hdr;
245: long bsize, baddr;
246:
247: epp->ep_taddr = SUNOS_N_TXTADDR(*execp, OMAGIC);
248: epp->ep_tsize = execp->a_text;
249: epp->ep_daddr = SUNOS_N_DATADDR(*execp, OMAGIC);
250: epp->ep_dsize = execp->a_data + execp->a_bss;
251: epp->ep_entry = execp->a_entry;
252:
253: /* set up command for text and data segments */
254: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn,
255: execp->a_text + execp->a_data, epp->ep_taddr, epp->ep_vp,
256: SUNOS_N_TXTOFF(*execp, OMAGIC), VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
257:
258: /* set up command for bss segment */
259: baddr = round_page(epp->ep_daddr + execp->a_data);
260: bsize = epp->ep_daddr + epp->ep_dsize - baddr;
261: if (bsize > 0)
262: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, bsize, baddr,
263: NULLVP, 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
264:
265: return exec_setup_stack(p, epp);
266: }
267: #endif /* !__sparc__ */
CVSweb