180e2ca85S /*
280e2ca85S  * CDDL HEADER START
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  */
2180e2ca85S 
2280e2ca85S /*
2380e2ca85S  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
2480e2ca85S  */
2580e2ca85S 
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>
4280e2ca85S 
4380e2ca85S extern brand_sysent_table_t brand_sysent_table[];
4480e2ca85S 
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;
5380e2ca85S 
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  */
15680e2ca85S 
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;
16280e2ca85S 
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;
16880e2ca85S 
16980e2ca85S 	/* kill ourselves */
17080e2ca85S 	abort();
17180e2ca85S 
17280e2ca85S 	/* If abort() didn't work, try something stronger. */
17380e2ca85S 	(void) __systemcall(&rval, SYS_lwp_kill + 1024, _lwp_self(), SIGKILL);
17480e2ca85S }
17580e2ca85S 
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;
18080e2ca85S 
18180e2ca85S 	if (__systemcall(&rval, SYS_uucopy + 1024, from, to, size) != 0)
18280e2ca85S 		return (EFAULT);
18380e2ca85S 	return (0);
18480e2ca85S }
18580e2ca85S 
18680e2ca85S /*
18780e2ca85S  * ATTENTION: uucopystr() does NOT ensure that string are null terminated!
18880e2ca85S  */
18980e2ca85S int
brand_uucopystr(const void * from,void * to,size_t size)19080e2ca85S brand_uucopystr(const void *from, void *to, size_t size)
19180e2ca85S {
19280e2ca85S 	sysret_t rval;
19380e2ca85S 
19480e2ca85S 	if (__systemcall(&rval, SYS_uucopystr + 1024, from, to, size) != 0)
19580e2ca85S 		return (EFAULT);
19680e2ca85S 	return (0);
19780e2ca85S }
19880e2ca85S 
19980e2ca85S /*
20080e2ca85S  * This function is defined to be NOSYS but it won't be called from the
20180e2ca85S  * the kernel since the NOSYS system calls are not enabled in the kernel.
20280e2ca85S  * Thus, the only time this function is called is directly from within the
20380e2ca85S  * indirect system call path.
20480e2ca85S  */
20580e2ca85S /*ARGSUSED*/
20680e2ca85S long
brand_unimpl(sysret_t * rv,uintptr_t p1)20780e2ca85S brand_unimpl(sysret_t *rv, uintptr_t p1)
20880e2ca85S {
20980e2ca85S 	sysret_t rval;
21080e2ca85S 
21180e2ca85S 	/*
21280e2ca85S 	 * We'd like to print out some kind of error message here like
21380e2ca85S 	 * "unsupported syscall", but we can't because it's not safe to
21480e2ca85S 	 * assume that stderr or STDERR_FILENO actually points to something
21580e2ca85S 	 * that is a terminal, and if we wrote to those files we could
21680e2ca85S 	 * inadvertantly write to some applications open files, which would
21780e2ca85S 	 * be bad.
21880e2ca85S 	 *
21980e2ca85S 	 * Normally, if an application calls an invalid system call
22080e2ca85S 	 * it get a SIGSYS sent to it.  So we'll just go ahead and send
22180e2ca85S 	 * ourselves a signal here.  Note that this is far from ideal since
22280e2ca85S 	 * if the application has registered a signal handler, that signal
22380e2ca85S 	 * handler may recieve a ucontext_t as the third parameter to
22480e2ca85S 	 * indicate the context of the process when the signal was
22580e2ca85S 	 * generated, and in this case that context will not be what the
22680e2ca85S 	 * application is expecting.  Hence, we should probably create a
22780e2ca85S 	 * brandsys() kernel function that can deliver the signal to us
22880e2ca85S 	 * with the correct ucontext_t.
22980e2ca85S 	 */
23080e2ca85S 	(void) __systemcall(&rval, SYS_lwp_kill + 1024, _lwp_self(), SIGSYS);
23180e2ca85S 	return (ENOSYS);
23280e2ca85S }
23380e2ca85S 
23480e2ca85S #if defined(__sparc) && !defined(__sparcv9)
23580e2ca85S /*
23680e2ca85S  * Yuck.  For 32-bit sparc applications, handle indirect system calls.
23780e2ca85S  * Note that we declare this interface to use the maximum number of
23880e2ca85S  * system call arguments.  If we recieve a system call that uses less
23980e2ca85S  * arguments, then the additional arguments will be garbage, but they
24080e2ca85S  * will also be ignored so that should be ok.
24180e2ca85S  */
24280e2ca85S long
brand_indir(sysret_t * rv,int code,uintptr_t a0,uintptr_t a1,uintptr_t a2,uintptr_t a3,uintptr_t a4,uintptr_t a5,uintptr_t a6,uintptr_t a7)24380e2ca85S brand_indir(sysret_t *rv, int code,
24480e2ca85S     uintptr_t a0, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4,
24580e2ca85S     uintptr_t a5, uintptr_t a6, uintptr_t a7)
24680e2ca85S {
24780e2ca85S 	brand_sysent_table_t *sst = &(brand_sysent_table[code]);
24880e2ca85S 
24980e2ca85S 	brand_assert(code < NSYSCALL);
25080e2ca85S 	switch (sst->st_args & NARGS_MASK) {
25180e2ca85S 	case 0:
25280e2ca85S 		return ((sst->st_callc)(rv));
25380e2ca85S 	case 1:
25480e2ca85S 		return ((sst->st_callc)(rv, a0));
25580e2ca85S 	case 2:
25680e2ca85S 		return ((sst->st_callc)(rv, a0, a1));
25780e2ca85S 	case 3:
25880e2ca85S 		return ((sst->st_callc)(rv, a0, a1, a2));
25980e2ca85S 	case 4:
26080e2ca85S 		return ((sst->st_callc)(rv, a0, a1, a2, a3));
26180e2ca85S 	case 5:
26280e2ca85S 		return ((sst->st_callc)(rv, a0, a1, a2, a3, a4));
26380e2ca85S 	case 6:
26480e2ca85S 		return ((sst->st_callc)(rv, a0, a1, a2, a3, a4, a5));
26580e2ca85S 	case 7:
26680e2ca85S 		return ((sst->st_callc)(rv, a0, a1, a2, a3, a4, a5, a6));
26780e2ca85S 	case 8:
26880e2ca85S 		return ((sst->st_callc)(rv, a0, a1, a2, a3, a4, a5, a6, a7));
26980e2ca85S 	}
27080e2ca85S 	brand_abort(0, "invalid entry in brand_sysent_table");
27180e2ca85S 	return (EINVAL);
27280e2ca85S }
27380e2ca85S #endif /* __sparc && !__sparcv9 */
27480e2ca85S 
27580e2ca85S /*
27680e2ca85S  * Close a libc file handle, but don't actually close the underlying
27780e2ca85S  * file descriptor.
27880e2ca85S  */
27980e2ca85S static void
brand_close_fh(FILE * file)28080e2ca85S brand_close_fh(FILE *file)
28180e2ca85S {
28280e2ca85S 	int fd, fd_new;
28380e2ca85S 
28480e2ca85S 	if (file == NULL)
28580e2ca85S 		return;
28680e2ca85S 
28780e2ca85S 	if ((fd = fileno(file)) < 0)
28880e2ca85S 		return;
28980e2ca85S 
29080e2ca85S 	/*
29180e2ca85S 	 * We're a branded process but our handler isn't installed yet.  We
29280e2ca85S 	 * can't use the dup() syscall since it no longer exists.
29380e2ca85S 	 */
29480e2ca85S 	fd_new = fcntl(fd, F_DUPFD, 0);
29580e2ca85S 	if (fd_new == -1)
29680e2ca85S 		return;
29780e2ca85S 
29880e2ca85S 	(void) fclose(file);
29980e2ca85S 	(void) dup2(fd_new, fd);
30080e2ca85S 	(void) close(fd_new);
30180e2ca85S }
30280e2ca85S 
30380e2ca85S /*ARGSUSED*/
30480e2ca85S void
brand_pre_init()30580e2ca85S brand_pre_init()
30680e2ca85S {
30780e2ca85S 	int			i;
30880e2ca85S 
30980e2ca85S 	/* Sanity check our translation table return value codes */
31080e2ca85S 	for (i = 0; i < NSYSCALL; i++) {
31180e2ca85S 		brand_sysent_table_t *est = &(brand_sysent_table[i]);
31280e2ca85S 		brand_assert(BIT_ONLYONESET(est->st_args & RV_MASK));
31380e2ca85S 	}
31480e2ca85S 
31580e2ca85S 	/*
31680e2ca85S 	 * We need to shutdown all libc stdio.  libc stdio normally goes to
31780e2ca85S 	 * file descriptors, but since we're actually part of a another
31880e2ca85S 	 * process we don't own these file descriptors and we can't make
31980e2ca85S 	 * any assumptions about their state.
32080e2ca85S 	 */
32180e2ca85S 	brand_close_fh(stdin);
32280e2ca85S 	brand_close_fh(stdout);
32380e2ca85S 	brand_close_fh(stderr);
32480e2ca85S }
32580e2ca85S 
32680e2ca85S /*ARGSUSED*/
32780e2ca85S ulong_t
brand_post_init(int version,int argc,char * argv[],char * envp[])32880e2ca85S brand_post_init(int version, int argc, char *argv[], char *envp[])
32980e2ca85S {
33080e2ca85S 	sysret_t		rval;
33180e2ca85S 	brand_proc_reg_t	reg;
33280e2ca85S 	brand_elf_data_t	sed;
33380e2ca85S 	auxv_t			*ap;
33480e2ca85S 	uintptr_t		*p;
33580e2ca85S 	int			err;
33680e2ca85S 
33780e2ca85S 	/*
33880e2ca85S 	 * Register our syscall emulation table with the kernel.
33980e2ca85S 	 * Note that we don't have to do invoke (syscall_number + 1024)
34080e2ca85S 	 * until we've actually establised a syscall emulation callback
34180e2ca85S 	 * handler address, which is what we're doing with this brand
34280e2ca85S 	 * syscall.
34380e2ca85S 	 */
34480e2ca85S 	reg.sbr_version = version;
34580e2ca85S #ifdef	__x86
34680e2ca85S 	reg.sbr_handler = (caddr_t)brand_handler_table;
34780e2ca85S #else	/* !__x86 */
34880e2ca85S 	reg.sbr_handler = (caddr_t)brand_handler;
34980e2ca85S #endif	/* !__x86 */
35080e2ca85S 
35180e2ca85S 	if ((err = __systemcall(&rval, SYS_brand, B_REGISTER, &reg)) != 0) {
35280e2ca85S 		brand_abort(err, "Failed to brand current process");
35380e2ca85S 
35480e2ca85S 		/*NOTREACHED*/
35580e2ca85S 	}
35680e2ca85S 
35780e2ca85S 	/* Get data about the executable we're running from the kernel. */
35880e2ca85S 	if ((err = __systemcall(&rval, SYS_brand + 1024,
35980e2ca85S 	    B_ELFDATA, (void *)&sed)) != 0) {
36080e2ca85S 		brand_abort(err,
36180e2ca85S 		    "Failed to get required brand ELF data from the kernel");
36280e2ca85S 		/*NOTREACHED*/
36380e2ca85S 	}
36480e2ca85S 
36580e2ca85S 	/*
36680e2ca85S 	 * Find the aux vector on the stack.
36780e2ca85S 	 */
36880e2ca85S 	p = (uintptr_t *)envp;
369*b168296dSToomas Soome 	while (*p != 0)
37080e2ca85S 		p++;
37180e2ca85S 
37280e2ca85S 	/*
37380e2ca85S 	 * p is now pointing at the 0 word after the environ pointers.
37480e2ca85S 	 * After that is the aux vectors.
37580e2ca85S 	 *
37680e2ca85S 	 * The aux vectors are currently pointing to the brand emulation
37780e2ca85S 	 * library and associated linker.  We're going to change them to
37880e2ca85S 	 * point to the brand executable and associated linker (or to no
37980e2ca85S 	 * linker for static binaries).  This matches the process data
38080e2ca85S 	 * stored within the kernel and visible from /proc, which was
38180e2ca85S 	 * all setup in sn1_elfexec().  We do this so that when a debugger
38280e2ca85S 	 * attaches to the process it sees the process as a normal solaris
38380e2ca85S 	 * process, this brand emulation library and everything on it's
38480e2ca85S 	 * link map will not be visible, unless our librtld_db plugin
38580e2ca85S 	 * is used.  Note that this is very different from how Linux
38680e2ca85S 	 * branded processes are implemented within lx branded zones.
38780e2ca85S 	 * In that situation, the primary linkmap of the process is the
38880e2ca85S 	 * brand emulation libraries linkmap, not the Linux applications
38980e2ca85S 	 * linkmap.
39080e2ca85S 	 *
39180e2ca85S 	 * We also need to clear the AF_SUN_NOPLM flag from the AT_SUN_AUXFLAGS
39280e2ca85S 	 * aux vector.  This flag told our linker that we don't have a
39380e2ca85S 	 * primary link map.  Now that our linker is done initializing, we
39480e2ca85S 	 * want to clear this flag before we transfer control to the
39580e2ca85S 	 * applications copy of the linker, since we want that linker to have
39680e2ca85S 	 * a primary link map which will be the link map for the application
39780e2ca85S 	 * we're running.
39880e2ca85S 	 */
39980e2ca85S 	p++;
40080e2ca85S 	for (ap = (auxv_t *)p; ap->a_type != AT_NULL; ap++) {
40180e2ca85S 		switch (ap->a_type) {
40280e2ca85S 			case AT_BASE:
40380e2ca85S 				/* Hide AT_BASE if static binary */
404*b168296dSToomas Soome 				if (sed.sed_base == 0) {
40580e2ca85S 					ap->a_type = AT_IGNORE;
406*b168296dSToomas Soome 					ap->a_un.a_val = 0;
40780e2ca85S 				} else {
40880e2ca85S 					ap->a_un.a_val = sed.sed_base;
40980e2ca85S 				}
41080e2ca85S 				break;
41180e2ca85S 			case AT_ENTRY:
41280e2ca85S 				ap->a_un.a_val = sed.sed_entry;
41380e2ca85S 				break;
41480e2ca85S 			case AT_PHDR:
41580e2ca85S 				ap->a_un.a_val = sed.sed_phdr;
41680e2ca85S 				break;
41780e2ca85S 			case AT_PHENT:
41880e2ca85S 				ap->a_un.a_val = sed.sed_phent;
41980e2ca85S 				break;
42080e2ca85S 			case AT_PHNUM:
42180e2ca85S 				ap->a_un.a_val = sed.sed_phnum;
42280e2ca85S 				break;
42380e2ca85S 			case AT_SUN_AUXFLAGS:
42480e2ca85S 				ap->a_un.a_val &= ~AF_SUN_NOPLM;
42580e2ca85S 				break;
42680e2ca85S 			case AT_SUN_EMULATOR:
42780e2ca85S 				/*
42880e2ca85S 				 * ld.so.1 inspects AT_SUN_EMULATOR to see if
42980e2ca85S 				 * if it is the linker for the brand emulation
43080e2ca85S 				 * library.  Hide AT_SUN_EMULATOR, as the
43180e2ca85S 				 * linker we are about to jump to is the linker
43280e2ca85S 				 * for the binary.
43380e2ca85S 				 */
43480e2ca85S 				ap->a_type = AT_IGNORE;
435*b168296dSToomas Soome 				ap->a_un.a_val = 0;
43680e2ca85S 				break;
43780e2ca85S 			case AT_SUN_LDDATA:
43880e2ca85S 				/* Hide AT_SUN_LDDATA if static binary */
439*b168296dSToomas Soome 				if (sed.sed_lddata == 0) {
44080e2ca85S 					ap->a_type = AT_IGNORE;
441*b168296dSToomas Soome 					ap->a_un.a_val = 0;
44280e2ca85S 				} else {
44380e2ca85S 					ap->a_un.a_val = sed.sed_lddata;
44480e2ca85S 				}
44580e2ca85S 				break;
44680e2ca85S 			default:
44780e2ca85S 				break;
44880e2ca85S 		}
44980e2ca85S 	}
45080e2ca85S 
45180e2ca85S 	return (sed.sed_ldentry);
45280e2ca85S }
453