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