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/*
23 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27/*
28 * This preload library must be applied to forth after libthread is
29 * folded into libc because forth/tokenize.exe is not ABI compliant; it
30 * uses all of the %g registers, including %g7, for its internal purposes.
31 * This preload library interposes on all of the external calls made
32 * from forth/tokenize.exe and, assuming that forth is single-threaded,
33 * sets %g7 properly for use inside libc and restores it to forth's
34 * use on return from the interposed-upon function.
35 */
36
37enum ix {
38	ix___filbuf = 0,
39	ix___flsbuf,
40	ix__dgettext,
41	ix__exit,
42	ix_access,
43	ix_atexit,
44	ix_atoi,
45	ix_cfgetospeed,
46	ix_chdir,
47	ix_close,
48	ix_exit,
49	ix_exit_handler,
50	ix_fclose,
51	ix_fflush,
52	ix_fgetc,
53	ix_fileno,
54	ix_fopen,
55	ix_fprintf,
56	ix_fputc,
57	ix_fputs,
58	ix_fread,
59	ix_free,
60	ix_fseek,
61	ix_fstat,
62	ix_ftell,
63	ix_fwrite,
64	ix_getcwd,
65	ix_getenv,
66	ix_getopt,
67	ix_getwd,
68	ix_ioctl,
69	ix_isatty,
70	ix_kill,
71	ix_localtime,
72	ix_lseek,
73	ix_malloc,
74	ix_memcpy,
75	ix_memset,
76	ix_open,
77	ix_perror,
78	ix_printf,
79	ix_psignal,
80	ix_putchar,
81	ix_read,
82	ix_sbrk,
83	ix_signal,
84	ix_sigset,
85	ix_snprintf,
86	ix_sprintf,
87	ix_stat,
88	ix_strcat,
89	ix_strchr,
90	ix_strcmp,
91	ix_strcpy,
92	ix_strdup,
93	ix_strlen,
94	ix_strncmp,
95	ix_strncpy,
96	ix_strrchr,
97	ix_system,
98	ix_tcgetattr,
99	ix_tcsetattr,
100	ix_tgetent,
101	ix_tgetflag,
102	ix_tgetnum,
103	ix_tgetstr,
104	ix_tgoto,
105	ix_time,
106	ix_tputs,
107	ix_tzset,
108	ix_ungetc,
109	ix_unlink,
110	ix_write
111};
112
113typedef long (*realfunc_t)(long, long, long, long, long, long);
114
115struct intpose {
116	char fname[12];
117	realfunc_t realfunc;
118} intpose[] = {
119	{ "__filbuf",		0 },
120	{ "__flsbuf",		0 },
121	{ "_dgettext",		0 },
122	{ "_exit",		0 },
123	{ "access",		0 },
124	{ "atexit",		0 },
125	{ "atoi",		0 },
126	{ "cfgetospeed",	0 },
127	{ "chdir",		0 },
128	{ "close",		0 },
129	{ "exit",		0 },
130	{ "exit_handler",	0 },
131	{ "fclose",		0 },
132	{ "fflush",		0 },
133	{ "fgetc",		0 },
134	{ "fileno",		0 },
135	{ "fopen",		0 },
136	{ "fprintf",		0 },
137	{ "fputc",		0 },
138	{ "fputs",		0 },
139	{ "fread",		0 },
140	{ "free",		0 },
141	{ "fseek",		0 },
142	{ "fstat",		0 },
143	{ "ftell",		0 },
144	{ "fwrite",		0 },
145	{ "getcwd",		0 },
146	{ "getenv",		0 },
147	{ "getopt",		0 },
148	{ "getwd",		0 },
149	{ "ioctl",		0 },
150	{ "isatty",		0 },
151	{ "kill",		0 },
152	{ "localtime",		0 },
153	{ "lseek",		0 },
154	{ "malloc",		0 },
155	{ "memcpy",		0 },
156	{ "memset",		0 },
157	{ "open",		0 },
158	{ "perror",		0 },
159	{ "printf",		0 },
160	{ "psignal",		0 },
161	{ "putchar",		0 },
162	{ "read",		0 },
163	{ "sbrk",		0 },
164	{ "signal",		0 },
165	{ "sigset",		0 },
166	{ "snprintf",		0 },
167	{ "sprintf",		0 },
168	{ "stat",		0 },
169	{ "strcat",		0 },
170	{ "strchr",		0 },
171	{ "strcmp",		0 },
172	{ "strcpy",		0 },
173	{ "strdup",		0 },
174	{ "strlen",		0 },
175	{ "strncmp",		0 },
176	{ "strncpy",		0 },
177	{ "strrchr",		0 },
178	{ "system",		0 },
179	{ "tcgetattr",		0 },
180	{ "tcsetattr",		0 },
181	{ "tgetent",		0 },
182	{ "tgetflag",		0 },
183	{ "tgetnum",		0 },
184	{ "tgetstr",		0 },
185	{ "tgoto",		0 },
186	{ "time",		0 },
187	{ "tputs",		0 },
188	{ "tzset",		0 },
189	{ "ungetc",		0 },
190	{ "unlink",		0 },
191	{ "write",		0 },
192};
193
194#define	RTLD_NEXT	(void *)-1
195extern	void	*dlsym(void *handle, const char *name);
196
197static	long	global_g7 = -1;
198
199long	get_g5(void);
200void	set_g5(long);
201
202long	get_g7(void);
203void	set_g7(long);
204
205static long
206callfunc(struct intpose *ip,
207	long a0, long a1, long a2, long a3, long a4, long a5)
208{
209	realfunc_t realfunc;
210	long my_g5;
211	long my_g7;
212	long rv;
213
214	my_g5 = get_g5();
215	my_g7 = get_g7();
216	if (global_g7 == -1)
217		global_g7 = my_g7;
218	set_g7(global_g7);
219	if ((realfunc = ip->realfunc) == 0)
220		ip->realfunc = realfunc =
221		    (realfunc_t)dlsym(RTLD_NEXT, ip->fname);
222	rv = realfunc(a0, a1, a2, a3, a4, a5);
223	set_g5(my_g5);
224	set_g7(my_g7);
225	return (rv);
226}
227
228#define	ipose(func)							\
229long									\
230func(long a0, long a1, long a2, long a3, long a4, long a5)		\
231{									\
232	return (callfunc(&intpose[ix_##func], a0, a1, a2, a3, a4, a5));	\
233}
234
235ipose(__filbuf)
236ipose(__flsbuf)
237ipose(_dgettext)
238ipose(_exit)
239ipose(access)
240ipose(atexit)
241ipose(atoi)
242ipose(cfgetospeed)
243ipose(chdir)
244ipose(close)
245ipose(exit)
246ipose(exit_handler)
247ipose(fclose)
248ipose(fflush)
249ipose(fgetc)
250ipose(fileno)
251ipose(fopen)
252ipose(fprintf)
253ipose(fputc)
254ipose(fputs)
255ipose(fread)
256ipose(free)
257ipose(fseek)
258ipose(fstat)
259ipose(ftell)
260ipose(fwrite)
261ipose(getcwd)
262ipose(getenv)
263ipose(getopt)
264ipose(getwd)
265ipose(ioctl)
266ipose(isatty)
267ipose(kill)
268ipose(localtime)
269ipose(lseek)
270ipose(malloc)
271ipose(memcpy)
272ipose(memset)
273ipose(open)
274ipose(perror)
275ipose(printf)
276ipose(psignal)
277ipose(putchar)
278ipose(read)
279ipose(sbrk)
280ipose(signal)
281ipose(sigset)
282ipose(snprintf)
283ipose(sprintf)
284ipose(stat)
285ipose(strcat)
286ipose(strchr)
287ipose(strcmp)
288ipose(strcpy)
289ipose(strdup)
290ipose(strlen)
291ipose(strncmp)
292ipose(strncpy)
293ipose(strrchr)
294ipose(system)
295ipose(tcgetattr)
296ipose(tcsetattr)
297ipose(tgetent)
298ipose(tgetflag)
299ipose(tgetnum)
300ipose(tgetstr)
301ipose(tgoto)
302ipose(time)
303ipose(tputs)
304ipose(tzset)
305ipose(ungetc)
306ipose(unlink)
307ipose(write)
308