diff options
Diffstat (limited to 'usr/src/lib/efcode/engine/extend.c')
-rw-r--r-- | usr/src/lib/efcode/engine/extend.c | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/usr/src/lib/efcode/engine/extend.c b/usr/src/lib/efcode/engine/extend.c new file mode 100644 index 0000000000..9e631012b2 --- /dev/null +++ b/usr/src/lib/efcode/engine/extend.c @@ -0,0 +1,147 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2000 by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <sys/shm.h> +#include <dlfcn.h> +#include <fcode/private.h> + +static void +do_dlopen(fcode_env_t *env) +{ + char *name; + int mode; + void *pl; + + mode = POP(DS); + name = pop_a_string(env, NULL); + pl = dlopen(name, mode); + PUSH(DS, (fstack_t)pl); +} + +static void +do_extend(fcode_env_t *env) +{ + parse_word(env); + PUSH(DS, (fstack_t)RTLD_NOW); + do_dlopen(env); + drop(env); +} + +static void +do_dlclose(fcode_env_t *env) +{ + void *pl = (void *)POP(DS); + dlclose(pl); +} + +static void +do_dlsym(fcode_env_t *env) +{ + char *name; + fstack_t d; + + name = pop_a_string(env, NULL); + d = POP(DS); + d = (fstack_t)dlsym((void *) d, name); + PUSH(DS, d); +} + +static void +do_dlexec(fcode_env_t *env) +{ + int args; + fstack_t a, b, c, d; + fstack_t (*fn0)(void); + fstack_t (*fn1)(fstack_t); + fstack_t (*fn2)(fstack_t, fstack_t); + fstack_t (*fn3)(fstack_t, fstack_t, fstack_t); + fstack_t (*fn4)(fstack_t, fstack_t, fstack_t, fstack_t); + + args = POP(DS); + a = POP(DS); + switch (args) { + + case 0: + fn0 = (fstack_t (*)(void)) a; + a = fn0(); + PUSH(DS, a); + break; + + case 1: + fn1 = (fstack_t (*)(fstack_t)) a; + a = POP(DS); + a = fn1(a); + PUSH(DS, a); + break; + + case 2: + fn2 = (fstack_t (*)(fstack_t, fstack_t))a; + a = POP(DS); + b = POP(DS); + a = fn2(a, b); + PUSH(DS, a); + break; + + case 3: + fn3 = (fstack_t (*)(fstack_t, fstack_t, fstack_t))a; + a = POP(DS); + b = POP(DS); + c = POP(DS); + a = fn3(a, b, c); + PUSH(DS, a); + break; + + case 4: + fn4 = (fstack_t (*)(fstack_t, fstack_t, fstack_t, fstack_t))a; + a = POP(DS); + b = POP(DS); + c = POP(DS); + d = POP(DS); + a = fn4(a, b, c, d); + PUSH(DS, a); + break; + } +} + +#pragma init(_init) + +static void +_init(void) +{ + fcode_env_t *env = initial_env; + + ASSERT(env); + NOTICE; + + FORTH(0, "dl-open", do_dlopen); + FORTH(0, "dl-close", do_dlclose); + FORTH(0, "dl-sym", do_dlsym); + FORTH(0, "dl-exec", do_dlexec); + FORTH(IMMEDIATE, "extend-from", do_extend); +} |