5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved.
24 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
25 */
26
27 #include <sys/errno.h>
28 #include <sys/exec.h>
29 #include <sys/file.h>
30 #include <sys/kmem.h>
31 #include <sys/modctl.h>
32 #include <sys/model.h>
33 #include <sys/proc.h>
34 #include <sys/syscall.h>
35 #include <sys/systm.h>
36 #include <sys/thread.h>
37 #include <sys/cmn_err.h>
38 #include <sys/archsystm.h>
39 #include <sys/pathname.h>
40 #include <sys/sunddi.h>
41
42 #include <sys/machbrand.h>
43 #include <sys/brand.h>
44 #include "s10_brand.h"
45
46 char *s10_emulation_table = NULL;
47
48 void s10_init_brand_data(zone_t *);
49 void s10_free_brand_data(zone_t *);
50 void s10_setbrand(proc_t *);
51 int s10_getattr(zone_t *, int, void *, size_t *);
52 int s10_setattr(zone_t *, int, void *, size_t);
53 int s10_brandsys(int, int64_t *, uintptr_t, uintptr_t, uintptr_t,
54 uintptr_t, uintptr_t, uintptr_t);
55 void s10_copy_procdata(proc_t *, proc_t *);
56 void s10_proc_exit(struct proc *, klwp_t *);
57 void s10_exec();
58 int s10_initlwp(klwp_t *);
59 void s10_forklwp(klwp_t *, klwp_t *);
60 void s10_freelwp(klwp_t *);
61 void s10_lwpexit(klwp_t *);
62 int s10_elfexec(vnode_t *, execa_t *, uarg_t *, intpdata_t *, int,
63 long *, int, caddr_t, cred_t *, int);
64 void s10_sigset_native_to_s10(sigset_t *);
65 void s10_sigset_s10_to_native(sigset_t *);
66
67 /* s10 brand */
68 struct brand_ops s10_brops = {
69 s10_init_brand_data,
70 s10_free_brand_data,
71 s10_brandsys,
72 s10_setbrand,
73 s10_getattr,
74 s10_setattr,
75 s10_copy_procdata,
76 s10_proc_exit,
77 s10_exec,
78 lwp_setrval,
79 s10_initlwp,
80 s10_forklwp,
81 s10_freelwp,
82 s10_lwpexit,
83 s10_elfexec,
84 s10_sigset_native_to_s10,
85 s10_sigset_s10_to_native,
86 S10_NSIG,
87 };
88
89 #ifdef sparc
90
91 struct brand_mach_ops s10_mops = {
92 s10_brand_syscall_callback,
93 s10_brand_syscall32_callback
94 };
95
96 #else /* sparc */
97
98 #ifdef __amd64
99
100 struct brand_mach_ops s10_mops = {
101 s10_brand_sysenter_callback,
102 s10_brand_int91_callback,
103 s10_brand_syscall_callback,
104 s10_brand_syscall32_callback
105 };
106
107 #else /* ! __amd64 */
108
109 struct brand_mach_ops s10_mops = {
110 s10_brand_sysenter_callback,
111 NULL,
112 s10_brand_syscall_callback,
113 NULL
114 };
115 #endif /* __amd64 */
116
117 #endif /* _sparc */
118
119 struct brand s10_brand = {
120 BRAND_VER_1,
121 "solaris10",
122 &s10_brops,
123 &s10_mops
124 };
125
126 static struct modlbrand modlbrand = {
127 &mod_brandops, /* type of module */
128 "Solaris 10 Brand", /* description of module */
129 &s10_brand /* driver ops */
130 };
131
132 static struct modlinkage modlinkage = {
133 MODREV_1, (void *)&modlbrand, NULL
134 };
135
136 void
137 s10_setbrand(proc_t *p)
138 {
139 brand_solaris_setbrand(p, &s10_brand);
140 }
141
142 /*ARGSUSED*/
143 int
232 return (0);
233
234 /*
235 * The sizeof has an extra value for the trailing '\0' so this covers
236 * the appended " " in the following strcmps.
237 */
238 if (strncmp(up->u_psargs, BRAND_NATIVE_LINKER64 " ",
239 sizeof (BRAND_NATIVE_LINKER64)) != 0 &&
240 strncmp(up->u_psargs, BRAND_NATIVE_LINKER32 " ",
241 sizeof (BRAND_NATIVE_LINKER32)) != 0)
242 return (0);
243
244 mutex_enter(&curproc->p_lock);
245 (void) strlcpy(up->u_comm, cmd_buf, sizeof (up->u_comm));
246 (void) strlcpy(up->u_psargs, arg_buf, sizeof (up->u_psargs));
247 mutex_exit(&curproc->p_lock);
248
249 return (0);
250 }
251
252 /*ARGSUSED*/
253 int
254 s10_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2,
255 uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, uintptr_t arg6)
256 {
257 proc_t *p = curproc;
258 int res;
259
260 *rval = 0;
261
262 if (cmd == B_S10_NATIVE)
263 return (s10_native((void *)arg1, (void *)arg2));
264
265 res = brand_solaris_cmd(cmd, arg1, arg2, arg3, &s10_brand, S10_VERSION);
266 if (res >= 0)
267 return (res);
268
269 switch ((cmd)) {
270 case B_S10_PIDINFO:
271 /*
272 * The s10 brand needs to be able to get the pid of the
273 * current process and the pid of the zone's init, and it
274 * needs to do this on every process startup. Early in
275 * brand startup, we can't call getpid() because calls to
309 * This subcommand exists so that the SYS_lwp_private and
310 * SYS_lwp_create syscalls can manually set the current thread's
311 * %fs register to the legacy S10 selector value for 64-bit x86
312 * processes.
313 */
314 s10_amd64_correct_fsreg(ttolwp(curthread));
315 return (0);
316 #endif /* __amd64 */
317 }
318
319 return (EINVAL);
320 }
321
322 void
323 s10_copy_procdata(proc_t *child, proc_t *parent)
324 {
325 brand_solaris_copy_procdata(child, parent, &s10_brand);
326 }
327
328 void
329 s10_proc_exit(struct proc *p, klwp_t *l)
330 {
331 brand_solaris_proc_exit(p, l, &s10_brand);
332 }
333
334 void
335 s10_exec()
336 {
337 brand_solaris_exec(&s10_brand);
338 }
339
340 int
341 s10_initlwp(klwp_t *l)
342 {
343 return (brand_solaris_initlwp(l, &s10_brand));
344 }
345
346 void
347 s10_forklwp(klwp_t *p, klwp_t *c)
348 {
349 brand_solaris_forklwp(p, c, &s10_brand);
350
351 #ifdef __amd64
352 /*
353 * Only correct the child's %fs register if the parent's %fs register
354 * is LWPFS_SEL. If the parent's %fs register is zero, then the Solaris
355 * 10 environment that we're emulating uses a version of libc that
356 * works when %fs is zero (i.e., it contains backports of CRs 6467491
357 * and 6501650).
358 */
359 if (p->lwp_pcb.pcb_fs == LWPFS_SEL)
360 s10_amd64_correct_fsreg(c);
361 #endif /* __amd64 */
362 }
363
364 void
365 s10_freelwp(klwp_t *l)
366 {
367 brand_solaris_freelwp(l, &s10_brand);
368 }
369
370 void
371 s10_lwpexit(klwp_t *l)
372 {
373 brand_solaris_lwpexit(l, &s10_brand);
374 }
375
376 void
377 s10_free_brand_data(zone_t *zone)
378 {
379 kmem_free(zone->zone_brand_data, sizeof (s10_zone_data_t));
380 }
381
382 void
383 s10_init_brand_data(zone_t *zone)
384 {
385 ASSERT(zone->zone_brand == &s10_brand);
386 ASSERT(zone->zone_brand_data == NULL);
387 zone->zone_brand_data = kmem_zalloc(sizeof (s10_zone_data_t), KM_SLEEP);
388 }
389
390 int
391 s10_elfexec(vnode_t *vp, execa_t *uap, uarg_t *args, intpdata_t *idatap,
392 int level, long *execsz, int setid, caddr_t exec_file, cred_t *cred,
393 int brand_action)
394 {
395 return (brand_solaris_elfexec(vp, uap, args, idatap, level, execsz,
396 setid, exec_file, cred, brand_action, &s10_brand, S10_BRANDNAME,
397 S10_LIB, S10_LIB32, S10_LINKER, S10_LINKER32));
398 }
399
400 void
401 s10_sigset_native_to_s10(sigset_t *set)
402 {
403 int nativesig;
404 int s10sig;
405 sigset_t s10set;
406
407 /*
408 * Shortcut: we know the first 32 signals are the same in both
409 * s10 and native Solaris. Just assign the first word.
410 */
411 s10set.__sigbits[0] = set->__sigbits[0];
412 s10set.__sigbits[1] = 0;
413 s10set.__sigbits[2] = 0;
414 s10set.__sigbits[3] = 0;
415
416 /*
417 * Copy the remainder of the initial set of common signals.
|
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved.
24 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
25 * Copyright 2016, Joyent, Inc.
26 */
27
28 #include <sys/errno.h>
29 #include <sys/exec.h>
30 #include <sys/file.h>
31 #include <sys/kmem.h>
32 #include <sys/modctl.h>
33 #include <sys/model.h>
34 #include <sys/proc.h>
35 #include <sys/syscall.h>
36 #include <sys/systm.h>
37 #include <sys/thread.h>
38 #include <sys/cmn_err.h>
39 #include <sys/archsystm.h>
40 #include <sys/pathname.h>
41 #include <sys/sunddi.h>
42
43 #include <sys/machbrand.h>
44 #include <sys/brand.h>
45 #include "s10_brand.h"
46
47 char *s10_emulation_table = NULL;
48
49 void s10_init_brand_data(zone_t *, kmutex_t *);
50 void s10_free_brand_data(zone_t *);
51 void s10_setbrand(proc_t *);
52 int s10_getattr(zone_t *, int, void *, size_t *);
53 int s10_setattr(zone_t *, int, void *, size_t);
54 int s10_brandsys(int, int64_t *, uintptr_t, uintptr_t, uintptr_t,
55 uintptr_t);
56 void s10_copy_procdata(proc_t *, proc_t *);
57 void s10_proc_exit(struct proc *);
58 void s10_exec();
59 void s10_initlwp(klwp_t *, void *);
60 void s10_forklwp(klwp_t *, klwp_t *);
61 void s10_freelwp(klwp_t *);
62 void s10_lwpexit(klwp_t *);
63 int s10_elfexec(vnode_t *, execa_t *, uarg_t *, intpdata_t *, int,
64 long *, int, caddr_t, cred_t *, int *);
65 void s10_sigset_native_to_s10(sigset_t *);
66 void s10_sigset_s10_to_native(sigset_t *);
67
68 /* s10 brand */
69 struct brand_ops s10_brops = {
70 s10_init_brand_data, /* b_init_brand_data */
71 s10_free_brand_data, /* b_free_brand_data */
72 s10_brandsys, /* b_brandsys */
73 s10_setbrand, /* b_setbrand */
74 s10_getattr, /* b_getattr */
75 s10_setattr, /* b_setattr */
76 s10_copy_procdata, /* b_copy_procdata */
77 s10_proc_exit, /* b_proc_exit */
78 s10_exec, /* b_exec */
79 lwp_setrval, /* b_lwp_setrval */
80 NULL, /* b_lwpdata_alloc */
81 NULL, /* b_lwpdata_free */
82 s10_initlwp, /* b_initlwp */
83 NULL, /* b_initlwp_post */
84 s10_forklwp, /* b_forklwp */
85 s10_freelwp, /* b_freelwp */
86 s10_lwpexit, /* b_lwpexit */
87 s10_elfexec, /* b_elfexec */
88 s10_sigset_native_to_s10, /* b_sigset_native_to_brand */
89 s10_sigset_s10_to_native, /* b_sigset_brand_to_native */
90 NULL, /* b_sigfd_translate */
91 S10_NSIG, /* b_nsig */
92 NULL, /* b_exit_with_sig */
93 NULL, /* b_wait_filter */
94 NULL, /* b_native_exec */
95 NULL, /* b_map32limit */
96 NULL, /* b_stop_notify */
97 NULL, /* b_waitid_helper */
98 NULL, /* b_sigcld_repost */
99 NULL, /* b_issig_stop */
100 NULL, /* b_sig_ignorable */
101 NULL, /* b_savecontext */
102 #if defined(_SYSCALL32_IMPL)
103 NULL, /* b_savecontext32 */
104 #endif
105 NULL, /* b_restorecontext */
106 NULL, /* b_sendsig_stack */
107 NULL, /* b_sendsig */
108 NULL, /* b_setid_clear */
109 NULL, /* b_pagefault */
110 B_TRUE /* b_intp_parse_arg */
111 };
112
113 #ifdef sparc
114
115 struct brand_mach_ops s10_mops = {
116 s10_brand_syscall_callback,
117 s10_brand_syscall32_callback
118 };
119
120 #else /* sparc */
121
122 #ifdef __amd64
123
124 struct brand_mach_ops s10_mops = {
125 s10_brand_sysenter_callback,
126 NULL,
127 s10_brand_int91_callback,
128 s10_brand_syscall_callback,
129 s10_brand_syscall32_callback,
130 NULL,
131 NULL
132 };
133
134 #else /* ! __amd64 */
135
136 struct brand_mach_ops s10_mops = {
137 s10_brand_sysenter_callback,
138 NULL,
139 NULL,
140 s10_brand_syscall_callback,
141 NULL,
142 NULL,
143 NULL
144 };
145 #endif /* __amd64 */
146
147 #endif /* _sparc */
148
149 struct brand s10_brand = {
150 BRAND_VER_1,
151 "solaris10",
152 &s10_brops,
153 &s10_mops,
154 sizeof (brand_proc_data_t),
155 };
156
157 static struct modlbrand modlbrand = {
158 &mod_brandops, /* type of module */
159 "Solaris 10 Brand", /* description of module */
160 &s10_brand /* driver ops */
161 };
162
163 static struct modlinkage modlinkage = {
164 MODREV_1, (void *)&modlbrand, NULL
165 };
166
167 void
168 s10_setbrand(proc_t *p)
169 {
170 brand_solaris_setbrand(p, &s10_brand);
171 }
172
173 /*ARGSUSED*/
174 int
263 return (0);
264
265 /*
266 * The sizeof has an extra value for the trailing '\0' so this covers
267 * the appended " " in the following strcmps.
268 */
269 if (strncmp(up->u_psargs, BRAND_NATIVE_LINKER64 " ",
270 sizeof (BRAND_NATIVE_LINKER64)) != 0 &&
271 strncmp(up->u_psargs, BRAND_NATIVE_LINKER32 " ",
272 sizeof (BRAND_NATIVE_LINKER32)) != 0)
273 return (0);
274
275 mutex_enter(&curproc->p_lock);
276 (void) strlcpy(up->u_comm, cmd_buf, sizeof (up->u_comm));
277 (void) strlcpy(up->u_psargs, arg_buf, sizeof (up->u_psargs));
278 mutex_exit(&curproc->p_lock);
279
280 return (0);
281 }
282
283 /* ARGSUSED5 */
284 int
285 s10_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2,
286 uintptr_t arg3, uintptr_t arg4)
287 {
288 proc_t *p = curproc;
289 int res;
290
291 *rval = 0;
292
293 if (cmd == B_S10_NATIVE)
294 return (s10_native((void *)arg1, (void *)arg2));
295
296 res = brand_solaris_cmd(cmd, arg1, arg2, arg3, &s10_brand, S10_VERSION);
297 if (res >= 0)
298 return (res);
299
300 switch ((cmd)) {
301 case B_S10_PIDINFO:
302 /*
303 * The s10 brand needs to be able to get the pid of the
304 * current process and the pid of the zone's init, and it
305 * needs to do this on every process startup. Early in
306 * brand startup, we can't call getpid() because calls to
340 * This subcommand exists so that the SYS_lwp_private and
341 * SYS_lwp_create syscalls can manually set the current thread's
342 * %fs register to the legacy S10 selector value for 64-bit x86
343 * processes.
344 */
345 s10_amd64_correct_fsreg(ttolwp(curthread));
346 return (0);
347 #endif /* __amd64 */
348 }
349
350 return (EINVAL);
351 }
352
353 void
354 s10_copy_procdata(proc_t *child, proc_t *parent)
355 {
356 brand_solaris_copy_procdata(child, parent, &s10_brand);
357 }
358
359 void
360 s10_proc_exit(struct proc *p)
361 {
362 brand_solaris_proc_exit(p, &s10_brand);
363 }
364
365 void
366 s10_exec()
367 {
368 brand_solaris_exec(&s10_brand);
369 }
370
371 /* ARGSUSED */
372 void
373 s10_initlwp(klwp_t *l, void *bd)
374 {
375 brand_solaris_initlwp(l, &s10_brand);
376 }
377
378 void
379 s10_forklwp(klwp_t *p, klwp_t *c)
380 {
381 brand_solaris_forklwp(p, c, &s10_brand);
382
383 #ifdef __amd64
384 /*
385 * Only correct the child's %fs register if the parent's %fs register
386 * is LWPFS_SEL. If the parent's %fs register is zero, then the Solaris
387 * 10 environment that we're emulating uses a version of libc that
388 * works when %fs is zero (i.e., it contains backports of CRs 6467491
389 * and 6501650).
390 */
391 if (p->lwp_pcb.pcb_fs == LWPFS_SEL)
392 s10_amd64_correct_fsreg(c);
393 #endif /* __amd64 */
394 }
395
396 void
397 s10_freelwp(klwp_t *l)
398 {
399 brand_solaris_freelwp(l, &s10_brand);
400 }
401
402 void
403 s10_lwpexit(klwp_t *l)
404 {
405 brand_solaris_lwpexit(l, &s10_brand);
406 }
407
408 void
409 s10_free_brand_data(zone_t *zone)
410 {
411 kmem_free(zone->zone_brand_data, sizeof (s10_zone_data_t));
412 }
413
414 /* ARGSUSED */
415 void
416 s10_init_brand_data(zone_t *zone, kmutex_t *zsl)
417 {
418 ASSERT(zone->zone_brand == &s10_brand);
419 ASSERT(zone->zone_brand_data == NULL);
420 zone->zone_brand_data = kmem_zalloc(sizeof (s10_zone_data_t), KM_SLEEP);
421 }
422
423 int
424 s10_elfexec(vnode_t *vp, execa_t *uap, uarg_t *args, intpdata_t *idatap,
425 int level, long *execsz, int setid, caddr_t exec_file, cred_t *cred,
426 int *brand_action)
427 {
428 return (brand_solaris_elfexec(vp, uap, args, idatap, level, execsz,
429 setid, exec_file, cred, brand_action, &s10_brand, S10_BRANDNAME,
430 S10_LIB, S10_LIB32));
431 }
432
433 void
434 s10_sigset_native_to_s10(sigset_t *set)
435 {
436 int nativesig;
437 int s10sig;
438 sigset_t s10set;
439
440 /*
441 * Shortcut: we know the first 32 signals are the same in both
442 * s10 and native Solaris. Just assign the first word.
443 */
444 s10set.__sigbits[0] = set->__sigbits[0];
445 s10set.__sigbits[1] = 0;
446 s10set.__sigbits[2] = 0;
447 s10set.__sigbits[3] = 0;
448
449 /*
450 * Copy the remainder of the initial set of common signals.
|