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 2003 Sun Microsystems, Inc. All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate /*
287c478bd9Sstevel@tonic-gate * Back-end functions for spec to mapfile converter
297c478bd9Sstevel@tonic-gate */
307c478bd9Sstevel@tonic-gate
317c478bd9Sstevel@tonic-gate #include <stdio.h>
327c478bd9Sstevel@tonic-gate #include <stdlib.h>
337c478bd9Sstevel@tonic-gate #include <ctype.h>
347c478bd9Sstevel@tonic-gate #include <string.h>
357c478bd9Sstevel@tonic-gate #include <errno.h>
367c478bd9Sstevel@tonic-gate #include <sys/utsname.h>
377c478bd9Sstevel@tonic-gate #include "xlator.h"
387c478bd9Sstevel@tonic-gate #include "util.h"
397c478bd9Sstevel@tonic-gate #include "bucket.h"
407c478bd9Sstevel@tonic-gate
417c478bd9Sstevel@tonic-gate /* Globals */
427c478bd9Sstevel@tonic-gate enum {
437c478bd9Sstevel@tonic-gate /* These first four (commented out) are defined in parser.h */
447c478bd9Sstevel@tonic-gate /* XLATOR_KW_NOTFOUND = 0, */
457c478bd9Sstevel@tonic-gate /* XLATOR_KW_FUNC, */
467c478bd9Sstevel@tonic-gate /* XLATOR_KW_DATA, */
477c478bd9Sstevel@tonic-gate /* XLATOR_KW_END, */
487c478bd9Sstevel@tonic-gate XLATOR_KW_VERSION = 4,
497c478bd9Sstevel@tonic-gate XLATOR_KW_ARCH,
507c478bd9Sstevel@tonic-gate XLATOR_KW_BINDING,
517c478bd9Sstevel@tonic-gate XLATOR_KW_FILTER,
527c478bd9Sstevel@tonic-gate XLATOR_KW_AUXILIARY
537c478bd9Sstevel@tonic-gate };
547c478bd9Sstevel@tonic-gate #define FIRST_TOKEN 4 /* Must match the first token in the enum above */
557c478bd9Sstevel@tonic-gate
567c478bd9Sstevel@tonic-gate static xlator_keyword_t Keywords[] = {
577c478bd9Sstevel@tonic-gate { "version", XLATOR_KW_VERSION },
587c478bd9Sstevel@tonic-gate { "arch", XLATOR_KW_ARCH },
597c478bd9Sstevel@tonic-gate { "binding", XLATOR_KW_BINDING },
607c478bd9Sstevel@tonic-gate { "filter", XLATOR_KW_FILTER },
617c478bd9Sstevel@tonic-gate { "auxiliary", XLATOR_KW_AUXILIARY },
627c478bd9Sstevel@tonic-gate { NULL, XLATOR_KW_NOTFOUND }
637c478bd9Sstevel@tonic-gate };
647c478bd9Sstevel@tonic-gate
657c478bd9Sstevel@tonic-gate static char const *OutputFile;
667c478bd9Sstevel@tonic-gate static char const *Curfile;
677c478bd9Sstevel@tonic-gate static char *Curfun;
687c478bd9Sstevel@tonic-gate static int Curline;
697c478bd9Sstevel@tonic-gate static Interface Iface;
707c478bd9Sstevel@tonic-gate
717c478bd9Sstevel@tonic-gate static int Verbosity;
727c478bd9Sstevel@tonic-gate static int TargetArchToken; /* set from -a option to front-end */
737c478bd9Sstevel@tonic-gate char *TargetArchStr = NULL; /* from -a option to front-end */
747c478bd9Sstevel@tonic-gate int IsFilterLib = 0; /* set from -F option to front-end */
757c478bd9Sstevel@tonic-gate static int Supported_Arch = XLATOR_ALLARCH; /* from "Arch" SPEC keyword */
767c478bd9Sstevel@tonic-gate static int Flags;
777c478bd9Sstevel@tonic-gate
787c478bd9Sstevel@tonic-gate /*
797c478bd9Sstevel@tonic-gate * WHAT!?
807c478bd9Sstevel@tonic-gate * from Version line
817c478bd9Sstevel@tonic-gate * 0 means architecture is not specified in the
827c478bd9Sstevel@tonic-gate * version line so it applies to all versions
837c478bd9Sstevel@tonic-gate */
847c478bd9Sstevel@tonic-gate static int Version_Arch;
857c478bd9Sstevel@tonic-gate int Num_versfiles = 0;
867c478bd9Sstevel@tonic-gate static int Has_Version;
877c478bd9Sstevel@tonic-gate
887c478bd9Sstevel@tonic-gate static char *Versfile;
897c478bd9Sstevel@tonic-gate
907c478bd9Sstevel@tonic-gate static char *getversion(const char *);
917c478bd9Sstevel@tonic-gate static int version_sanity(const char *value, char **subv);
927c478bd9Sstevel@tonic-gate static int arch_version_sanity(char *av);
937c478bd9Sstevel@tonic-gate static char *getfilter(const char *);
947c478bd9Sstevel@tonic-gate static void writemapfile(FILE *);
957c478bd9Sstevel@tonic-gate static int set_version_arch(const char *);
967c478bd9Sstevel@tonic-gate static int set_supported_arch(const char *);
977c478bd9Sstevel@tonic-gate
987c478bd9Sstevel@tonic-gate /*
997c478bd9Sstevel@tonic-gate * xlator_init()
1007c478bd9Sstevel@tonic-gate * back-end initialization
1017c478bd9Sstevel@tonic-gate * returns pointer to Keywords on success
1027c478bd9Sstevel@tonic-gate * returns NULL pointer on failure
1037c478bd9Sstevel@tonic-gate */
1047c478bd9Sstevel@tonic-gate xlator_keyword_t *
xlator_init(const Translator_info * t_info)1057c478bd9Sstevel@tonic-gate xlator_init(const Translator_info *t_info)
1067c478bd9Sstevel@tonic-gate {
1077c478bd9Sstevel@tonic-gate /*
1087c478bd9Sstevel@tonic-gate * initially so we don't lose error messages from version_check
1097c478bd9Sstevel@tonic-gate * we'll set this again later based on ti_info.ti_verbosity
1107c478bd9Sstevel@tonic-gate */
1117c478bd9Sstevel@tonic-gate seterrseverity(WARNING);
1127c478bd9Sstevel@tonic-gate
1137c478bd9Sstevel@tonic-gate /* set verbosity */
1147c478bd9Sstevel@tonic-gate Verbosity = t_info->ti_verbosity;
1157c478bd9Sstevel@tonic-gate seterrseverity(t_info->ti_verbosity);
1167c478bd9Sstevel@tonic-gate
1177c478bd9Sstevel@tonic-gate /* Obtain translator flags */
1187c478bd9Sstevel@tonic-gate Flags = t_info->ti_flags;
1197c478bd9Sstevel@tonic-gate
1207c478bd9Sstevel@tonic-gate /*
1217c478bd9Sstevel@tonic-gate * set Library Type
1227c478bd9Sstevel@tonic-gate * 1 if filter lib, 0 otherwise
1237c478bd9Sstevel@tonic-gate */
1247c478bd9Sstevel@tonic-gate IsFilterLib = t_info->ti_libtype;
1257c478bd9Sstevel@tonic-gate
1267c478bd9Sstevel@tonic-gate /* set target architecture */
1277c478bd9Sstevel@tonic-gate TargetArchStr = t_info->ti_arch;
1287c478bd9Sstevel@tonic-gate TargetArchToken = t_info->ti_archtoken;
1297c478bd9Sstevel@tonic-gate
1307c478bd9Sstevel@tonic-gate errlog(STATUS, "Architecture set to \"%s\"", TargetArchStr);
1317c478bd9Sstevel@tonic-gate
1327c478bd9Sstevel@tonic-gate /* set output file */
1337c478bd9Sstevel@tonic-gate OutputFile = t_info->ti_output_file;
1347c478bd9Sstevel@tonic-gate if (OutputFile) {
1357c478bd9Sstevel@tonic-gate errlog(STATUS, "Output will go into %s",
1367c478bd9Sstevel@tonic-gate OutputFile);
1377c478bd9Sstevel@tonic-gate } else {
1387c478bd9Sstevel@tonic-gate OutputFile = "mapfile";
1397c478bd9Sstevel@tonic-gate errlog(STATUS, "Using default output filename: %s",
1407c478bd9Sstevel@tonic-gate OutputFile);
1417c478bd9Sstevel@tonic-gate }
1427c478bd9Sstevel@tonic-gate
1437c478bd9Sstevel@tonic-gate /* obtain name of version file */
1447c478bd9Sstevel@tonic-gate Versfile = t_info->ti_versfile;
1457c478bd9Sstevel@tonic-gate
1467c478bd9Sstevel@tonic-gate /* call create_lists() to setup for parse_versions() */
1477c478bd9Sstevel@tonic-gate create_lists();
1487c478bd9Sstevel@tonic-gate
1497c478bd9Sstevel@tonic-gate /* Process Vers Files */
1507c478bd9Sstevel@tonic-gate if (parse_versions(Versfile)) {
1517c478bd9Sstevel@tonic-gate return (NULL);
1527c478bd9Sstevel@tonic-gate }
1537c478bd9Sstevel@tonic-gate
1547c478bd9Sstevel@tonic-gate return (Keywords);
1557c478bd9Sstevel@tonic-gate }
1567c478bd9Sstevel@tonic-gate
1577c478bd9Sstevel@tonic-gate /*
1587c478bd9Sstevel@tonic-gate * xlator_startlib()
1597c478bd9Sstevel@tonic-gate * start of library
1607c478bd9Sstevel@tonic-gate * returns: XLATOR_SUCCESS on success
1617c478bd9Sstevel@tonic-gate * XLATOR_SKIP if library is to be skipped
1627c478bd9Sstevel@tonic-gate * XLATOR_NONFATAL on error
1637c478bd9Sstevel@tonic-gate */
1647c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1657c478bd9Sstevel@tonic-gate int
xlator_startlib(char const * libname)1667c478bd9Sstevel@tonic-gate xlator_startlib(char const *libname)
1677c478bd9Sstevel@tonic-gate {
1687c478bd9Sstevel@tonic-gate errlog(TRACING, "xlator_startlib");
1697c478bd9Sstevel@tonic-gate return (XLATOR_SUCCESS);
1707c478bd9Sstevel@tonic-gate }
1717c478bd9Sstevel@tonic-gate
1727c478bd9Sstevel@tonic-gate /*
1737c478bd9Sstevel@tonic-gate * xlator_startfile()
1747c478bd9Sstevel@tonic-gate * start of spec file
1757c478bd9Sstevel@tonic-gate * returns: XLATOR_SUCCESS on success
1767c478bd9Sstevel@tonic-gate * XLATOR_SKIP if file is to be skipped
1777c478bd9Sstevel@tonic-gate * XLATOR_NONFATAL on error
1787c478bd9Sstevel@tonic-gate */
1797c478bd9Sstevel@tonic-gate int
xlator_startfile(char const * filename)1807c478bd9Sstevel@tonic-gate xlator_startfile(char const *filename)
1817c478bd9Sstevel@tonic-gate {
1827c478bd9Sstevel@tonic-gate errlog(TRACING, "xlator_startfile");
1837c478bd9Sstevel@tonic-gate
1847c478bd9Sstevel@tonic-gate Curfile = filename;
1857c478bd9Sstevel@tonic-gate
1867c478bd9Sstevel@tonic-gate return (XLATOR_SUCCESS);
1877c478bd9Sstevel@tonic-gate }
1887c478bd9Sstevel@tonic-gate
1897c478bd9Sstevel@tonic-gate /*
1907c478bd9Sstevel@tonic-gate * xlator_start_if ()
1917c478bd9Sstevel@tonic-gate * start of interface specification
1927c478bd9Sstevel@tonic-gate * returns: XLATOR_SUCCESS on success
1937c478bd9Sstevel@tonic-gate * XLATOR_SKIP if interface is to be skipped
1947c478bd9Sstevel@tonic-gate * XLATOR_NONFATAL on error
1957c478bd9Sstevel@tonic-gate * XLATOR_FATAL on fatal error
1967c478bd9Sstevel@tonic-gate */
1977c478bd9Sstevel@tonic-gate int
xlator_start_if(const Meta_info meta_info,const int token,char * value)1987c478bd9Sstevel@tonic-gate xlator_start_if(const Meta_info meta_info, const int token, char *value)
1997c478bd9Sstevel@tonic-gate {
2007c478bd9Sstevel@tonic-gate char rhs[BUFSIZ];
2017c478bd9Sstevel@tonic-gate char *kw;
2027c478bd9Sstevel@tonic-gate int err;
2037c478bd9Sstevel@tonic-gate
2047c478bd9Sstevel@tonic-gate errlog(TRACING, "xlator_start_if %s", value);
2057c478bd9Sstevel@tonic-gate
2067c478bd9Sstevel@tonic-gate switch (token) {
2077c478bd9Sstevel@tonic-gate case XLATOR_KW_FUNC:
2087c478bd9Sstevel@tonic-gate kw = "Function";
2097c478bd9Sstevel@tonic-gate break;
2107c478bd9Sstevel@tonic-gate case XLATOR_KW_DATA:
2117c478bd9Sstevel@tonic-gate kw = "Data";
2127c478bd9Sstevel@tonic-gate break;
2137c478bd9Sstevel@tonic-gate default:
2147c478bd9Sstevel@tonic-gate /* This should never happen */
2157c478bd9Sstevel@tonic-gate errlog(ERROR,
2167c478bd9Sstevel@tonic-gate "\"%s\", line %d: Implementation error! "
2177c478bd9Sstevel@tonic-gate "Please file a bug\n", __FILE__, __LINE__);
2187c478bd9Sstevel@tonic-gate return (XLATOR_FATAL);
2197c478bd9Sstevel@tonic-gate }
2207c478bd9Sstevel@tonic-gate
2217c478bd9Sstevel@tonic-gate Curline = meta_info.mi_line_number;
2227c478bd9Sstevel@tonic-gate seterrline(Curline, meta_info.mi_filename, kw, value);
2237c478bd9Sstevel@tonic-gate
2247c478bd9Sstevel@tonic-gate if (Curfun != NULL) {
2257c478bd9Sstevel@tonic-gate errlog(INPUT|ERROR,
2267c478bd9Sstevel@tonic-gate "Error: Interface spec is missing the "
2277c478bd9Sstevel@tonic-gate "End keyword: %s", Curfun);
2287c478bd9Sstevel@tonic-gate return (XLATOR_NONFATAL);
2297c478bd9Sstevel@tonic-gate }
2307c478bd9Sstevel@tonic-gate
2317c478bd9Sstevel@tonic-gate err = sscanf(value, "%s", rhs);
2327c478bd9Sstevel@tonic-gate if (err == 0 || err == EOF) {
2337c478bd9Sstevel@tonic-gate errlog(INPUT|ERROR,
2347c478bd9Sstevel@tonic-gate "Error: Missing argument in \"%s\" line", kw);
2357c478bd9Sstevel@tonic-gate return (XLATOR_NONFATAL);
2367c478bd9Sstevel@tonic-gate }
2377c478bd9Sstevel@tonic-gate
2387c478bd9Sstevel@tonic-gate Curfun = strdup(rhs);
2397c478bd9Sstevel@tonic-gate
2407c478bd9Sstevel@tonic-gate if (Curfun == NULL) {
2417c478bd9Sstevel@tonic-gate errlog(ERROR | FATAL,
2427c478bd9Sstevel@tonic-gate "Internal Error: strdup() failure in xlator_startif()");
2437c478bd9Sstevel@tonic-gate }
2447c478bd9Sstevel@tonic-gate
2457c478bd9Sstevel@tonic-gate Iface.IF_name = Curfun;
2467c478bd9Sstevel@tonic-gate Iface.IF_type = token; /* FUNCTION or DATA */
2477c478bd9Sstevel@tonic-gate
2487c478bd9Sstevel@tonic-gate Iface.IF_version = NULL;
2497c478bd9Sstevel@tonic-gate Iface.IF_class = NULL;
2507c478bd9Sstevel@tonic-gate Has_Version = 0;
2517c478bd9Sstevel@tonic-gate Supported_Arch = XLATOR_ALLARCH;
2527c478bd9Sstevel@tonic-gate Version_Arch = 0;
2537c478bd9Sstevel@tonic-gate
2547c478bd9Sstevel@tonic-gate Iface.IF_binding = DEFAULT;
2557c478bd9Sstevel@tonic-gate
2567c478bd9Sstevel@tonic-gate Iface.IF_filter = NULL;
2577c478bd9Sstevel@tonic-gate Iface.IF_auxiliary = NULL;
2587c478bd9Sstevel@tonic-gate
2597c478bd9Sstevel@tonic-gate return (XLATOR_SUCCESS);
2607c478bd9Sstevel@tonic-gate }
2617c478bd9Sstevel@tonic-gate
2627c478bd9Sstevel@tonic-gate /*
2637c478bd9Sstevel@tonic-gate * xlator_take_kvpair()
2647c478bd9Sstevel@tonic-gate * processes spec keyword-value pairs
2657c478bd9Sstevel@tonic-gate * returns: XLATOR_SUCCESS on success
2667c478bd9Sstevel@tonic-gate * XLATOR_NONFATAL on error
2677c478bd9Sstevel@tonic-gate */
2687c478bd9Sstevel@tonic-gate int
xlator_take_kvpair(const Meta_info meta_info,const int token,char * value)269*c473d156SToomas Soome xlator_take_kvpair(const Meta_info meta_info, const int token, char *value)
2707c478bd9Sstevel@tonic-gate {
2717c478bd9Sstevel@tonic-gate char *p;
2727c478bd9Sstevel@tonic-gate char *subv = NULL;
2737c478bd9Sstevel@tonic-gate char *key = Keywords[token-FIRST_TOKEN].key;
2747c478bd9Sstevel@tonic-gate
2757c478bd9Sstevel@tonic-gate Curline = meta_info.mi_line_number;
2767c478bd9Sstevel@tonic-gate seterrline(Curline, meta_info.mi_filename, key, value);
2777c478bd9Sstevel@tonic-gate
2787c478bd9Sstevel@tonic-gate errlog(TRACING,
2797c478bd9Sstevel@tonic-gate "take_kvpair called. ext_cnt=%d token=%d key=%s value=%s",
2807c478bd9Sstevel@tonic-gate meta_info.mi_ext_cnt, token, key, value);
2817c478bd9Sstevel@tonic-gate
2827c478bd9Sstevel@tonic-gate if (Curfun == NULL) {
2837c478bd9Sstevel@tonic-gate errlog(INPUT|ERROR, "Error: Keyword found outside "
2847c478bd9Sstevel@tonic-gate "an interface specification block, line %d", Curline);
2857c478bd9Sstevel@tonic-gate return (XLATOR_NONFATAL);
2867c478bd9Sstevel@tonic-gate }
2877c478bd9Sstevel@tonic-gate
2887c478bd9Sstevel@tonic-gate switch (token) {
2897c478bd9Sstevel@tonic-gate case XLATOR_KW_VERSION:
2907c478bd9Sstevel@tonic-gate if (meta_info.mi_ext_cnt != 0)
2917c478bd9Sstevel@tonic-gate return (XLATOR_SUCCESS);
2927c478bd9Sstevel@tonic-gate
2937c478bd9Sstevel@tonic-gate errlog(TRACING, "Version found. Setting Version to %s", value);
2947c478bd9Sstevel@tonic-gate
2957c478bd9Sstevel@tonic-gate /* Version line found ; used for auditing the SPEC */
2967c478bd9Sstevel@tonic-gate Has_Version = 1;
2977c478bd9Sstevel@tonic-gate
2987c478bd9Sstevel@tonic-gate /* remove trailing white space */
2997c478bd9Sstevel@tonic-gate p = strrchr(value, '\n');
3007c478bd9Sstevel@tonic-gate if (p) {
3017c478bd9Sstevel@tonic-gate while (p >= value && isspace(*p)) {
3027c478bd9Sstevel@tonic-gate *p = '\0';
3037c478bd9Sstevel@tonic-gate --p;
3047c478bd9Sstevel@tonic-gate }
3057c478bd9Sstevel@tonic-gate }
3067c478bd9Sstevel@tonic-gate
3077c478bd9Sstevel@tonic-gate /* is the version line valid */
3087c478bd9Sstevel@tonic-gate switch (version_sanity(value, &subv)) {
3097c478bd9Sstevel@tonic-gate case VS_OK: /* OK, subv not set */
3107c478bd9Sstevel@tonic-gate break;
3117c478bd9Sstevel@tonic-gate
3127c478bd9Sstevel@tonic-gate case VS_INVARCH: /* Invalid Arch */
3137c478bd9Sstevel@tonic-gate errlog(INPUT|ERROR, "Error: Invalid architecture "
3147c478bd9Sstevel@tonic-gate "string found in spec or version file: %s", subv);
3157c478bd9Sstevel@tonic-gate free(subv);
3167c478bd9Sstevel@tonic-gate return (XLATOR_NONFATAL);
3177c478bd9Sstevel@tonic-gate
3187c478bd9Sstevel@tonic-gate case VS_INVVERS: /* Invalid Version String */
3197c478bd9Sstevel@tonic-gate errlog(INPUT|ERROR, "Error: Invalid version string "
3207c478bd9Sstevel@tonic-gate "in spec or version file: %s", subv);
3217c478bd9Sstevel@tonic-gate free(subv);
3227c478bd9Sstevel@tonic-gate return (XLATOR_NONFATAL);
3237c478bd9Sstevel@tonic-gate
3247c478bd9Sstevel@tonic-gate case VS_INVALID: /* Both Version and Arch are invalid */
3257c478bd9Sstevel@tonic-gate errlog(INPUT|ERROR, "Error: Invalid version and "
3267c478bd9Sstevel@tonic-gate "architecture string in spec or version file"
327*c473d156SToomas Soome ": %s", subv);
3287c478bd9Sstevel@tonic-gate free(subv);
3297c478bd9Sstevel@tonic-gate return (XLATOR_NONFATAL);
3307c478bd9Sstevel@tonic-gate
3317c478bd9Sstevel@tonic-gate default: /* BAD IMPLEMENTATION OF version_sanity */
3327c478bd9Sstevel@tonic-gate errlog(FATAL, "Error: bad return value from "
3337c478bd9Sstevel@tonic-gate "version_sanity()! This should never happen!");
3347c478bd9Sstevel@tonic-gate }
3357c478bd9Sstevel@tonic-gate
3367c478bd9Sstevel@tonic-gate errlog(TRACING, "Version_Arch=%d", Version_Arch);
3377c478bd9Sstevel@tonic-gate
3387c478bd9Sstevel@tonic-gate Iface.IF_version = getversion(value);
3397c478bd9Sstevel@tonic-gate break;
3407c478bd9Sstevel@tonic-gate
3417c478bd9Sstevel@tonic-gate case XLATOR_KW_ARCH:
3427c478bd9Sstevel@tonic-gate if (meta_info.mi_ext_cnt != 0)
3437c478bd9Sstevel@tonic-gate return (XLATOR_SUCCESS);
3447c478bd9Sstevel@tonic-gate
3457c478bd9Sstevel@tonic-gate if (value[0] != '\0') {
3467c478bd9Sstevel@tonic-gate Supported_Arch = 0;
3477c478bd9Sstevel@tonic-gate if (set_supported_arch(value)) {
3487c478bd9Sstevel@tonic-gate errlog(INPUT|ERROR,
3497c478bd9Sstevel@tonic-gate "Error: Unable to parse Arch line");
3507c478bd9Sstevel@tonic-gate return (XLATOR_NONFATAL);
3517c478bd9Sstevel@tonic-gate }
3527c478bd9Sstevel@tonic-gate } else {
3537c478bd9Sstevel@tonic-gate errlog(INPUT | ERROR, "Error: Empty Arch line.");
3547c478bd9Sstevel@tonic-gate }
3557c478bd9Sstevel@tonic-gate
3567c478bd9Sstevel@tonic-gate if (Supported_Arch == 0) {
3577c478bd9Sstevel@tonic-gate errlog(INPUT | ERROR,
3587c478bd9Sstevel@tonic-gate "Error: Unknown architecture defined in Arch line");
3597c478bd9Sstevel@tonic-gate }
3607c478bd9Sstevel@tonic-gate
3617c478bd9Sstevel@tonic-gate errlog(TRACING,
3627c478bd9Sstevel@tonic-gate "Interface %s supports the following architectures: "
3637c478bd9Sstevel@tonic-gate "%s\tSupported_Arch=%d", Curfun, value, Supported_Arch);
3647c478bd9Sstevel@tonic-gate break;
3657c478bd9Sstevel@tonic-gate
3667c478bd9Sstevel@tonic-gate case XLATOR_KW_BINDING:
3677c478bd9Sstevel@tonic-gate
3687c478bd9Sstevel@tonic-gate /*
3697c478bd9Sstevel@tonic-gate * Note that we allow extends for the binding keyword by
3707c478bd9Sstevel@tonic-gate * not checking that meta_info.mi_ext_cnt == 0 here.
3717c478bd9Sstevel@tonic-gate */
3727c478bd9Sstevel@tonic-gate
3737c478bd9Sstevel@tonic-gate /* remove trailing white space */
3747c478bd9Sstevel@tonic-gate p = strrchr(value, '\n');
3757c478bd9Sstevel@tonic-gate if (p) {
3767c478bd9Sstevel@tonic-gate while (p >= value && isspace(*p)) {
3777c478bd9Sstevel@tonic-gate *p = '\0';
3787c478bd9Sstevel@tonic-gate --p;
3797c478bd9Sstevel@tonic-gate }
3807c478bd9Sstevel@tonic-gate }
3817c478bd9Sstevel@tonic-gate
3827c478bd9Sstevel@tonic-gate if (value[0] != '\0') {
3837c478bd9Sstevel@tonic-gate if (strcmp(value, "direct") == 0) {
3847c478bd9Sstevel@tonic-gate Iface.IF_binding = DIRECT;
3857c478bd9Sstevel@tonic-gate } else if (strcmp(value, "nodirect") == 0) {
3867c478bd9Sstevel@tonic-gate Iface.IF_binding = NODIRECT;
3877c478bd9Sstevel@tonic-gate } else if (strcmp(value, "protected") == 0) {
3887c478bd9Sstevel@tonic-gate Iface.IF_binding = PROTECTED;
3897c478bd9Sstevel@tonic-gate } else {
3907c478bd9Sstevel@tonic-gate errlog(INPUT|ERROR,
3917c478bd9Sstevel@tonic-gate "Error: Invalid binding value: %s", value);
3927c478bd9Sstevel@tonic-gate }
3937c478bd9Sstevel@tonic-gate } else {
3947c478bd9Sstevel@tonic-gate errlog(INPUT | ERROR, "Error: Empty Binding line.");
3957c478bd9Sstevel@tonic-gate }
3967c478bd9Sstevel@tonic-gate
3977c478bd9Sstevel@tonic-gate errlog(TRACING,
3987c478bd9Sstevel@tonic-gate "Interface %s has binding value: "
3997c478bd9Sstevel@tonic-gate "%s", Curfun, value);
4007c478bd9Sstevel@tonic-gate break;
4017c478bd9Sstevel@tonic-gate
4027c478bd9Sstevel@tonic-gate case XLATOR_KW_FILTER:
4037c478bd9Sstevel@tonic-gate case XLATOR_KW_AUXILIARY:
4047c478bd9Sstevel@tonic-gate /*
4057c478bd9Sstevel@tonic-gate * The following is for the "extends" clause. As with
4067c478bd9Sstevel@tonic-gate * XLATOR_KW_VERSION, we do not want to follow an "extends"
4077c478bd9Sstevel@tonic-gate * chain to get the filter or auxiliary values: we want
4087c478bd9Sstevel@tonic-gate * the first/most-tightly-bound one (mi_ext_cnt = 0).
4097c478bd9Sstevel@tonic-gate */
4107c478bd9Sstevel@tonic-gate if (meta_info.mi_ext_cnt != 0)
4117c478bd9Sstevel@tonic-gate return (XLATOR_SUCCESS);
4127c478bd9Sstevel@tonic-gate
4137c478bd9Sstevel@tonic-gate errlog(TRACING, "Filter[token=%d] found. Setting Filter to %s",
4147c478bd9Sstevel@tonic-gate token, value);
4157c478bd9Sstevel@tonic-gate
4167c478bd9Sstevel@tonic-gate /* remove trailing white space */
4177c478bd9Sstevel@tonic-gate p = strrchr(value, '\n');
4187c478bd9Sstevel@tonic-gate if (p) {
4197c478bd9Sstevel@tonic-gate while (p >= value && isspace(*p)) {
4207c478bd9Sstevel@tonic-gate *p = '\0';
4217c478bd9Sstevel@tonic-gate --p;
4227c478bd9Sstevel@tonic-gate }
4237c478bd9Sstevel@tonic-gate }
4247c478bd9Sstevel@tonic-gate
4257c478bd9Sstevel@tonic-gate errlog(TRACING, "Version_Arch=%d", Version_Arch);
4267c478bd9Sstevel@tonic-gate
4277c478bd9Sstevel@tonic-gate if (token == XLATOR_KW_FILTER) {
4287c478bd9Sstevel@tonic-gate Iface.IF_filter = getfilter(value);
4297c478bd9Sstevel@tonic-gate } else if (token == XLATOR_KW_AUXILIARY) {
4307c478bd9Sstevel@tonic-gate Iface.IF_auxiliary = getfilter(value);
4317c478bd9Sstevel@tonic-gate }
4327c478bd9Sstevel@tonic-gate
4337c478bd9Sstevel@tonic-gate break;
4347c478bd9Sstevel@tonic-gate default:
4357c478bd9Sstevel@tonic-gate errlog(INPUT|ERROR, "Error: Unrecognized keyword snuck in!"
4367c478bd9Sstevel@tonic-gate "\tThis is a programmer error: %s", key);
4377c478bd9Sstevel@tonic-gate return (XLATOR_NONFATAL);
4387c478bd9Sstevel@tonic-gate }
4397c478bd9Sstevel@tonic-gate
4407c478bd9Sstevel@tonic-gate return (XLATOR_SUCCESS);
4417c478bd9Sstevel@tonic-gate }
4427c478bd9Sstevel@tonic-gate
4437c478bd9Sstevel@tonic-gate /*
4447c478bd9Sstevel@tonic-gate * xlator_end_if ()
4457c478bd9Sstevel@tonic-gate * signal end of spec interface spec
4467c478bd9Sstevel@tonic-gate * returns: XLATOR_SUCCESS on success
4477c478bd9Sstevel@tonic-gate * XLATOR_NONFATAL on error
4487c478bd9Sstevel@tonic-gate */
4497c478bd9Sstevel@tonic-gate /*ARGSUSED*/
4507c478bd9Sstevel@tonic-gate int
xlator_end_if(const Meta_info M,const char * value)4517c478bd9Sstevel@tonic-gate xlator_end_if(const Meta_info M, const char *value)
4527c478bd9Sstevel@tonic-gate {
4537c478bd9Sstevel@tonic-gate int retval = XLATOR_NONFATAL;
4547c478bd9Sstevel@tonic-gate int picky = Flags & XLATOR_PICKY_FLAG;
4557c478bd9Sstevel@tonic-gate
4567c478bd9Sstevel@tonic-gate seterrline(M.mi_line_number, M.mi_filename, "End", "");
4577c478bd9Sstevel@tonic-gate errlog(TRACING, "xlator_end_if");
4587c478bd9Sstevel@tonic-gate
4597c478bd9Sstevel@tonic-gate if (Curfun == NULL) {
4607c478bd9Sstevel@tonic-gate errlog(INPUT | ERROR, "Error: End without "
4617c478bd9Sstevel@tonic-gate "matching Function or Data in file \"%s\"", Curfile);
4627c478bd9Sstevel@tonic-gate goto cleanup;
4637c478bd9Sstevel@tonic-gate }
4647c478bd9Sstevel@tonic-gate
4657c478bd9Sstevel@tonic-gate errlog(TRACING, "Interface=%s", Iface.IF_name);
4667c478bd9Sstevel@tonic-gate
4677c478bd9Sstevel@tonic-gate if (!Has_Version) {
4687c478bd9Sstevel@tonic-gate if (picky) {
4697c478bd9Sstevel@tonic-gate errlog(INPUT | ERROR, "Error: Interface has no "
4707c478bd9Sstevel@tonic-gate "Version!\n\tInterface=%s\n\tSPEC File=%s",
4717c478bd9Sstevel@tonic-gate Iface.IF_name, Curfile);
4727c478bd9Sstevel@tonic-gate } else {
4737c478bd9Sstevel@tonic-gate errlog(INPUT | WARNING, "Warning: Interface has "
4747c478bd9Sstevel@tonic-gate "no Version!\n\tInterface=%s\n\tSPEC File=%s",
4757c478bd9Sstevel@tonic-gate Iface.IF_name, Curfile);
4767c478bd9Sstevel@tonic-gate retval = XLATOR_SUCCESS;
4777c478bd9Sstevel@tonic-gate }
4787c478bd9Sstevel@tonic-gate goto cleanup;
4797c478bd9Sstevel@tonic-gate }
4807c478bd9Sstevel@tonic-gate
4817c478bd9Sstevel@tonic-gate if (Version_Arch & (~Supported_Arch)) {
4827c478bd9Sstevel@tonic-gate errlog(INPUT | ERROR, "Error: Architectures in Version "
4837c478bd9Sstevel@tonic-gate "line must be a subset of Architectures in Arch line\n"
4847c478bd9Sstevel@tonic-gate "\tInterface=%s\n\tSPEC File=%s", Iface.IF_name, Curfile);
4857c478bd9Sstevel@tonic-gate goto cleanup;
4867c478bd9Sstevel@tonic-gate }
4877c478bd9Sstevel@tonic-gate
4887c478bd9Sstevel@tonic-gate if ((TargetArchToken & Supported_Arch) == 0) {
4897c478bd9Sstevel@tonic-gate /*
4907c478bd9Sstevel@tonic-gate * This interface is not for the architecture
4917c478bd9Sstevel@tonic-gate * we are currently processing, so we skip it.
4927c478bd9Sstevel@tonic-gate */
4937c478bd9Sstevel@tonic-gate retval = XLATOR_SUCCESS;
4947c478bd9Sstevel@tonic-gate goto cleanup;
4957c478bd9Sstevel@tonic-gate }
4967c478bd9Sstevel@tonic-gate
4977c478bd9Sstevel@tonic-gate if (Iface.IF_version == NULL) {
4987c478bd9Sstevel@tonic-gate if (picky) {
4997c478bd9Sstevel@tonic-gate errlog(ERROR|INPUT,
5007c478bd9Sstevel@tonic-gate "Error: Version was not found for "
5017c478bd9Sstevel@tonic-gate "\"%s\" architecture\n\tInterface=%s",
5027c478bd9Sstevel@tonic-gate TargetArchStr, Iface.IF_name);
5037c478bd9Sstevel@tonic-gate } else {
5047c478bd9Sstevel@tonic-gate errlog(WARNING | INPUT,
5057c478bd9Sstevel@tonic-gate "Warning: Version was not found for "
5067c478bd9Sstevel@tonic-gate "\"%s\" architecture\n\tInterface=%s",
5077c478bd9Sstevel@tonic-gate TargetArchStr, Iface.IF_name);
5087c478bd9Sstevel@tonic-gate retval = XLATOR_SUCCESS;
5097c478bd9Sstevel@tonic-gate }
5107c478bd9Sstevel@tonic-gate goto cleanup;
5117c478bd9Sstevel@tonic-gate }
5127c478bd9Sstevel@tonic-gate
5137c478bd9Sstevel@tonic-gate /* check Iface.IF_type */
5147c478bd9Sstevel@tonic-gate switch (Iface.IF_type) {
5157c478bd9Sstevel@tonic-gate case FUNCTION:
5167c478bd9Sstevel@tonic-gate errlog(VERBOSE, "Interface type = FUNCTION");
5177c478bd9Sstevel@tonic-gate break;
5187c478bd9Sstevel@tonic-gate case DATA:
5197c478bd9Sstevel@tonic-gate errlog(VERBOSE, "Interface type = DATA");
5207c478bd9Sstevel@tonic-gate break;
5217c478bd9Sstevel@tonic-gate case NOTYPE:
5227c478bd9Sstevel@tonic-gate errlog(WARNING,
5237c478bd9Sstevel@tonic-gate "Warning: Interface is neither "
5247c478bd9Sstevel@tonic-gate "DATA nor FUNCTION!!\n\t"
5257c478bd9Sstevel@tonic-gate "Interface=%s\n\tSPEC File=%s",
5267c478bd9Sstevel@tonic-gate Iface.IF_name, Curfile);
5277c478bd9Sstevel@tonic-gate break;
5287c478bd9Sstevel@tonic-gate default:
5297c478bd9Sstevel@tonic-gate errlog(ERROR, "Error: Bad spec2map implementation!\n"
5307c478bd9Sstevel@tonic-gate "\tInterface type is invalid\n"
5317c478bd9Sstevel@tonic-gate "\tThis should never happen.\n"
5327c478bd9Sstevel@tonic-gate "\tInterface=%s\tSPEC File=%s", Iface.IF_name, Curfile);
5337c478bd9Sstevel@tonic-gate goto cleanup;
5347c478bd9Sstevel@tonic-gate }
5357c478bd9Sstevel@tonic-gate
5367c478bd9Sstevel@tonic-gate (void) add_by_name(Iface.IF_version, &Iface);
5377c478bd9Sstevel@tonic-gate
5387c478bd9Sstevel@tonic-gate retval = XLATOR_SUCCESS;
5397c478bd9Sstevel@tonic-gate
5407c478bd9Sstevel@tonic-gate cleanup:
5417c478bd9Sstevel@tonic-gate
5427c478bd9Sstevel@tonic-gate /* cleanup */
5437c478bd9Sstevel@tonic-gate Iface.IF_name = NULL;
5447c478bd9Sstevel@tonic-gate
5457c478bd9Sstevel@tonic-gate free(Iface.IF_version);
5467c478bd9Sstevel@tonic-gate Iface.IF_version = NULL;
5477c478bd9Sstevel@tonic-gate
5487c478bd9Sstevel@tonic-gate free(Iface.IF_class);
5497c478bd9Sstevel@tonic-gate Iface.IF_class = NULL;
5507c478bd9Sstevel@tonic-gate
5517c478bd9Sstevel@tonic-gate free(Curfun);
5527c478bd9Sstevel@tonic-gate Curfun = NULL;
5537c478bd9Sstevel@tonic-gate
5547c478bd9Sstevel@tonic-gate Supported_Arch = XLATOR_ALLARCH;
5557c478bd9Sstevel@tonic-gate return (retval);
5567c478bd9Sstevel@tonic-gate }
5577c478bd9Sstevel@tonic-gate
5587c478bd9Sstevel@tonic-gate /*
5597c478bd9Sstevel@tonic-gate * xlator_endfile()
5607c478bd9Sstevel@tonic-gate * signal end of spec file
5617c478bd9Sstevel@tonic-gate * returns: XLATOR_SUCCESS on success
5627c478bd9Sstevel@tonic-gate * XLATOR_NONFATAL on error
5637c478bd9Sstevel@tonic-gate */
5647c478bd9Sstevel@tonic-gate int
xlator_endfile(void)5657c478bd9Sstevel@tonic-gate xlator_endfile(void)
5667c478bd9Sstevel@tonic-gate {
5677c478bd9Sstevel@tonic-gate
5687c478bd9Sstevel@tonic-gate errlog(TRACING, "xlator_endfile");
5697c478bd9Sstevel@tonic-gate
5707c478bd9Sstevel@tonic-gate Curfile = NULL;
5717c478bd9Sstevel@tonic-gate
5727c478bd9Sstevel@tonic-gate return (XLATOR_SUCCESS);
5737c478bd9Sstevel@tonic-gate }
5747c478bd9Sstevel@tonic-gate
5757c478bd9Sstevel@tonic-gate /*
5767c478bd9Sstevel@tonic-gate * xlator_endlib()
5777c478bd9Sstevel@tonic-gate * signal end of library
5787c478bd9Sstevel@tonic-gate * returns: XLATOR_SUCCESS on success
5797c478bd9Sstevel@tonic-gate * XLATOR_NONFATAL on error
5807c478bd9Sstevel@tonic-gate */
5817c478bd9Sstevel@tonic-gate int
xlator_endlib(void)5827c478bd9Sstevel@tonic-gate xlator_endlib(void)
5837c478bd9Sstevel@tonic-gate {
5847c478bd9Sstevel@tonic-gate FILE *mapfp;
5857c478bd9Sstevel@tonic-gate int retval = XLATOR_SUCCESS;
5867c478bd9Sstevel@tonic-gate
5877c478bd9Sstevel@tonic-gate errlog(TRACING, "xlator_endlib");
5887c478bd9Sstevel@tonic-gate
5897c478bd9Sstevel@tonic-gate /* Pretend to print mapfile */
5907c478bd9Sstevel@tonic-gate if (Verbosity >= TRACING) {
5917c478bd9Sstevel@tonic-gate print_all_buckets();
5927c478bd9Sstevel@tonic-gate }
5937c478bd9Sstevel@tonic-gate
5947c478bd9Sstevel@tonic-gate /* Everything read, now organize it! */
5957c478bd9Sstevel@tonic-gate sort_buckets();
5967c478bd9Sstevel@tonic-gate add_local();
5977c478bd9Sstevel@tonic-gate
5987c478bd9Sstevel@tonic-gate /* Create Output */
5997c478bd9Sstevel@tonic-gate mapfp = fopen(OutputFile, "w");
6007c478bd9Sstevel@tonic-gate if (mapfp == NULL) {
6017c478bd9Sstevel@tonic-gate errlog(ERROR,
6027c478bd9Sstevel@tonic-gate "Error: Unable to open output file \"%s\"\n\t%s",
6037c478bd9Sstevel@tonic-gate OutputFile, strerror(errno));
6047c478bd9Sstevel@tonic-gate retval = XLATOR_NONFATAL;
6057c478bd9Sstevel@tonic-gate } else {
6067c478bd9Sstevel@tonic-gate writemapfile(mapfp);
6077c478bd9Sstevel@tonic-gate (void) fclose(mapfp);
6087c478bd9Sstevel@tonic-gate }
6097c478bd9Sstevel@tonic-gate
6107c478bd9Sstevel@tonic-gate return (retval);
6117c478bd9Sstevel@tonic-gate }
6127c478bd9Sstevel@tonic-gate
6137c478bd9Sstevel@tonic-gate /*
6147c478bd9Sstevel@tonic-gate * xlator_end()
6157c478bd9Sstevel@tonic-gate * signal end of translation
6167c478bd9Sstevel@tonic-gate * returns: XLATOR_SUCCESS on success
6177c478bd9Sstevel@tonic-gate * XLATOR_NONFATAL on error
6187c478bd9Sstevel@tonic-gate */
6197c478bd9Sstevel@tonic-gate int
xlator_end(void)6207c478bd9Sstevel@tonic-gate xlator_end(void)
6217c478bd9Sstevel@tonic-gate {
6227c478bd9Sstevel@tonic-gate errlog(TRACING, "xlator_end");
6237c478bd9Sstevel@tonic-gate
6247c478bd9Sstevel@tonic-gate /* Destroy the list created by create_lists */
6257c478bd9Sstevel@tonic-gate delete_lists();
6267c478bd9Sstevel@tonic-gate
6277c478bd9Sstevel@tonic-gate return (XLATOR_SUCCESS);
6287c478bd9Sstevel@tonic-gate }
6297c478bd9Sstevel@tonic-gate
6307c478bd9Sstevel@tonic-gate /*
6317c478bd9Sstevel@tonic-gate * getversion()
6327c478bd9Sstevel@tonic-gate * called by xlator_take_kvpair when Version keyword is found
6337c478bd9Sstevel@tonic-gate * parses the Version string and returns the one that matches
6347c478bd9Sstevel@tonic-gate * the current target architecture
6357c478bd9Sstevel@tonic-gate *
6367c478bd9Sstevel@tonic-gate * the pointer returned by this function must be freed later.
6377c478bd9Sstevel@tonic-gate */
6387c478bd9Sstevel@tonic-gate static char *
getversion(const char * value)6397c478bd9Sstevel@tonic-gate getversion(const char *value)
6407c478bd9Sstevel@tonic-gate {
6417c478bd9Sstevel@tonic-gate char *v, *p;
6427c478bd9Sstevel@tonic-gate char arch[ARCHBUFLEN];
6437c478bd9Sstevel@tonic-gate int archlen;
6447c478bd9Sstevel@tonic-gate
6457c478bd9Sstevel@tonic-gate /* up to ARCHBUFLEN-1 */
6467c478bd9Sstevel@tonic-gate (void) strncpy(arch, TargetArchStr, ARCHBUFLEN-1);
6477c478bd9Sstevel@tonic-gate arch[ARCHBUFLEN-2] = '\0';
6487c478bd9Sstevel@tonic-gate (void) strcat(arch, "="); /* append an '=' */
6497c478bd9Sstevel@tonic-gate archlen = strlen(arch);
6507c478bd9Sstevel@tonic-gate
6517c478bd9Sstevel@tonic-gate errlog(VERBOSE, "getversion: value=%s", value);
6527c478bd9Sstevel@tonic-gate
6537c478bd9Sstevel@tonic-gate if (strchr(value, '=') != NULL) {
6547c478bd9Sstevel@tonic-gate if ((v = strstr(value, arch)) != NULL) {
6557c478bd9Sstevel@tonic-gate p = strdup(v + archlen);
6567c478bd9Sstevel@tonic-gate if (p == NULL) {
6577c478bd9Sstevel@tonic-gate errlog(ERROR | FATAL,
6587c478bd9Sstevel@tonic-gate "Internal Error: strdup() failure "
6597c478bd9Sstevel@tonic-gate "in getversion()");
6607c478bd9Sstevel@tonic-gate }
6617c478bd9Sstevel@tonic-gate v = p;
6627c478bd9Sstevel@tonic-gate while (!isspace(*v) && *v != '\0')
6637c478bd9Sstevel@tonic-gate ++v;
6647c478bd9Sstevel@tonic-gate *v = '\0';
6657c478bd9Sstevel@tonic-gate } else {
6667c478bd9Sstevel@tonic-gate errlog(VERBOSE, "getversion returns: NULL");
6677c478bd9Sstevel@tonic-gate return (NULL);
6687c478bd9Sstevel@tonic-gate }
6697c478bd9Sstevel@tonic-gate } else {
6707c478bd9Sstevel@tonic-gate p = strdup(value);
6717c478bd9Sstevel@tonic-gate if (p == NULL) {
6727c478bd9Sstevel@tonic-gate errlog(ERROR | FATAL, "Internal Error: strdup() "
6737c478bd9Sstevel@tonic-gate "failure in getversion()");
6747c478bd9Sstevel@tonic-gate }
6757c478bd9Sstevel@tonic-gate }
6767c478bd9Sstevel@tonic-gate
6777c478bd9Sstevel@tonic-gate if (p != NULL)
6787c478bd9Sstevel@tonic-gate errlog(VERBOSE, "getversion returns: %s", p);
6797c478bd9Sstevel@tonic-gate else
6807c478bd9Sstevel@tonic-gate errlog(VERBOSE, "getversion returns: NULL");
6817c478bd9Sstevel@tonic-gate
6827c478bd9Sstevel@tonic-gate return (p);
6837c478bd9Sstevel@tonic-gate }
6847c478bd9Sstevel@tonic-gate
6857c478bd9Sstevel@tonic-gate /*
6867c478bd9Sstevel@tonic-gate * getfilter()
6877c478bd9Sstevel@tonic-gate * Called by xlator_take_kvpair when "filter" or "auxiliary" keyword is
6887c478bd9Sstevel@tonic-gate * found. Parses the Filter/Auxiliary string and returns the one that
6897c478bd9Sstevel@tonic-gate * matches the current target architecture
6907c478bd9Sstevel@tonic-gate *
6917c478bd9Sstevel@tonic-gate * The pointer returned by this function must be freed later.
6927c478bd9Sstevel@tonic-gate *
6937c478bd9Sstevel@tonic-gate * Note that returning NULL here indicates there was no desired
6947c478bd9Sstevel@tonic-gate * arch=path item in value, i.e. for TargetArchStr the interface is
6957c478bd9Sstevel@tonic-gate * not a filter.
6967c478bd9Sstevel@tonic-gate */
6977c478bd9Sstevel@tonic-gate static char *
getfilter(const char * value)6987c478bd9Sstevel@tonic-gate getfilter(const char *value)
6997c478bd9Sstevel@tonic-gate {
7007c478bd9Sstevel@tonic-gate char *v, *p;
7017c478bd9Sstevel@tonic-gate char arch[ARCHBUFLEN];
7027c478bd9Sstevel@tonic-gate int archlen;
7037c478bd9Sstevel@tonic-gate
7047c478bd9Sstevel@tonic-gate /* up to ARCHBUFLEN-1 */
7057c478bd9Sstevel@tonic-gate (void) strncpy(arch, TargetArchStr, ARCHBUFLEN-1);
7067c478bd9Sstevel@tonic-gate arch[ARCHBUFLEN-2] = '\0';
7077c478bd9Sstevel@tonic-gate (void) strcat(arch, "="); /* append an '=' */
7087c478bd9Sstevel@tonic-gate archlen = strlen(arch);
7097c478bd9Sstevel@tonic-gate
7107c478bd9Sstevel@tonic-gate errlog(VERBOSE, "getfilter: value=%s", value);
7117c478bd9Sstevel@tonic-gate
7127c478bd9Sstevel@tonic-gate if (strchr(value, '=') != NULL) {
7137c478bd9Sstevel@tonic-gate if ((v = strstr(value, arch)) != NULL) {
7147c478bd9Sstevel@tonic-gate p = strdup(v + archlen);
7157c478bd9Sstevel@tonic-gate if (p == NULL) {
7167c478bd9Sstevel@tonic-gate errlog(ERROR | FATAL,
7177c478bd9Sstevel@tonic-gate "Internal Error: strdup() failure "
7187c478bd9Sstevel@tonic-gate "in getfilter()");
7197c478bd9Sstevel@tonic-gate }
7207c478bd9Sstevel@tonic-gate v = p;
7217c478bd9Sstevel@tonic-gate while (!isspace(*v) && *v != '\0')
7227c478bd9Sstevel@tonic-gate ++v;
7237c478bd9Sstevel@tonic-gate *v = '\0';
7247c478bd9Sstevel@tonic-gate } else {
7257c478bd9Sstevel@tonic-gate errlog(VERBOSE, "getfilter returns: NULL");
7267c478bd9Sstevel@tonic-gate return (NULL);
7277c478bd9Sstevel@tonic-gate }
7287c478bd9Sstevel@tonic-gate } else {
7297c478bd9Sstevel@tonic-gate p = strdup(value);
7307c478bd9Sstevel@tonic-gate if (p == NULL) {
7317c478bd9Sstevel@tonic-gate errlog(ERROR | FATAL, "Internal Error: strdup() "
7327c478bd9Sstevel@tonic-gate "failure in getfilter()");
7337c478bd9Sstevel@tonic-gate }
7347c478bd9Sstevel@tonic-gate }
7357c478bd9Sstevel@tonic-gate
7367c478bd9Sstevel@tonic-gate if (p != NULL)
7377c478bd9Sstevel@tonic-gate errlog(VERBOSE, "getfilter returns: %s", p);
7387c478bd9Sstevel@tonic-gate else
7397c478bd9Sstevel@tonic-gate errlog(VERBOSE, "getfilter returns: NULL");
7407c478bd9Sstevel@tonic-gate
7417c478bd9Sstevel@tonic-gate return (p);
7427c478bd9Sstevel@tonic-gate }
7437c478bd9Sstevel@tonic-gate
7447c478bd9Sstevel@tonic-gate /*
7457c478bd9Sstevel@tonic-gate * version_sanity()
7467c478bd9Sstevel@tonic-gate * for each version info in the Version line
7477c478bd9Sstevel@tonic-gate * check for its validity.
7487c478bd9Sstevel@tonic-gate * Set Version_arch to reflect all supported architectures if successful.
7497c478bd9Sstevel@tonic-gate * Upon return on failure, subv will contain the last version string
7507c478bd9Sstevel@tonic-gate * processed
7517c478bd9Sstevel@tonic-gate * returns: VS_OK OK
7527c478bd9Sstevel@tonic-gate * VS_INVARCH Invalid Architecture
7537c478bd9Sstevel@tonic-gate * VS_INVVERS Invalid Version String
7547c478bd9Sstevel@tonic-gate * VS_INVALID Both Version and Architecture are invalid;
7557c478bd9Sstevel@tonic-gate */
7567c478bd9Sstevel@tonic-gate static int
version_sanity(const char * value,char ** subv)7577c478bd9Sstevel@tonic-gate version_sanity(const char *value, char **subv)
7587c478bd9Sstevel@tonic-gate {
7597c478bd9Sstevel@tonic-gate char *p, *v, *a;
7607c478bd9Sstevel@tonic-gate int retval = VS_INVALID;
7617c478bd9Sstevel@tonic-gate
7627c478bd9Sstevel@tonic-gate if (strchr(value, '=')) {
7637c478bd9Sstevel@tonic-gate /* Form 1: Version arch=Version_string */
7647c478bd9Sstevel@tonic-gate v = strdup(value);
7657c478bd9Sstevel@tonic-gate if (v == NULL) {
7667c478bd9Sstevel@tonic-gate errlog(ERROR | FATAL,
7677c478bd9Sstevel@tonic-gate "Internal Error: strdup() failure in "
7687c478bd9Sstevel@tonic-gate "version_sanity()");
7697c478bd9Sstevel@tonic-gate }
7707c478bd9Sstevel@tonic-gate
7717c478bd9Sstevel@tonic-gate /* process each arch=version string */
7727c478bd9Sstevel@tonic-gate p = v;
7737c478bd9Sstevel@tonic-gate while ((a = strtok(p, " \t\n"))) {
7747c478bd9Sstevel@tonic-gate if ((retval = arch_version_sanity(a)) != VS_OK) {
7757c478bd9Sstevel@tonic-gate *subv = strdup(a);
7767c478bd9Sstevel@tonic-gate if (subv == NULL) {
7777c478bd9Sstevel@tonic-gate errlog(ERROR | FATAL,
7787c478bd9Sstevel@tonic-gate "Internal Error: strdup() failure "
7797c478bd9Sstevel@tonic-gate "in version_sanity()");
7807c478bd9Sstevel@tonic-gate }
7817c478bd9Sstevel@tonic-gate break;
7827c478bd9Sstevel@tonic-gate }
7837c478bd9Sstevel@tonic-gate if ((retval = set_version_arch(a)) != VS_OK) {
7847c478bd9Sstevel@tonic-gate /* set the global Version_arch */
7857c478bd9Sstevel@tonic-gate *subv = strdup(a);
7867c478bd9Sstevel@tonic-gate if (subv == NULL) {
7877c478bd9Sstevel@tonic-gate errlog(ERROR | FATAL,
7887c478bd9Sstevel@tonic-gate "Internal Error: strdup() failure "
7897c478bd9Sstevel@tonic-gate "in version_sanity()");
7907c478bd9Sstevel@tonic-gate }
7917c478bd9Sstevel@tonic-gate break;
7927c478bd9Sstevel@tonic-gate }
7937c478bd9Sstevel@tonic-gate p = NULL;
7947c478bd9Sstevel@tonic-gate }
7957c478bd9Sstevel@tonic-gate free(v);
7967c478bd9Sstevel@tonic-gate } else {
7977c478bd9Sstevel@tonic-gate /* Form 2: Version Version_string */
7987c478bd9Sstevel@tonic-gate if (valid_version(value)) {
7997c478bd9Sstevel@tonic-gate retval = VS_OK;
8007c478bd9Sstevel@tonic-gate } else {
8017c478bd9Sstevel@tonic-gate *subv = strdup(value);
8027c478bd9Sstevel@tonic-gate if (subv == NULL) {
8037c478bd9Sstevel@tonic-gate errlog(ERROR | FATAL,
8047c478bd9Sstevel@tonic-gate "Internal Error: strdup() failure "
8057c478bd9Sstevel@tonic-gate "in version_sanity()");
8067c478bd9Sstevel@tonic-gate }
8077c478bd9Sstevel@tonic-gate }
8087c478bd9Sstevel@tonic-gate }
8097c478bd9Sstevel@tonic-gate return (retval);
8107c478bd9Sstevel@tonic-gate }
8117c478bd9Sstevel@tonic-gate
8127c478bd9Sstevel@tonic-gate /*
8137c478bd9Sstevel@tonic-gate * arch_version_sanity()
8147c478bd9Sstevel@tonic-gate * checks version lines of the form "arch=version"
8157c478bd9Sstevel@tonic-gate * av MUST be a string of the form "arch=version" (no spaces)
8167c478bd9Sstevel@tonic-gate * returns: VS_OK OK
8177c478bd9Sstevel@tonic-gate * VS_INVARCH Invalid Architecture
8187c478bd9Sstevel@tonic-gate * VS_INVVERS Invalid Version String
8197c478bd9Sstevel@tonic-gate * VS_INVALID Both Versions are invalid;
8207c478bd9Sstevel@tonic-gate */
8217c478bd9Sstevel@tonic-gate static int
arch_version_sanity(char * av)8227c478bd9Sstevel@tonic-gate arch_version_sanity(char *av)
8237c478bd9Sstevel@tonic-gate {
8247c478bd9Sstevel@tonic-gate char *p, *v;
8257c478bd9Sstevel@tonic-gate int retval = VS_OK;
8267c478bd9Sstevel@tonic-gate
8277c478bd9Sstevel@tonic-gate p = strchr(av, '=');
8287c478bd9Sstevel@tonic-gate if (p == NULL) {
8297c478bd9Sstevel@tonic-gate errlog(INPUT|ERROR, "Error: Incorrect format of Version line");
8307c478bd9Sstevel@tonic-gate return (VS_INVALID);
8317c478bd9Sstevel@tonic-gate }
8327c478bd9Sstevel@tonic-gate
8337c478bd9Sstevel@tonic-gate *p = '\0'; /* stick a '\0' where the '=' was */
8347c478bd9Sstevel@tonic-gate v = p + 1;
8357c478bd9Sstevel@tonic-gate
8367c478bd9Sstevel@tonic-gate if (valid_arch(av) == 0)
8377c478bd9Sstevel@tonic-gate retval = VS_INVARCH;
8387c478bd9Sstevel@tonic-gate
8397c478bd9Sstevel@tonic-gate if (valid_version(v) == 0)
8407c478bd9Sstevel@tonic-gate retval += VS_INVVERS;
8417c478bd9Sstevel@tonic-gate
8427c478bd9Sstevel@tonic-gate *p = '='; /* restore the '=' */
8437c478bd9Sstevel@tonic-gate
8447c478bd9Sstevel@tonic-gate return (retval);
8457c478bd9Sstevel@tonic-gate }
8467c478bd9Sstevel@tonic-gate
8477c478bd9Sstevel@tonic-gate /*
8487c478bd9Sstevel@tonic-gate * writemapfile()
8497c478bd9Sstevel@tonic-gate * called by xlator_endlib();
8507c478bd9Sstevel@tonic-gate * writes out the map file
8517c478bd9Sstevel@tonic-gate */
8527c478bd9Sstevel@tonic-gate static void
writemapfile(FILE * mapfp)8537c478bd9Sstevel@tonic-gate writemapfile(FILE *mapfp)
8547c478bd9Sstevel@tonic-gate {
8557c478bd9Sstevel@tonic-gate bucket_t *l; /* List of buckets. */
8567c478bd9Sstevel@tonic-gate bucket_t *b; /* Bucket within list. */
8577c478bd9Sstevel@tonic-gate struct bucketlist *bl;
8587c478bd9Sstevel@tonic-gate table_t *t;
8597c478bd9Sstevel@tonic-gate int i = 0, n = 0;
8607c478bd9Sstevel@tonic-gate char **p;
8617c478bd9Sstevel@tonic-gate
8627c478bd9Sstevel@tonic-gate errlog(BEGIN, "writemapfile() {");
8637c478bd9Sstevel@tonic-gate for (l = first_list(); l != NULL; l = next_list()) {
8647c478bd9Sstevel@tonic-gate
8657c478bd9Sstevel@tonic-gate for (b = first_from_list(l); b != NULL; b = next_from_list()) {
8667c478bd9Sstevel@tonic-gate errlog(TRACING, "b_name = %s", b->b_name);
8677c478bd9Sstevel@tonic-gate print_bucket(b); /* Debugging routine. */
8687c478bd9Sstevel@tonic-gate
8697c478bd9Sstevel@tonic-gate if (!b->b_was_printed) {
8707c478bd9Sstevel@tonic-gate /* Ok, we can print it. */
8717c478bd9Sstevel@tonic-gate b->b_was_printed = 1;
8727c478bd9Sstevel@tonic-gate (void) fprintf(mapfp, "%s {\n", b->b_name);
8737c478bd9Sstevel@tonic-gate
8747c478bd9Sstevel@tonic-gate if (b->b_weak != 1) {
8757c478bd9Sstevel@tonic-gate char *strtab;
8767c478bd9Sstevel@tonic-gate
8777c478bd9Sstevel@tonic-gate (void) fprintf(mapfp, " global:\n");
8787c478bd9Sstevel@tonic-gate
8797c478bd9Sstevel@tonic-gate strtab = get_stringtable(
880*c473d156SToomas Soome b->b_global_table, 0);
8817c478bd9Sstevel@tonic-gate
8827c478bd9Sstevel@tonic-gate if (strtab == NULL) {
8837c478bd9Sstevel@tonic-gate /*
8847c478bd9Sstevel@tonic-gate * There were no interfaces
8857c478bd9Sstevel@tonic-gate * in the bucket.
8867c478bd9Sstevel@tonic-gate * Insert a dummy entry
8877c478bd9Sstevel@tonic-gate * to avoid a "weak version"
8887c478bd9Sstevel@tonic-gate */
8897c478bd9Sstevel@tonic-gate (void) fprintf(mapfp,
8907c478bd9Sstevel@tonic-gate "\t%s;\n", b->b_name);
8917c478bd9Sstevel@tonic-gate }
8927c478bd9Sstevel@tonic-gate } else {
8937c478bd9Sstevel@tonic-gate (void) fprintf(mapfp,
8947c478bd9Sstevel@tonic-gate " # Weak version\n");
8957c478bd9Sstevel@tonic-gate }
8967c478bd9Sstevel@tonic-gate /* Print all the interfaces in the bucket. */
8977c478bd9Sstevel@tonic-gate t = b->b_global_table;
8987c478bd9Sstevel@tonic-gate n = t->used;
8997c478bd9Sstevel@tonic-gate
9007c478bd9Sstevel@tonic-gate for (i = 0; i <= n; ++i) {
9017c478bd9Sstevel@tonic-gate (void) fprintf(mapfp, "\t%s;\n",
9027c478bd9Sstevel@tonic-gate get_stringtable(t, i));
9037c478bd9Sstevel@tonic-gate }
9047c478bd9Sstevel@tonic-gate
9057c478bd9Sstevel@tonic-gate if (b->b_has_protecteds) {
9067c478bd9Sstevel@tonic-gate t = b->b_protected_table;
9077c478bd9Sstevel@tonic-gate n = t->used;
9087c478bd9Sstevel@tonic-gate
9097c478bd9Sstevel@tonic-gate (void) fprintf(mapfp,
9107c478bd9Sstevel@tonic-gate " protected:\n");
9117c478bd9Sstevel@tonic-gate
9127c478bd9Sstevel@tonic-gate for (i = 0; i <= n; ++i) {
9137c478bd9Sstevel@tonic-gate (void) fprintf(mapfp, "\t%s;\n",
9147c478bd9Sstevel@tonic-gate get_stringtable(t, i));
9157c478bd9Sstevel@tonic-gate }
9167c478bd9Sstevel@tonic-gate }
9177c478bd9Sstevel@tonic-gate
9187c478bd9Sstevel@tonic-gate /* Conditionally add ``local: *;''. */
9197c478bd9Sstevel@tonic-gate if (b->b_has_locals) {
9207c478bd9Sstevel@tonic-gate (void) fprintf(mapfp,
9217c478bd9Sstevel@tonic-gate " local:\n\t*;\n}");
9227c478bd9Sstevel@tonic-gate } else {
9237c478bd9Sstevel@tonic-gate (void) fprintf(mapfp, "}");
9247c478bd9Sstevel@tonic-gate }
9257c478bd9Sstevel@tonic-gate /* Print name of all parents. */
9267c478bd9Sstevel@tonic-gate for (p = parents_of(b);
927*c473d156SToomas Soome p != NULL && *p != NULL; ++p) {
9287c478bd9Sstevel@tonic-gate (void) fprintf(mapfp, " %s", *p);
9297c478bd9Sstevel@tonic-gate }
9307c478bd9Sstevel@tonic-gate bl = b->b_uncles;
9317c478bd9Sstevel@tonic-gate while (bl != NULL) {
9327c478bd9Sstevel@tonic-gate (void) fprintf(mapfp, " %s",
9337c478bd9Sstevel@tonic-gate bl->bl_bucket->b_name);
9347c478bd9Sstevel@tonic-gate bl = bl->bl_next;
9357c478bd9Sstevel@tonic-gate }
9367c478bd9Sstevel@tonic-gate
9377c478bd9Sstevel@tonic-gate (void) fprintf(mapfp, ";\n\n");
9387c478bd9Sstevel@tonic-gate } else {
9397c478bd9Sstevel@tonic-gate /*
9407c478bd9Sstevel@tonic-gate * We've printed this one before,
9417c478bd9Sstevel@tonic-gate * so don't do it again.
9427c478bd9Sstevel@tonic-gate */
9437c478bd9Sstevel@tonic-gate /*EMPTY*/;
9447c478bd9Sstevel@tonic-gate }
9457c478bd9Sstevel@tonic-gate }
9467c478bd9Sstevel@tonic-gate }
9477c478bd9Sstevel@tonic-gate errlog(END, "}");
9487c478bd9Sstevel@tonic-gate }
9497c478bd9Sstevel@tonic-gate
9507c478bd9Sstevel@tonic-gate /*
9517c478bd9Sstevel@tonic-gate * set_version_arch ()
9527c478bd9Sstevel@tonic-gate * input must be a string of the form "arch=version"
9537c478bd9Sstevel@tonic-gate * turns on bits of global Version_Arch that correspond to the "arch"
9547c478bd9Sstevel@tonic-gate * return VS_OK upon success
9557c478bd9Sstevel@tonic-gate * VS_INVARCH if architecture is invalid
9567c478bd9Sstevel@tonic-gate * EINVAL on other failure
9577c478bd9Sstevel@tonic-gate */
9587c478bd9Sstevel@tonic-gate static int
set_version_arch(const char * arch)9597c478bd9Sstevel@tonic-gate set_version_arch(const char *arch)
9607c478bd9Sstevel@tonic-gate {
9617c478bd9Sstevel@tonic-gate char *a, *p;
9627c478bd9Sstevel@tonic-gate int x;
9637c478bd9Sstevel@tonic-gate int retval = EINVAL;
9647c478bd9Sstevel@tonic-gate
9657c478bd9Sstevel@tonic-gate if (arch == NULL)
9667c478bd9Sstevel@tonic-gate return (retval);
9677c478bd9Sstevel@tonic-gate
9687c478bd9Sstevel@tonic-gate a = strdup(arch);
9697c478bd9Sstevel@tonic-gate if (a == NULL) {
9707c478bd9Sstevel@tonic-gate errlog(ERROR | FATAL,
9717c478bd9Sstevel@tonic-gate "Internal Error: strdup() failure in "
9727c478bd9Sstevel@tonic-gate "set_version_arch()");
9737c478bd9Sstevel@tonic-gate }
9747c478bd9Sstevel@tonic-gate
9757c478bd9Sstevel@tonic-gate p = strchr(a, '=');
9767c478bd9Sstevel@tonic-gate if (p) {
9777c478bd9Sstevel@tonic-gate *p = '\0';
9787c478bd9Sstevel@tonic-gate x = arch_strtoi(a);
9797c478bd9Sstevel@tonic-gate if (x == 0) {
9807c478bd9Sstevel@tonic-gate errlog(INPUT|ERROR,
9817c478bd9Sstevel@tonic-gate "Error: Invalid architecture: %s", a);
9827c478bd9Sstevel@tonic-gate retval = VS_INVARCH;
9837c478bd9Sstevel@tonic-gate } else {
9847c478bd9Sstevel@tonic-gate Version_Arch |= x;
9857c478bd9Sstevel@tonic-gate retval = 0;
9867c478bd9Sstevel@tonic-gate }
9877c478bd9Sstevel@tonic-gate }
9887c478bd9Sstevel@tonic-gate
9897c478bd9Sstevel@tonic-gate free(a);
9907c478bd9Sstevel@tonic-gate return (retval);
9917c478bd9Sstevel@tonic-gate }
9927c478bd9Sstevel@tonic-gate
9937c478bd9Sstevel@tonic-gate /*
9947c478bd9Sstevel@tonic-gate * set_supported_arch ()
9957c478bd9Sstevel@tonic-gate * input must be a string listing the architectures to be supported
9967c478bd9Sstevel@tonic-gate * turns on bits of global Supported_Arch that correspond to the architecture
9977c478bd9Sstevel@tonic-gate * return 0 upon success, EINVAL on failure
9987c478bd9Sstevel@tonic-gate */
9997c478bd9Sstevel@tonic-gate static int
set_supported_arch(const char * arch)10007c478bd9Sstevel@tonic-gate set_supported_arch(const char *arch)
10017c478bd9Sstevel@tonic-gate {
10027c478bd9Sstevel@tonic-gate char *a, *p, *tmp;
10037c478bd9Sstevel@tonic-gate int retval = EINVAL;
10047c478bd9Sstevel@tonic-gate
10057c478bd9Sstevel@tonic-gate if (arch == NULL || *arch == '\0')
10067c478bd9Sstevel@tonic-gate return (EINVAL);
10077c478bd9Sstevel@tonic-gate
10087c478bd9Sstevel@tonic-gate tmp = strdup(arch);
10097c478bd9Sstevel@tonic-gate if (tmp == NULL) {
10107c478bd9Sstevel@tonic-gate errlog(ERROR | FATAL, "Internal Error: strdup() failure in "
10117c478bd9Sstevel@tonic-gate "set_supported_arch()");
10127c478bd9Sstevel@tonic-gate }
10137c478bd9Sstevel@tonic-gate
10147c478bd9Sstevel@tonic-gate p = tmp;
10157c478bd9Sstevel@tonic-gate while ((a = strtok(p, " ,\t\n"))) {
10167c478bd9Sstevel@tonic-gate int x;
10177c478bd9Sstevel@tonic-gate x = arch_strtoi(a);
10187c478bd9Sstevel@tonic-gate if (x == 0) {
10197c478bd9Sstevel@tonic-gate errlog(INPUT|ERROR,
10207c478bd9Sstevel@tonic-gate "Error: Invalid architecture: %s", a);
10217c478bd9Sstevel@tonic-gate free(tmp);
10227c478bd9Sstevel@tonic-gate return (EINVAL);
10237c478bd9Sstevel@tonic-gate }
10247c478bd9Sstevel@tonic-gate Supported_Arch |= x;
10257c478bd9Sstevel@tonic-gate retval = 0;
10267c478bd9Sstevel@tonic-gate p = NULL;
10277c478bd9Sstevel@tonic-gate }
10287c478bd9Sstevel@tonic-gate
10297c478bd9Sstevel@tonic-gate free(tmp);
10307c478bd9Sstevel@tonic-gate return (retval);
10317c478bd9Sstevel@tonic-gate }
1032