OpenSolaris_b135/tools/tokenize/forth_preload.c

Compare this file to the similar file:
Show the results in this format:

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (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 2008 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

/*
 * This preload library must be applied to forth after libthread is
 * folded into libc because forth/tokenize.exe is not ABI compliant; it
 * uses all of the %g registers, including %g7, for its internal purposes.
 * This preload library interposes on all of the external calls made
 * from forth/tokenize.exe and, assuming that forth is single-threaded,
 * sets %g7 properly for use inside libc and restores it to forth's
 * use on return from the interposed-upon function.
 */

enum ix {
	ix___filbuf = 0,
	ix___flsbuf,
	ix__dgettext,
	ix__exit,
	ix_access,
	ix_atexit,
	ix_atoi,
	ix_cfgetospeed,
	ix_chdir,
	ix_close,
	ix_exit,
	ix_exit_handler,
	ix_fclose,
	ix_fflush,
	ix_fgetc,
	ix_fileno,
	ix_fopen,
	ix_fprintf,
	ix_fputc,
	ix_fputs,
	ix_fread,
	ix_free,
	ix_fseek,
	ix_fstat,
	ix_ftell,
	ix_fwrite,
	ix_getcwd,
	ix_getenv,
	ix_getopt,
	ix_getwd,
	ix_ioctl,
	ix_isatty,
	ix_kill,
	ix_localtime,
	ix_lseek,
	ix_malloc,
	ix_memcpy,
	ix_memset,
	ix_open,
	ix_perror,
	ix_printf,
	ix_psignal,
	ix_putchar,
	ix_read,
	ix_sbrk,
	ix_signal,
	ix_sigset,
	ix_snprintf,
	ix_sprintf,
	ix_stat,
	ix_strcat,
	ix_strchr,
	ix_strcmp,
	ix_strcpy,
	ix_strdup,
	ix_strlen,
	ix_strncmp,
	ix_strncpy,
	ix_strrchr,
	ix_system,
	ix_tcgetattr,
	ix_tcsetattr,
	ix_tgetent,
	ix_tgetflag,
	ix_tgetnum,
	ix_tgetstr,
	ix_tgoto,
	ix_time,
	ix_tputs,
	ix_tzset,
	ix_ungetc,
	ix_unlink,
	ix_write
};

typedef long (*realfunc_t)(long, long, long, long, long, long);

struct intpose {
	char fname[12];
	realfunc_t realfunc;
} intpose[] = {
	{ "__filbuf",		0 },
	{ "__flsbuf",		0 },
	{ "_dgettext",		0 },
	{ "_exit",		0 },
	{ "access",		0 },
	{ "atexit",		0 },
	{ "atoi",		0 },
	{ "cfgetospeed",	0 },
	{ "chdir",		0 },
	{ "close",		0 },
	{ "exit",		0 },
	{ "exit_handler",	0 },
	{ "fclose",		0 },
	{ "fflush",		0 },
	{ "fgetc",		0 },
	{ "fileno",		0 },
	{ "fopen",		0 },
	{ "fprintf",		0 },
	{ "fputc",		0 },
	{ "fputs",		0 },
	{ "fread",		0 },
	{ "free",		0 },
	{ "fseek",		0 },
	{ "fstat",		0 },
	{ "ftell",		0 },
	{ "fwrite",		0 },
	{ "getcwd",		0 },
	{ "getenv",		0 },
	{ "getopt",		0 },
	{ "getwd",		0 },
	{ "ioctl",		0 },
	{ "isatty",		0 },
	{ "kill",		0 },
	{ "localtime",		0 },
	{ "lseek",		0 },
	{ "malloc",		0 },
	{ "memcpy",		0 },
	{ "memset",		0 },
	{ "open",		0 },
	{ "perror",		0 },
	{ "printf",		0 },
	{ "psignal",		0 },
	{ "putchar",		0 },
	{ "read",		0 },
	{ "sbrk",		0 },
	{ "signal",		0 },
	{ "sigset",		0 },
	{ "snprintf",		0 },
	{ "sprintf",		0 },
	{ "stat",		0 },
	{ "strcat",		0 },
	{ "strchr",		0 },
	{ "strcmp",		0 },
	{ "strcpy",		0 },
	{ "strdup",		0 },
	{ "strlen",		0 },
	{ "strncmp",		0 },
	{ "strncpy",		0 },
	{ "strrchr",		0 },
	{ "system",		0 },
	{ "tcgetattr",		0 },
	{ "tcsetattr",		0 },
	{ "tgetent",		0 },
	{ "tgetflag",		0 },
	{ "tgetnum",		0 },
	{ "tgetstr",		0 },
	{ "tgoto",		0 },
	{ "time",		0 },
	{ "tputs",		0 },
	{ "tzset",		0 },
	{ "ungetc",		0 },
	{ "unlink",		0 },
	{ "write",		0 },
};

#define	RTLD_NEXT	(void *)-1
extern	void	*dlsym(void *handle, const char *name);

static	long	global_g7 = -1;

long	get_g5(void);
void	set_g5(long);

long	get_g7(void);
void	set_g7(long);

static long
callfunc(struct intpose *ip,
	long a0, long a1, long a2, long a3, long a4, long a5)
{
	realfunc_t realfunc;
	long my_g5;
	long my_g7;
	long rv;

	my_g5 = get_g5();
	my_g7 = get_g7();
	if (global_g7 == -1)
		global_g7 = my_g7;
	set_g7(global_g7);
	if ((realfunc = ip->realfunc) == 0)
		ip->realfunc = realfunc =
		    (realfunc_t)dlsym(RTLD_NEXT, ip->fname);
	rv = realfunc(a0, a1, a2, a3, a4, a5);
	set_g5(my_g5);
	set_g7(my_g7);
	return (rv);
}

#define	ipose(func)							\
long									\
func(long a0, long a1, long a2, long a3, long a4, long a5)		\
{									\
	return (callfunc(&intpose[ix_##func], a0, a1, a2, a3, a4, a5));	\
}

ipose(__filbuf)
ipose(__flsbuf)
ipose(_dgettext)
ipose(_exit)
ipose(access)
ipose(atexit)
ipose(atoi)
ipose(cfgetospeed)
ipose(chdir)
ipose(close)
ipose(exit)
ipose(exit_handler)
ipose(fclose)
ipose(fflush)
ipose(fgetc)
ipose(fileno)
ipose(fopen)
ipose(fprintf)
ipose(fputc)
ipose(fputs)
ipose(fread)
ipose(free)
ipose(fseek)
ipose(fstat)
ipose(ftell)
ipose(fwrite)
ipose(getcwd)
ipose(getenv)
ipose(getopt)
ipose(getwd)
ipose(ioctl)
ipose(isatty)
ipose(kill)
ipose(localtime)
ipose(lseek)
ipose(malloc)
ipose(memcpy)
ipose(memset)
ipose(open)
ipose(perror)
ipose(printf)
ipose(psignal)
ipose(putchar)
ipose(read)
ipose(sbrk)
ipose(signal)
ipose(sigset)
ipose(snprintf)
ipose(sprintf)
ipose(stat)
ipose(strcat)
ipose(strchr)
ipose(strcmp)
ipose(strcpy)
ipose(strdup)
ipose(strlen)
ipose(strncmp)
ipose(strncpy)
ipose(strrchr)
ipose(system)
ipose(tcgetattr)
ipose(tcsetattr)
ipose(tgetent)
ipose(tgetflag)
ipose(tgetnum)
ipose(tgetstr)
ipose(tgoto)
ipose(time)
ipose(tputs)
ipose(tzset)
ipose(ungetc)
ipose(unlink)
ipose(write)