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
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  * Copyright (c) 1997-2000 by Sun Microsystems, Inc.
247c478bd9Sstevel@tonic-gate  * All rights reserved.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /*
287c478bd9Sstevel@tonic-gate  * interceptor.c -- a functional decomposition of generate.c,
297c478bd9Sstevel@tonic-gate  *	the code generator for apptrace
307c478bd9Sstevel@tonic-gate  */
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #include <stdio.h>
337c478bd9Sstevel@tonic-gate #include <stdlib.h>
347c478bd9Sstevel@tonic-gate #include <string.h>
357c478bd9Sstevel@tonic-gate #include <unistd.h>
367c478bd9Sstevel@tonic-gate #include <sys/types.h>
377c478bd9Sstevel@tonic-gate #include "parser.h"
387c478bd9Sstevel@tonic-gate #include "trace.h"
397c478bd9Sstevel@tonic-gate #include "util.h"
407c478bd9Sstevel@tonic-gate #include "db.h"
417c478bd9Sstevel@tonic-gate #include "symtab.h"
427c478bd9Sstevel@tonic-gate #include "io.h"
437c478bd9Sstevel@tonic-gate #include "bindings.h"
447c478bd9Sstevel@tonic-gate #include "printfuncs.h"
457c478bd9Sstevel@tonic-gate #include "errlog.h"
467c478bd9Sstevel@tonic-gate #include "parseproto.h"
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate static void generate_i_declarations(char *, int, char *);
497c478bd9Sstevel@tonic-gate static void generate_i_preamble(ENTRY *);
507c478bd9Sstevel@tonic-gate static void generate_i_call();
517c478bd9Sstevel@tonic-gate static int  generate_i_bindings(int);
527c478bd9Sstevel@tonic-gate static void generate_i_postamble(ENTRY *, int, char *, char *);
537c478bd9Sstevel@tonic-gate static void generate_i_evaluations(ENTRY *);
547c478bd9Sstevel@tonic-gate static void generate_i_prints(ENTRY *, char *, char *);
557c478bd9Sstevel@tonic-gate static void generate_i_closedown(char *, int);
567c478bd9Sstevel@tonic-gate static void generate_i_live_vars(ENTRY *);
577c478bd9Sstevel@tonic-gate static void generate_return_printf(int);
587c478bd9Sstevel@tonic-gate static char *variables_get_errorname(void);
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate /*
617c478bd9Sstevel@tonic-gate  * generate_interceptor -- make code for an individual interceptor, written
627c478bd9Sstevel@tonic-gate  *	as an output grammar
637c478bd9Sstevel@tonic-gate  */
647c478bd9Sstevel@tonic-gate void
generate_interceptor(ENTRY * function)657c478bd9Sstevel@tonic-gate generate_interceptor(ENTRY *function)
667c478bd9Sstevel@tonic-gate {
677c478bd9Sstevel@tonic-gate 	char	*prototype = symtab_get_prototype(),
687c478bd9Sstevel@tonic-gate 		*library_name = db_get_current_library(),
697c478bd9Sstevel@tonic-gate 		*function_name,
707c478bd9Sstevel@tonic-gate 		*error_name;
717c478bd9Sstevel@tonic-gate 	int	void_func;
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate 	errlog(BEGIN, "generate_interceptor() {");
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate 	/* Check for required information. */
767c478bd9Sstevel@tonic-gate 	if (validity_of(function) == NO) {
777c478bd9Sstevel@tonic-gate 		symtab_set_skip(YES);
787c478bd9Sstevel@tonic-gate 		errlog(WARNING|INPUT, "No prototype for interface, "
797c478bd9Sstevel@tonic-gate 			"it will be skipped");
807c478bd9Sstevel@tonic-gate 		errlog(END, "}");
817c478bd9Sstevel@tonic-gate 		return;
827c478bd9Sstevel@tonic-gate 	}
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate 	/* Collect things we'll use more than once. */
857c478bd9Sstevel@tonic-gate 	function_name = name_of(function);
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate 	error_name = variables_get_errorname();
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate 	void_func = is_void(function);
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate 	/*
927c478bd9Sstevel@tonic-gate 	 * Emit "artificial" prototype here so that if there's a
937c478bd9Sstevel@tonic-gate 	 * disagreement between it and the prototype contained in the
947c478bd9Sstevel@tonic-gate 	 * declaring header, the compiler will flag it.
957c478bd9Sstevel@tonic-gate 	 * First #undef the function to make sure the prototype in the header
967c478bd9Sstevel@tonic-gate 	 * is exposed and to avoid breaking the artificial prototype if it's
977c478bd9Sstevel@tonic-gate 	 * not.
987c478bd9Sstevel@tonic-gate 	 */
997c478bd9Sstevel@tonic-gate 	{
1007c478bd9Sstevel@tonic-gate 		decl_t *dp;
1017c478bd9Sstevel@tonic-gate 		char *buf;
1027c478bd9Sstevel@tonic-gate 		char const *err;
1037c478bd9Sstevel@tonic-gate 		size_t s;
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate 		s = strlen(prototype) + 2;
1067c478bd9Sstevel@tonic-gate 		buf = malloc(s);
1077c478bd9Sstevel@tonic-gate 		if (buf == NULL)
1087c478bd9Sstevel@tonic-gate 			abort();
1097c478bd9Sstevel@tonic-gate 		(void) strcpy(buf, prototype);
1107c478bd9Sstevel@tonic-gate 		buf[s - 2] = ';';
1117c478bd9Sstevel@tonic-gate 		buf[s - 1] = '\0';
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate 		err = decl_Parse(buf, &dp);
1147c478bd9Sstevel@tonic-gate 		if (err != NULL)
1157c478bd9Sstevel@tonic-gate 			errlog(FATAL, "\"%s\", line %d: %s: %s",
1167c478bd9Sstevel@tonic-gate 			    symtab_get_filename(), line_of(function),
1177c478bd9Sstevel@tonic-gate 			    err, prototype);
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate 		/* generate the mapfile entry */
1207c478bd9Sstevel@tonic-gate 		(void) fprintf(Mapfp, "\t__abi_%s;\n", decl_GetName(dp));
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate 		(void) decl_ToString(buf, DTS_DECL, dp, function_name);
1237c478bd9Sstevel@tonic-gate 		(void) fprintf(Bodyfp, "#line %d \"%s\"\n",
1247c478bd9Sstevel@tonic-gate 		    line_of(function), symtab_get_filename());
1257c478bd9Sstevel@tonic-gate 		(void) fprintf(Bodyfp, "#undef %s\n", function_name);
1267c478bd9Sstevel@tonic-gate 		(void) fprintf(Bodyfp, "extern %s;\n", buf);
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate 		(void) fprintf(Bodyfp, "static %s\n{\n", prototype);
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate 		(void) decl_ToString(buf, DTS_RET, dp, "_return");
1317c478bd9Sstevel@tonic-gate 		generate_i_declarations(error_name, void_func, buf);
1327c478bd9Sstevel@tonic-gate 		decl_Destroy(dp);
1337c478bd9Sstevel@tonic-gate 		free(buf);
1347c478bd9Sstevel@tonic-gate 	}
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate 	generate_i_preamble(function);
1377c478bd9Sstevel@tonic-gate 	generate_i_call(function, void_func, library_name, error_name);
1387c478bd9Sstevel@tonic-gate 	generate_i_postamble(function, void_func, error_name, library_name);
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate 	errlog(END, "}");
1417c478bd9Sstevel@tonic-gate }
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate /*
1447c478bd9Sstevel@tonic-gate  * print_function_signature -- print the line defining the function, without
1457c478bd9Sstevel@tonic-gate  *      an ``extern'' prefix or either a ``;'' or ''{'' suffix.
1467c478bd9Sstevel@tonic-gate  */
1477c478bd9Sstevel@tonic-gate void
print_function_signature(char * xtype,char * name,char * formals)1487c478bd9Sstevel@tonic-gate print_function_signature(char *xtype, char *name, char *formals)
1497c478bd9Sstevel@tonic-gate {
1507c478bd9Sstevel@tonic-gate 	char	buffer[MAXLINE];
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate 	(void) snprintf(buffer, sizeof (buffer), "%s", name);
1537c478bd9Sstevel@tonic-gate 	(void) fprintf(Bodyfp,  xtype, buffer);
1547c478bd9Sstevel@tonic-gate 	if (strstr(xtype, "(*") == NULL) {
1557c478bd9Sstevel@tonic-gate 		(void) fprintf(Bodyfp,  "(%s)", formals);
1567c478bd9Sstevel@tonic-gate 	}
1577c478bd9Sstevel@tonic-gate }
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate /*
1617c478bd9Sstevel@tonic-gate  * generate_i_declarations -- generate the declarations which
1627c478bd9Sstevel@tonic-gate  *      are local to the interceptor function itself.
1637c478bd9Sstevel@tonic-gate  */
1647c478bd9Sstevel@tonic-gate static void
generate_i_declarations(char * errname,int voidfunc,char * ret_str)1657c478bd9Sstevel@tonic-gate generate_i_declarations(char *errname, int voidfunc, char *ret_str)
1667c478bd9Sstevel@tonic-gate {
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate 	errlog(BEGIN, "generate_i_declarations() {");
169*07c94cbfSToomas Soome 	if (*errname != '\0') {
1707c478bd9Sstevel@tonic-gate 		/* Create locals for errno-type variable, */
1717c478bd9Sstevel@tonic-gate 		(void) fprintf(Bodyfp,
1727c478bd9Sstevel@tonic-gate 		    "    int saved_errvar = %s;\n", errname);
1737c478bd9Sstevel@tonic-gate 		(void) fprintf(Bodyfp,  "    int functions_errvar;\n");
1747c478bd9Sstevel@tonic-gate 	}
1757c478bd9Sstevel@tonic-gate 
1767c478bd9Sstevel@tonic-gate 	if (need_exception_binding()) {
1777c478bd9Sstevel@tonic-gate 		/* Create a local for that. */
1787c478bd9Sstevel@tonic-gate 		(void) fprintf(Bodyfp,  "    int exception = 0;\n");
1797c478bd9Sstevel@tonic-gate 	}
1807c478bd9Sstevel@tonic-gate 	if (! voidfunc) {
1817c478bd9Sstevel@tonic-gate 		/* Create a return value. */
1827c478bd9Sstevel@tonic-gate 		(void) fprintf(Bodyfp,  "    %s;\n", ret_str);
1837c478bd9Sstevel@tonic-gate 	}
1847c478bd9Sstevel@tonic-gate 	(void) fprintf(Bodyfp, "    sigset_t omask;\n");
1857c478bd9Sstevel@tonic-gate 	(void) putc('\n', Bodyfp);
1867c478bd9Sstevel@tonic-gate 	errlog(END, "}");
1877c478bd9Sstevel@tonic-gate }
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate /*
1917c478bd9Sstevel@tonic-gate  * generate_i_preamble -- do the actions which must occur
1927c478bd9Sstevel@tonic-gate  *      before the call.
1937c478bd9Sstevel@tonic-gate  */
1947c478bd9Sstevel@tonic-gate static void
generate_i_preamble(ENTRY * function)1957c478bd9Sstevel@tonic-gate generate_i_preamble(ENTRY *function)
1967c478bd9Sstevel@tonic-gate {
1977c478bd9Sstevel@tonic-gate 	errlog(BEGIN, "generate_i_preamble() {");
1987c478bd9Sstevel@tonic-gate 	generate_i_live_vars(function); /* Deferred. */
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate 	if (symtab_get_nonreturn() == YES) {
2017c478bd9Sstevel@tonic-gate 		/* Make things safe for printing */
2027c478bd9Sstevel@tonic-gate 		(void) fprintf(Bodyfp,
2037c478bd9Sstevel@tonic-gate 		    "    abilock(&omask);\n");
2047c478bd9Sstevel@tonic-gate 		/* Print all the args in terse format. */
2057c478bd9Sstevel@tonic-gate 		generate_printf(function);
2067c478bd9Sstevel@tonic-gate 		(void) fputs("    putc('\\n', ABISTREAM);\n\n", Bodyfp);
2077c478bd9Sstevel@tonic-gate 		/* unlock stdio */
2087c478bd9Sstevel@tonic-gate 		(void) fprintf(Bodyfp,
2097c478bd9Sstevel@tonic-gate 		    "    abiunlock(&omask);\n");
2107c478bd9Sstevel@tonic-gate 	}
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate 	errlog(END, "}");
2137c478bd9Sstevel@tonic-gate }
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate /*
2167c478bd9Sstevel@tonic-gate  * generate_i_call -- implement the save/call/restore cycle
2177c478bd9Sstevel@tonic-gate  */
2187c478bd9Sstevel@tonic-gate static void
generate_i_call(ENTRY * function,int void_func,char * library_name,char * error_name)2197c478bd9Sstevel@tonic-gate generate_i_call(
2207c478bd9Sstevel@tonic-gate 	ENTRY	*function,
2217c478bd9Sstevel@tonic-gate 	int	void_func,
2227c478bd9Sstevel@tonic-gate 	char	*library_name,
2237c478bd9Sstevel@tonic-gate 	char	*error_name)
2247c478bd9Sstevel@tonic-gate {
2257c478bd9Sstevel@tonic-gate 	char	*function_name = name_of(function),
2267c478bd9Sstevel@tonic-gate 		*function_cast = symtab_get_cast(),
2277c478bd9Sstevel@tonic-gate 		*actual_args = symtab_get_actuals();
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate 	errlog(BEGIN, "generate_i_call() {");
2307c478bd9Sstevel@tonic-gate 	/* Zero the error variable. */
231*07c94cbfSToomas Soome 	if (*error_name != '\0') {
2327c478bd9Sstevel@tonic-gate 		(void) fprintf(Bodyfp,  "    %s = 0;\n", error_name);
2337c478bd9Sstevel@tonic-gate 	}
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate 	/* Then print the call itself. */
2367c478bd9Sstevel@tonic-gate 	if (void_func) {
2377c478bd9Sstevel@tonic-gate 		(void) fprintf(Bodyfp,
2387c478bd9Sstevel@tonic-gate 		    "    (void) ABI_CALL_REAL(%s, %s, %s)(%s);\n",
2397c478bd9Sstevel@tonic-gate 		    library_name, function_name, function_cast, actual_args);
2407c478bd9Sstevel@tonic-gate 	} else {
2417c478bd9Sstevel@tonic-gate 		(void) fprintf(Bodyfp,
2427c478bd9Sstevel@tonic-gate 		    "    _return = ABI_CALL_REAL(%s, %s, %s)(%s);\n",
2437c478bd9Sstevel@tonic-gate 		    library_name, function_name, function_cast, actual_args);
2447c478bd9Sstevel@tonic-gate 	}
2457c478bd9Sstevel@tonic-gate 
2467c478bd9Sstevel@tonic-gate 	/* Then set the local copy of the error variable. */
247*07c94cbfSToomas Soome 	if (*error_name != '\0') {
2487c478bd9Sstevel@tonic-gate 		(void) fprintf(Bodyfp,
2497c478bd9Sstevel@tonic-gate 		    "    functions_errvar = %s;\n", error_name);
2507c478bd9Sstevel@tonic-gate 	}
2517c478bd9Sstevel@tonic-gate 	(void) putc('\n', Bodyfp);
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate 	/* Make things safe for printing */
2547c478bd9Sstevel@tonic-gate 	(void) fprintf(Bodyfp,
2557c478bd9Sstevel@tonic-gate 	    "    abilock(&omask);\n");
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate 	errlog(END, "}");
2587c478bd9Sstevel@tonic-gate }
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate /*
2617c478bd9Sstevel@tonic-gate  * generate_i_postamble -- do all the things which come
2627c478bd9Sstevel@tonic-gate  *      after the call.  In the case of apptrace, this is most of the work.
2637c478bd9Sstevel@tonic-gate  */
2647c478bd9Sstevel@tonic-gate static void
generate_i_postamble(ENTRY * function,int void_func,char * error_name,char * library_name)2657c478bd9Sstevel@tonic-gate generate_i_postamble(ENTRY *function, int void_func,
2667c478bd9Sstevel@tonic-gate     char *error_name, char *library_name)
2677c478bd9Sstevel@tonic-gate {
2687c478bd9Sstevel@tonic-gate 	errlog(BEGIN, "generate_i_postamble() {");
2697c478bd9Sstevel@tonic-gate 	if (symtab_get_nonreturn() == NO) {
2707c478bd9Sstevel@tonic-gate 		/* Print all the args in terse format. */
2717c478bd9Sstevel@tonic-gate 		generate_printf(function);
2727c478bd9Sstevel@tonic-gate 	}
2737c478bd9Sstevel@tonic-gate 
2747c478bd9Sstevel@tonic-gate 	/* If it isn't supposed to return, and actually ends up here, */
2757c478bd9Sstevel@tonic-gate 	/* we'd better be prepared to print all sorts of diagnostic stuff */
2767c478bd9Sstevel@tonic-gate 	(void) putc('\n', Bodyfp);
2777c478bd9Sstevel@tonic-gate 	if (generate_i_bindings(void_func) == YES) {
2787c478bd9Sstevel@tonic-gate 		generate_return_printf(void_func);
2797c478bd9Sstevel@tonic-gate 	}
2807c478bd9Sstevel@tonic-gate 
2817c478bd9Sstevel@tonic-gate 	generate_i_prints(function, library_name, name_of(function));
2827c478bd9Sstevel@tonic-gate 	generate_i_evaluations(function); /* Deferred */
2837c478bd9Sstevel@tonic-gate 	generate_i_closedown(error_name, void_func);
2847c478bd9Sstevel@tonic-gate 	errlog(END, "}");
2857c478bd9Sstevel@tonic-gate }
2867c478bd9Sstevel@tonic-gate 
2877c478bd9Sstevel@tonic-gate /*
2887c478bd9Sstevel@tonic-gate  * generate_i_bindings -- see about success and failure, so we can decide
2897c478bd9Sstevel@tonic-gate  *      what to do next.
2907c478bd9Sstevel@tonic-gate  */
2917c478bd9Sstevel@tonic-gate static int
generate_i_bindings(int void_func)2927c478bd9Sstevel@tonic-gate generate_i_bindings(int void_func)
2937c478bd9Sstevel@tonic-gate {
2947c478bd9Sstevel@tonic-gate 	ENTRY   *e;
2957c478bd9Sstevel@tonic-gate 	char *exception;
2967c478bd9Sstevel@tonic-gate 
2977c478bd9Sstevel@tonic-gate 	exception  = ((e = symtab_get_exception()) != NULL)?
2987c478bd9Sstevel@tonic-gate 	    (name_of(e)? name_of(e): ""): "";
2997c478bd9Sstevel@tonic-gate 
3007c478bd9Sstevel@tonic-gate 	errlog(BEGIN, "generate_i_bindings() {");
3017c478bd9Sstevel@tonic-gate 	if (void_func && bindings_exist()) {
3027c478bd9Sstevel@tonic-gate 		/* To become a warning, as there are spec errors! TBD */
3037c478bd9Sstevel@tonic-gate 		errlog(FATAL, "exception bindings found in a "
3047c478bd9Sstevel@tonic-gate 			"void function");
3057c478bd9Sstevel@tonic-gate 	} else if (void_func || need_bindings(exception) == NO) {
3067c478bd9Sstevel@tonic-gate 		(void) fprintf(Bodyfp,
3077c478bd9Sstevel@tonic-gate 		    "    (void) putc('\\n', ABISTREAM);\n");
3087c478bd9Sstevel@tonic-gate 		(void) putc('\n', Bodyfp);
3097c478bd9Sstevel@tonic-gate 		errlog(END, "}");
3107c478bd9Sstevel@tonic-gate 		return (NO);
3117c478bd9Sstevel@tonic-gate 	} else {
3127c478bd9Sstevel@tonic-gate 		/*
3137c478bd9Sstevel@tonic-gate 		 * Then there is a return value, so we try to
3147c478bd9Sstevel@tonic-gate 		 * generate exception bindings
3157c478bd9Sstevel@tonic-gate 		 * and code to print errno on exception.
3167c478bd9Sstevel@tonic-gate 		 */
3177c478bd9Sstevel@tonic-gate 		if ((generate_bindings(exception)) != ANTONYMS) {
3187c478bd9Sstevel@tonic-gate 			/* Generate code to cross-evaluate them. */
3197c478bd9Sstevel@tonic-gate 			(void) fprintf(Bodyfp,
3207c478bd9Sstevel@tonic-gate 			    "    if (!exception) {\n");
3217c478bd9Sstevel@tonic-gate 			errlog(END, "}");
3227c478bd9Sstevel@tonic-gate 			return (YES);
3237c478bd9Sstevel@tonic-gate 		}
3247c478bd9Sstevel@tonic-gate 	}
3257c478bd9Sstevel@tonic-gate 
3267c478bd9Sstevel@tonic-gate 	/* should not get here */
3277c478bd9Sstevel@tonic-gate 	errlog(END, "}");
3287c478bd9Sstevel@tonic-gate 	return (NO);
3297c478bd9Sstevel@tonic-gate }
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate /*
3327c478bd9Sstevel@tonic-gate  * generate_return_printf -- print the return value and end the line
3337c478bd9Sstevel@tonic-gate  */
3347c478bd9Sstevel@tonic-gate static void
generate_return_printf(int void_func)3357c478bd9Sstevel@tonic-gate generate_return_printf(int void_func)
3367c478bd9Sstevel@tonic-gate {
3377c478bd9Sstevel@tonic-gate 	errlog(BEGIN, "generate_return_printf() {");
3387c478bd9Sstevel@tonic-gate 	if (void_func) {
3397c478bd9Sstevel@tonic-gate 		(void) fprintf(Bodyfp,  "    putc('\\n', ABISTREAM);\n");
3407c478bd9Sstevel@tonic-gate 		errlog(END, "}");
3417c478bd9Sstevel@tonic-gate 		return;
3427c478bd9Sstevel@tonic-gate 	}
3437c478bd9Sstevel@tonic-gate 	/* If its a non-void function there are bindings. */
3447c478bd9Sstevel@tonic-gate 	(void) fprintf(Bodyfp,
3457c478bd9Sstevel@tonic-gate 	    "\t/* Just end the line */\n"
3467c478bd9Sstevel@tonic-gate 	    "\tputc('\\n', ABISTREAM);\n"
3477c478bd9Sstevel@tonic-gate 	    "    }\n"
3487c478bd9Sstevel@tonic-gate 	    "    else {\n"
3497c478bd9Sstevel@tonic-gate 	    "        fprintf(ABISTREAM, \"%%s%%d (%%s)\\n\", errnostr, "
3507c478bd9Sstevel@tonic-gate 	    "functions_errvar, strerror((int)functions_errvar));\n"
3517c478bd9Sstevel@tonic-gate 	    "    }\n\n");
3527c478bd9Sstevel@tonic-gate 	errlog(END, "}");
3537c478bd9Sstevel@tonic-gate }
3547c478bd9Sstevel@tonic-gate 
3557c478bd9Sstevel@tonic-gate /*
3567c478bd9Sstevel@tonic-gate  * generate_i_prints -- if we're doing the verbose stuff,
3577c478bd9Sstevel@tonic-gate  *      generate verbose printouts of the variables.
3587c478bd9Sstevel@tonic-gate  */
3597c478bd9Sstevel@tonic-gate static void
generate_i_prints(ENTRY * function,char * lib,char * func)3607c478bd9Sstevel@tonic-gate generate_i_prints(ENTRY *function, char *lib, char *func)
3617c478bd9Sstevel@tonic-gate {
3627c478bd9Sstevel@tonic-gate 	ENTRY   *e;
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate 	errlog(BEGIN, "generate_i_prints() {");
3657c478bd9Sstevel@tonic-gate 	if ((e = symtab_get_first_arg()) != NULL || !is_void(e)) {
3667c478bd9Sstevel@tonic-gate 		/* Then we have to generate code for verbose reports. */
3677c478bd9Sstevel@tonic-gate 		(void) fprintf(Bodyfp,  "    if (ABI_VFLAG(%s, %s) != 0) {\n",
3687c478bd9Sstevel@tonic-gate 			lib, func);
3697c478bd9Sstevel@tonic-gate 		generate_printfunc_calls(function);
3707c478bd9Sstevel@tonic-gate 		(void) fprintf(Bodyfp,  "    }\n");
3717c478bd9Sstevel@tonic-gate 	}
3727c478bd9Sstevel@tonic-gate 	(void) putc('\n', Bodyfp);
3737c478bd9Sstevel@tonic-gate 	errlog(END, "}");
3747c478bd9Sstevel@tonic-gate }
3757c478bd9Sstevel@tonic-gate 
3767c478bd9Sstevel@tonic-gate /*
3777c478bd9Sstevel@tonic-gate  * generate_i_closedown -- restore error variables and return.
3787c478bd9Sstevel@tonic-gate  */
3797c478bd9Sstevel@tonic-gate static void
generate_i_closedown(char * error_name,int void_func)3807c478bd9Sstevel@tonic-gate generate_i_closedown(char *error_name, int void_func)
3817c478bd9Sstevel@tonic-gate {
3827c478bd9Sstevel@tonic-gate 	errlog(BEGIN, "generate_i_closedown() {");
3837c478bd9Sstevel@tonic-gate 
3847c478bd9Sstevel@tonic-gate 	/* unlock stdio */
3857c478bd9Sstevel@tonic-gate 	(void) fprintf(Bodyfp,
3867c478bd9Sstevel@tonic-gate 	    "    abiunlock(&omask);\n");
3877c478bd9Sstevel@tonic-gate 
388*07c94cbfSToomas Soome 	if (*error_name != '\0') {
3897c478bd9Sstevel@tonic-gate 		/* Restore error variables. */
3907c478bd9Sstevel@tonic-gate 		(void) fprintf(Bodyfp,
3917c478bd9Sstevel@tonic-gate 		    "    %s = (functions_errvar == 0)? "
3927c478bd9Sstevel@tonic-gate 		    "            saved_errvar: functions_errvar;\n",
3937c478bd9Sstevel@tonic-gate 		    error_name);
3947c478bd9Sstevel@tonic-gate 	}
3957c478bd9Sstevel@tonic-gate 
3967c478bd9Sstevel@tonic-gate 	/* And return. */
3977c478bd9Sstevel@tonic-gate 	(void) fprintf(Bodyfp,
3987c478bd9Sstevel@tonic-gate 	    "    return%s;\n",
3997c478bd9Sstevel@tonic-gate 	    (void_func)? "": " _return");
4007c478bd9Sstevel@tonic-gate 	(void) fprintf(Bodyfp,  "}\n");
4017c478bd9Sstevel@tonic-gate 	(void) putc('\n', Bodyfp);
4027c478bd9Sstevel@tonic-gate 	errlog(END, "}");
4037c478bd9Sstevel@tonic-gate }
4047c478bd9Sstevel@tonic-gate 
4057c478bd9Sstevel@tonic-gate 
4067c478bd9Sstevel@tonic-gate /*
4077c478bd9Sstevel@tonic-gate  * generate_i_live_vars -- generate temps for any ``out''
4087c478bd9Sstevel@tonic-gate  *	or ``inout'' variables in the function.  Deferred.
4097c478bd9Sstevel@tonic-gate  */
4107c478bd9Sstevel@tonic-gate /*ARGSUSED*/
4117c478bd9Sstevel@tonic-gate static void
generate_i_live_vars(ENTRY * function)4127c478bd9Sstevel@tonic-gate generate_i_live_vars(ENTRY *function)
4137c478bd9Sstevel@tonic-gate {
4147c478bd9Sstevel@tonic-gate 	errlog(BEGIN, "generate_i_live_vars() {");
4157c478bd9Sstevel@tonic-gate 	errlog(END, "}");
4167c478bd9Sstevel@tonic-gate }
4177c478bd9Sstevel@tonic-gate 
4187c478bd9Sstevel@tonic-gate /*
4197c478bd9Sstevel@tonic-gate  * generate_i_evaluations -- generate evaluations for
4207c478bd9Sstevel@tonic-gate  *	all the expressions. Deferred.
4217c478bd9Sstevel@tonic-gate  */
4227c478bd9Sstevel@tonic-gate /*ARGSUSED*/
4237c478bd9Sstevel@tonic-gate static void
generate_i_evaluations(ENTRY * function)4247c478bd9Sstevel@tonic-gate generate_i_evaluations(ENTRY *function)
4257c478bd9Sstevel@tonic-gate {
4267c478bd9Sstevel@tonic-gate 	errlog(BEGIN, "generate_i_evaluations() {");
4277c478bd9Sstevel@tonic-gate 	errlog(END, "}");
4287c478bd9Sstevel@tonic-gate }
4297c478bd9Sstevel@tonic-gate 
4307c478bd9Sstevel@tonic-gate 
4317c478bd9Sstevel@tonic-gate static char *
variables_get_errorname(void)4327c478bd9Sstevel@tonic-gate variables_get_errorname(void)
4337c478bd9Sstevel@tonic-gate {
4347c478bd9Sstevel@tonic-gate 	return ("ABI_ERRNO");
4357c478bd9Sstevel@tonic-gate }
436