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
37 enum 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
113 typedef long (*realfunc_t)(long, long, long, long, long, long);
114
115 struct 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
195 extern void *dlsym(void *handle, const char *name);
196
197 static long global_g7 = -1;
198
199 long get_g5(void);
200 void set_g5(long);
201
202 long get_g7(void);
203 void set_g7(long);
204
205 static long
callfunc(struct intpose * ip,long a0,long a1,long a2,long a3,long a4,long a5)206 callfunc(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) \
229 long \
230 func(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
235 ipose(__filbuf)
236 ipose(__flsbuf)
237 ipose(_dgettext)
238 ipose(_exit)
239 ipose(access)
240 ipose(atexit)
241 ipose(atoi)
242 ipose(cfgetospeed)
243 ipose(chdir)
244 ipose(close)
245 ipose(exit)
246 ipose(exit_handler)
247 ipose(fclose)
248 ipose(fflush)
249 ipose(fgetc)
250 ipose(fileno)
251 ipose(fopen)
252 ipose(fprintf)
253 ipose(fputc)
254 ipose(fputs)
255 ipose(fread)
256 ipose(free)
257 ipose(fseek)
258 ipose(fstat)
259 ipose(ftell)
260 ipose(fwrite)
261 ipose(getcwd)
262 ipose(getenv)
263 ipose(getopt)
264 ipose(getwd)
265 ipose(ioctl)
266 ipose(isatty)
267 ipose(kill)
268 ipose(localtime)
269 ipose(lseek)
270 ipose(malloc)
271 ipose(memcpy)
272 ipose(memset)
273 ipose(open)
274 ipose(perror)
275 ipose(printf)
276 ipose(psignal)
277 ipose(putchar)
278 ipose(read)
279 ipose(sbrk)
280 ipose(signal)
281 ipose(sigset)
282 ipose(snprintf)
283 ipose(sprintf)
284 ipose(stat)
285 ipose(strcat)
286 ipose(strchr)
287 ipose(strcmp)
288 ipose(strcpy)
289 ipose(strdup)
290 ipose(strlen)
291 ipose(strncmp)
292 ipose(strncpy)
293 ipose(strrchr)
294 ipose(system)
295 ipose(tcgetattr)
296 ipose(tcsetattr)
297 ipose(tgetent)
298 ipose(tgetflag)
299 ipose(tgetnum)
300 ipose(tgetstr)
301 ipose(tgoto)
302 ipose(time)
303 ipose(tputs)
304 ipose(tzset)
305 ipose(ungetc)
306 ipose(unlink)
307 ipose(write)
308