Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Aic7xxx SCSI host adapter firmware assembler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (c) 1997, 1998, 2000, 2001 Justin T. Gibbs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (c) 2001, 2002 Adaptec Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * modification, are permitted provided that the following conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * 1. Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *    notice, this list of conditions, and the following disclaimer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *    without modification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *    substantially similar to the "NO WARRANTY" disclaimer below
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  *    ("Disclaimer") and any redistribution must be conditioned upon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  *    including a substantially similar Disclaimer requirement for further
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  *    binary redistribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * 3. Neither the names of the above-listed copyright holders nor the names
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *    of any contributors may be used to endorse or promote products derived
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  *    from this software without specific prior written permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * Alternatively, this software may be distributed under the terms of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * GNU General Public License ("GPL") version 2 as published by the Free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * NO WARRANTY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * POSSIBILITY OF SUCH DAMAGES.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#23 $
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  * $FreeBSD$
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #include <sys/mman.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #include <ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #include <inttypes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #include <regex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #include <sysexits.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #if linux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #include <endian.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #include <machine/endian.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #include "aicasm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #include "aicasm_symbol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #include "aicasm_insformat.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) typedef struct patch {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	STAILQ_ENTRY(patch) links;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	int		patch_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	u_int		begin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	u_int		skip_instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	u_int		skip_patch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) } patch_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) STAILQ_HEAD(patch_list, patch) patches;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) static void usage(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) static void back_patch(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) static void output_code(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) static void output_listing(char *ifilename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) static void dump_scope(scope_t *scope);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) static void emit_patch(scope_t *scope, int patch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) static int check_patch(patch_t **start_patch, int start_instr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		       int *skip_addr, int *func_vals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) struct path_list search_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) int includes_search_curdir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) char *appname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) char *stock_include_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) FILE *ofile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) char *ofilename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) char *regfilename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) FILE *regfile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) char *listfilename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) FILE *listfile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) char *regdiagfilename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) FILE *regdiagfile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) int   src_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) int   dst_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static STAILQ_HEAD(,instruction) seq_program;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct cs_tailq cs_tailq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct scope_list scope_stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) symlist_t patch_functions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #if DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) extern int yy_flex_debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) extern int mm_flex_debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) extern int yydebug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) extern int mmdebug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) extern FILE *yyin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) extern int yyparse(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int main(int argc, char *argv[]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) main(int argc, char *argv[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	extern char *optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	extern int optind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	int  ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	int  retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	char *inputfilename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	scope_t *sentinal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	STAILQ_INIT(&patches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	SLIST_INIT(&search_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	STAILQ_INIT(&seq_program);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	TAILQ_INIT(&cs_tailq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	SLIST_INIT(&scope_stack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	/* Set Sentinal scope node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	sentinal = scope_alloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	sentinal->type = SCOPE_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	includes_search_curdir = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	appname = *argv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	regfile = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	listfile = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #if DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	yy_flex_debug = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	mm_flex_debug = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	yydebug = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	mmdebug = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	while ((ch = getopt(argc, argv, "d:i:l:n:o:p:r:I:")) != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		switch(ch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		case 'd':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #if DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 			if (strcmp(optarg, "s") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 				yy_flex_debug = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 				mm_flex_debug = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 			} else if (strcmp(optarg, "p") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 				yydebug = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 				mmdebug = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 				fprintf(stderr, "%s: -d Requires either an "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 					"'s' or 'p' argument\n", appname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 				usage();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			stop("-d: Assembler not built with debugging "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 			     "information", EX_SOFTWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		case 'i':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 			stock_include_file = optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		case 'l':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 			/* Create a program listing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 			if ((listfile = fopen(optarg, "w")) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 				perror(optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 				stop(NULL, EX_CANTCREAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 			listfilename = optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		case 'n':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 			/* Don't complain about the -nostdinc directrive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 			if (strcmp(optarg, "ostdinc")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 				fprintf(stderr, "%s: Unknown option -%c%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 					appname, ch, optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 				usage();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 				/* NOTREACHED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		case 'o':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 			if ((ofile = fopen(optarg, "w")) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 				perror(optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 				stop(NULL, EX_CANTCREAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 			ofilename = optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		case 'p':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 			/* Create Register Diagnostic "printing" Functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 			if ((regdiagfile = fopen(optarg, "w")) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 				perror(optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 				stop(NULL, EX_CANTCREAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 			regdiagfilename = optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		case 'r':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			if ((regfile = fopen(optarg, "w")) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 				perror(optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 				stop(NULL, EX_CANTCREAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 			regfilename = optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		case 'I':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 			path_entry_t include_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 			if (strcmp(optarg, "-") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 				if (includes_search_curdir == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 					fprintf(stderr, "%s: Warning - '-I-' "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 							"specified multiple "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 							"times\n", appname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 				includes_search_curdir = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 				for (include_dir = SLIST_FIRST(&search_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 				     include_dir != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 				     include_dir = SLIST_NEXT(include_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 							      links))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 					/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 					 * All entries before a '-I-' only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 					 * apply to includes specified with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 					 * quotes instead of "<>".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 					 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 					include_dir->quoted_includes_only = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 				include_dir =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 				    (path_entry_t)malloc(sizeof(*include_dir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 				if (include_dir == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 					perror(optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 					stop(NULL, EX_OSERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 				include_dir->directory = strdup(optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 				if (include_dir->directory == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 					perror(optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 					stop(NULL, EX_OSERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 				include_dir->quoted_includes_only = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 				SLIST_INSERT_HEAD(&search_path, include_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 						  links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		case '?':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 			usage();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 			/* NOTREACHED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	argc -= optind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	argv += optind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	if (argc != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		fprintf(stderr, "%s: No input file specified\n", appname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		usage();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		/* NOTREACHED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	if (regdiagfile != NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	 && (regfile == NULL || stock_include_file == NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 			"%s: The -p option requires the -r and -i options.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 			appname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		usage();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		/* NOTREACHED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	symtable_open();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	inputfilename = *argv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	include_file(*argv, SOURCE_FILE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	retval = yyparse();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	if (retval == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		if (SLIST_FIRST(&scope_stack) == NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		 || SLIST_FIRST(&scope_stack)->type != SCOPE_ROOT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 			stop("Unterminated conditional expression", EX_DATAERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 			/* NOTREACHED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		/* Process outmost scope */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		process_scope(SLIST_FIRST(&scope_stack));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		 * Decend the tree of scopes and insert/emit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		 * patches as appropriate.  We perform a depth first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		 * tranversal, recursively handling each scope.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		/* start at the root scope */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		dump_scope(SLIST_FIRST(&scope_stack));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		/* Patch up forward jump addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		back_patch();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		if (ofile != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 			output_code();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		if (regfile != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 			symtable_dump(regfile, regdiagfile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		if (listfile != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 			output_listing(inputfilename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	stop(NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	/* NOTREACHED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) usage()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	(void)fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) "usage: %-16s [-nostdinc] [-I-] [-I directory] [-o output_file]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) "	[-r register_output_file [-p register_diag_file -i includefile]]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) "	[-l program_list_file]\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) "	input_file\n", appname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	exit(EX_USAGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) back_patch()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	struct instruction *cur_instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	for (cur_instr = STAILQ_FIRST(&seq_program);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	     cur_instr != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	     cur_instr = STAILQ_NEXT(cur_instr, links)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		if (cur_instr->patch_label != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 			struct ins_format3 *f3_instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 			u_int address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 			if (cur_instr->patch_label->type != LABEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 				char buf[255];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 				snprintf(buf, sizeof(buf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 					 "Undefined label %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 					 cur_instr->patch_label->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 				stop(buf, EX_DATAERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 				/* NOTREACHED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 			f3_instr = &cur_instr->format.format3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 			address = f3_instr->address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 			address += cur_instr->patch_label->info.linfo->address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 			f3_instr->address = address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) output_code()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	struct instruction *cur_instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	patch_t *cur_patch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	critical_section_t *cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	symbol_node_t *cur_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	int instrcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	instrcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	fprintf(ofile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) "/*\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) " * DO NOT EDIT - This file is automatically generated\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) " *		 from the following source files:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) " *\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) "%s */\n", versions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	fprintf(ofile, "static const uint8_t seqprog[] = {\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	for (cur_instr = STAILQ_FIRST(&seq_program);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	     cur_instr != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	     cur_instr = STAILQ_NEXT(cur_instr, links)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		fprintf(ofile, "%s\t0x%02x, 0x%02x, 0x%02x, 0x%02x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 			cur_instr == STAILQ_FIRST(&seq_program) ? "" : ",\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) #ifdef __LITTLE_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 			cur_instr->format.bytes[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 			cur_instr->format.bytes[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 			cur_instr->format.bytes[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 			cur_instr->format.bytes[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 			cur_instr->format.bytes[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 			cur_instr->format.bytes[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 			cur_instr->format.bytes[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 			cur_instr->format.bytes[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		instrcount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	fprintf(ofile, "\n};\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	if (patch_arg_list == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		stop("Patch argument list not defined",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		     EX_DATAERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	 *  Output patch information.  Patch functions first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	fprintf(ofile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) "typedef int %spatch_func_t (%s);\n", prefix, patch_arg_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	for (cur_node = SLIST_FIRST(&patch_functions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	     cur_node != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	     cur_node = SLIST_NEXT(cur_node,links)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		fprintf(ofile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) "static %spatch_func_t %spatch%d_func;\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) "\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) "static int\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) "%spatch%d_func(%s)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) "{\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) "	return (%s);\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) "}\n\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 			prefix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 			prefix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 			cur_node->symbol->info.condinfo->func_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 			prefix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 			cur_node->symbol->info.condinfo->func_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 			patch_arg_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 			cur_node->symbol->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	fprintf(ofile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) "static const struct patch {\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) "	%spatch_func_t		*patch_func;\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) "	uint32_t		 begin		:10,\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) "				 skip_instr	:10,\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) "				 skip_patch	:12;\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) "} patches[] = {\n", prefix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	for (cur_patch = STAILQ_FIRST(&patches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	     cur_patch != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	     cur_patch = STAILQ_NEXT(cur_patch,links)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		fprintf(ofile, "%s\t{ %spatch%d_func, %d, %d, %d }",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 			cur_patch == STAILQ_FIRST(&patches) ? "" : ",\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 			prefix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 			cur_patch->patch_func, cur_patch->begin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 			cur_patch->skip_instr, cur_patch->skip_patch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	fprintf(ofile, "\n};\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	fprintf(ofile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) "static const struct cs {\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) "	uint16_t	begin;\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) "	uint16_t	end;\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) "} critical_sections[] = {\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	for (cs = TAILQ_FIRST(&cs_tailq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	     cs != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	     cs = TAILQ_NEXT(cs, links)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		fprintf(ofile, "%s\t{ %d, %d }",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 			cs == TAILQ_FIRST(&cs_tailq) ? "" : ",\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 			cs->begin_addr, cs->end_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	fprintf(ofile, "\n};\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	fprintf(ofile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	"#define NUM_CRITICAL_SECTIONS ARRAY_SIZE(critical_sections)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	fprintf(stderr, "%s: %d instructions used\n", appname, instrcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) dump_scope(scope_t *scope)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	scope_t *cur_scope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	 * Emit the first patch for this scope
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	emit_patch(scope, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	 * Dump each scope within this one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	cur_scope = TAILQ_FIRST(&scope->inner_scope);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	while (cur_scope != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		dump_scope(cur_scope);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		cur_scope = TAILQ_NEXT(cur_scope, scope_links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	 * Emit the second, closing, patch for this scope
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	emit_patch(scope, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) emit_patch(scope_t *scope, int patch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	patch_info_t *pinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	patch_t *new_patch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	pinfo = &scope->patches[patch];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	if (pinfo->skip_instr == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		/* No-Op patch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	new_patch = (patch_t *)malloc(sizeof(*new_patch));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	if (new_patch == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		stop("Could not malloc patch structure", EX_OSERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	memset(new_patch, 0, sizeof(*new_patch));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	if (patch == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		new_patch->patch_func = scope->func_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 		new_patch->begin = scope->begin_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 		new_patch->patch_func = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		new_patch->begin = scope->end_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	new_patch->skip_instr = pinfo->skip_instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	new_patch->skip_patch = pinfo->skip_patch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	STAILQ_INSERT_TAIL(&patches, new_patch, links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) output_listing(char *ifilename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	char buf[1024];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	FILE *ifile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	struct instruction *cur_instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	patch_t *cur_patch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	symbol_node_t *cur_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	int *func_values;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	int instrcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	int instrptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	int line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	int func_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	int skip_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	instrcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	instrptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	line = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	skip_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	if ((ifile = fopen(ifilename, "r")) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		perror(ifilename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		stop(NULL, EX_DATAERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	 * Determine which options to apply to this listing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	for (func_count = 0, cur_func = SLIST_FIRST(&patch_functions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	    cur_func != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	    cur_func = SLIST_NEXT(cur_func, links))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		func_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	func_values = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	if (func_count != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 		func_values = (int *)malloc(func_count * sizeof(int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 		if (func_values == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 			stop("Could not malloc", EX_OSERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		func_values[0] = 0; /* FALSE func */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 		func_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		 * Ask the user to fill in the return values for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 		 * the rest of the functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 		for (cur_func = SLIST_FIRST(&patch_functions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 		     cur_func != NULL && SLIST_NEXT(cur_func, links) != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 		     cur_func = SLIST_NEXT(cur_func, links), func_count--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 			int input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 			
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 			fprintf(stdout, "\n(%s)\n", cur_func->symbol->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 			fprintf(stdout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 				"Enter the return value for "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 				"this expression[T/F]:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 			while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 				input = getchar();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 				input = toupper(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 				if (input == 'T') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 					func_values[func_count] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 				} else if (input == 'F') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 					func_values[func_count] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 			if (isatty(fileno(stdin)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 				putchar(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 		fprintf(stdout, "\nThanks!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	/* Now output the listing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	cur_patch = STAILQ_FIRST(&patches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	for (cur_instr = STAILQ_FIRST(&seq_program);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	     cur_instr != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	     cur_instr = STAILQ_NEXT(cur_instr, links), instrcount++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 		if (check_patch(&cur_patch, instrcount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 				&skip_addr, func_values) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 			/* Don't count this instruction as it is in a patch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 			 * that was removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)                         continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 		while (line < cur_instr->srcline) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 			fgets(buf, sizeof(buf), ifile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 				fprintf(listfile, "             \t%s", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 				line++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 		fprintf(listfile, "%04x %02x%02x%02x%02x", instrptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) #ifdef __LITTLE_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 			cur_instr->format.bytes[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 			cur_instr->format.bytes[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 			cur_instr->format.bytes[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 			cur_instr->format.bytes[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 			cur_instr->format.bytes[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 			cur_instr->format.bytes[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 			cur_instr->format.bytes[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 			cur_instr->format.bytes[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 		 * Macro expansions can cause several instructions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 		 * to be output for a single source line.  Only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 		 * advance the line once in these cases.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 		if (line == cur_instr->srcline) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 			fgets(buf, sizeof(buf), ifile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 			fprintf(listfile, "\t%s", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 			line++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 			fprintf(listfile, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 		instrptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	/* Dump the remainder of the file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	while(fgets(buf, sizeof(buf), ifile) != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 		fprintf(listfile, "             %s", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	fclose(ifile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) check_patch(patch_t **start_patch, int start_instr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	    int *skip_addr, int *func_vals)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	patch_t *cur_patch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	cur_patch = *start_patch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	while (cur_patch != NULL && start_instr == cur_patch->begin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 		if (func_vals[cur_patch->patch_func] == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 			int skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 			/* Start rejecting code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 			*skip_addr = start_instr + cur_patch->skip_instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 			for (skip = cur_patch->skip_patch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 			     skip > 0 && cur_patch != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 			     skip--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 				cur_patch = STAILQ_NEXT(cur_patch, links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 			/* Accepted this patch.  Advance to the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 			 * one and wait for our intruction pointer to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 			 * hit this point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 			cur_patch = STAILQ_NEXT(cur_patch, links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	*start_patch = cur_patch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	if (start_instr < *skip_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 		/* Still skipping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 		return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)  * Print out error information if appropriate, and clean up before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)  * terminating the program.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) stop(const char *string, int err_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	if (string != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 		fprintf(stderr, "%s: ", appname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 		if (yyfilename != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 			fprintf(stderr, "Stopped at file %s, line %d - ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 				yyfilename, yylineno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 		fprintf(stderr, "%s\n", string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	if (ofile != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 		fclose(ofile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 		if (err_code != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 			fprintf(stderr, "%s: Removing %s due to error\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 				appname, ofilename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 			unlink(ofilename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	if (regfile != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 		fclose(regfile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 		if (err_code != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 			fprintf(stderr, "%s: Removing %s due to error\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 				appname, regfilename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 			unlink(regfilename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 	if (listfile != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 		fclose(listfile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 		if (err_code != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 			fprintf(stderr, "%s: Removing %s due to error\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 				appname, listfilename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 			unlink(listfilename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 	symlist_free(&patch_functions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	symtable_close();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 	exit(err_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) struct instruction *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) seq_alloc()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	struct instruction *new_instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	new_instr = (struct instruction *)malloc(sizeof(struct instruction));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	if (new_instr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 		stop("Unable to malloc instruction object", EX_SOFTWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 	memset(new_instr, 0, sizeof(*new_instr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	STAILQ_INSERT_TAIL(&seq_program, new_instr, links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 	new_instr->srcline = yylineno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 	return new_instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) critical_section_t *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) cs_alloc()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 	critical_section_t *new_cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	new_cs= (critical_section_t *)malloc(sizeof(critical_section_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 	if (new_cs == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 		stop("Unable to malloc critical_section object", EX_SOFTWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 	memset(new_cs, 0, sizeof(*new_cs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 	TAILQ_INSERT_TAIL(&cs_tailq, new_cs, links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 	return new_cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) scope_t *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) scope_alloc()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 	scope_t *new_scope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 	new_scope = (scope_t *)malloc(sizeof(scope_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 	if (new_scope == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 		stop("Unable to malloc scope object", EX_SOFTWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 	memset(new_scope, 0, sizeof(*new_scope));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 	TAILQ_INIT(&new_scope->inner_scope);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 	if (SLIST_FIRST(&scope_stack) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 		TAILQ_INSERT_TAIL(&SLIST_FIRST(&scope_stack)->inner_scope,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 				  new_scope, scope_links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 	/* This patch is now the current scope */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 	SLIST_INSERT_HEAD(&scope_stack, new_scope, scope_stack_links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 	return new_scope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) process_scope(scope_t *scope)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 	 * We are "leaving" this scope.  We should now have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 	 * enough information to process the lists of scopes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 	 * we encapsulate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 	scope_t *cur_scope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 	u_int skip_patch_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 	u_int skip_instr_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 	cur_scope = TAILQ_LAST(&scope->inner_scope, scope_tailq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 	skip_patch_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 	skip_instr_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 	while (cur_scope != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 		u_int patch0_patch_skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 		patch0_patch_skip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 		switch (cur_scope->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 		case SCOPE_IF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 		case SCOPE_ELSE_IF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 			if (skip_instr_count != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 				/* Create a tail patch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 				patch0_patch_skip++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 				cur_scope->patches[1].skip_patch =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 				    skip_patch_count + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 				cur_scope->patches[1].skip_instr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 				    skip_instr_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 			/* Count Head patch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 			patch0_patch_skip++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 			/* Count any patches contained in our inner scope */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 			patch0_patch_skip += cur_scope->inner_scope_patches;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 			cur_scope->patches[0].skip_patch = patch0_patch_skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 			cur_scope->patches[0].skip_instr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 			    cur_scope->end_addr - cur_scope->begin_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 			skip_instr_count += cur_scope->patches[0].skip_instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 			skip_patch_count += patch0_patch_skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 			if (cur_scope->type == SCOPE_IF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 				scope->inner_scope_patches += skip_patch_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 				skip_patch_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 			        skip_instr_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 		case SCOPE_ELSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 			/* Count any patches contained in our innter scope */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 			skip_patch_count += cur_scope->inner_scope_patches;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 			skip_instr_count += cur_scope->end_addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 					  - cur_scope->begin_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 		case SCOPE_ROOT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 			stop("Unexpected scope type encountered", EX_SOFTWARE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 			/* NOTREACHED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 		cur_scope = TAILQ_PREV(cur_scope, scope_tailq, scope_links);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }