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, &reg, sizeof (reg)) != 0)
 290                                 return (EFAULT);
 291 #if defined(_LP64)
 292                 } else {
 293                         s10_brand_reg32_t reg32;
 294 
 295                         if (copyin((void *)arg1, &reg32, 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 }