1c5cb3888SJustin T. Gibbs /* 2c5cb3888SJustin T. Gibbs * Aic7xxx SCSI host adapter firmware asssembler 30ef8c301SJustin T. Gibbs * 4c5cb3888SJustin T. Gibbs * Copyright (c) 1997 Justin T. Gibbs. 53cddb2a3SJustin T. Gibbs * All rights reserved. 60ef8c301SJustin T. Gibbs * 73cddb2a3SJustin T. Gibbs * Redistribution and use in source and binary forms, with or without 83cddb2a3SJustin T. Gibbs * modification, are permitted provided that the following conditions 93cddb2a3SJustin T. Gibbs * are met: 103cddb2a3SJustin T. Gibbs * 1. Redistributions of source code must retain the above copyright 11c5cb3888SJustin T. Gibbs * notice immediately at the beginning of the file, without modification, 12c5cb3888SJustin T. Gibbs * this list of conditions, and the following disclaimer. 133cddb2a3SJustin T. Gibbs * 2. Redistributions in binary form must reproduce the above copyright 143cddb2a3SJustin T. Gibbs * notice, this list of conditions and the following disclaimer in the 153cddb2a3SJustin T. Gibbs * documentation and/or other materials provided with the distribution. 16c5cb3888SJustin T. Gibbs * 3. The name of the author may not be used to endorse or promote products 17c5cb3888SJustin T. Gibbs * derived from this software without specific prior written permission. 180ef8c301SJustin T. Gibbs * 193cddb2a3SJustin T. Gibbs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 203cddb2a3SJustin T. Gibbs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 213cddb2a3SJustin T. Gibbs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22c5cb3888SJustin T. Gibbs * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 23c5cb3888SJustin T. Gibbs * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 243cddb2a3SJustin T. Gibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 253cddb2a3SJustin T. Gibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 263cddb2a3SJustin T. Gibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 273cddb2a3SJustin T. Gibbs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 283cddb2a3SJustin T. Gibbs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 293cddb2a3SJustin T. Gibbs * SUCH DAMAGE. 300ef8c301SJustin T. Gibbs * 311c147cc3SJustin T. Gibbs * $Id: aic7xxx_asm.c,v 1.15 1997/03/16 07:08:15 gibbs Exp $ 32c5cb3888SJustin T. Gibbs */ 33c5cb3888SJustin T. Gibbs #include <sys/types.h> 34c5cb3888SJustin T. Gibbs #include <sys/mman.h> 35c5cb3888SJustin T. Gibbs 360ef8c301SJustin T. Gibbs #include <stdio.h> 370ef8c301SJustin T. Gibbs #include <stdlib.h> 38c5cb3888SJustin T. Gibbs #include <string.h> 39c5cb3888SJustin T. Gibbs #include <sysexits.h> 400ef8c301SJustin T. Gibbs #include <unistd.h> 410ef8c301SJustin T. Gibbs 42c5cb3888SJustin T. Gibbs #include "aic7xxx_asm.h" 43c5cb3888SJustin T. Gibbs #include "symbol.h" 44c5cb3888SJustin T. Gibbs #include "sequencer.h" 450ef8c301SJustin T. Gibbs 46c5cb3888SJustin T. Gibbs static void usage __P((void)); 47c5cb3888SJustin T. Gibbs static void back_patch __P((void)); 48c5cb3888SJustin T. Gibbs static void output_code __P((FILE *ofile)); 491c147cc3SJustin T. Gibbs static void output_listing __P((FILE *listfile, char *ifilename, 501c147cc3SJustin T. Gibbs char *options)); 511c147cc3SJustin T. Gibbs static struct patch *next_patch __P((struct patch *cur_patch, int options, 521c147cc3SJustin T. Gibbs int instrptr)); 530ef8c301SJustin T. Gibbs 54c5cb3888SJustin T. Gibbs struct path_list search_path; 55c5cb3888SJustin T. Gibbs int includes_search_curdir; 56c5cb3888SJustin T. Gibbs char *appname; 57adf51647SJustin T. Gibbs FILE *ofile; 58c5cb3888SJustin T. Gibbs char *ofilename; 590ef8c301SJustin T. Gibbs 60c5cb3888SJustin T. Gibbs static STAILQ_HEAD(,instruction) seq_program; 61c5cb3888SJustin T. Gibbs static STAILQ_HEAD(, patch) patch_list; 62c5cb3888SJustin T. Gibbs symlist_t patch_options; 63c5cb3888SJustin T. Gibbs 64c5cb3888SJustin T. Gibbs #if DEBUG 65c5cb3888SJustin T. Gibbs extern int yy_flex_debug; 66c5cb3888SJustin T. Gibbs extern int yydebug; 67c5cb3888SJustin T. Gibbs #endif 68c5cb3888SJustin T. Gibbs extern FILE *yyin; 69c5cb3888SJustin T. Gibbs extern int yyparse __P((void)); 70c5cb3888SJustin T. Gibbs 71c5cb3888SJustin T. Gibbs int 72c5cb3888SJustin T. Gibbs main(argc, argv) 73c5cb3888SJustin T. Gibbs int argc; 74c5cb3888SJustin T. Gibbs char *argv[]; 753cddb2a3SJustin T. Gibbs { 76c5cb3888SJustin T. Gibbs extern char *optarg; 77c5cb3888SJustin T. Gibbs extern int optind; 78c5cb3888SJustin T. Gibbs int ch; 79c5cb3888SJustin T. Gibbs int retval; 80c5cb3888SJustin T. Gibbs char *inputfilename; 81c5cb3888SJustin T. Gibbs char *regfilename; 82c5cb3888SJustin T. Gibbs FILE *regfile; 83c5cb3888SJustin T. Gibbs char *listfilename; 84c5cb3888SJustin T. Gibbs FILE *listfile; 851c147cc3SJustin T. Gibbs char *options; 86adf51647SJustin T. Gibbs 87c5cb3888SJustin T. Gibbs SLIST_INIT(&search_path); 88c5cb3888SJustin T. Gibbs STAILQ_INIT(&seq_program); 89c5cb3888SJustin T. Gibbs STAILQ_INIT(&patch_list); 90c5cb3888SJustin T. Gibbs SLIST_INIT(&patch_options); 91c5cb3888SJustin T. Gibbs includes_search_curdir = 1; 92c5cb3888SJustin T. Gibbs appname = *argv; 93c5cb3888SJustin T. Gibbs regfile = NULL; 94c5cb3888SJustin T. Gibbs listfile = NULL; 951c147cc3SJustin T. Gibbs options = NULL; 96c5cb3888SJustin T. Gibbs #if DEBUG 97c5cb3888SJustin T. Gibbs yy_flex_debug = 0; 98c5cb3888SJustin T. Gibbs #endif 991c147cc3SJustin T. Gibbs while ((ch = getopt(argc, argv, "d:l:n:o:r:I:O:")) != EOF) { 100c5cb3888SJustin T. Gibbs switch(ch) { 101c5cb3888SJustin T. Gibbs case 'd': 102c5cb3888SJustin T. Gibbs #if DEBUG 103c5cb3888SJustin T. Gibbs if (strcmp(optarg, "s") == 0) 104c5cb3888SJustin T. Gibbs yy_flex_debug = 1; 105c5cb3888SJustin T. Gibbs else if (strcmp(optarg, "p") == 0) 106c5cb3888SJustin T. Gibbs yydebug = 1; 107c5cb3888SJustin T. Gibbs #else 108c5cb3888SJustin T. Gibbs stop("-d: Assembler not built with debugging " 109c5cb3888SJustin T. Gibbs "information", EX_SOFTWARE); 110c5cb3888SJustin T. Gibbs #endif 111c5cb3888SJustin T. Gibbs break; 112c5cb3888SJustin T. Gibbs case 'l': 113c5cb3888SJustin T. Gibbs /* Create a program listing */ 114c5cb3888SJustin T. Gibbs if ((listfile = fopen(optarg, "w")) == NULL) { 115c5cb3888SJustin T. Gibbs perror(optarg); 116c5cb3888SJustin T. Gibbs stop(NULL, EX_CANTCREAT); 117c5cb3888SJustin T. Gibbs } 118c5cb3888SJustin T. Gibbs listfilename = optarg; 119c5cb3888SJustin T. Gibbs break; 120c5cb3888SJustin T. Gibbs case 'n': 121c5cb3888SJustin T. Gibbs /* Don't complain about the -nostdinc directrive */ 122c5cb3888SJustin T. Gibbs if (strcmp(optarg, "ostdinc")) { 123c5cb3888SJustin T. Gibbs fprintf(stderr, "%s: Unknown option -%c%s\n", 124c5cb3888SJustin T. Gibbs appname, ch, optarg); 125c5cb3888SJustin T. Gibbs usage(); 126c5cb3888SJustin T. Gibbs /* NOTREACHED */ 127c5cb3888SJustin T. Gibbs } 128c5cb3888SJustin T. Gibbs break; 129c5cb3888SJustin T. Gibbs case 'o': 130c2c5fd34SJustin T. Gibbs if ((ofile = fopen(optarg, "w")) == NULL) { 1310ef8c301SJustin T. Gibbs perror(optarg); 132c5cb3888SJustin T. Gibbs stop(NULL, EX_CANTCREAT); 133c5cb3888SJustin T. Gibbs } 134c5cb3888SJustin T. Gibbs ofilename = optarg; 135c5cb3888SJustin T. Gibbs break; 1361c147cc3SJustin T. Gibbs case 'O': 1371c147cc3SJustin T. Gibbs /* Patches to include in the listing */ 1381c147cc3SJustin T. Gibbs options = optarg; 1391c147cc3SJustin T. Gibbs break; 140c5cb3888SJustin T. Gibbs case 'r': 141c5cb3888SJustin T. Gibbs if ((regfile = fopen(optarg, "w")) == NULL) { 142c5cb3888SJustin T. Gibbs perror(optarg); 143c5cb3888SJustin T. Gibbs stop(NULL, EX_CANTCREAT); 144c5cb3888SJustin T. Gibbs } 145c5cb3888SJustin T. Gibbs regfilename = optarg; 146c5cb3888SJustin T. Gibbs break; 147c5cb3888SJustin T. Gibbs case 'I': 148c5cb3888SJustin T. Gibbs { 149c5cb3888SJustin T. Gibbs path_entry_t include_dir; 150c5cb3888SJustin T. Gibbs 151c5cb3888SJustin T. Gibbs if (strcmp(optarg, "-") == 0) { 152c5cb3888SJustin T. Gibbs if (includes_search_curdir == 0) { 153c5cb3888SJustin T. Gibbs fprintf(stderr, "%s: Warning - '-I-' " 154c5cb3888SJustin T. Gibbs "specified multiple " 155c5cb3888SJustin T. Gibbs "times\n", appname); 156c5cb3888SJustin T. Gibbs } 157c5cb3888SJustin T. Gibbs includes_search_curdir = 0; 158c5cb3888SJustin T. Gibbs for (include_dir = search_path.slh_first; 159c5cb3888SJustin T. Gibbs include_dir != NULL; 160c5cb3888SJustin T. Gibbs include_dir = include_dir->links.sle_next) 161c5cb3888SJustin T. Gibbs /* 162c5cb3888SJustin T. Gibbs * All entries before a '-I-' only 163c5cb3888SJustin T. Gibbs * apply to includes specified with 164c5cb3888SJustin T. Gibbs * quotes instead of "<>". 165c5cb3888SJustin T. Gibbs */ 166c5cb3888SJustin T. Gibbs include_dir->quoted_includes_only = 1; 167c5cb3888SJustin T. Gibbs } else { 168c5cb3888SJustin T. Gibbs include_dir = 169c5cb3888SJustin T. Gibbs (path_entry_t)malloc(sizeof(*include_dir)); 170c5cb3888SJustin T. Gibbs if (include_dir == NULL) { 171c5cb3888SJustin T. Gibbs perror(optarg); 172c5cb3888SJustin T. Gibbs stop(NULL, EX_OSERR); 173c5cb3888SJustin T. Gibbs } 174c5cb3888SJustin T. Gibbs include_dir->directory = strdup(optarg); 175c5cb3888SJustin T. Gibbs if (include_dir->directory == NULL) { 176c5cb3888SJustin T. Gibbs perror(optarg); 177c5cb3888SJustin T. Gibbs stop(NULL, EX_OSERR); 178c5cb3888SJustin T. Gibbs } 179c5cb3888SJustin T. Gibbs include_dir->quoted_includes_only = 0; 180c5cb3888SJustin T. Gibbs SLIST_INSERT_HEAD(&search_path, include_dir, 181c5cb3888SJustin T. Gibbs links); 1820ef8c301SJustin T. Gibbs } 1830ef8c301SJustin T. Gibbs break; 184c5cb3888SJustin T. Gibbs } 185c5cb3888SJustin T. Gibbs case '?': 1860ef8c301SJustin T. Gibbs default: 187c5cb3888SJustin T. Gibbs usage(); 188c5cb3888SJustin T. Gibbs /* NOTREACHED */ 189c5cb3888SJustin T. Gibbs } 190c5cb3888SJustin T. Gibbs } 191c5cb3888SJustin T. Gibbs argc -= optind; 192c5cb3888SJustin T. Gibbs argv += optind; 193c5cb3888SJustin T. Gibbs 194c5cb3888SJustin T. Gibbs if (argc != 1) { 195c5cb3888SJustin T. Gibbs fprintf(stderr, "%s: No input file specifiled\n", appname); 196c5cb3888SJustin T. Gibbs usage(); 197c5cb3888SJustin T. Gibbs /* NOTREACHED */ 198c5cb3888SJustin T. Gibbs } 199c5cb3888SJustin T. Gibbs 200c5cb3888SJustin T. Gibbs symtable_open(); 201c5cb3888SJustin T. Gibbs inputfilename = *argv; 202c5cb3888SJustin T. Gibbs include_file(*argv, SOURCE_FILE); 203c5cb3888SJustin T. Gibbs retval = yyparse(); 204c5cb3888SJustin T. Gibbs if (retval == 0) { 205c5cb3888SJustin T. Gibbs back_patch(); 206c5cb3888SJustin T. Gibbs if (ofile != NULL) 207c5cb3888SJustin T. Gibbs output_code(ofile); 208c5cb3888SJustin T. Gibbs if (regfile != NULL) 209c5cb3888SJustin T. Gibbs symtable_dump(regfile); 210c5cb3888SJustin T. Gibbs if (listfile != NULL) 2111c147cc3SJustin T. Gibbs output_listing(listfile, inputfilename, options); 212c5cb3888SJustin T. Gibbs } 213c5cb3888SJustin T. Gibbs 214c5cb3888SJustin T. Gibbs stop(NULL, 0); 215c5cb3888SJustin T. Gibbs /* NOTREACHED */ 216c5cb3888SJustin T. Gibbs return (0); 217c5cb3888SJustin T. Gibbs } 218c5cb3888SJustin T. Gibbs 219c5cb3888SJustin T. Gibbs static void 220c5cb3888SJustin T. Gibbs usage() 221c5cb3888SJustin T. Gibbs { 222c5cb3888SJustin T. Gibbs 2231c147cc3SJustin T. Gibbs (void)fprintf(stderr, 2241c147cc3SJustin T. Gibbs "usage: %-16s [-nostdinc] [-I-] [-I directory] [-o output_file] 2251c147cc3SJustin T. Gibbs [-r register_output_file] [-l program_list_file] 2261c147cc3SJustin T. Gibbs [-O option_name[|options_name2]] input_file\n", 2271c147cc3SJustin T. Gibbs appname); 228c5cb3888SJustin T. Gibbs exit(EX_USAGE); 229c5cb3888SJustin T. Gibbs } 230c5cb3888SJustin T. Gibbs 231c5cb3888SJustin T. Gibbs static void 232c5cb3888SJustin T. Gibbs back_patch() 233c5cb3888SJustin T. Gibbs { 234c5cb3888SJustin T. Gibbs struct instruction *cur_instr; 235c5cb3888SJustin T. Gibbs 236c5cb3888SJustin T. Gibbs for(cur_instr = seq_program.stqh_first; 237c5cb3888SJustin T. Gibbs cur_instr != NULL; 238c5cb3888SJustin T. Gibbs cur_instr = cur_instr->links.stqe_next) { 239c5cb3888SJustin T. Gibbs if (cur_instr->patch_label != NULL) { 240c5cb3888SJustin T. Gibbs struct ins_format3 *f3_instr; 241c5cb3888SJustin T. Gibbs u_int address; 242c5cb3888SJustin T. Gibbs 243c5cb3888SJustin T. Gibbs if (cur_instr->patch_label->type != LABEL) { 244c5cb3888SJustin T. Gibbs char buf[255]; 245c5cb3888SJustin T. Gibbs 246c5cb3888SJustin T. Gibbs snprintf(buf, sizeof(buf), 247c5cb3888SJustin T. Gibbs "Undefined label %s", 248c5cb3888SJustin T. Gibbs cur_instr->patch_label->name); 249c5cb3888SJustin T. Gibbs stop(buf, EX_DATAERR); 250c5cb3888SJustin T. Gibbs /* NOTREACHED */ 251c5cb3888SJustin T. Gibbs } 252c5cb3888SJustin T. Gibbs f3_instr = &cur_instr->format.format3; 253c5cb3888SJustin T. Gibbs address = ((f3_instr->opcode_addr & ADDR_HIGH_BIT) << 8) 254c5cb3888SJustin T. Gibbs | f3_instr->address; 255c5cb3888SJustin T. Gibbs address += cur_instr->patch_label->info.linfo->address; 256c5cb3888SJustin T. Gibbs f3_instr->opcode_addr &= ~ADDR_HIGH_BIT; 257c5cb3888SJustin T. Gibbs f3_instr->opcode_addr |= (address >> 8) & ADDR_HIGH_BIT; 258c5cb3888SJustin T. Gibbs f3_instr->address = address & 0xFF; 259c5cb3888SJustin T. Gibbs } 2600ef8c301SJustin T. Gibbs } 2610ef8c301SJustin T. Gibbs } 2620ef8c301SJustin T. Gibbs 263c5cb3888SJustin T. Gibbs static void 264c5cb3888SJustin T. Gibbs output_code(ofile) 265c5cb3888SJustin T. Gibbs FILE *ofile; 266c5cb3888SJustin T. Gibbs { 267c5cb3888SJustin T. Gibbs struct instruction *cur_instr; 268c5cb3888SJustin T. Gibbs patch_t *cur_patch; 269c5cb3888SJustin T. Gibbs symbol_node_t *cur_node; 270c5cb3888SJustin T. Gibbs int instrcount; 271c5cb3888SJustin T. Gibbs 272c5cb3888SJustin T. Gibbs instrcount = 0; 273c5cb3888SJustin T. Gibbs fprintf(ofile, 274c5cb3888SJustin T. Gibbs "/* 275c5cb3888SJustin T. Gibbs * DO NOT EDIT - This file is automatically generated. 276c5cb3888SJustin T. Gibbs */\n"); 277c5cb3888SJustin T. Gibbs 278c5cb3888SJustin T. Gibbs fprintf(ofile, "static u_int8_t seqprog[] = {\n"); 279c5cb3888SJustin T. Gibbs for(cur_instr = seq_program.stqh_first; 280c5cb3888SJustin T. Gibbs cur_instr != NULL; 281c5cb3888SJustin T. Gibbs cur_instr = cur_instr->links.stqe_next) { 282c5cb3888SJustin T. Gibbs fprintf(ofile, "\t0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", 283c5cb3888SJustin T. Gibbs cur_instr->format.bytes[0], 284c5cb3888SJustin T. Gibbs cur_instr->format.bytes[1], 285c5cb3888SJustin T. Gibbs cur_instr->format.bytes[2], 286c5cb3888SJustin T. Gibbs cur_instr->format.bytes[3]); 287c5cb3888SJustin T. Gibbs instrcount++; 2880ef8c301SJustin T. Gibbs } 289c5cb3888SJustin T. Gibbs fprintf(ofile, "};\n"); 2900ef8c301SJustin T. Gibbs 291c5cb3888SJustin T. Gibbs /* 292c5cb3888SJustin T. Gibbs * Output the patch list, option definitions first. 293c5cb3888SJustin T. Gibbs */ 294c5cb3888SJustin T. Gibbs for(cur_node = patch_options.slh_first; 295c5cb3888SJustin T. Gibbs cur_node != NULL; 296c5cb3888SJustin T. Gibbs cur_node = cur_node->links.sle_next) { 297c5cb3888SJustin T. Gibbs fprintf(ofile, "#define\t%-16s\t0x%x\n", cur_node->symbol->name, 298c5cb3888SJustin T. Gibbs cur_node->symbol->info.condinfo->value); 299c5cb3888SJustin T. Gibbs } 300adf51647SJustin T. Gibbs 301c5cb3888SJustin T. Gibbs fprintf(ofile, 302c5cb3888SJustin T. Gibbs "struct patch { 303c5cb3888SJustin T. Gibbs int options; 304c5cb3888SJustin T. Gibbs int negative; 305c5cb3888SJustin T. Gibbs int begin; 306c5cb3888SJustin T. Gibbs int end; 307c5cb3888SJustin T. Gibbs } patches[] = {\n"); 308c5cb3888SJustin T. Gibbs 309c5cb3888SJustin T. Gibbs for(cur_patch = patch_list.stqh_first; 310c5cb3888SJustin T. Gibbs cur_patch != NULL; 311c5cb3888SJustin T. Gibbs cur_patch = cur_patch->links.stqe_next) 312c5cb3888SJustin T. Gibbs 313c5cb3888SJustin T. Gibbs fprintf(ofile, "\t{ 0x%08x, %d, 0x%03x, 0x%03x },\n", 314c5cb3888SJustin T. Gibbs cur_patch->options, cur_patch->negative, cur_patch->begin, 315c5cb3888SJustin T. Gibbs cur_patch->end); 316c5cb3888SJustin T. Gibbs 317c5cb3888SJustin T. Gibbs fprintf(ofile, "\t{ 0x%08x, %d, 0x%03x, 0x%03x }\n};\n", 318c5cb3888SJustin T. Gibbs 0, 0, 0, 0); 319c5cb3888SJustin T. Gibbs 320c5cb3888SJustin T. Gibbs fprintf(stderr, "%s: %d instructions used\n", appname, instrcount); 3210ef8c301SJustin T. Gibbs } 3220ef8c301SJustin T. Gibbs 323c5cb3888SJustin T. Gibbs void 3241c147cc3SJustin T. Gibbs output_listing(listfile, ifilename, patches) 325c5cb3888SJustin T. Gibbs FILE *listfile; 326c5cb3888SJustin T. Gibbs char *ifilename; 3271c147cc3SJustin T. Gibbs char *patches; 328c5cb3888SJustin T. Gibbs { 329c5cb3888SJustin T. Gibbs FILE *ifile; 330c5cb3888SJustin T. Gibbs int line; 331c5cb3888SJustin T. Gibbs struct instruction *cur_instr; 332c5cb3888SJustin T. Gibbs int instrcount; 3331c147cc3SJustin T. Gibbs int instrptr; 334c5cb3888SJustin T. Gibbs char buf[1024]; 3351c147cc3SJustin T. Gibbs patch_t *cur_patch; 3361c147cc3SJustin T. Gibbs char *option_spec; 3371c147cc3SJustin T. Gibbs int options; 338c5cb3888SJustin T. Gibbs 339c5cb3888SJustin T. Gibbs instrcount = 0; 3401c147cc3SJustin T. Gibbs instrptr = 0; 341c5cb3888SJustin T. Gibbs line = 1; 3421c147cc3SJustin T. Gibbs options = 1; /* All code outside of patch blocks */ 343c5cb3888SJustin T. Gibbs if ((ifile = fopen(ifilename, "r")) == NULL) { 344c5cb3888SJustin T. Gibbs perror(ifilename); 345c5cb3888SJustin T. Gibbs stop(NULL, EX_DATAERR); 346c5cb3888SJustin T. Gibbs } 3471c147cc3SJustin T. Gibbs 3481c147cc3SJustin T. Gibbs /* 3491c147cc3SJustin T. Gibbs * Determine which options to apply to this listing. 3501c147cc3SJustin T. Gibbs */ 3511c147cc3SJustin T. Gibbs while ((option_spec = strsep(&patches, "|")) != NULL) { 3521c147cc3SJustin T. Gibbs symbol_t *symbol; 3531c147cc3SJustin T. Gibbs 3541c147cc3SJustin T. Gibbs symbol = symtable_get(option_spec); 3551c147cc3SJustin T. Gibbs if (symbol->type != CONDITIONAL) { 3561c147cc3SJustin T. Gibbs stop("Invalid option specified in patch list for " 3571c147cc3SJustin T. Gibbs "program listing", EX_USAGE); 3581c147cc3SJustin T. Gibbs /* NOTREACHED */ 3591c147cc3SJustin T. Gibbs } 3601c147cc3SJustin T. Gibbs options |= symbol->info.condinfo->value; 3611c147cc3SJustin T. Gibbs } 3621c147cc3SJustin T. Gibbs 3631c147cc3SJustin T. Gibbs cur_patch = patch_list.stqh_first; 364c5cb3888SJustin T. Gibbs for(cur_instr = seq_program.stqh_first; 365c5cb3888SJustin T. Gibbs cur_instr != NULL; 3661c147cc3SJustin T. Gibbs cur_instr = cur_instr->links.stqe_next,instrcount++) { 3671c147cc3SJustin T. Gibbs 3681c147cc3SJustin T. Gibbs cur_patch = next_patch(cur_patch, options, instrcount); 3691c147cc3SJustin T. Gibbs if (cur_patch 3701c147cc3SJustin T. Gibbs && cur_patch->begin <= instrcount 3711c147cc3SJustin T. Gibbs && cur_patch->end > instrcount) 3721c147cc3SJustin T. Gibbs /* Don't count this instruction as it is in a patch 3731c147cc3SJustin T. Gibbs * that was removed. 3741c147cc3SJustin T. Gibbs */ 3751c147cc3SJustin T. Gibbs continue; 3761c147cc3SJustin T. Gibbs 377c5cb3888SJustin T. Gibbs while (line < cur_instr->srcline) { 378c5cb3888SJustin T. Gibbs fgets(buf, sizeof(buf), ifile); 379c5cb3888SJustin T. Gibbs fprintf(listfile, "\t\t%s", buf); 380c5cb3888SJustin T. Gibbs line++; 381c5cb3888SJustin T. Gibbs } 3821c147cc3SJustin T. Gibbs fprintf(listfile, "%03x %02x%02x%02x%02x", instrptr, 383c5cb3888SJustin T. Gibbs cur_instr->format.bytes[0], 384c5cb3888SJustin T. Gibbs cur_instr->format.bytes[1], 385c5cb3888SJustin T. Gibbs cur_instr->format.bytes[2], 386c5cb3888SJustin T. Gibbs cur_instr->format.bytes[3]); 387c5cb3888SJustin T. Gibbs fgets(buf, sizeof(buf), ifile); 3881c147cc3SJustin T. Gibbs fprintf(listfile, "\t%s", buf); 389c5cb3888SJustin T. Gibbs line++; 3901c147cc3SJustin T. Gibbs instrptr++; 391c5cb3888SJustin T. Gibbs } 3921c147cc3SJustin T. Gibbs /* Dump the remainder of the file */ 3931c147cc3SJustin T. Gibbs while(fgets(buf, sizeof(buf), ifile) != NULL) 3941c147cc3SJustin T. Gibbs fprintf(listfile, "\t\t%s", buf); 3951c147cc3SJustin T. Gibbs 396c5cb3888SJustin T. Gibbs fclose(ifile); 397c5cb3888SJustin T. Gibbs } 398c5cb3888SJustin T. Gibbs 3991c147cc3SJustin T. Gibbs static struct patch * 4001c147cc3SJustin T. Gibbs next_patch(cur_patch, options, instrptr) 4011c147cc3SJustin T. Gibbs struct patch *cur_patch; 4021c147cc3SJustin T. Gibbs int options; 4031c147cc3SJustin T. Gibbs int instrptr; 4041c147cc3SJustin T. Gibbs { 4051c147cc3SJustin T. Gibbs while(cur_patch != NULL) { 4061c147cc3SJustin T. Gibbs if (((cur_patch->options & options) != 0 4071c147cc3SJustin T. Gibbs && cur_patch->negative == FALSE) 4081c147cc3SJustin T. Gibbs || ((cur_patch->options & options) == 0 4091c147cc3SJustin T. Gibbs && cur_patch->negative == TRUE) 4101c147cc3SJustin T. Gibbs || (instrptr >= cur_patch->end)) { 4111c147cc3SJustin T. Gibbs /* 4121c147cc3SJustin T. Gibbs * Either we want to keep this section of code, 4131c147cc3SJustin T. Gibbs * or we have consumed this patch. Skip to the 4141c147cc3SJustin T. Gibbs * next patch. 4151c147cc3SJustin T. Gibbs */ 4161c147cc3SJustin T. Gibbs cur_patch = cur_patch->links.stqe_next; 4171c147cc3SJustin T. Gibbs } else 4181c147cc3SJustin T. Gibbs /* Found an okay patch */ 4191c147cc3SJustin T. Gibbs break; 4201c147cc3SJustin T. Gibbs } 4211c147cc3SJustin T. Gibbs return (cur_patch); 4221c147cc3SJustin T. Gibbs } 4231c147cc3SJustin T. Gibbs 424c5cb3888SJustin T. Gibbs /* 425c5cb3888SJustin T. Gibbs * Print out error information if appropriate, and clean up before 426c5cb3888SJustin T. Gibbs * terminating the program. 427c5cb3888SJustin T. Gibbs */ 428c5cb3888SJustin T. Gibbs void 429c5cb3888SJustin T. Gibbs stop(string, err_code) 430c5cb3888SJustin T. Gibbs const char *string; 431c5cb3888SJustin T. Gibbs int err_code; 432c5cb3888SJustin T. Gibbs { 433c5cb3888SJustin T. Gibbs if (string != NULL) { 434c5cb3888SJustin T. Gibbs fprintf(stderr, "%s: ", appname); 435c5cb3888SJustin T. Gibbs if (yyfilename != NULL) { 436c5cb3888SJustin T. Gibbs fprintf(stderr, "Stopped at file %s, line %d - ", 437c5cb3888SJustin T. Gibbs yyfilename, yylineno); 438c5cb3888SJustin T. Gibbs } 439c5cb3888SJustin T. Gibbs fprintf(stderr, "%s\n", string); 440c5cb3888SJustin T. Gibbs } 441c5cb3888SJustin T. Gibbs 442c5cb3888SJustin T. Gibbs if (ofile != NULL) { 443c5cb3888SJustin T. Gibbs fclose(ofile); 444c5cb3888SJustin T. Gibbs if (err_code != 0) { 445c5cb3888SJustin T. Gibbs fprintf(stderr, "%s: Removing %s due to error\n", 446c5cb3888SJustin T. Gibbs appname, ofilename); 447c5cb3888SJustin T. Gibbs unlink(ofilename); 4480ef8c301SJustin T. Gibbs } 4490ef8c301SJustin T. Gibbs } 4500ef8c301SJustin T. Gibbs 4511c147cc3SJustin T. Gibbs symlist_free(&patch_options); 452c5cb3888SJustin T. Gibbs symtable_close(); 453c5cb3888SJustin T. Gibbs 454c5cb3888SJustin T. Gibbs exit(err_code); 455adf51647SJustin T. Gibbs } 456adf51647SJustin T. Gibbs 457c5cb3888SJustin T. Gibbs struct instruction * 458c5cb3888SJustin T. Gibbs seq_alloc() 459c5cb3888SJustin T. Gibbs { 460c5cb3888SJustin T. Gibbs struct instruction *new_instr; 461c5cb3888SJustin T. Gibbs 462c5cb3888SJustin T. Gibbs new_instr = (struct instruction *)malloc(sizeof(struct instruction)); 463c5cb3888SJustin T. Gibbs if (new_instr == NULL) 464c5cb3888SJustin T. Gibbs stop("Unable to malloc instruction object", EX_SOFTWARE); 465c5cb3888SJustin T. Gibbs memset(new_instr, 0, sizeof(*new_instr)); 466c5cb3888SJustin T. Gibbs STAILQ_INSERT_TAIL(&seq_program, new_instr, links); 467c5cb3888SJustin T. Gibbs new_instr->srcline = yylineno; 468c5cb3888SJustin T. Gibbs return new_instr; 469adf51647SJustin T. Gibbs } 470c5cb3888SJustin T. Gibbs 471c5cb3888SJustin T. Gibbs patch_t * 472c5cb3888SJustin T. Gibbs patch_alloc() 473c5cb3888SJustin T. Gibbs { 474c5cb3888SJustin T. Gibbs patch_t *new_patch; 475c5cb3888SJustin T. Gibbs 476c5cb3888SJustin T. Gibbs new_patch = (patch_t *)malloc(sizeof(patch_t)); 477c5cb3888SJustin T. Gibbs if (new_patch == NULL) 478c5cb3888SJustin T. Gibbs stop("Unable to malloc patch object", EX_SOFTWARE); 479c5cb3888SJustin T. Gibbs memset(new_patch, 0, sizeof(*new_patch)); 480c5cb3888SJustin T. Gibbs STAILQ_INSERT_TAIL(&patch_list, new_patch, links); 481c5cb3888SJustin T. Gibbs return new_patch; 482adf51647SJustin T. Gibbs } 483