1098ca2bdSWarner Losh /*- 2c5cb3888SJustin T. Gibbs * Aic7xxx SCSI host adapter firmware asssembler symbol table implementation 3c5cb3888SJustin T. Gibbs * 4718cf2ccSPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 5718cf2ccSPedro F. Giffuni * 6c5cb3888SJustin T. Gibbs * Copyright (c) 1997 Justin T. Gibbs. 763183d8cSJustin T. Gibbs * Copyright (c) 2002 Adaptec Inc. 8c5cb3888SJustin T. Gibbs * All rights reserved. 9c5cb3888SJustin T. Gibbs * 10c5cb3888SJustin T. Gibbs * Redistribution and use in source and binary forms, with or without 11c5cb3888SJustin T. Gibbs * modification, are permitted provided that the following conditions 12c5cb3888SJustin T. Gibbs * are met: 13c5cb3888SJustin T. Gibbs * 1. Redistributions of source code must retain the above copyright 14f68f348bSJustin T. Gibbs * notice, this list of conditions, and the following disclaimer, 1541c47eeeSJustin T. Gibbs * without modification. 167ce72dbaSJustin T. Gibbs * 2. Redistributions in binary form must reproduce at minimum a disclaimer 177ce72dbaSJustin T. Gibbs * substantially similar to the "NO WARRANTY" disclaimer below 187ce72dbaSJustin T. Gibbs * ("Disclaimer") and any redistribution must be conditioned upon 197ce72dbaSJustin T. Gibbs * including a substantially similar Disclaimer requirement for further 207ce72dbaSJustin T. Gibbs * binary redistribution. 217ce72dbaSJustin T. Gibbs * 3. Neither the names of the above-listed copyright holders nor the names 227ce72dbaSJustin T. Gibbs * of any contributors may be used to endorse or promote products derived 237ce72dbaSJustin T. Gibbs * from this software without specific prior written permission. 24c5cb3888SJustin T. Gibbs * 25aa6dfd9dSJustin T. Gibbs * Alternatively, this software may be distributed under the terms of the 267ce72dbaSJustin T. Gibbs * GNU General Public License ("GPL") version 2 as published by the Free 277ce72dbaSJustin T. Gibbs * Software Foundation. 28aa6dfd9dSJustin T. Gibbs * 297ce72dbaSJustin T. Gibbs * NO WARRANTY 307ce72dbaSJustin T. Gibbs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 317ce72dbaSJustin T. Gibbs * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 327ce72dbaSJustin T. Gibbs * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 337ce72dbaSJustin T. Gibbs * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 347ce72dbaSJustin T. Gibbs * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 35c5cb3888SJustin T. Gibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 36c5cb3888SJustin T. Gibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 377ce72dbaSJustin T. Gibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 387ce72dbaSJustin T. Gibbs * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 397ce72dbaSJustin T. Gibbs * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 407ce72dbaSJustin T. Gibbs * POSSIBILITY OF SUCH DAMAGES. 41c5cb3888SJustin T. Gibbs * 42357c1c6aSJustin T. Gibbs * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#24 $ 43c5cb3888SJustin T. Gibbs */ 44c5cb3888SJustin T. Gibbs 45c5cb3888SJustin T. Gibbs #include <sys/types.h> 46cb0f0a02SEd Maste #include <sys/param.h> 47fb27c25aSRobert Millan #if defined(BSD) && !defined(__GNU__) 48c5cb3888SJustin T. Gibbs #include <db.h> 49cb0f0a02SEd Maste #else 50cb0f0a02SEd Maste #include <db_185.h> 5132da3127SJustin T. Gibbs #endif 52b18a2ef1SXin LI #include <ctype.h> 537fc23fe6SScott Long #include <fcntl.h> 5499ddedd8SJustin T. Gibbs #include <inttypes.h> 557ce72dbaSJustin T. Gibbs #include <regex.h> 56c5cb3888SJustin T. Gibbs #include <stdio.h> 57c5cb3888SJustin T. Gibbs #include <stdlib.h> 58c5cb3888SJustin T. Gibbs #include <string.h> 59c5cb3888SJustin T. Gibbs #include <sysexits.h> 60c5cb3888SJustin T. Gibbs 61c66dbc92SJustin T. Gibbs #include "aicasm_symbol.h" 62c66dbc92SJustin T. Gibbs #include "aicasm.h" 63c5cb3888SJustin T. Gibbs 64c5cb3888SJustin T. Gibbs static DB *symtable; 65c5cb3888SJustin T. Gibbs 66b18a2ef1SXin LI static symbol_t * 67b18a2ef1SXin LI symbol_create(const char *name) 68c5cb3888SJustin T. Gibbs { 69c5cb3888SJustin T. Gibbs symbol_t *new_symbol; 70c5cb3888SJustin T. Gibbs 71c5cb3888SJustin T. Gibbs new_symbol = (symbol_t *)malloc(sizeof(symbol_t)); 72c5cb3888SJustin T. Gibbs if (new_symbol == NULL) { 73c5cb3888SJustin T. Gibbs perror("Unable to create new symbol"); 74c5cb3888SJustin T. Gibbs exit(EX_SOFTWARE); 75c5cb3888SJustin T. Gibbs } 76c5cb3888SJustin T. Gibbs memset(new_symbol, 0, sizeof(*new_symbol)); 77c5cb3888SJustin T. Gibbs new_symbol->name = strdup(name); 7863183d8cSJustin T. Gibbs if (new_symbol->name == NULL) 7963183d8cSJustin T. Gibbs stop("Unable to strdup symbol name", EX_SOFTWARE); 80c5cb3888SJustin T. Gibbs new_symbol->type = UNINITIALIZED; 81c5cb3888SJustin T. Gibbs return (new_symbol); 82c5cb3888SJustin T. Gibbs } 83c5cb3888SJustin T. Gibbs 84c5cb3888SJustin T. Gibbs void 8532da3127SJustin T. Gibbs symbol_delete(symbol_t *symbol) 86c5cb3888SJustin T. Gibbs { 87c5cb3888SJustin T. Gibbs if (symtable != NULL) { 88c5cb3888SJustin T. Gibbs DBT key; 89c5cb3888SJustin T. Gibbs 90c5cb3888SJustin T. Gibbs key.data = symbol->name; 91c5cb3888SJustin T. Gibbs key.size = strlen(symbol->name); 92c5cb3888SJustin T. Gibbs symtable->del(symtable, &key, /*flags*/0); 93c5cb3888SJustin T. Gibbs } 94c5cb3888SJustin T. Gibbs switch(symbol->type) { 95c5cb3888SJustin T. Gibbs case SCBLOC: 96c5cb3888SJustin T. Gibbs case SRAMLOC: 97c5cb3888SJustin T. Gibbs case REGISTER: 98c5cb3888SJustin T. Gibbs if (symbol->info.rinfo != NULL) 99c5cb3888SJustin T. Gibbs free(symbol->info.rinfo); 100c5cb3888SJustin T. Gibbs break; 101c5cb3888SJustin T. Gibbs case ALIAS: 102c5cb3888SJustin T. Gibbs if (symbol->info.ainfo != NULL) 103c5cb3888SJustin T. Gibbs free(symbol->info.ainfo); 104c5cb3888SJustin T. Gibbs break; 105c5cb3888SJustin T. Gibbs case MASK: 10663183d8cSJustin T. Gibbs case FIELD: 10763183d8cSJustin T. Gibbs case ENUM: 10863183d8cSJustin T. Gibbs case ENUM_ENTRY: 10963183d8cSJustin T. Gibbs if (symbol->info.finfo != NULL) { 11063183d8cSJustin T. Gibbs symlist_free(&symbol->info.finfo->symrefs); 11163183d8cSJustin T. Gibbs free(symbol->info.finfo); 112c5cb3888SJustin T. Gibbs } 113c5cb3888SJustin T. Gibbs break; 11437507c1bSJustin T. Gibbs case DOWNLOAD_CONST: 115c5cb3888SJustin T. Gibbs case CONST: 116c5cb3888SJustin T. Gibbs if (symbol->info.cinfo != NULL) 117c5cb3888SJustin T. Gibbs free(symbol->info.cinfo); 118c5cb3888SJustin T. Gibbs break; 119c5cb3888SJustin T. Gibbs case LABEL: 120c5cb3888SJustin T. Gibbs if (symbol->info.linfo != NULL) 121c5cb3888SJustin T. Gibbs free(symbol->info.linfo); 122c5cb3888SJustin T. Gibbs break; 123c5cb3888SJustin T. Gibbs case UNINITIALIZED: 124c5cb3888SJustin T. Gibbs default: 125c5cb3888SJustin T. Gibbs break; 126c5cb3888SJustin T. Gibbs } 127c5cb3888SJustin T. Gibbs free(symbol->name); 128c5cb3888SJustin T. Gibbs free(symbol); 129c5cb3888SJustin T. Gibbs } 130c5cb3888SJustin T. Gibbs 131c5cb3888SJustin T. Gibbs void 13273c4bad0SEd Schouten symtable_open(void) 133c5cb3888SJustin T. Gibbs { 134c5cb3888SJustin T. Gibbs symtable = dbopen(/*filename*/NULL, 135c5cb3888SJustin T. Gibbs O_CREAT | O_NONBLOCK | O_RDWR, /*mode*/0, DB_HASH, 136c5cb3888SJustin T. Gibbs /*openinfo*/NULL); 137c5cb3888SJustin T. Gibbs 138c5cb3888SJustin T. Gibbs if (symtable == NULL) { 139c5cb3888SJustin T. Gibbs perror("Symbol table creation failed"); 140c5cb3888SJustin T. Gibbs exit(EX_SOFTWARE); 141c5cb3888SJustin T. Gibbs /* NOTREACHED */ 142c5cb3888SJustin T. Gibbs } 143c5cb3888SJustin T. Gibbs } 144c5cb3888SJustin T. Gibbs 145c5cb3888SJustin T. Gibbs void 14673c4bad0SEd Schouten symtable_close(void) 147c5cb3888SJustin T. Gibbs { 148c5cb3888SJustin T. Gibbs if (symtable != NULL) { 149c5cb3888SJustin T. Gibbs DBT key; 150c5cb3888SJustin T. Gibbs DBT data; 151c5cb3888SJustin T. Gibbs 152c5cb3888SJustin T. Gibbs while (symtable->seq(symtable, &key, &data, R_FIRST) == 0) { 15300fa2b1fSJustin T. Gibbs symbol_t *stored_ptr; 154c5cb3888SJustin T. Gibbs 15500fa2b1fSJustin T. Gibbs memcpy(&stored_ptr, data.data, sizeof(stored_ptr)); 15600fa2b1fSJustin T. Gibbs symbol_delete(stored_ptr); 157c5cb3888SJustin T. Gibbs } 158c5cb3888SJustin T. Gibbs symtable->close(symtable); 159c5cb3888SJustin T. Gibbs } 160c5cb3888SJustin T. Gibbs } 161c5cb3888SJustin T. Gibbs 162c5cb3888SJustin T. Gibbs /* 163c5cb3888SJustin T. Gibbs * The semantics of get is to return an uninitialized symbol entry 164c5cb3888SJustin T. Gibbs * if a lookup fails. 165c5cb3888SJustin T. Gibbs */ 166c5cb3888SJustin T. Gibbs symbol_t * 167b18a2ef1SXin LI symtable_get(const char *name) 168c5cb3888SJustin T. Gibbs { 16900fa2b1fSJustin T. Gibbs symbol_t *stored_ptr; 170c5cb3888SJustin T. Gibbs DBT key; 171c5cb3888SJustin T. Gibbs DBT data; 172c5cb3888SJustin T. Gibbs int retval; 173c5cb3888SJustin T. Gibbs 174b18a2ef1SXin LI key.data = strdup(name); 175c5cb3888SJustin T. Gibbs key.size = strlen(name); 176c5cb3888SJustin T. Gibbs 177c5cb3888SJustin T. Gibbs if ((retval = symtable->get(symtable, &key, &data, /*flags*/0)) != 0) { 178c5cb3888SJustin T. Gibbs if (retval == -1) { 179c5cb3888SJustin T. Gibbs perror("Symbol table get operation failed"); 180c5cb3888SJustin T. Gibbs exit(EX_SOFTWARE); 181c5cb3888SJustin T. Gibbs /* NOTREACHED */ 182c5cb3888SJustin T. Gibbs } else if (retval == 1) { 183c5cb3888SJustin T. Gibbs /* Symbol wasn't found, so create a new one */ 184c5cb3888SJustin T. Gibbs symbol_t *new_symbol; 185c5cb3888SJustin T. Gibbs 186c5cb3888SJustin T. Gibbs new_symbol = symbol_create(name); 187c5cb3888SJustin T. Gibbs data.data = &new_symbol; 188c5cb3888SJustin T. Gibbs data.size = sizeof(new_symbol); 189c5cb3888SJustin T. Gibbs if (symtable->put(symtable, &key, &data, 190c5cb3888SJustin T. Gibbs /*flags*/0) !=0) { 191c5cb3888SJustin T. Gibbs perror("Symtable put failed"); 192c5cb3888SJustin T. Gibbs exit(EX_SOFTWARE); 193c5cb3888SJustin T. Gibbs } 194b18a2ef1SXin LI free(key.data); 195c5cb3888SJustin T. Gibbs return (new_symbol); 196c5cb3888SJustin T. Gibbs } else { 197c5cb3888SJustin T. Gibbs perror("Unexpected return value from db get routine"); 198c5cb3888SJustin T. Gibbs exit(EX_SOFTWARE); 199c5cb3888SJustin T. Gibbs /* NOTREACHED */ 200c5cb3888SJustin T. Gibbs } 201c5cb3888SJustin T. Gibbs } 20200fa2b1fSJustin T. Gibbs memcpy(&stored_ptr, data.data, sizeof(stored_ptr)); 203b18a2ef1SXin LI free(key.data); 20400fa2b1fSJustin T. Gibbs return (stored_ptr); 205c5cb3888SJustin T. Gibbs } 206c5cb3888SJustin T. Gibbs 207c5cb3888SJustin T. Gibbs symbol_node_t * 20832da3127SJustin T. Gibbs symlist_search(symlist_t *symlist, char *symname) 209c5cb3888SJustin T. Gibbs { 210c5cb3888SJustin T. Gibbs symbol_node_t *curnode; 211c5cb3888SJustin T. Gibbs 212fc2ffbe6SPoul-Henning Kamp curnode = SLIST_FIRST(symlist); 213c5cb3888SJustin T. Gibbs while(curnode != NULL) { 214c5cb3888SJustin T. Gibbs if (strcmp(symname, curnode->symbol->name) == 0) 215c5cb3888SJustin T. Gibbs break; 216fc2ffbe6SPoul-Henning Kamp curnode = SLIST_NEXT(curnode, links); 217c5cb3888SJustin T. Gibbs } 218c5cb3888SJustin T. Gibbs return (curnode); 219c5cb3888SJustin T. Gibbs } 220c5cb3888SJustin T. Gibbs 221c5cb3888SJustin T. Gibbs void 22232da3127SJustin T. Gibbs symlist_add(symlist_t *symlist, symbol_t *symbol, int how) 223c5cb3888SJustin T. Gibbs { 224c5cb3888SJustin T. Gibbs symbol_node_t *newnode; 225c5cb3888SJustin T. Gibbs 226c5cb3888SJustin T. Gibbs newnode = (symbol_node_t *)malloc(sizeof(symbol_node_t)); 227c5cb3888SJustin T. Gibbs if (newnode == NULL) { 228c5cb3888SJustin T. Gibbs stop("symlist_add: Unable to malloc symbol_node", EX_SOFTWARE); 229c5cb3888SJustin T. Gibbs /* NOTREACHED */ 230c5cb3888SJustin T. Gibbs } 231c5cb3888SJustin T. Gibbs newnode->symbol = symbol; 232c5cb3888SJustin T. Gibbs if (how == SYMLIST_SORT) { 233c5cb3888SJustin T. Gibbs symbol_node_t *curnode; 23463183d8cSJustin T. Gibbs int field; 235c5cb3888SJustin T. Gibbs 23663183d8cSJustin T. Gibbs field = FALSE; 237c5cb3888SJustin T. Gibbs switch(symbol->type) { 238c5cb3888SJustin T. Gibbs case REGISTER: 239c5cb3888SJustin T. Gibbs case SCBLOC: 240c5cb3888SJustin T. Gibbs case SRAMLOC: 241c5cb3888SJustin T. Gibbs break; 24263183d8cSJustin T. Gibbs case FIELD: 243c5cb3888SJustin T. Gibbs case MASK: 24463183d8cSJustin T. Gibbs case ENUM: 24563183d8cSJustin T. Gibbs case ENUM_ENTRY: 24663183d8cSJustin T. Gibbs field = TRUE; 247c5cb3888SJustin T. Gibbs break; 248c5cb3888SJustin T. Gibbs default: 249c5cb3888SJustin T. Gibbs stop("symlist_add: Invalid symbol type for sorting", 250c5cb3888SJustin T. Gibbs EX_SOFTWARE); 251c5cb3888SJustin T. Gibbs /* NOTREACHED */ 252c5cb3888SJustin T. Gibbs } 253c5cb3888SJustin T. Gibbs 254fc2ffbe6SPoul-Henning Kamp curnode = SLIST_FIRST(symlist); 255c5cb3888SJustin T. Gibbs if (curnode == NULL 25663183d8cSJustin T. Gibbs || (field 25763183d8cSJustin T. Gibbs && (curnode->symbol->type > newnode->symbol->type 25863183d8cSJustin T. Gibbs || (curnode->symbol->type == newnode->symbol->type 25963183d8cSJustin T. Gibbs && (curnode->symbol->info.finfo->value > 26063183d8cSJustin T. Gibbs newnode->symbol->info.finfo->value)))) 26163183d8cSJustin T. Gibbs || (!field && (curnode->symbol->info.rinfo->address > 262c5cb3888SJustin T. Gibbs newnode->symbol->info.rinfo->address))) { 263c5cb3888SJustin T. Gibbs SLIST_INSERT_HEAD(symlist, newnode, links); 264c5cb3888SJustin T. Gibbs return; 265c5cb3888SJustin T. Gibbs } 266c5cb3888SJustin T. Gibbs 267c5cb3888SJustin T. Gibbs while (1) { 268fc2ffbe6SPoul-Henning Kamp if (SLIST_NEXT(curnode, links) == NULL) { 269c5cb3888SJustin T. Gibbs SLIST_INSERT_AFTER(curnode, newnode, 270c5cb3888SJustin T. Gibbs links); 271c5cb3888SJustin T. Gibbs break; 272c5cb3888SJustin T. Gibbs } else { 273c5cb3888SJustin T. Gibbs symbol_t *cursymbol; 274c5cb3888SJustin T. Gibbs 275fc2ffbe6SPoul-Henning Kamp cursymbol = SLIST_NEXT(curnode, links)->symbol; 27663183d8cSJustin T. Gibbs if ((field 27763183d8cSJustin T. Gibbs && (cursymbol->type > symbol->type 27863183d8cSJustin T. Gibbs || (cursymbol->type == symbol->type 27963183d8cSJustin T. Gibbs && (cursymbol->info.finfo->value > 28063183d8cSJustin T. Gibbs symbol->info.finfo->value)))) 28163183d8cSJustin T. Gibbs || (!field 28263183d8cSJustin T. Gibbs && (cursymbol->info.rinfo->address > 283c5cb3888SJustin T. Gibbs symbol->info.rinfo->address))) { 284c5cb3888SJustin T. Gibbs SLIST_INSERT_AFTER(curnode, newnode, 285c5cb3888SJustin T. Gibbs links); 286c5cb3888SJustin T. Gibbs break; 287c5cb3888SJustin T. Gibbs } 288c5cb3888SJustin T. Gibbs } 289fc2ffbe6SPoul-Henning Kamp curnode = SLIST_NEXT(curnode, links); 290c5cb3888SJustin T. Gibbs } 291c5cb3888SJustin T. Gibbs } else { 292c5cb3888SJustin T. Gibbs SLIST_INSERT_HEAD(symlist, newnode, links); 293c5cb3888SJustin T. Gibbs } 294c5cb3888SJustin T. Gibbs } 295c5cb3888SJustin T. Gibbs 296c5cb3888SJustin T. Gibbs void 29732da3127SJustin T. Gibbs symlist_free(symlist_t *symlist) 298c5cb3888SJustin T. Gibbs { 299c5cb3888SJustin T. Gibbs symbol_node_t *node1, *node2; 300c5cb3888SJustin T. Gibbs 301fc2ffbe6SPoul-Henning Kamp node1 = SLIST_FIRST(symlist); 302c5cb3888SJustin T. Gibbs while (node1 != NULL) { 303fc2ffbe6SPoul-Henning Kamp node2 = SLIST_NEXT(node1, links); 304c5cb3888SJustin T. Gibbs free(node1); 305c5cb3888SJustin T. Gibbs node1 = node2; 306c5cb3888SJustin T. Gibbs } 307c5cb3888SJustin T. Gibbs SLIST_INIT(symlist); 308c5cb3888SJustin T. Gibbs } 309c5cb3888SJustin T. Gibbs 310c5cb3888SJustin T. Gibbs void 31132da3127SJustin T. Gibbs symlist_merge(symlist_t *symlist_dest, symlist_t *symlist_src1, 31232da3127SJustin T. Gibbs symlist_t *symlist_src2) 313c5cb3888SJustin T. Gibbs { 314c5cb3888SJustin T. Gibbs symbol_node_t *node; 315c5cb3888SJustin T. Gibbs 316c5cb3888SJustin T. Gibbs *symlist_dest = *symlist_src1; 317fc2ffbe6SPoul-Henning Kamp while((node = SLIST_FIRST(symlist_src2)) != NULL) { 318c5cb3888SJustin T. Gibbs SLIST_REMOVE_HEAD(symlist_src2, links); 319c5cb3888SJustin T. Gibbs SLIST_INSERT_HEAD(symlist_dest, node, links); 320c5cb3888SJustin T. Gibbs } 321c5cb3888SJustin T. Gibbs 322c5cb3888SJustin T. Gibbs /* These are now empty */ 323c5cb3888SJustin T. Gibbs SLIST_INIT(symlist_src1); 324c5cb3888SJustin T. Gibbs SLIST_INIT(symlist_src2); 325c5cb3888SJustin T. Gibbs } 326c5cb3888SJustin T. Gibbs 327b18a2ef1SXin LI static void 32863183d8cSJustin T. Gibbs aic_print_file_prologue(FILE *ofile) 32963183d8cSJustin T. Gibbs { 33063183d8cSJustin T. Gibbs 33163183d8cSJustin T. Gibbs if (ofile == NULL) 33263183d8cSJustin T. Gibbs return; 33363183d8cSJustin T. Gibbs 33463183d8cSJustin T. Gibbs fprintf(ofile, 33563183d8cSJustin T. Gibbs "/*\n" 33663183d8cSJustin T. Gibbs " * DO NOT EDIT - This file is automatically generated\n" 33763183d8cSJustin T. Gibbs " * from the following source files:\n" 33863183d8cSJustin T. Gibbs " *\n" 33963183d8cSJustin T. Gibbs "%s */\n", 34063183d8cSJustin T. Gibbs versions); 34163183d8cSJustin T. Gibbs } 34263183d8cSJustin T. Gibbs 343b18a2ef1SXin LI static void 344b18a2ef1SXin LI aic_print_include(FILE *dfile, char *header_file) 34563183d8cSJustin T. Gibbs { 34663183d8cSJustin T. Gibbs if (dfile == NULL) 34763183d8cSJustin T. Gibbs return; 348*34db47a9SHP van Braam 349*34db47a9SHP van Braam if (header_file[0] == '<') 350*34db47a9SHP van Braam fprintf(dfile, "\n#include %s\n\n", header_file); 351*34db47a9SHP van Braam else 352b18a2ef1SXin LI fprintf(dfile, "\n#include \"%s\"\n\n", header_file); 35363183d8cSJustin T. Gibbs } 35463183d8cSJustin T. Gibbs 355b18a2ef1SXin LI static void 35663183d8cSJustin T. Gibbs aic_print_reg_dump_types(FILE *ofile) 35763183d8cSJustin T. Gibbs { 35863183d8cSJustin T. Gibbs if (ofile == NULL) 35963183d8cSJustin T. Gibbs return; 36063183d8cSJustin T. Gibbs 36163183d8cSJustin T. Gibbs fprintf(ofile, 36263183d8cSJustin T. Gibbs "typedef int (%sreg_print_t)(u_int, u_int *, u_int);\n" 36363183d8cSJustin T. Gibbs "typedef struct %sreg_parse_entry {\n" 36463183d8cSJustin T. Gibbs " char *name;\n" 36563183d8cSJustin T. Gibbs " uint8_t value;\n" 36663183d8cSJustin T. Gibbs " uint8_t mask;\n" 36763183d8cSJustin T. Gibbs "} %sreg_parse_entry_t;\n" 36863183d8cSJustin T. Gibbs "\n", 36963183d8cSJustin T. Gibbs prefix, prefix, prefix); 37063183d8cSJustin T. Gibbs } 37163183d8cSJustin T. Gibbs 37263183d8cSJustin T. Gibbs static void 37363183d8cSJustin T. Gibbs aic_print_reg_dump_start(FILE *dfile, symbol_node_t *regnode) 37463183d8cSJustin T. Gibbs { 37563183d8cSJustin T. Gibbs if (dfile == NULL) 37663183d8cSJustin T. Gibbs return; 37763183d8cSJustin T. Gibbs 37863183d8cSJustin T. Gibbs fprintf(dfile, 37963183d8cSJustin T. Gibbs "static %sreg_parse_entry_t %s_parse_table[] = {\n", 38063183d8cSJustin T. Gibbs prefix, 38163183d8cSJustin T. Gibbs regnode->symbol->name); 38263183d8cSJustin T. Gibbs } 38363183d8cSJustin T. Gibbs 38463183d8cSJustin T. Gibbs static void 38563183d8cSJustin T. Gibbs aic_print_reg_dump_end(FILE *ofile, FILE *dfile, 38663183d8cSJustin T. Gibbs symbol_node_t *regnode, u_int num_entries) 38763183d8cSJustin T. Gibbs { 38863183d8cSJustin T. Gibbs char *lower_name; 38963183d8cSJustin T. Gibbs char *letter; 39063183d8cSJustin T. Gibbs 39163183d8cSJustin T. Gibbs lower_name = strdup(regnode->symbol->name); 39263183d8cSJustin T. Gibbs if (lower_name == NULL) 39363183d8cSJustin T. Gibbs stop("Unable to strdup symbol name", EX_SOFTWARE); 39463183d8cSJustin T. Gibbs 39563183d8cSJustin T. Gibbs for (letter = lower_name; *letter != '\0'; letter++) 39663183d8cSJustin T. Gibbs *letter = tolower(*letter); 39763183d8cSJustin T. Gibbs 39863183d8cSJustin T. Gibbs if (dfile != NULL) { 39963183d8cSJustin T. Gibbs if (num_entries != 0) 40063183d8cSJustin T. Gibbs fprintf(dfile, 40163183d8cSJustin T. Gibbs "\n" 40263183d8cSJustin T. Gibbs "};\n" 40363183d8cSJustin T. Gibbs "\n"); 40463183d8cSJustin T. Gibbs 40563183d8cSJustin T. Gibbs fprintf(dfile, 40663183d8cSJustin T. Gibbs "int\n" 40763183d8cSJustin T. Gibbs "%s%s_print(u_int regvalue, u_int *cur_col, u_int wrap)\n" 40863183d8cSJustin T. Gibbs "{\n" 40963183d8cSJustin T. Gibbs " return (%sprint_register(%s%s, %d, \"%s\",\n" 41063183d8cSJustin T. Gibbs " 0x%02x, regvalue, cur_col, wrap));\n" 41163183d8cSJustin T. Gibbs "}\n" 41263183d8cSJustin T. Gibbs "\n", 41363183d8cSJustin T. Gibbs prefix, 41463183d8cSJustin T. Gibbs lower_name, 41563183d8cSJustin T. Gibbs prefix, 41663183d8cSJustin T. Gibbs num_entries != 0 ? regnode->symbol->name : "NULL", 41763183d8cSJustin T. Gibbs num_entries != 0 ? "_parse_table" : "", 41863183d8cSJustin T. Gibbs num_entries, 41963183d8cSJustin T. Gibbs regnode->symbol->name, 42063183d8cSJustin T. Gibbs regnode->symbol->info.rinfo->address); 42163183d8cSJustin T. Gibbs } 42263183d8cSJustin T. Gibbs 42363183d8cSJustin T. Gibbs fprintf(ofile, 42463183d8cSJustin T. Gibbs "#if AIC_DEBUG_REGISTERS\n" 42563183d8cSJustin T. Gibbs "%sreg_print_t %s%s_print;\n" 42663183d8cSJustin T. Gibbs "#else\n" 42763183d8cSJustin T. Gibbs "#define %s%s_print(regvalue, cur_col, wrap) \\\n" 42863183d8cSJustin T. Gibbs " %sprint_register(NULL, 0, \"%s\", 0x%02x, regvalue, cur_col, wrap)\n" 42963183d8cSJustin T. Gibbs "#endif\n" 43063183d8cSJustin T. Gibbs "\n", 43163183d8cSJustin T. Gibbs prefix, 43263183d8cSJustin T. Gibbs prefix, 43363183d8cSJustin T. Gibbs lower_name, 43463183d8cSJustin T. Gibbs prefix, 43563183d8cSJustin T. Gibbs lower_name, 43663183d8cSJustin T. Gibbs prefix, 43763183d8cSJustin T. Gibbs regnode->symbol->name, 43863183d8cSJustin T. Gibbs regnode->symbol->info.rinfo->address); 43963183d8cSJustin T. Gibbs } 44063183d8cSJustin T. Gibbs 44163183d8cSJustin T. Gibbs static void 44263183d8cSJustin T. Gibbs aic_print_reg_dump_entry(FILE *dfile, symbol_node_t *curnode) 44363183d8cSJustin T. Gibbs { 44463183d8cSJustin T. Gibbs int num_tabs; 44563183d8cSJustin T. Gibbs 44663183d8cSJustin T. Gibbs if (dfile == NULL) 44763183d8cSJustin T. Gibbs return; 44863183d8cSJustin T. Gibbs 44963183d8cSJustin T. Gibbs fprintf(dfile, 45063183d8cSJustin T. Gibbs " { \"%s\",", 45163183d8cSJustin T. Gibbs curnode->symbol->name); 45263183d8cSJustin T. Gibbs 45363183d8cSJustin T. Gibbs num_tabs = 3 - (strlen(curnode->symbol->name) + 5) / 8; 45463183d8cSJustin T. Gibbs 45563183d8cSJustin T. Gibbs while (num_tabs-- > 0) 45663183d8cSJustin T. Gibbs fputc('\t', dfile); 45763183d8cSJustin T. Gibbs fprintf(dfile, "0x%02x, 0x%02x }", 45863183d8cSJustin T. Gibbs curnode->symbol->info.finfo->value, 45963183d8cSJustin T. Gibbs curnode->symbol->info.finfo->mask); 46063183d8cSJustin T. Gibbs } 46163183d8cSJustin T. Gibbs 46263183d8cSJustin T. Gibbs void 46363183d8cSJustin T. Gibbs symtable_dump(FILE *ofile, FILE *dfile) 464c5cb3888SJustin T. Gibbs { 465c5cb3888SJustin T. Gibbs /* 466c5cb3888SJustin T. Gibbs * Sort the registers by address with a simple insertion sort. 467c5cb3888SJustin T. Gibbs * Put bitmasks next to the first register that defines them. 468c5cb3888SJustin T. Gibbs * Put constants at the end. 469c5cb3888SJustin T. Gibbs */ 470c5cb3888SJustin T. Gibbs symlist_t registers; 471c5cb3888SJustin T. Gibbs symlist_t masks; 472c5cb3888SJustin T. Gibbs symlist_t constants; 47337507c1bSJustin T. Gibbs symlist_t download_constants; 474c5cb3888SJustin T. Gibbs symlist_t aliases; 4757ce72dbaSJustin T. Gibbs symlist_t exported_labels; 47663183d8cSJustin T. Gibbs symbol_node_t *curnode; 47763183d8cSJustin T. Gibbs symbol_node_t *regnode; 47863183d8cSJustin T. Gibbs DBT key; 47963183d8cSJustin T. Gibbs DBT data; 48063183d8cSJustin T. Gibbs int flag; 4817ce72dbaSJustin T. Gibbs u_int i; 482c5cb3888SJustin T. Gibbs 48363183d8cSJustin T. Gibbs if (symtable == NULL) 48463183d8cSJustin T. Gibbs return; 48563183d8cSJustin T. Gibbs 486c5cb3888SJustin T. Gibbs SLIST_INIT(®isters); 487c5cb3888SJustin T. Gibbs SLIST_INIT(&masks); 488c5cb3888SJustin T. Gibbs SLIST_INIT(&constants); 48937507c1bSJustin T. Gibbs SLIST_INIT(&download_constants); 490c5cb3888SJustin T. Gibbs SLIST_INIT(&aliases); 4917ce72dbaSJustin T. Gibbs SLIST_INIT(&exported_labels); 49263183d8cSJustin T. Gibbs flag = R_FIRST; 493c5cb3888SJustin T. Gibbs while (symtable->seq(symtable, &key, &data, flag) == 0) { 494c5cb3888SJustin T. Gibbs symbol_t *cursym; 495c5cb3888SJustin T. Gibbs 49600fa2b1fSJustin T. Gibbs memcpy(&cursym, data.data, sizeof(cursym)); 497c5cb3888SJustin T. Gibbs switch(cursym->type) { 498c5cb3888SJustin T. Gibbs case REGISTER: 499c5cb3888SJustin T. Gibbs case SCBLOC: 500c5cb3888SJustin T. Gibbs case SRAMLOC: 501c5cb3888SJustin T. Gibbs symlist_add(®isters, cursym, SYMLIST_SORT); 502c5cb3888SJustin T. Gibbs break; 503c5cb3888SJustin T. Gibbs case MASK: 50463183d8cSJustin T. Gibbs case FIELD: 50563183d8cSJustin T. Gibbs case ENUM: 50663183d8cSJustin T. Gibbs case ENUM_ENTRY: 507c5cb3888SJustin T. Gibbs symlist_add(&masks, cursym, SYMLIST_SORT); 508c5cb3888SJustin T. Gibbs break; 509c5cb3888SJustin T. Gibbs case CONST: 510c5cb3888SJustin T. Gibbs symlist_add(&constants, cursym, 511c5cb3888SJustin T. Gibbs SYMLIST_INSERT_HEAD); 512c5cb3888SJustin T. Gibbs break; 51337507c1bSJustin T. Gibbs case DOWNLOAD_CONST: 51437507c1bSJustin T. Gibbs symlist_add(&download_constants, cursym, 51537507c1bSJustin T. Gibbs SYMLIST_INSERT_HEAD); 51637507c1bSJustin T. Gibbs break; 517c5cb3888SJustin T. Gibbs case ALIAS: 518c5cb3888SJustin T. Gibbs symlist_add(&aliases, cursym, 519c5cb3888SJustin T. Gibbs SYMLIST_INSERT_HEAD); 52037507c1bSJustin T. Gibbs break; 5217ce72dbaSJustin T. Gibbs case LABEL: 5227ce72dbaSJustin T. Gibbs if (cursym->info.linfo->exported == 0) 5237ce72dbaSJustin T. Gibbs break; 5247ce72dbaSJustin T. Gibbs symlist_add(&exported_labels, cursym, 5257ce72dbaSJustin T. Gibbs SYMLIST_INSERT_HEAD); 5267ce72dbaSJustin T. Gibbs break; 527c5cb3888SJustin T. Gibbs default: 528c5cb3888SJustin T. Gibbs break; 529c5cb3888SJustin T. Gibbs } 530c5cb3888SJustin T. Gibbs flag = R_NEXT; 531c5cb3888SJustin T. Gibbs } 532c5cb3888SJustin T. Gibbs 53363183d8cSJustin T. Gibbs /* Register dianostic functions/declarations first. */ 53463183d8cSJustin T. Gibbs aic_print_file_prologue(ofile); 53563183d8cSJustin T. Gibbs aic_print_reg_dump_types(ofile); 53663183d8cSJustin T. Gibbs aic_print_file_prologue(dfile); 53763183d8cSJustin T. Gibbs aic_print_include(dfile, stock_include_file); 53863183d8cSJustin T. Gibbs SLIST_FOREACH(curnode, ®isters, links) { 53963183d8cSJustin T. Gibbs switch(curnode->symbol->type) { 54063183d8cSJustin T. Gibbs case REGISTER: 54163183d8cSJustin T. Gibbs case SCBLOC: 54263183d8cSJustin T. Gibbs case SRAMLOC: 54363183d8cSJustin T. Gibbs { 54463183d8cSJustin T. Gibbs symlist_t *fields; 54563183d8cSJustin T. Gibbs symbol_node_t *fieldnode; 54663183d8cSJustin T. Gibbs int num_entries; 54763183d8cSJustin T. Gibbs 54863183d8cSJustin T. Gibbs num_entries = 0; 54963183d8cSJustin T. Gibbs fields = &curnode->symbol->info.rinfo->fields; 55063183d8cSJustin T. Gibbs SLIST_FOREACH(fieldnode, fields, links) { 55163183d8cSJustin T. Gibbs if (num_entries == 0) 55263183d8cSJustin T. Gibbs aic_print_reg_dump_start(dfile, 55363183d8cSJustin T. Gibbs curnode); 554357c1c6aSJustin T. Gibbs else if (dfile != NULL) 55563183d8cSJustin T. Gibbs fputs(",\n", dfile); 55663183d8cSJustin T. Gibbs num_entries++; 55763183d8cSJustin T. Gibbs aic_print_reg_dump_entry(dfile, fieldnode); 55863183d8cSJustin T. Gibbs } 55963183d8cSJustin T. Gibbs aic_print_reg_dump_end(ofile, dfile, 56063183d8cSJustin T. Gibbs curnode, num_entries); 56163183d8cSJustin T. Gibbs } 56263183d8cSJustin T. Gibbs default: 56363183d8cSJustin T. Gibbs break; 56463183d8cSJustin T. Gibbs } 56563183d8cSJustin T. Gibbs } 56663183d8cSJustin T. Gibbs 56763183d8cSJustin T. Gibbs /* Fold in the masks and bits */ 568fc2ffbe6SPoul-Henning Kamp while (SLIST_FIRST(&masks) != NULL) { 569c5cb3888SJustin T. Gibbs char *regname; 570c5cb3888SJustin T. Gibbs 571fc2ffbe6SPoul-Henning Kamp curnode = SLIST_FIRST(&masks); 572c5cb3888SJustin T. Gibbs SLIST_REMOVE_HEAD(&masks, links); 573c5cb3888SJustin T. Gibbs 57463183d8cSJustin T. Gibbs regnode = SLIST_FIRST(&curnode->symbol->info.finfo->symrefs); 575c5cb3888SJustin T. Gibbs regname = regnode->symbol->name; 576c5cb3888SJustin T. Gibbs regnode = symlist_search(®isters, regname); 577c5cb3888SJustin T. Gibbs SLIST_INSERT_AFTER(regnode, curnode, links); 578c5cb3888SJustin T. Gibbs } 579c5cb3888SJustin T. Gibbs 580c5cb3888SJustin T. Gibbs /* Add the aliases */ 581fc2ffbe6SPoul-Henning Kamp while (SLIST_FIRST(&aliases) != NULL) { 582c5cb3888SJustin T. Gibbs char *regname; 583c5cb3888SJustin T. Gibbs 584fc2ffbe6SPoul-Henning Kamp curnode = SLIST_FIRST(&aliases); 585c5cb3888SJustin T. Gibbs SLIST_REMOVE_HEAD(&aliases, links); 586c5cb3888SJustin T. Gibbs 587c5cb3888SJustin T. Gibbs regname = curnode->symbol->info.ainfo->parent->name; 588c5cb3888SJustin T. Gibbs regnode = symlist_search(®isters, regname); 589c5cb3888SJustin T. Gibbs SLIST_INSERT_AFTER(regnode, curnode, links); 590c5cb3888SJustin T. Gibbs } 591c5cb3888SJustin T. Gibbs 59263183d8cSJustin T. Gibbs /* Output generated #defines. */ 593fc2ffbe6SPoul-Henning Kamp while (SLIST_FIRST(®isters) != NULL) { 5947ce72dbaSJustin T. Gibbs u_int value; 595b18a2ef1SXin LI const char *tab_str; 596b18a2ef1SXin LI const char *tab_str2; 597c5cb3888SJustin T. Gibbs 598fc2ffbe6SPoul-Henning Kamp curnode = SLIST_FIRST(®isters); 599c5cb3888SJustin T. Gibbs SLIST_REMOVE_HEAD(®isters, links); 600c5cb3888SJustin T. Gibbs switch(curnode->symbol->type) { 601c5cb3888SJustin T. Gibbs case REGISTER: 602c5cb3888SJustin T. Gibbs case SCBLOC: 603c5cb3888SJustin T. Gibbs case SRAMLOC: 604c5cb3888SJustin T. Gibbs fprintf(ofile, "\n"); 605c5cb3888SJustin T. Gibbs value = curnode->symbol->info.rinfo->address; 606c5cb3888SJustin T. Gibbs tab_str = "\t"; 607c5cb3888SJustin T. Gibbs tab_str2 = "\t\t"; 608c5cb3888SJustin T. Gibbs break; 609c5cb3888SJustin T. Gibbs case ALIAS: 610c5cb3888SJustin T. Gibbs { 611c5cb3888SJustin T. Gibbs symbol_t *parent; 612c5cb3888SJustin T. Gibbs 613c5cb3888SJustin T. Gibbs parent = curnode->symbol->info.ainfo->parent; 614c5cb3888SJustin T. Gibbs value = parent->info.rinfo->address; 615c5cb3888SJustin T. Gibbs tab_str = "\t"; 616c5cb3888SJustin T. Gibbs tab_str2 = "\t\t"; 617c5cb3888SJustin T. Gibbs break; 618c5cb3888SJustin T. Gibbs } 619c5cb3888SJustin T. Gibbs case MASK: 62063183d8cSJustin T. Gibbs case FIELD: 62163183d8cSJustin T. Gibbs case ENUM: 62263183d8cSJustin T. Gibbs case ENUM_ENTRY: 62363183d8cSJustin T. Gibbs value = curnode->symbol->info.finfo->value; 624c5cb3888SJustin T. Gibbs tab_str = "\t\t"; 625c5cb3888SJustin T. Gibbs tab_str2 = "\t"; 626c5cb3888SJustin T. Gibbs break; 627c5cb3888SJustin T. Gibbs default: 628c5cb3888SJustin T. Gibbs value = 0; /* Quiet compiler */ 629c5cb3888SJustin T. Gibbs tab_str = NULL; 630c5cb3888SJustin T. Gibbs tab_str2 = NULL; 631c5cb3888SJustin T. Gibbs stop("symtable_dump: Invalid symbol type " 632c5cb3888SJustin T. Gibbs "encountered", EX_SOFTWARE); 633c5cb3888SJustin T. Gibbs break; 634c5cb3888SJustin T. Gibbs } 635c5cb3888SJustin T. Gibbs fprintf(ofile, "#define%s%-16s%s0x%02x\n", 636c5cb3888SJustin T. Gibbs tab_str, curnode->symbol->name, tab_str2, 637c5cb3888SJustin T. Gibbs value); 638c5cb3888SJustin T. Gibbs free(curnode); 639c5cb3888SJustin T. Gibbs } 640c5cb3888SJustin T. Gibbs fprintf(ofile, "\n\n"); 641c5cb3888SJustin T. Gibbs 642fc2ffbe6SPoul-Henning Kamp while (SLIST_FIRST(&constants) != NULL) { 643fc2ffbe6SPoul-Henning Kamp curnode = SLIST_FIRST(&constants); 644c5cb3888SJustin T. Gibbs SLIST_REMOVE_HEAD(&constants, links); 645c5cb3888SJustin T. Gibbs fprintf(ofile, "#define\t%-8s\t0x%02x\n", 646c5cb3888SJustin T. Gibbs curnode->symbol->name, 647c5cb3888SJustin T. Gibbs curnode->symbol->info.cinfo->value); 648c5cb3888SJustin T. Gibbs free(curnode); 649c5cb3888SJustin T. Gibbs } 65037507c1bSJustin T. Gibbs 65137507c1bSJustin T. Gibbs fprintf(ofile, "\n\n/* Downloaded Constant Definitions */\n"); 65237507c1bSJustin T. Gibbs 6537ce72dbaSJustin T. Gibbs for (i = 0; SLIST_FIRST(&download_constants) != NULL; i++) { 654fc2ffbe6SPoul-Henning Kamp curnode = SLIST_FIRST(&download_constants); 65537507c1bSJustin T. Gibbs SLIST_REMOVE_HEAD(&download_constants, links); 65637507c1bSJustin T. Gibbs fprintf(ofile, "#define\t%-8s\t0x%02x\n", 65737507c1bSJustin T. Gibbs curnode->symbol->name, 65837507c1bSJustin T. Gibbs curnode->symbol->info.cinfo->value); 65937507c1bSJustin T. Gibbs free(curnode); 66037507c1bSJustin T. Gibbs } 6617ce72dbaSJustin T. Gibbs fprintf(ofile, "#define\tDOWNLOAD_CONST_COUNT\t0x%02x\n", i); 6627ce72dbaSJustin T. Gibbs 6637ce72dbaSJustin T. Gibbs fprintf(ofile, "\n\n/* Exported Labels */\n"); 6647ce72dbaSJustin T. Gibbs 6657ce72dbaSJustin T. Gibbs while (SLIST_FIRST(&exported_labels) != NULL) { 6667ce72dbaSJustin T. Gibbs curnode = SLIST_FIRST(&exported_labels); 6677ce72dbaSJustin T. Gibbs SLIST_REMOVE_HEAD(&exported_labels, links); 6687ce72dbaSJustin T. Gibbs fprintf(ofile, "#define\tLABEL_%-8s\t0x%02x\n", 6697ce72dbaSJustin T. Gibbs curnode->symbol->name, 6707ce72dbaSJustin T. Gibbs curnode->symbol->info.linfo->address); 6717ce72dbaSJustin T. Gibbs free(curnode); 6727ce72dbaSJustin T. Gibbs } 673c5cb3888SJustin T. Gibbs } 674