180e2ca85S /*
380e2ca85S  *
480e2ca85S  * The contents of this file are subject to the terms of the
580e2ca85S  * Common Development and Distribution License (the "License").
680e2ca85S  * You may not use this file except in compliance with the License.
780e2ca85S  *
880e2ca85S  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
980e2ca85S  * or http://www.opensolaris.org/os/licensing.
1080e2ca85S  * See the License for the specific language governing permissions
1180e2ca85S  * and limitations under the License.
1280e2ca85S  *
1380e2ca85S  * When distributing Covered Code, include this CDDL HEADER in each
1480e2ca85S  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1580e2ca85S  * If applicable, add the following below this CDDL HEADER, with the
1680e2ca85S  * fields enclosed by brackets "[]" replaced with your own identifying
1780e2ca85S  * information: Portions Copyright [yyyy] [name of copyright owner]
1880e2ca85S  *
1980e2ca85S  * CDDL HEADER END
2080e2ca85S  */
2280e2ca85S /*
2380e2ca85S  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
2480e2ca85S  */
2680e2ca85S #include <errno.h>
2780e2ca85S #include <stdio.h>
2880e2ca85S #include <stdlib.h>
2980e2ca85S #include <strings.h>
3080e2ca85S #include <unistd.h>
3180e2ca85S #include <sys/auxv.h>
3280e2ca85S #include <sys/bitmap.h>
3380e2ca85S #include <sys/brand.h>
3480e2ca85S #include <sys/inttypes.h>
3580e2ca85S #include <sys/lwp.h>
3680e2ca85S #include <sys/syscall.h>
3780e2ca85S #include <sys/systm.h>
3880e2ca85S #include <sys/utsname.h>
3980e2ca85S #include <fcntl.h>
4080e2ca85S #include <brand_misc.h>
4180e2ca85S #include <sys/brand.h>
4380e2ca85S extern brand_sysent_table_t brand_sysent_table[];
4580e2ca85S /*LINTED: static unused*/
4680e2ca85S static volatile int		brand_abort_err;
4780e2ca85S /*LINTED: static unused*/
4880e2ca85S static volatile const char	*brand_abort_msg;
4980e2ca85S /*LINTED: static unused*/
5080e2ca85S static volatile const char	*brand_abort_file;
5180e2ca85S /*LINTED: static unused*/
5280e2ca85S static volatile int		brand_abort_line;
5480e2ca85S /*
5580e2ca85S  * Principles of emulation 101.
5680e2ca85S  *
5780e2ca85S  *
5880e2ca85S  * *** Setting errno
5980e2ca85S  *
6080e2ca85S  * Just don't do it.  This emulation library is loaded onto a
6180e2ca85S  * seperate link map from the application who's address space we're
6280e2ca85S  * running in.  We have our own private copy of libc, so there for,
6380e2ca85S  * the errno value accessible from here is is also private and changing
6480e2ca85S  * it will not affect any errno value that the processes who's address
6580e2ca85S  * space we are running in will see.  To return an error condition we
6680e2ca85S  * should return the errno value we'd like the system to return.
6780e2ca85S  * For more information about this see the comments in brand_misc.h.
6880e2ca85S  * Basically, when we return to the caller that initiated the system
6980e2ca85S  * call it's their responsibility to set errno.
7080e2ca85S  *
7180e2ca85S  *
7280e2ca85S  * *** Recursion Considerations
7380e2ca85S  *
7480e2ca85S  * When emulating system calls we need to be very careful about what
7580e2ca85S  * library calls we invoke.  Library calls should be kept to a minimum.
7680e2ca85S  * One issue is that library calls can invoke system calls, so if we're
7780e2ca85S  * emulating a system call and we invoke a library call that depends on
7880e2ca85S  * that system call we will probably enter a recursive loop, which would
7980e2ca85S  * be bad.
8080e2ca85S  *
8180e2ca85S  *
8280e2ca85S  * *** Return Values.
8380e2ca85S  *
8480e2ca85S  * See brand_misc.h.
8580e2ca85S  *
8680e2ca85S  * *** Agent lwp considerations
8780e2ca85S  *
8880e2ca85S  * It is currently impossible to do any emulation for these system call
8980e2ca85S  * when they are being invoked on behalf of an agent lwp.  To understand why
9080e2ca85S  * it's impossible you have to understand how agent lwp syscalls work.
9180e2ca85S  *
9280e2ca85S  * The agent lwp syscall process works as follows:
9380e2ca85S  *   1  The controlling process stops the target.
9480e2ca85S  *   2  The controlling process injects an agent lwp which is also stopped.
9580e2ca85S  *      This agent lwp assumes the userland stack and register values
9680e2ca85S  *      of another stopped lwp in the current process.
9780e2ca85S  *   3  The controlling process configures the agent lwp to start
9880e2ca85S  *      executing the requested system call.
9980e2ca85S  *   4  The controlling process configure /proc to stop the agent lwp when
10080e2ca85S  *      it enters the requested system call.
10180e2ca85S  *   5  The controlling processes allows the agent lwp to start executing.
10280e2ca85S  *   6  The agent lwp traps into the kernel to perform the requested system
10380e2ca85S  *      call and immediately stop.
10480e2ca85S  *   7  The controlling process copies all the arguments for the requested
10580e2ca85S  *      system call onto the agent lwp's stack.
10680e2ca85S  *   8  The controlling process configures /proc to stop the agent lwp
10780e2ca85S  *      when it completes the requested system call.
10880e2ca85S  *   9  The controlling processes allows the agent lwp to start executing.
10980e2ca85S  *  10  The agent lwp executes the system call and then stop before returning
11080e2ca85S  *      to userland.
11180e2ca85S  *  11  The controlling process copies the return value and return arguments
11280e2ca85S  *      back from the agent lwps stack.
11380e2ca85S  *  12  The controlling process destroys the agent lwp and restarts
11480e2ca85S  *      the target process.
11580e2ca85S  *
11680e2ca85S  * The fundamental problem is that when the agent executes the request
11780e2ca85S  * system call in step 5, if we're emulating that system call then the
11880e2ca85S  * lwp is redirected back to our emulation layer without blocking
11980e2ca85S  * in the kernel.  But our emulation layer can't access the arguments
12080e2ca85S  * for the system call because they haven't been copied to the stack
12180e2ca85S  * yet and they still only exist in the controlling processes address
12280e2ca85S  * space.  This prevents us from being able to do any emulation of
12380e2ca85S  * agent lwp system calls.  Hence, currently our brand trap interposition
12480e2ca85S  * callback (XXX_brand_syscall_callback_common) will detect if a system
12580e2ca85S  * call is being made by an agent lwp, and if this is the case it will
12680e2ca85S  * never redirect the system call to this emulation library.
12780e2ca85S  *
12880e2ca85S  * In the future, if this proves to be a problem the the easiest solution
12980e2ca85S  * would probably be to replace the branded versions of these application
13080e2ca85S  * with their native counterparts.  Ie,  truss, plimit, and pfiles could be
13180e2ca85S  * replace with wrapper scripts that execute the native versions of these
13280e2ca85S  * applications.  In the case of plimit and pfiles this should be pretty
13380e2ca85S  * strait forward.  Truss would probably be more tricky since it can
13480e2ca85S  * execute applications which would be branded applications, so in that
13580e2ca85S  * case it might be necessary to create a loadable library which could
13680e2ca85S  * be LD_PRELOADed into truss and this library would interpose on the
13780e2ca85S  * exec() system call to allow truss to correctly execute branded
13880e2ca85S  * processes.  It should be pointed out that this solution could work
13980e2ca85S  * because "native agent lwps" (ie, agent lwps created by native
14080e2ca85S  * processes) can be treated differently from "branded aged lwps" (ie,
14180e2ca85S  * agent lwps created by branded processes), since native agent lwps
14280e2ca85S  * would presumably be making native system calls and hence not need
14380e2ca85S  * any interposition.
14480e2ca85S  *
14580e2ca85S  * *** General considerations
14680e2ca85S  *
14780e2ca85S  * One of the differences between the lx brand and the s10
14880e2ca85S  * brand, is that the s10 brand only interposes on syscalls
14980e2ca85S  * that need some kind of emulation, whereas the lx brand interposes
15080e2ca85S  * on _all_ system calls.  Lx branded system calls that don't need
15180e2ca85S  * any emulation are then redirected back to the kernel from the
15280e2ca85S  * userland library via the IN_KERNEL_SYSCALL macro.  The lx-syscall
15380e2ca85S  * dtrace provider depends on this behavior.
15480e2ca85S  *
15580e2ca85S  */
15780e2ca85S /*ARGSUSED*/
15880e2ca85S void
_brand_abort(int err,const char * msg,const char * file,int line)15980e2ca85S _brand_abort(int err, const char *msg, const char *file, int line)
16080e2ca85S {
16180e2ca85S 	sysret_t rval;
16380e2ca85S 	/* Save the error message into convenient globals */
16480e2ca85S 	brand_abort_err = err;
16580e2ca85S 	brand_abort_msg = msg;
16680e2ca85S 	brand_abort_file = file;
16780e2ca85S 	brand_abort_line = line;
16980e2ca85S 	/* kill ourselves */
17080e2ca85S 	abort();
17280e2ca85S 	/* If abort() didn't work, try something stronger. */
17380e2ca85S 	(void) __systemcall(&rval, SYS_lwp_kill + 1024, _lwp_self(), SIGKILL);
17480e2ca85S }
17680e2ca85S int
brand_uucopy(const void * from,void * to,size_t size)17780e2ca85S brand_uucopy(const void *from, void *to, size_t size)
17880e2ca85S {
17980e2ca85S 	sysret_t rval;
18180e2ca85S 	if (__systemcall(&rval, SYS_uucopy + 1024, from, to, size) != 0)