1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
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 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <sys/errno.h>
27 #include <sys/exec.h>
28 #include <sys/kmem.h>
29 #include <sys/modctl.h>
30 #include <sys/model.h>
31 #include <sys/proc.h>
32 #include <sys/syscall.h>
33 #include <sys/systm.h>
34 #include <sys/thread.h>
35 #include <sys/cmn_err.h>
36 #include <sys/archsystm.h>
37 #include <sys/pathname.h>
38 #include <sys/sunddi.h>
39
40 #include <sys/machbrand.h>
41 #include <sys/brand.h>
42 #include "s10_brand.h"
43
44 char *s10_emulation_table = NULL;
45
46 void s10_init_brand_data(zone_t *);
47 void s10_free_brand_data(zone_t *);
48 void s10_setbrand(proc_t *);
49 int s10_getattr(zone_t *, int, void *, size_t *);
50 int s10_setattr(zone_t *, int, void *, size_t);
51 int s10_brandsys(int, int64_t *, uintptr_t, uintptr_t, uintptr_t,
52 uintptr_t, uintptr_t, uintptr_t);
53 void s10_copy_procdata(proc_t *, proc_t *);
54 void s10_proc_exit(struct proc *, klwp_t *);
55 void s10_exec();
56 int s10_initlwp(klwp_t *);
57 void s10_forklwp(klwp_t *, klwp_t *);
58 void s10_freelwp(klwp_t *);
59 void s10_lwpexit(klwp_t *);
60 int s10_elfexec(vnode_t *, execa_t *, uarg_t *, intpdata_t *, int,
61 long *, int, caddr_t, cred_t *, int);
62
63 /* s10 brand */
64 struct brand_ops s10_brops = {
65 s10_init_brand_data,
66 s10_free_brand_data,
67 s10_brandsys,
68 s10_setbrand,
69 s10_getattr,
70 s10_setattr,
71 s10_copy_procdata,
72 s10_proc_exit,
73 s10_exec,
74 lwp_setrval,
75 s10_initlwp,
76 s10_forklwp,
77 s10_freelwp,
78 s10_lwpexit,
79 s10_elfexec
80 };
81
82 #ifdef sparc
83
84 struct brand_mach_ops s10_mops = {
85 s10_brand_syscall_callback,
86 s10_brand_syscall32_callback
87 };
88
89 #else /* sparc */
90
91 #ifdef __amd64
92
93 struct brand_mach_ops s10_mops = {
94 s10_brand_sysenter_callback,
95 NULL,
96 s10_brand_int91_callback,
97 s10_brand_syscall_callback,
98 s10_brand_syscall32_callback,
99 NULL
100 };
101
102 #else /* ! __amd64 */
103
104 struct brand_mach_ops s10_mops = {
105 s10_brand_sysenter_callback,
106 NULL,
107 NULL,
108 s10_brand_syscall_callback,
109 NULL,
110 NULL
111 };
112 #endif /* __amd64 */
113
114 #endif /* _sparc */
115
116 struct brand s10_brand = {
117 BRAND_VER_1,
118 "solaris10",
119 &s10_brops,
120 &s10_mops
121 };
122
123 static struct modlbrand modlbrand = {
124 &mod_brandops, /* type of module */
125 "Solaris 10 Brand", /* description of module */
126 &s10_brand /* driver ops */
127 };
128
129 static struct modlinkage modlinkage = {
130 MODREV_1, (void *)&modlbrand, NULL
131 };
132
133 void
134 s10_setbrand(proc_t *p)
135 {
136 ASSERT(p->p_brand == &s10_brand);
137 ASSERT(p->p_brand_data == NULL);
138
139 /*
140 * We should only be called from exec(), when we know the process
141 * is single-threaded.
142 */
143 ASSERT(p->p_tlist == p->p_tlist->t_forw);
144
145 p->p_brand_data = kmem_zalloc(sizeof (s10_proc_data_t), KM_SLEEP);
146 (void) s10_initlwp(p->p_tlist->t_lwp);
147 }
148
149 int
150 s10_get_zone_emul_version(zone_t *zone)
151 {
152 return (((s10_zone_data_t *)
153 zone->zone_brand_data)->s10zd_emul_version);
154 }
155
156 int
157 s10_get_emul_version()
158 {
159 return (s10_get_zone_emul_version(curzone));
160 }
161
162 void
163 s10_set_emul_version(zone_t *zone, int vers)
164 {
165 s10_zone_data_t *s10zd = (s10_zone_data_t *)zone->zone_brand_data;
166 s10zd->s10zd_emul_version = vers;
167 }
168
169 /*ARGSUSED*/
170 int
171 s10_getattr(zone_t *zone, int attr, void *buf, size_t *bufsize)
172 {
173 int num;
174
175 ASSERT(zone->zone_brand == &s10_brand);
176 if (attr == S10_EMUL_VERSION_NUM) {
177 if (*bufsize < sizeof (int))
178 return (ERANGE);
179 num = s10_get_emul_version();
180 if (copyout(&num, buf, sizeof (int)) != 0)
181 return (EFAULT);
182 *bufsize = sizeof (int);
183 return (0);
184 }
185
186 return (EINVAL);
187 }
188
189 int
190 s10_setattr(zone_t *zone, int attr, void *buf, size_t bufsize)
191 {
192 int num;
193
194 ASSERT(zone->zone_brand == &s10_brand);
195 if (attr == S10_EMUL_VERSION_NUM) {
196 if (bufsize > sizeof (int))
197 return (ERANGE);
198 if (copyin(buf, &num, sizeof (num)) != 0)
199 return (EFAULT);
200 s10_set_emul_version(zone, num);
201 return (0);
202 }
203
204 return (EINVAL);
205 }
206
207 int
208 s10_native()
209 {
210 struct user *up = PTOU(curproc);
211 char *args_new, *comm_new, *p;
212 int len;
213
214 len = sizeof ("/.SUNWnative/lib/ld.so.1 ") - 1;
215
216 if (strcmp(up->u_comm, "ld.so.1") != 0)
217 return (0);
218 if (strncmp(up->u_psargs, "/.SUNWnative/lib/ld.so.1 /", len + 1) != 0)
219 return (0);
220
221 args_new = strdup(&up->u_psargs[len]);
222 if ((p = strchr(args_new, ' ')) != NULL)
223 *p = '\0';
224 if ((comm_new = strrchr(args_new, '/')) != NULL)
225 comm_new = strdup(comm_new + 1);
226 else
227 comm_new = strdup(args_new);
228 if (p != NULL)
229 *p = ' ';
230
231 if ((strlen(args_new) != 0) && (strlen(comm_new) != 0)) {
232 mutex_enter(&curproc->p_lock);
233 (void) strlcpy(up->u_comm, comm_new, MAXCOMLEN+1);
234 (void) strlcpy(up->u_psargs, args_new, PSARGSZ);
235 mutex_exit(&curproc->p_lock);
236 }
237
238 strfree(args_new);
239 strfree(comm_new);
240 return (0);
241 }
242
243 /*
244 * Get the address of the user-space system call handler from the user
245 * process and attach it to the proc structure.
246 */
247 /*ARGSUSED*/
248 int
249 s10_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2,
250 uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, uintptr_t arg6)
251 {
252 s10_proc_data_t *spd;
253 s10_brand_reg_t reg;
254 proc_t *p = curproc;
255 int err;
256
257 *rval = 0;
258
259 /*
260 * B_EXEC_BRAND is redundant
261 * since the kernel assumes a native process doing an exec
262 * in a branded zone is going to run a branded processes.
263 * hence we don't support this operation.
264 */
265 if (cmd == B_EXEC_BRAND)
266 return (ENOSYS);
267
268 if (cmd == B_S10_NATIVE)
269 return (s10_native());
270
271 /* For all other operations this must be a branded process. */
272 if (p->p_brand == &native_brand)
273 return (ENOSYS);
274
275 ASSERT(p->p_brand == &s10_brand);
276 ASSERT(p->p_brand_data != NULL);
277
278 spd = (s10_proc_data_t *)p->p_brand_data;
279
280 switch (cmd) {
281 case B_EXEC_NATIVE:
282 err = exec_common(
283 (char *)arg1, (const char **)arg2, (const char **)arg3,
284 EBA_NATIVE);
285 return (err);
286
287 case B_REGISTER:
288 if (p->p_model == DATAMODEL_NATIVE) {
289 if (copyin((void *)arg1, ®, sizeof (reg)) != 0)
290 return (EFAULT);
291 #if defined(_LP64)
292 } else {
293 s10_brand_reg32_t reg32;
294
295 if (copyin((void *)arg1, ®32, sizeof (reg32)) != 0)
296 return (EFAULT);
297 reg.sbr_version = reg32.sbr_version;
298 reg.sbr_handler = (caddr_t)(uintptr_t)reg32.sbr_handler;
299 #endif /* _LP64 */
300 }
301
302 if (reg.sbr_version != S10_VERSION)
303 return (ENOTSUP);
304 spd->spd_handler = reg.sbr_handler;
305 return (0);
306
307 case B_ELFDATA:
308 if (p->p_model == DATAMODEL_NATIVE) {
309 if (copyout(&spd->spd_elf_data, (void *)arg1,
310 sizeof (s10_elf_data_t)) != 0)
311 return (EFAULT);
312 #if defined(_LP64)
313 } else {
314 s10_elf_data32_t sed32;
315
316 sed32.sed_phdr = spd->spd_elf_data.sed_phdr;
317 sed32.sed_phent = spd->spd_elf_data.sed_phent;
318 sed32.sed_phnum = spd->spd_elf_data.sed_phnum;
319 sed32.sed_entry = spd->spd_elf_data.sed_entry;
320 sed32.sed_base = spd->spd_elf_data.sed_base;
321 sed32.sed_ldentry = spd->spd_elf_data.sed_ldentry;
322 sed32.sed_lddata = spd->spd_elf_data.sed_lddata;
323 if (copyout(&sed32, (void *)arg1, sizeof (sed32)) != 0)
324 return (EFAULT);
325 #endif /* _LP64 */
326 }
327 return (0);
328
329 case B_S10_PIDINFO:
330 /*
331 * The s10 brand needs to be able to get the pid of the
332 * current process and the pid of the zone's init, and it
333 * needs to do this on every process startup. Early in
334 * brand startup, we can't call getpid() because calls to
335 * getpid() represent a magical signal to some old-skool
336 * debuggers. By merging all of this into one call, we
337 * make this quite a bit cheaper and easier to handle in
338 * the brand module.
339 */
340 if (copyout(&p->p_pid, (void *)arg1, sizeof (pid_t)) != 0)
341 return (EFAULT);
342 if (copyout(&p->p_zone->zone_proc_initpid, (void *)arg2,
343 sizeof (pid_t)) != 0)
344 return (EFAULT);
345 return (0);
346
347 case B_S10_TRUSS_POINT:
348 /*
349 * This subcommand exists so that we can see truss output
350 * from interposed system calls that return without first
351 * calling any other system call, meaning they would be
352 * invisible to truss(1).
353 *
354 * If the second argument is set non-zero, set errno to that
355 * value as well.
356 *
357 * Arguments are:
358 *
359 * arg1: syscall number
360 * arg2: errno
361 */
362 return ((arg2 == 0) ? 0 : set_errno((uint_t)arg2));
363 }
364
365 return (EINVAL);
366 }
367
368 /*
369 * Copy the per-process brand data from a parent proc to a child.
370 */
371 void
372 s10_copy_procdata(proc_t *child, proc_t *parent)
373 {
374 s10_proc_data_t *spd;
375
376 ASSERT(parent->p_brand == &s10_brand);
377 ASSERT(child->p_brand == &s10_brand);
378 ASSERT(parent->p_brand_data != NULL);
379 ASSERT(child->p_brand_data == NULL);
380
381 /* Just duplicate all the proc data of the parent for the child */
382 spd = kmem_alloc(sizeof (s10_proc_data_t), KM_SLEEP);
383 bcopy(parent->p_brand_data, spd, sizeof (s10_proc_data_t));
384 child->p_brand_data = spd;
385 }
386
387 /*ARGSUSED*/
388 void
389 s10_proc_exit(struct proc *p, klwp_t *l)
390 {
391 ASSERT(p->p_brand == &s10_brand);
392 ASSERT(p->p_brand_data != NULL);
393
394 /*
395 * We should only be called from proc_exit(), when we know that
396 * process is single-threaded.
397 */
398 ASSERT(p->p_tlist == p->p_tlist->t_forw);
399
400 /* upon exit, free our lwp brand data */
401 (void) s10_freelwp(ttolwp(curthread));
402
403 /* upon exit, free our proc brand data */
404 kmem_free(p->p_brand_data, sizeof (s10_proc_data_t));
405 p->p_brand_data = NULL;
406 }
407
408 void
409 s10_exec()
410 {
411 s10_proc_data_t *spd = curproc->p_brand_data;
412
413 ASSERT(curproc->p_brand == &s10_brand);
414 ASSERT(curproc->p_brand_data != NULL);
415 ASSERT(ttolwp(curthread)->lwp_brand != NULL);
416
417 /*
418 * We should only be called from exec(), when we know the process
419 * is single-threaded.
420 */
421 ASSERT(curproc->p_tlist == curproc->p_tlist->t_forw);
422
423 /* Upon exec, reset our lwp brand data. */
424 (void) s10_freelwp(ttolwp(curthread));
425 (void) s10_initlwp(ttolwp(curthread));
426
427 /*
428 * Upon exec, reset all the proc brand data, except for the elf
429 * data associated with the executable we are exec'ing.
430 */
431 spd->spd_handler = NULL;
432 }
433
434 /*ARGSUSED*/
435 int
436 s10_initlwp(klwp_t *l)
437 {
438 ASSERT(l->lwp_procp->p_brand == &s10_brand);
439 ASSERT(l->lwp_procp->p_brand_data != NULL);
440 ASSERT(l->lwp_brand == NULL);
441 l->lwp_brand = (void *)-1;
442 return (0);
443 }
444
445 /*ARGSUSED*/
446 void
447 s10_forklwp(klwp_t *p, klwp_t *c)
448 {
449 ASSERT(p->lwp_procp->p_brand == &s10_brand);
450 ASSERT(c->lwp_procp->p_brand == &s10_brand);
451
452 ASSERT(p->lwp_procp->p_brand_data != NULL);
453 ASSERT(c->lwp_procp->p_brand_data != NULL);
454
455 /* Both LWPs have already had been initialized via s10_initlwp() */
456 ASSERT(p->lwp_brand != NULL);
457 ASSERT(c->lwp_brand != NULL);
458 }
459
460 /*ARGSUSED*/
461 void
462 s10_freelwp(klwp_t *l)
463 {
464 ASSERT(l->lwp_procp->p_brand == &s10_brand);
465 ASSERT(l->lwp_procp->p_brand_data != NULL);
466 ASSERT(l->lwp_brand != NULL);
467 l->lwp_brand = NULL;
468 }
469
470 /*ARGSUSED*/
471 void
472 s10_lwpexit(klwp_t *l)
473 {
474 proc_t *p = l->lwp_procp;
475
476 ASSERT(l->lwp_procp->p_brand == &s10_brand);
477 ASSERT(l->lwp_procp->p_brand_data != NULL);
478 ASSERT(l->lwp_brand != NULL);
479
480 /*
481 * We should never be called for the last thread in a process.
482 * (That case is handled by s10_proc_exit().) There for this lwp
483 * must be exiting from a multi-threaded process.
484 */
485 ASSERT(p->p_tlist != p->p_tlist->t_forw);
486
487 l->lwp_brand = NULL;
488 }
489
490 void
491 s10_free_brand_data(zone_t *zone)
492 {
493 kmem_free(zone->zone_brand_data, sizeof (s10_zone_data_t));
494 }
495
496 void
497 s10_init_brand_data(zone_t *zone)
498 {
499 s10_zone_data_t *data;
500 ASSERT(zone->zone_brand == &s10_brand);
501 ASSERT(zone->zone_brand_data == NULL);
502 data = (s10_zone_data_t *)kmem_zalloc(sizeof (s10_zone_data_t),
503 KM_SLEEP);
504 /*
505 * Initialize the default s10zd_emul_version to S10_EMUL_UNDEF.
506 * This can be changed by a call to setattr() during zone boot.
507 */
508 data->s10zd_emul_version = S10_EMUL_UNDEF;
509 zone->zone_brand_data = data;
510 }
511
512 #if defined(_LP64)
513 static void
514 Ehdr32to64(Elf32_Ehdr *src, Ehdr *dst)
515 {
516 bcopy(src->e_ident, dst->e_ident, sizeof (src->e_ident));
517 dst->e_type = src->e_type;
518 dst->e_machine = src->e_machine;
519 dst->e_version = src->e_version;
520 dst->e_entry = src->e_entry;
521 dst->e_phoff = src->e_phoff;
522 dst->e_shoff = src->e_shoff;
523 dst->e_flags = src->e_flags;
524 dst->e_ehsize = src->e_ehsize;
525 dst->e_phentsize = src->e_phentsize;
526 dst->e_phnum = src->e_phnum;
527 dst->e_shentsize = src->e_shentsize;
528 dst->e_shnum = src->e_shnum;
529 dst->e_shstrndx = src->e_shstrndx;
530 }
531 #endif /* _LP64 */
532
533 int
534 s10_elfexec(vnode_t *vp, execa_t *uap, uarg_t *args, intpdata_t *idatap,
535 int level, long *execsz, int setid, caddr_t exec_file, cred_t *cred,
536 int brand_action)
537 {
538 vnode_t *nvp;
539 Ehdr ehdr;
540 Addr uphdr_vaddr;
541 intptr_t voffset;
542 int interp;
543 int i, err;
544 struct execenv env;
545 struct user *up = PTOU(curproc);
546 s10_proc_data_t *spd;
547 s10_elf_data_t sed, *sedp;
548 char *linker;
549 uintptr_t lddata; /* lddata of executable's linker */
550
551 ASSERT(curproc->p_brand == &s10_brand);
552 ASSERT(curproc->p_brand_data != NULL);
553
554 spd = (s10_proc_data_t *)curproc->p_brand_data;
555 sedp = &spd->spd_elf_data;
556
557 args->brandname = S10_BRANDNAME;
558
559 /*
560 * We will exec the brand library and then map in the target
561 * application and (optionally) the brand's default linker.
562 */
563 if (args->to_model == DATAMODEL_NATIVE) {
564 args->emulator = S10_LIB;
565 linker = S10_LINKER;
566 #if defined(_LP64)
567 } else {
568 args->emulator = S10_LIB32;
569 linker = S10_LINKER32;
570 #endif /* _LP64 */
571 }
572
573 if ((err = lookupname(args->emulator, UIO_SYSSPACE, FOLLOW, NULLVPP,
574 &nvp)) != 0) {
575 uprintf("%s: not found.", args->emulator);
576 return (err);
577 }
578
579 if (args->to_model == DATAMODEL_NATIVE) {
580 err = elfexec(nvp, uap, args, idatap, level + 1, execsz,
581 setid, exec_file, cred, brand_action);
582 #if defined(_LP64)
583 } else {
584 err = elf32exec(nvp, uap, args, idatap, level + 1, execsz,
585 setid, exec_file, cred, brand_action);
586 #endif /* _LP64 */
587 }
588 VN_RELE(nvp);
589 if (err != 0)
590 return (err);
591
592 /*
593 * The u_auxv vectors are set up by elfexec to point to the brand
594 * emulation library and linker. Save these so they can be copied to
595 * the specific brand aux vectors.
596 */
597 bzero(&sed, sizeof (sed));
598 for (i = 0; i < __KERN_NAUXV_IMPL; i++) {
599 switch (up->u_auxv[i].a_type) {
600 case AT_SUN_LDDATA:
601 sed.sed_lddata = up->u_auxv[i].a_un.a_val;
602 break;
603 case AT_BASE:
604 sed.sed_base = up->u_auxv[i].a_un.a_val;
605 break;
606 case AT_ENTRY:
607 sed.sed_entry = up->u_auxv[i].a_un.a_val;
608 break;
609 case AT_PHDR:
610 sed.sed_phdr = up->u_auxv[i].a_un.a_val;
611 break;
612 case AT_PHENT:
613 sed.sed_phent = up->u_auxv[i].a_un.a_val;
614 break;
615 case AT_PHNUM:
616 sed.sed_phnum = up->u_auxv[i].a_un.a_val;
617 break;
618 default:
619 break;
620 }
621 }
622 /* Make sure the emulator has an entry point */
623 ASSERT(sed.sed_entry != NULL);
624 ASSERT(sed.sed_phdr != NULL);
625
626 bzero(&env, sizeof (env));
627 if (args->to_model == DATAMODEL_NATIVE) {
628 err = mapexec_brand(vp, args, &ehdr, &uphdr_vaddr, &voffset,
629 exec_file, &interp, &env.ex_bssbase, &env.ex_brkbase,
630 &env.ex_brksize, NULL);
631 #if defined(_LP64)
632 } else {
633 Elf32_Ehdr ehdr32;
634 Elf32_Addr uphdr_vaddr32;
635 err = mapexec32_brand(vp, args, &ehdr32, &uphdr_vaddr32,
636 &voffset, exec_file, &interp, &env.ex_bssbase,
637 &env.ex_brkbase, &env.ex_brksize, NULL);
638 Ehdr32to64(&ehdr32, &ehdr);
639 if (uphdr_vaddr32 == (Elf32_Addr)-1)
640 uphdr_vaddr = (Addr)-1;
641 else
642 uphdr_vaddr = uphdr_vaddr32;
643 #endif /* _LP64 */
644 }
645 if (err != 0)
646 return (err);
647
648 /*
649 * Save off the important properties of the executable. The brand
650 * library will ask us for this data later, when it is initializing
651 * and getting ready to transfer control to the brand application.
652 */
653 if (uphdr_vaddr == (Addr)-1)
654 sedp->sed_phdr = voffset + ehdr.e_phoff;
655 else
656 sedp->sed_phdr = voffset + uphdr_vaddr;
657 sedp->sed_entry = voffset + ehdr.e_entry;
658 sedp->sed_phent = ehdr.e_phentsize;
659 sedp->sed_phnum = ehdr.e_phnum;
660
661 if (interp) {
662 if (ehdr.e_type == ET_DYN) {
663 /*
664 * This is a shared object executable, so we need to
665 * pick a reasonable place to put the heap. Just don't
666 * use the first page.
667 */
668 env.ex_brkbase = (caddr_t)PAGESIZE;
669 env.ex_bssbase = (caddr_t)PAGESIZE;
670 }
671
672 /*
673 * If the program needs an interpreter (most do), map it in and
674 * store relevant information about it in the aux vector, where
675 * the brand library can find it.
676 */
677 if ((err = lookupname(linker, UIO_SYSSPACE,
678 FOLLOW, NULLVPP, &nvp)) != 0) {
679 uprintf("%s: not found.", S10_LINKER);
680 return (err);
681 }
682 if (args->to_model == DATAMODEL_NATIVE) {
683 err = mapexec_brand(nvp, args, &ehdr,
684 &uphdr_vaddr, &voffset, exec_file, &interp,
685 NULL, NULL, NULL, &lddata);
686 #if defined(_LP64)
687 } else {
688 Elf32_Ehdr ehdr32;
689 Elf32_Addr uphdr_vaddr32;
690 err = mapexec32_brand(nvp, args, &ehdr32,
691 &uphdr_vaddr32, &voffset, exec_file, &interp,
692 NULL, NULL, NULL, &lddata);
693 Ehdr32to64(&ehdr32, &ehdr);
694 if (uphdr_vaddr32 == (Elf32_Addr)-1)
695 uphdr_vaddr = (Addr)-1;
696 else
697 uphdr_vaddr = uphdr_vaddr32;
698 #endif /* _LP64 */
699 }
700 VN_RELE(nvp);
701 if (err != 0)
702 return (err);
703
704 /*
705 * Now that we know the base address of the brand's linker,
706 * place it in the aux vector.
707 */
708 sedp->sed_base = voffset;
709 sedp->sed_ldentry = voffset + ehdr.e_entry;
710 sedp->sed_lddata = voffset + lddata;
711 } else {
712 /*
713 * This program has no interpreter. The brand library will
714 * jump to the address in the AT_SUN_BRAND_LDENTRY aux vector,
715 * so in this case, put the entry point of the main executable
716 * there.
717 */
718 if (ehdr.e_type == ET_EXEC) {
719 /*
720 * An executable with no interpreter, this must be a
721 * statically linked executable, which means we loaded
722 * it at the address specified in the elf header, in
723 * which case the e_entry field of the elf header is an
724 * absolute address.
725 */
726 sedp->sed_ldentry = ehdr.e_entry;
727 sedp->sed_entry = ehdr.e_entry;
728 sedp->sed_lddata = NULL;
729 sedp->sed_base = NULL;
730 } else {
731 /*
732 * A shared object with no interpreter, we use the
733 * calculated address from above.
734 */
735 sedp->sed_ldentry = sedp->sed_entry;
736 sedp->sed_lddata = NULL;
737 sedp->sed_base = NULL;
738 }
739 }
740
741 if (uphdr_vaddr != (Addr)-1) {
742 if (ehdr.e_type == ET_DYN) {
743 /*
744 * Delay setting the brkbase until the first call to
745 * brk(); see elfexec() for details.
746 */
747 env.ex_bssbase = (caddr_t)0;
748 env.ex_brkbase = (caddr_t)0;
749 env.ex_brksize = 0;
750 }
751 }
752
753 env.ex_magic = elfmagic;
754 env.ex_vp = vp;
755 setexecenv(&env);
756
757 /*
758 * It's time to manipulate the process aux vectors. First
759 * we need to update the AT_SUN_AUXFLAGS aux vector to set
760 * the AF_SUN_NOPLM flag.
761 */
762 if (args->to_model == DATAMODEL_NATIVE) {
763 auxv_t auxflags_auxv;
764
765 if (copyin(args->auxp_auxflags, &auxflags_auxv,
766 sizeof (auxflags_auxv)) != 0)
767 return (EFAULT);
768
769 ASSERT(auxflags_auxv.a_type == AT_SUN_AUXFLAGS);
770 auxflags_auxv.a_un.a_val |= AF_SUN_NOPLM;
771 if (copyout(&auxflags_auxv, args->auxp_auxflags,
772 sizeof (auxflags_auxv)) != 0)
773 return (EFAULT);
774 #if defined(_LP64)
775 } else {
776 auxv32_t auxflags_auxv32;
777
778 if (copyin(args->auxp_auxflags, &auxflags_auxv32,
779 sizeof (auxflags_auxv32)) != 0)
780 return (EFAULT);
781
782 ASSERT(auxflags_auxv32.a_type == AT_SUN_AUXFLAGS);
783 auxflags_auxv32.a_un.a_val |= AF_SUN_NOPLM;
784 if (copyout(&auxflags_auxv32, args->auxp_auxflags,
785 sizeof (auxflags_auxv32)) != 0)
786 return (EFAULT);
787 #endif /* _LP64 */
788 }
789
790 /* Second, copy out the brand specific aux vectors. */
791 if (args->to_model == DATAMODEL_NATIVE) {
792 auxv_t s10_auxv[] = {
793 { AT_SUN_BRAND_AUX1, 0 },
794 { AT_SUN_BRAND_AUX2, 0 },
795 { AT_SUN_BRAND_AUX3, 0 }
796 };
797
798 ASSERT(s10_auxv[0].a_type == AT_SUN_BRAND_S10_LDDATA);
799 s10_auxv[0].a_un.a_val = sed.sed_lddata;
800
801 if (copyout(&s10_auxv, args->auxp_brand,
802 sizeof (s10_auxv)) != 0)
803 return (EFAULT);
804 #if defined(_LP64)
805 } else {
806 auxv32_t s10_auxv32[] = {
807 { AT_SUN_BRAND_AUX1, 0 },
808 { AT_SUN_BRAND_AUX2, 0 },
809 { AT_SUN_BRAND_AUX3, 0 }
810 };
811
812 ASSERT(s10_auxv32[0].a_type == AT_SUN_BRAND_S10_LDDATA);
813 s10_auxv32[0].a_un.a_val = (uint32_t)sed.sed_lddata;
814 if (copyout(&s10_auxv32, args->auxp_brand,
815 sizeof (s10_auxv32)) != 0)
816 return (EFAULT);
817 #endif /* _LP64 */
818 }
819
820 /*
821 * Third, the the /proc aux vectors set up by elfexec() point to brand
822 * emulation library and it's linker. Copy these to the /proc brand
823 * specific aux vector, and update the regular /proc aux vectors to
824 * point to the executable (and it's linker). This will enable
825 * debuggers to access the executable via the usual /proc or elf notes
826 * aux vectors.
827 *
828 * The brand emulation library's linker will get it's aux vectors off
829 * the stack, and then update the stack with the executable's aux
830 * vectors before jumping to the executable's linker.
831 *
832 * Debugging the brand emulation library must be done from
833 * the global zone, where the librtld_db module knows how to fetch the
834 * brand specific aux vectors to access the brand emulation libraries
835 * linker.
836 */
837 for (i = 0; i < __KERN_NAUXV_IMPL; i++) {
838 switch (up->u_auxv[i].a_type) {
839 case AT_SUN_BRAND_S10_LDDATA:
840 up->u_auxv[i].a_un.a_val = sed.sed_lddata;
841 break;
842 case AT_BASE:
843 if (sedp->sed_base == NULL) {
844 /* Hide base for static binaries */
845 up->u_auxv[i].a_type = AT_IGNORE;
846 up->u_auxv[i].a_un.a_val = NULL;
847 } else {
848 up->u_auxv[i].a_un.a_val = sedp->sed_base;
849 }
850 break;
851 case AT_ENTRY:
852 up->u_auxv[i].a_un.a_val = sedp->sed_entry;
853 break;
854 case AT_PHDR:
855 up->u_auxv[i].a_un.a_val = sedp->sed_phdr;
856 break;
857 case AT_PHENT:
858 up->u_auxv[i].a_un.a_val = sedp->sed_phent;
859 break;
860 case AT_PHNUM:
861 up->u_auxv[i].a_un.a_val = sedp->sed_phnum;
862 break;
863 case AT_SUN_LDDATA:
864 if (sedp->sed_lddata == NULL) {
865 /* Hide lddata for static binaries */
866 up->u_auxv[i].a_type = AT_IGNORE;
867 up->u_auxv[i].a_un.a_val = NULL;
868 } else {
869 up->u_auxv[i].a_un.a_val = sedp->sed_lddata;
870 }
871 break;
872 default:
873 break;
874 }
875 }
876
877 /*
878 * The last thing we do here is clear spd->spd_handler. This is
879 * important because if we're already a branded process and if this
880 * exec succeeds, there is a window between when the exec() first
881 * returns to the userland of the new process and when our brand
882 * library get's initialized, during which we don't want system
883 * calls to be re-directed to our brand library since it hasn't
884 * been initialized yet.
885 */
886 spd->spd_handler = NULL;
887
888 return (0);
889 }
890
891
892 int
893 _init(void)
894 {
895 int err;
896
897 /*
898 * Set up the table indicating which system calls we want to
899 * interpose on. We should probably build this automatically from
900 * a list of system calls that is shared with the user-space
901 * library.
902 */
903 s10_emulation_table = kmem_zalloc(NSYSCALL, KM_SLEEP);
904 s10_emulation_table[SYS_exec] = 1; /* 11 */
905 s10_emulation_table[SYS_ioctl] = 1; /* 54 */
906 s10_emulation_table[SYS_execve] = 1; /* 59 */
907 s10_emulation_table[SYS_acctctl] = 1; /* 71 */
908 s10_emulation_table[SYS_getpagesizes] = 1; /* 73 */
909 s10_emulation_table[S10_SYS_issetugid] = 1; /* 75 */
910 s10_emulation_table[SYS_uname] = 1; /* 135 */
911 s10_emulation_table[SYS_pwrite] = 1; /* 174 */
912 s10_emulation_table[SYS_sigqueue] = 1; /* 190 */
913 s10_emulation_table[SYS_pwrite64] = 1; /* 223 */
914 s10_emulation_table[SYS_zone] = 1; /* 227 */
915
916 err = mod_install(&modlinkage);
917 if (err) {
918 cmn_err(CE_WARN, "Couldn't install brand module");
919 kmem_free(s10_emulation_table, NSYSCALL);
920 }
921
922 return (err);
923 }
924
925 int
926 _info(struct modinfo *modinfop)
927 {
928 return (mod_info(&modlinkage, modinfop));
929 }
930
931 int
932 _fini(void)
933 {
934 int err;
935
936 /*
937 * If there are any zones using this brand, we can't allow it to be
938 * unloaded.
939 */
940 if (brand_zone_count(&s10_brand))
941 return (EBUSY);
942
943 kmem_free(s10_emulation_table, NSYSCALL);
944 s10_emulation_table = NULL;
945
946 err = mod_remove(&modlinkage);
947 if (err)
948 cmn_err(CE_WARN, "Couldn't unload s10 brand module");
949
950 return (err);
951 }