17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57257d1b4Sraf * Common Development and Distribution License (the "License").
67257d1b4Sraf * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217257d1b4Sraf
227c478bd9Sstevel@tonic-gate /*
237257d1b4Sraf * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate /*
287c478bd9Sstevel@tonic-gate * This preload library must be applied to forth after libthread is
297c478bd9Sstevel@tonic-gate * folded into libc because forth/tokenize.exe is not ABI compliant; it
307c478bd9Sstevel@tonic-gate * uses all of the %g registers, including %g7, for its internal purposes.
317c478bd9Sstevel@tonic-gate * This preload library interposes on all of the external calls made
327c478bd9Sstevel@tonic-gate * from forth/tokenize.exe and, assuming that forth is single-threaded,
337c478bd9Sstevel@tonic-gate * sets %g7 properly for use inside libc and restores it to forth's
347c478bd9Sstevel@tonic-gate * use on return from the interposed-upon function.
357c478bd9Sstevel@tonic-gate */
367c478bd9Sstevel@tonic-gate
377c478bd9Sstevel@tonic-gate enum ix {
387c478bd9Sstevel@tonic-gate ix___filbuf = 0,
397c478bd9Sstevel@tonic-gate ix___flsbuf,
407c478bd9Sstevel@tonic-gate ix__dgettext,
417c478bd9Sstevel@tonic-gate ix__exit,
427c478bd9Sstevel@tonic-gate ix_access,
437c478bd9Sstevel@tonic-gate ix_atexit,
447c478bd9Sstevel@tonic-gate ix_atoi,
457c478bd9Sstevel@tonic-gate ix_cfgetospeed,
467c478bd9Sstevel@tonic-gate ix_chdir,
477c478bd9Sstevel@tonic-gate ix_close,
487c478bd9Sstevel@tonic-gate ix_exit,
497c478bd9Sstevel@tonic-gate ix_exit_handler,
507c478bd9Sstevel@tonic-gate ix_fclose,
517c478bd9Sstevel@tonic-gate ix_fflush,
527c478bd9Sstevel@tonic-gate ix_fgetc,
537c478bd9Sstevel@tonic-gate ix_fileno,
547c478bd9Sstevel@tonic-gate ix_fopen,
557c478bd9Sstevel@tonic-gate ix_fprintf,
567c478bd9Sstevel@tonic-gate ix_fputc,
577c478bd9Sstevel@tonic-gate ix_fputs,
587c478bd9Sstevel@tonic-gate ix_fread,
597c478bd9Sstevel@tonic-gate ix_free,
607c478bd9Sstevel@tonic-gate ix_fseek,
617c478bd9Sstevel@tonic-gate ix_fstat,
627c478bd9Sstevel@tonic-gate ix_ftell,
637c478bd9Sstevel@tonic-gate ix_fwrite,
647c478bd9Sstevel@tonic-gate ix_getcwd,
657c478bd9Sstevel@tonic-gate ix_getenv,
667c478bd9Sstevel@tonic-gate ix_getopt,
677c478bd9Sstevel@tonic-gate ix_getwd,
687c478bd9Sstevel@tonic-gate ix_ioctl,
697c478bd9Sstevel@tonic-gate ix_isatty,
707c478bd9Sstevel@tonic-gate ix_kill,
717c478bd9Sstevel@tonic-gate ix_localtime,
727c478bd9Sstevel@tonic-gate ix_lseek,
737c478bd9Sstevel@tonic-gate ix_malloc,
747c478bd9Sstevel@tonic-gate ix_memcpy,
757c478bd9Sstevel@tonic-gate ix_memset,
767c478bd9Sstevel@tonic-gate ix_open,
777c478bd9Sstevel@tonic-gate ix_perror,
787c478bd9Sstevel@tonic-gate ix_printf,
797c478bd9Sstevel@tonic-gate ix_psignal,
807c478bd9Sstevel@tonic-gate ix_putchar,
817c478bd9Sstevel@tonic-gate ix_read,
827c478bd9Sstevel@tonic-gate ix_sbrk,
837c478bd9Sstevel@tonic-gate ix_signal,
847c478bd9Sstevel@tonic-gate ix_sigset,
857c478bd9Sstevel@tonic-gate ix_snprintf,
867c478bd9Sstevel@tonic-gate ix_sprintf,
877c478bd9Sstevel@tonic-gate ix_stat,
887c478bd9Sstevel@tonic-gate ix_strcat,
897c478bd9Sstevel@tonic-gate ix_strchr,
907c478bd9Sstevel@tonic-gate ix_strcmp,
917c478bd9Sstevel@tonic-gate ix_strcpy,
927c478bd9Sstevel@tonic-gate ix_strdup,
937c478bd9Sstevel@tonic-gate ix_strlen,
947c478bd9Sstevel@tonic-gate ix_strncmp,
957c478bd9Sstevel@tonic-gate ix_strncpy,
967c478bd9Sstevel@tonic-gate ix_strrchr,
977c478bd9Sstevel@tonic-gate ix_system,
987c478bd9Sstevel@tonic-gate ix_tcgetattr,
997c478bd9Sstevel@tonic-gate ix_tcsetattr,
1007c478bd9Sstevel@tonic-gate ix_tgetent,
1017c478bd9Sstevel@tonic-gate ix_tgetflag,
1027c478bd9Sstevel@tonic-gate ix_tgetnum,
1037c478bd9Sstevel@tonic-gate ix_tgetstr,
1047c478bd9Sstevel@tonic-gate ix_tgoto,
1057c478bd9Sstevel@tonic-gate ix_time,
1067c478bd9Sstevel@tonic-gate ix_tputs,
1077c478bd9Sstevel@tonic-gate ix_tzset,
1087c478bd9Sstevel@tonic-gate ix_ungetc,
1097c478bd9Sstevel@tonic-gate ix_unlink,
1107c478bd9Sstevel@tonic-gate ix_write
1117c478bd9Sstevel@tonic-gate };
1127c478bd9Sstevel@tonic-gate
1137c478bd9Sstevel@tonic-gate typedef long (*realfunc_t)(long, long, long, long, long, long);
1147c478bd9Sstevel@tonic-gate
1157c478bd9Sstevel@tonic-gate struct intpose {
1167c478bd9Sstevel@tonic-gate char fname[12];
1177c478bd9Sstevel@tonic-gate realfunc_t realfunc;
1187c478bd9Sstevel@tonic-gate } intpose[] = {
1197c478bd9Sstevel@tonic-gate { "__filbuf", 0 },
1207c478bd9Sstevel@tonic-gate { "__flsbuf", 0 },
1217c478bd9Sstevel@tonic-gate { "_dgettext", 0 },
1227c478bd9Sstevel@tonic-gate { "_exit", 0 },
1237c478bd9Sstevel@tonic-gate { "access", 0 },
1247c478bd9Sstevel@tonic-gate { "atexit", 0 },
1257c478bd9Sstevel@tonic-gate { "atoi", 0 },
1267c478bd9Sstevel@tonic-gate { "cfgetospeed", 0 },
1277c478bd9Sstevel@tonic-gate { "chdir", 0 },
1287c478bd9Sstevel@tonic-gate { "close", 0 },
1297c478bd9Sstevel@tonic-gate { "exit", 0 },
1307c478bd9Sstevel@tonic-gate { "exit_handler", 0 },
1317c478bd9Sstevel@tonic-gate { "fclose", 0 },
1327c478bd9Sstevel@tonic-gate { "fflush", 0 },
1337c478bd9Sstevel@tonic-gate { "fgetc", 0 },
1347c478bd9Sstevel@tonic-gate { "fileno", 0 },
1357c478bd9Sstevel@tonic-gate { "fopen", 0 },
1367c478bd9Sstevel@tonic-gate { "fprintf", 0 },
1377c478bd9Sstevel@tonic-gate { "fputc", 0 },
1387c478bd9Sstevel@tonic-gate { "fputs", 0 },
1397c478bd9Sstevel@tonic-gate { "fread", 0 },
1407c478bd9Sstevel@tonic-gate { "free", 0 },
1417c478bd9Sstevel@tonic-gate { "fseek", 0 },
1427c478bd9Sstevel@tonic-gate { "fstat", 0 },
1437c478bd9Sstevel@tonic-gate { "ftell", 0 },
1447c478bd9Sstevel@tonic-gate { "fwrite", 0 },
1457c478bd9Sstevel@tonic-gate { "getcwd", 0 },
1467c478bd9Sstevel@tonic-gate { "getenv", 0 },
1477c478bd9Sstevel@tonic-gate { "getopt", 0 },
1487c478bd9Sstevel@tonic-gate { "getwd", 0 },
1497c478bd9Sstevel@tonic-gate { "ioctl", 0 },
1507c478bd9Sstevel@tonic-gate { "isatty", 0 },
1517c478bd9Sstevel@tonic-gate { "kill", 0 },
1527c478bd9Sstevel@tonic-gate { "localtime", 0 },
1537c478bd9Sstevel@tonic-gate { "lseek", 0 },
1547c478bd9Sstevel@tonic-gate { "malloc", 0 },
1557c478bd9Sstevel@tonic-gate { "memcpy", 0 },
1567c478bd9Sstevel@tonic-gate { "memset", 0 },
1577c478bd9Sstevel@tonic-gate { "open", 0 },
1587c478bd9Sstevel@tonic-gate { "perror", 0 },
1597c478bd9Sstevel@tonic-gate { "printf", 0 },
1607c478bd9Sstevel@tonic-gate { "psignal", 0 },
1617c478bd9Sstevel@tonic-gate { "putchar", 0 },
1627c478bd9Sstevel@tonic-gate { "read", 0 },
1637c478bd9Sstevel@tonic-gate { "sbrk", 0 },
1647c478bd9Sstevel@tonic-gate { "signal", 0 },
1657c478bd9Sstevel@tonic-gate { "sigset", 0 },
1667c478bd9Sstevel@tonic-gate { "snprintf", 0 },
1677c478bd9Sstevel@tonic-gate { "sprintf", 0 },
1687c478bd9Sstevel@tonic-gate { "stat", 0 },
1697c478bd9Sstevel@tonic-gate { "strcat", 0 },
1707c478bd9Sstevel@tonic-gate { "strchr", 0 },
1717c478bd9Sstevel@tonic-gate { "strcmp", 0 },
1727c478bd9Sstevel@tonic-gate { "strcpy", 0 },
1737c478bd9Sstevel@tonic-gate { "strdup", 0 },
1747c478bd9Sstevel@tonic-gate { "strlen", 0 },
1757c478bd9Sstevel@tonic-gate { "strncmp", 0 },
1767c478bd9Sstevel@tonic-gate { "strncpy", 0 },
1777c478bd9Sstevel@tonic-gate { "strrchr", 0 },
1787c478bd9Sstevel@tonic-gate { "system", 0 },
1797c478bd9Sstevel@tonic-gate { "tcgetattr", 0 },
1807c478bd9Sstevel@tonic-gate { "tcsetattr", 0 },
1817c478bd9Sstevel@tonic-gate { "tgetent", 0 },
1827c478bd9Sstevel@tonic-gate { "tgetflag", 0 },
1837c478bd9Sstevel@tonic-gate { "tgetnum", 0 },
1847c478bd9Sstevel@tonic-gate { "tgetstr", 0 },
1857c478bd9Sstevel@tonic-gate { "tgoto", 0 },
1867c478bd9Sstevel@tonic-gate { "time", 0 },
1877c478bd9Sstevel@tonic-gate { "tputs", 0 },
1887c478bd9Sstevel@tonic-gate { "tzset", 0 },
1897c478bd9Sstevel@tonic-gate { "ungetc", 0 },
1907c478bd9Sstevel@tonic-gate { "unlink", 0 },
1917c478bd9Sstevel@tonic-gate { "write", 0 },
1927c478bd9Sstevel@tonic-gate };
1937c478bd9Sstevel@tonic-gate
1947c478bd9Sstevel@tonic-gate #define RTLD_NEXT (void *)-1
1957257d1b4Sraf extern void *dlsym(void *handle, const char *name);
1967c478bd9Sstevel@tonic-gate
1977c478bd9Sstevel@tonic-gate static long global_g7 = -1;
1987c478bd9Sstevel@tonic-gate
199*d9b365efSRoger A. Faulkner long get_g5(void);
200*d9b365efSRoger A. Faulkner void set_g5(long);
201*d9b365efSRoger A. Faulkner
2027c478bd9Sstevel@tonic-gate long get_g7(void);
2037c478bd9Sstevel@tonic-gate void set_g7(long);
2047c478bd9Sstevel@tonic-gate
2057c478bd9Sstevel@tonic-gate static long
callfunc(struct intpose * ip,long a0,long a1,long a2,long a3,long a4,long a5)2067c478bd9Sstevel@tonic-gate callfunc(struct intpose *ip,
2077c478bd9Sstevel@tonic-gate long a0, long a1, long a2, long a3, long a4, long a5)
2087c478bd9Sstevel@tonic-gate {
2097c478bd9Sstevel@tonic-gate realfunc_t realfunc;
210*d9b365efSRoger A. Faulkner long my_g5;
2117c478bd9Sstevel@tonic-gate long my_g7;
2127c478bd9Sstevel@tonic-gate long rv;
2137c478bd9Sstevel@tonic-gate
214*d9b365efSRoger A. Faulkner my_g5 = get_g5();
2157c478bd9Sstevel@tonic-gate my_g7 = get_g7();
2167c478bd9Sstevel@tonic-gate if (global_g7 == -1)
2177c478bd9Sstevel@tonic-gate global_g7 = my_g7;
2187c478bd9Sstevel@tonic-gate set_g7(global_g7);
2197c478bd9Sstevel@tonic-gate if ((realfunc = ip->realfunc) == 0)
2207c478bd9Sstevel@tonic-gate ip->realfunc = realfunc =
2217257d1b4Sraf (realfunc_t)dlsym(RTLD_NEXT, ip->fname);
2227c478bd9Sstevel@tonic-gate rv = realfunc(a0, a1, a2, a3, a4, a5);
223*d9b365efSRoger A. Faulkner set_g5(my_g5);
2247c478bd9Sstevel@tonic-gate set_g7(my_g7);
2257c478bd9Sstevel@tonic-gate return (rv);
2267c478bd9Sstevel@tonic-gate }
2277c478bd9Sstevel@tonic-gate
2287c478bd9Sstevel@tonic-gate #define ipose(func) \
2297c478bd9Sstevel@tonic-gate long \
2307c478bd9Sstevel@tonic-gate func(long a0, long a1, long a2, long a3, long a4, long a5) \
2317c478bd9Sstevel@tonic-gate { \
2327c478bd9Sstevel@tonic-gate return (callfunc(&intpose[ix_##func], a0, a1, a2, a3, a4, a5)); \
2337c478bd9Sstevel@tonic-gate }
2347c478bd9Sstevel@tonic-gate
2357c478bd9Sstevel@tonic-gate ipose(__filbuf)
2367c478bd9Sstevel@tonic-gate ipose(__flsbuf)
2377c478bd9Sstevel@tonic-gate ipose(_dgettext)
2387c478bd9Sstevel@tonic-gate ipose(_exit)
2397c478bd9Sstevel@tonic-gate ipose(access)
2407c478bd9Sstevel@tonic-gate ipose(atexit)
2417c478bd9Sstevel@tonic-gate ipose(atoi)
2427c478bd9Sstevel@tonic-gate ipose(cfgetospeed)
2437c478bd9Sstevel@tonic-gate ipose(chdir)
2447c478bd9Sstevel@tonic-gate ipose(close)
2457c478bd9Sstevel@tonic-gate ipose(exit)
2467c478bd9Sstevel@tonic-gate ipose(exit_handler)
2477c478bd9Sstevel@tonic-gate ipose(fclose)
2487c478bd9Sstevel@tonic-gate ipose(fflush)
2497c478bd9Sstevel@tonic-gate ipose(fgetc)
2507c478bd9Sstevel@tonic-gate ipose(fileno)
2517c478bd9Sstevel@tonic-gate ipose(fopen)
2527c478bd9Sstevel@tonic-gate ipose(fprintf)
2537c478bd9Sstevel@tonic-gate ipose(fputc)
2547c478bd9Sstevel@tonic-gate ipose(fputs)
2557c478bd9Sstevel@tonic-gate ipose(fread)
2567c478bd9Sstevel@tonic-gate ipose(free)
2577c478bd9Sstevel@tonic-gate ipose(fseek)
2587c478bd9Sstevel@tonic-gate ipose(fstat)
2597c478bd9Sstevel@tonic-gate ipose(ftell)
2607c478bd9Sstevel@tonic-gate ipose(fwrite)
2617c478bd9Sstevel@tonic-gate ipose(getcwd)
2627c478bd9Sstevel@tonic-gate ipose(getenv)
2637c478bd9Sstevel@tonic-gate ipose(getopt)
2647c478bd9Sstevel@tonic-gate ipose(getwd)
2657c478bd9Sstevel@tonic-gate ipose(ioctl)
2667c478bd9Sstevel@tonic-gate ipose(isatty)
2677c478bd9Sstevel@tonic-gate ipose(kill)
2687c478bd9Sstevel@tonic-gate ipose(localtime)
2697c478bd9Sstevel@tonic-gate ipose(lseek)
2707c478bd9Sstevel@tonic-gate ipose(malloc)
2717c478bd9Sstevel@tonic-gate ipose(memcpy)
2727c478bd9Sstevel@tonic-gate ipose(memset)
2737c478bd9Sstevel@tonic-gate ipose(open)
2747c478bd9Sstevel@tonic-gate ipose(perror)
2757c478bd9Sstevel@tonic-gate ipose(printf)
2767c478bd9Sstevel@tonic-gate ipose(psignal)
2777c478bd9Sstevel@tonic-gate ipose(putchar)
2787c478bd9Sstevel@tonic-gate ipose(read)
2797c478bd9Sstevel@tonic-gate ipose(sbrk)
2807c478bd9Sstevel@tonic-gate ipose(signal)
2817c478bd9Sstevel@tonic-gate ipose(sigset)
2827c478bd9Sstevel@tonic-gate ipose(snprintf)
2837c478bd9Sstevel@tonic-gate ipose(sprintf)
2847c478bd9Sstevel@tonic-gate ipose(stat)
2857c478bd9Sstevel@tonic-gate ipose(strcat)
2867c478bd9Sstevel@tonic-gate ipose(strchr)
2877c478bd9Sstevel@tonic-gate ipose(strcmp)
2887c478bd9Sstevel@tonic-gate ipose(strcpy)
2897c478bd9Sstevel@tonic-gate ipose(strdup)
2907c478bd9Sstevel@tonic-gate ipose(strlen)
2917c478bd9Sstevel@tonic-gate ipose(strncmp)
2927c478bd9Sstevel@tonic-gate ipose(strncpy)
2937c478bd9Sstevel@tonic-gate ipose(strrchr)
2947c478bd9Sstevel@tonic-gate ipose(system)
2957c478bd9Sstevel@tonic-gate ipose(tcgetattr)
2967c478bd9Sstevel@tonic-gate ipose(tcsetattr)
2977c478bd9Sstevel@tonic-gate ipose(tgetent)
2987c478bd9Sstevel@tonic-gate ipose(tgetflag)
2997c478bd9Sstevel@tonic-gate ipose(tgetnum)
3007c478bd9Sstevel@tonic-gate ipose(tgetstr)
3017c478bd9Sstevel@tonic-gate ipose(tgoto)
3027c478bd9Sstevel@tonic-gate ipose(time)
3037c478bd9Sstevel@tonic-gate ipose(tputs)
3047c478bd9Sstevel@tonic-gate ipose(tzset)
3057c478bd9Sstevel@tonic-gate ipose(ungetc)
3067c478bd9Sstevel@tonic-gate ipose(unlink)
3077c478bd9Sstevel@tonic-gate ipose(write)
308