1139749Simp/*- 223925Sgibbs * Aic7xxx SCSI host adapter firmware asssembler symbol table implementation 323925Sgibbs * 423925Sgibbs * Copyright (c) 1997 Justin T. Gibbs. 5102668Sgibbs * Copyright (c) 2002 Adaptec Inc. 623925Sgibbs * All rights reserved. 723925Sgibbs * 823925Sgibbs * Redistribution and use in source and binary forms, with or without 923925Sgibbs * modification, are permitted provided that the following conditions 1023925Sgibbs * are met: 1123925Sgibbs * 1. Redistributions of source code must retain the above copyright 1226997Sgibbs * notice, this list of conditions, and the following disclaimer, 1354211Sgibbs * without modification. 1495376Sgibbs * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1595376Sgibbs * substantially similar to the "NO WARRANTY" disclaimer below 1695376Sgibbs * ("Disclaimer") and any redistribution must be conditioned upon 1795376Sgibbs * including a substantially similar Disclaimer requirement for further 1895376Sgibbs * binary redistribution. 1995376Sgibbs * 3. Neither the names of the above-listed copyright holders nor the names 2095376Sgibbs * of any contributors may be used to endorse or promote products derived 2195376Sgibbs * from this software without specific prior written permission. 2223925Sgibbs * 2363457Sgibbs * Alternatively, this software may be distributed under the terms of the 2495376Sgibbs * GNU General Public License ("GPL") version 2 as published by the Free 2595376Sgibbs * Software Foundation. 2663457Sgibbs * 2795376Sgibbs * NO WARRANTY 2895376Sgibbs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2995376Sgibbs * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3095376Sgibbs * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3195376Sgibbs * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3295376Sgibbs * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3323925Sgibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3423925Sgibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3595376Sgibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3695376Sgibbs * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 3795376Sgibbs * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3895376Sgibbs * POSSIBILITY OF SUCH DAMAGES. 3923925Sgibbs * 40109575Sgibbs * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#24 $ 4165943Sgibbs * 4250477Speter * $FreeBSD$ 4323925Sgibbs */ 4423925Sgibbs 4523925Sgibbs#include <sys/types.h> 46224046Semaste#include <sys/param.h> 47233479Srmh#if defined(BSD) && !defined(__GNU__) 48224046Semaste#include <db.h> 4965943Sgibbs#else 50224046Semaste#include <db_185.h> 5165943Sgibbs#endif 52193244Sdelphij#include <ctype.h> 53107303Sscottl#include <fcntl.h> 54104028Sgibbs#include <inttypes.h> 5595376Sgibbs#include <regex.h> 5623925Sgibbs#include <stdio.h> 5723925Sgibbs#include <stdlib.h> 5823925Sgibbs#include <string.h> 5923925Sgibbs#include <sysexits.h> 6023925Sgibbs 6129050Sgibbs#include "aicasm_symbol.h" 6229050Sgibbs#include "aicasm.h" 6323925Sgibbs 6423925Sgibbsstatic DB *symtable; 6523925Sgibbs 66193244Sdelphijstatic symbol_t * 67193244Sdelphijsymbol_create(const char *name) 6823925Sgibbs{ 6923925Sgibbs symbol_t *new_symbol; 7023925Sgibbs 7123925Sgibbs new_symbol = (symbol_t *)malloc(sizeof(symbol_t)); 7223925Sgibbs if (new_symbol == NULL) { 7323925Sgibbs perror("Unable to create new symbol"); 7423925Sgibbs exit(EX_SOFTWARE); 7523925Sgibbs } 7623925Sgibbs memset(new_symbol, 0, sizeof(*new_symbol)); 7723925Sgibbs new_symbol->name = strdup(name); 78102668Sgibbs if (new_symbol->name == NULL) 79102668Sgibbs stop("Unable to strdup symbol name", EX_SOFTWARE); 8023925Sgibbs new_symbol->type = UNINITIALIZED; 8123925Sgibbs return (new_symbol); 8223925Sgibbs} 8323925Sgibbs 8423925Sgibbsvoid 8565943Sgibbssymbol_delete(symbol_t *symbol) 8623925Sgibbs{ 8723925Sgibbs if (symtable != NULL) { 8823925Sgibbs DBT key; 8923925Sgibbs 9023925Sgibbs key.data = symbol->name; 9123925Sgibbs key.size = strlen(symbol->name); 9223925Sgibbs symtable->del(symtable, &key, /*flags*/0); 9323925Sgibbs } 9423925Sgibbs switch(symbol->type) { 9523925Sgibbs case SCBLOC: 9623925Sgibbs case SRAMLOC: 9723925Sgibbs case REGISTER: 9823925Sgibbs if (symbol->info.rinfo != NULL) 9923925Sgibbs free(symbol->info.rinfo); 10023925Sgibbs break; 10123925Sgibbs case ALIAS: 10223925Sgibbs if (symbol->info.ainfo != NULL) 10323925Sgibbs free(symbol->info.ainfo); 10423925Sgibbs break; 10523925Sgibbs case MASK: 106102668Sgibbs case FIELD: 107102668Sgibbs case ENUM: 108102668Sgibbs case ENUM_ENTRY: 109102668Sgibbs if (symbol->info.finfo != NULL) { 110102668Sgibbs symlist_free(&symbol->info.finfo->symrefs); 111102668Sgibbs free(symbol->info.finfo); 11223925Sgibbs } 11323925Sgibbs break; 11429897Sgibbs case DOWNLOAD_CONST: 11523925Sgibbs case CONST: 11623925Sgibbs if (symbol->info.cinfo != NULL) 11723925Sgibbs free(symbol->info.cinfo); 11823925Sgibbs break; 11923925Sgibbs case LABEL: 12023925Sgibbs if (symbol->info.linfo != NULL) 12123925Sgibbs free(symbol->info.linfo); 12223925Sgibbs break; 12323925Sgibbs case UNINITIALIZED: 12423925Sgibbs default: 12523925Sgibbs break; 12623925Sgibbs } 12723925Sgibbs free(symbol->name); 12823925Sgibbs free(symbol); 12923925Sgibbs} 13023925Sgibbs 13123925Sgibbsvoid 132201261Sedsymtable_open(void) 13323925Sgibbs{ 13423925Sgibbs symtable = dbopen(/*filename*/NULL, 13523925Sgibbs O_CREAT | O_NONBLOCK | O_RDWR, /*mode*/0, DB_HASH, 13623925Sgibbs /*openinfo*/NULL); 13723925Sgibbs 13823925Sgibbs if (symtable == NULL) { 13923925Sgibbs perror("Symbol table creation failed"); 14023925Sgibbs exit(EX_SOFTWARE); 14123925Sgibbs /* NOTREACHED */ 14223925Sgibbs } 14323925Sgibbs} 14423925Sgibbs 14523925Sgibbsvoid 146201261Sedsymtable_close(void) 14723925Sgibbs{ 14823925Sgibbs if (symtable != NULL) { 14923925Sgibbs DBT key; 15023925Sgibbs DBT data; 15123925Sgibbs 15223925Sgibbs while (symtable->seq(symtable, &key, &data, R_FIRST) == 0) { 15345965Sgibbs symbol_t *stored_ptr; 15423925Sgibbs 15545965Sgibbs memcpy(&stored_ptr, data.data, sizeof(stored_ptr)); 15645965Sgibbs symbol_delete(stored_ptr); 15723925Sgibbs } 15823925Sgibbs symtable->close(symtable); 15923925Sgibbs } 16023925Sgibbs} 16123925Sgibbs 16223925Sgibbs/* 16323925Sgibbs * The semantics of get is to return an uninitialized symbol entry 16423925Sgibbs * if a lookup fails. 16523925Sgibbs */ 16623925Sgibbssymbol_t * 167193244Sdelphijsymtable_get(const char *name) 16823925Sgibbs{ 16945965Sgibbs symbol_t *stored_ptr; 17045965Sgibbs DBT key; 17145965Sgibbs DBT data; 17245965Sgibbs int retval; 17323925Sgibbs 174193244Sdelphij key.data = strdup(name); 17523925Sgibbs key.size = strlen(name); 17623925Sgibbs 17723925Sgibbs if ((retval = symtable->get(symtable, &key, &data, /*flags*/0)) != 0) { 17823925Sgibbs if (retval == -1) { 17923925Sgibbs perror("Symbol table get operation failed"); 18023925Sgibbs exit(EX_SOFTWARE); 18123925Sgibbs /* NOTREACHED */ 18223925Sgibbs } else if (retval == 1) { 18323925Sgibbs /* Symbol wasn't found, so create a new one */ 18423925Sgibbs symbol_t *new_symbol; 18523925Sgibbs 18623925Sgibbs new_symbol = symbol_create(name); 18723925Sgibbs data.data = &new_symbol; 18823925Sgibbs data.size = sizeof(new_symbol); 18923925Sgibbs if (symtable->put(symtable, &key, &data, 19023925Sgibbs /*flags*/0) !=0) { 19123925Sgibbs perror("Symtable put failed"); 19223925Sgibbs exit(EX_SOFTWARE); 19323925Sgibbs } 194193244Sdelphij free(key.data); 19523925Sgibbs return (new_symbol); 19623925Sgibbs } else { 19723925Sgibbs perror("Unexpected return value from db get routine"); 19823925Sgibbs exit(EX_SOFTWARE); 19923925Sgibbs /* NOTREACHED */ 20023925Sgibbs } 20123925Sgibbs } 20245965Sgibbs memcpy(&stored_ptr, data.data, sizeof(stored_ptr)); 203193244Sdelphij free(key.data); 20445965Sgibbs return (stored_ptr); 20523925Sgibbs} 20623925Sgibbs 20723925Sgibbssymbol_node_t * 20865943Sgibbssymlist_search(symlist_t *symlist, char *symname) 20923925Sgibbs{ 21023925Sgibbs symbol_node_t *curnode; 21123925Sgibbs 21271999Sphk curnode = SLIST_FIRST(symlist); 21323925Sgibbs while(curnode != NULL) { 21423925Sgibbs if (strcmp(symname, curnode->symbol->name) == 0) 21523925Sgibbs break; 21671999Sphk curnode = SLIST_NEXT(curnode, links); 21723925Sgibbs } 21823925Sgibbs return (curnode); 21923925Sgibbs} 22023925Sgibbs 22123925Sgibbsvoid 22265943Sgibbssymlist_add(symlist_t *symlist, symbol_t *symbol, int how) 22323925Sgibbs{ 22423925Sgibbs symbol_node_t *newnode; 22523925Sgibbs 22623925Sgibbs newnode = (symbol_node_t *)malloc(sizeof(symbol_node_t)); 22723925Sgibbs if (newnode == NULL) { 22823925Sgibbs stop("symlist_add: Unable to malloc symbol_node", EX_SOFTWARE); 22923925Sgibbs /* NOTREACHED */ 23023925Sgibbs } 23123925Sgibbs newnode->symbol = symbol; 23223925Sgibbs if (how == SYMLIST_SORT) { 23323925Sgibbs symbol_node_t *curnode; 234102668Sgibbs int field; 23523925Sgibbs 236102668Sgibbs field = FALSE; 23723925Sgibbs switch(symbol->type) { 23823925Sgibbs case REGISTER: 23923925Sgibbs case SCBLOC: 24023925Sgibbs case SRAMLOC: 24123925Sgibbs break; 242102668Sgibbs case FIELD: 24323925Sgibbs case MASK: 244102668Sgibbs case ENUM: 245102668Sgibbs case ENUM_ENTRY: 246102668Sgibbs field = TRUE; 24723925Sgibbs break; 24823925Sgibbs default: 24923925Sgibbs stop("symlist_add: Invalid symbol type for sorting", 25023925Sgibbs EX_SOFTWARE); 25123925Sgibbs /* NOTREACHED */ 25223925Sgibbs } 25323925Sgibbs 25471999Sphk curnode = SLIST_FIRST(symlist); 25523925Sgibbs if (curnode == NULL 256102668Sgibbs || (field 257102668Sgibbs && (curnode->symbol->type > newnode->symbol->type 258102668Sgibbs || (curnode->symbol->type == newnode->symbol->type 259102668Sgibbs && (curnode->symbol->info.finfo->value > 260102668Sgibbs newnode->symbol->info.finfo->value)))) 261102668Sgibbs || (!field && (curnode->symbol->info.rinfo->address > 26223925Sgibbs newnode->symbol->info.rinfo->address))) { 26323925Sgibbs SLIST_INSERT_HEAD(symlist, newnode, links); 26423925Sgibbs return; 26523925Sgibbs } 26623925Sgibbs 26723925Sgibbs while (1) { 26871999Sphk if (SLIST_NEXT(curnode, links) == NULL) { 26923925Sgibbs SLIST_INSERT_AFTER(curnode, newnode, 27023925Sgibbs links); 27123925Sgibbs break; 27223925Sgibbs } else { 27323925Sgibbs symbol_t *cursymbol; 27423925Sgibbs 27571999Sphk cursymbol = SLIST_NEXT(curnode, links)->symbol; 276102668Sgibbs if ((field 277102668Sgibbs && (cursymbol->type > symbol->type 278102668Sgibbs || (cursymbol->type == symbol->type 279102668Sgibbs && (cursymbol->info.finfo->value > 280102668Sgibbs symbol->info.finfo->value)))) 281102668Sgibbs || (!field 282102668Sgibbs && (cursymbol->info.rinfo->address > 283102668Sgibbs symbol->info.rinfo->address))) { 28423925Sgibbs SLIST_INSERT_AFTER(curnode, newnode, 28523925Sgibbs links); 28623925Sgibbs break; 28723925Sgibbs } 28823925Sgibbs } 28971999Sphk curnode = SLIST_NEXT(curnode, links); 29023925Sgibbs } 29123925Sgibbs } else { 29223925Sgibbs SLIST_INSERT_HEAD(symlist, newnode, links); 29323925Sgibbs } 29423925Sgibbs} 29523925Sgibbs 29623925Sgibbsvoid 29765943Sgibbssymlist_free(symlist_t *symlist) 29823925Sgibbs{ 29923925Sgibbs symbol_node_t *node1, *node2; 30023925Sgibbs 30171999Sphk node1 = SLIST_FIRST(symlist); 30223925Sgibbs while (node1 != NULL) { 30371999Sphk node2 = SLIST_NEXT(node1, links); 30423925Sgibbs free(node1); 30523925Sgibbs node1 = node2; 30623925Sgibbs } 30723925Sgibbs SLIST_INIT(symlist); 30823925Sgibbs} 30923925Sgibbs 31023925Sgibbsvoid 31165943Sgibbssymlist_merge(symlist_t *symlist_dest, symlist_t *symlist_src1, 31265943Sgibbs symlist_t *symlist_src2) 31323925Sgibbs{ 31423925Sgibbs symbol_node_t *node; 31523925Sgibbs 31623925Sgibbs *symlist_dest = *symlist_src1; 31771999Sphk while((node = SLIST_FIRST(symlist_src2)) != NULL) { 31823925Sgibbs SLIST_REMOVE_HEAD(symlist_src2, links); 31923925Sgibbs SLIST_INSERT_HEAD(symlist_dest, node, links); 32023925Sgibbs } 32123925Sgibbs 32223925Sgibbs /* These are now empty */ 32323925Sgibbs SLIST_INIT(symlist_src1); 32423925Sgibbs SLIST_INIT(symlist_src2); 32523925Sgibbs} 32623925Sgibbs 327193244Sdelphijstatic void 328102668Sgibbsaic_print_file_prologue(FILE *ofile) 32923925Sgibbs{ 330102668Sgibbs 331102668Sgibbs if (ofile == NULL) 332102668Sgibbs return; 333102668Sgibbs 334102668Sgibbs fprintf(ofile, 335102668Sgibbs"/*\n" 336102668Sgibbs" * DO NOT EDIT - This file is automatically generated\n" 337102668Sgibbs" * from the following source files:\n" 338102668Sgibbs" *\n" 339102668Sgibbs"%s */\n", 340102668Sgibbs versions); 341102668Sgibbs} 342102668Sgibbs 343193244Sdelphijstatic void 344193244Sdelphijaic_print_include(FILE *dfile, char *header_file) 345102668Sgibbs{ 346102668Sgibbs 347102668Sgibbs if (dfile == NULL) 348102668Sgibbs return; 349193244Sdelphij fprintf(dfile, "\n#include \"%s\"\n\n", header_file); 350102668Sgibbs} 351102668Sgibbs 352193244Sdelphijstatic void 353102668Sgibbsaic_print_reg_dump_types(FILE *ofile) 354102668Sgibbs{ 355102668Sgibbs if (ofile == NULL) 356102668Sgibbs return; 357102668Sgibbs 358102668Sgibbs fprintf(ofile, 359102668Sgibbs"typedef int (%sreg_print_t)(u_int, u_int *, u_int);\n" 360102668Sgibbs"typedef struct %sreg_parse_entry {\n" 361102668Sgibbs" char *name;\n" 362102668Sgibbs" uint8_t value;\n" 363102668Sgibbs" uint8_t mask;\n" 364102668Sgibbs"} %sreg_parse_entry_t;\n" 365102668Sgibbs"\n", 366102668Sgibbs prefix, prefix, prefix); 367102668Sgibbs} 368102668Sgibbs 369102668Sgibbsstatic void 370102668Sgibbsaic_print_reg_dump_start(FILE *dfile, symbol_node_t *regnode) 371102668Sgibbs{ 372102668Sgibbs if (dfile == NULL) 373102668Sgibbs return; 374102668Sgibbs 375102668Sgibbs fprintf(dfile, 376102668Sgibbs"static %sreg_parse_entry_t %s_parse_table[] = {\n", 377102668Sgibbs prefix, 378102668Sgibbs regnode->symbol->name); 379102668Sgibbs} 380102668Sgibbs 381102668Sgibbsstatic void 382102668Sgibbsaic_print_reg_dump_end(FILE *ofile, FILE *dfile, 383102668Sgibbs symbol_node_t *regnode, u_int num_entries) 384102668Sgibbs{ 385102668Sgibbs char *lower_name; 386102668Sgibbs char *letter; 387102668Sgibbs 388102668Sgibbs lower_name = strdup(regnode->symbol->name); 389102668Sgibbs if (lower_name == NULL) 390102668Sgibbs stop("Unable to strdup symbol name", EX_SOFTWARE); 391102668Sgibbs 392102668Sgibbs for (letter = lower_name; *letter != '\0'; letter++) 393102668Sgibbs *letter = tolower(*letter); 394102668Sgibbs 395102668Sgibbs if (dfile != NULL) { 396102668Sgibbs if (num_entries != 0) 397102668Sgibbs fprintf(dfile, 398102668Sgibbs"\n" 399102668Sgibbs"};\n" 400102668Sgibbs"\n"); 401102668Sgibbs 402102668Sgibbs fprintf(dfile, 403102668Sgibbs"int\n" 404102668Sgibbs"%s%s_print(u_int regvalue, u_int *cur_col, u_int wrap)\n" 405102668Sgibbs"{\n" 406102668Sgibbs" return (%sprint_register(%s%s, %d, \"%s\",\n" 407102668Sgibbs" 0x%02x, regvalue, cur_col, wrap));\n" 408102668Sgibbs"}\n" 409102668Sgibbs"\n", 410102668Sgibbs prefix, 411102668Sgibbs lower_name, 412102668Sgibbs prefix, 413102668Sgibbs num_entries != 0 ? regnode->symbol->name : "NULL", 414102668Sgibbs num_entries != 0 ? "_parse_table" : "", 415102668Sgibbs num_entries, 416102668Sgibbs regnode->symbol->name, 417102668Sgibbs regnode->symbol->info.rinfo->address); 418102668Sgibbs } 419102668Sgibbs 420102668Sgibbs fprintf(ofile, 421102668Sgibbs"#if AIC_DEBUG_REGISTERS\n" 422102668Sgibbs"%sreg_print_t %s%s_print;\n" 423102668Sgibbs"#else\n" 424102668Sgibbs"#define %s%s_print(regvalue, cur_col, wrap) \\\n" 425102668Sgibbs" %sprint_register(NULL, 0, \"%s\", 0x%02x, regvalue, cur_col, wrap)\n" 426102668Sgibbs"#endif\n" 427102668Sgibbs"\n", 428102668Sgibbs prefix, 429102668Sgibbs prefix, 430102668Sgibbs lower_name, 431102668Sgibbs prefix, 432102668Sgibbs lower_name, 433102668Sgibbs prefix, 434102668Sgibbs regnode->symbol->name, 435102668Sgibbs regnode->symbol->info.rinfo->address); 436102668Sgibbs} 437102668Sgibbs 438102668Sgibbsstatic void 439102668Sgibbsaic_print_reg_dump_entry(FILE *dfile, symbol_node_t *curnode) 440102668Sgibbs{ 441102668Sgibbs int num_tabs; 442102668Sgibbs 443102668Sgibbs if (dfile == NULL) 444102668Sgibbs return; 445102668Sgibbs 446102668Sgibbs fprintf(dfile, 447102668Sgibbs" { \"%s\",", 448102668Sgibbs curnode->symbol->name); 449102668Sgibbs 450102668Sgibbs num_tabs = 3 - (strlen(curnode->symbol->name) + 5) / 8; 451102668Sgibbs 452102668Sgibbs while (num_tabs-- > 0) 453102668Sgibbs fputc('\t', dfile); 454102668Sgibbs fprintf(dfile, "0x%02x, 0x%02x }", 455102668Sgibbs curnode->symbol->info.finfo->value, 456102668Sgibbs curnode->symbol->info.finfo->mask); 457102668Sgibbs} 458102668Sgibbs 459102668Sgibbsvoid 460102668Sgibbssymtable_dump(FILE *ofile, FILE *dfile) 461102668Sgibbs{ 46223925Sgibbs /* 46323925Sgibbs * Sort the registers by address with a simple insertion sort. 46423925Sgibbs * Put bitmasks next to the first register that defines them. 46523925Sgibbs * Put constants at the end. 46623925Sgibbs */ 467102668Sgibbs symlist_t registers; 468102668Sgibbs symlist_t masks; 469102668Sgibbs symlist_t constants; 470102668Sgibbs symlist_t download_constants; 471102668Sgibbs symlist_t aliases; 472102668Sgibbs symlist_t exported_labels; 473102668Sgibbs symbol_node_t *curnode; 474102668Sgibbs symbol_node_t *regnode; 475102668Sgibbs DBT key; 476102668Sgibbs DBT data; 477102668Sgibbs int flag; 478102668Sgibbs u_int i; 47923925Sgibbs 480102668Sgibbs if (symtable == NULL) 481102668Sgibbs return; 482102668Sgibbs 48323925Sgibbs SLIST_INIT(®isters); 48423925Sgibbs SLIST_INIT(&masks); 48523925Sgibbs SLIST_INIT(&constants); 48629897Sgibbs SLIST_INIT(&download_constants); 48723925Sgibbs SLIST_INIT(&aliases); 48895376Sgibbs SLIST_INIT(&exported_labels); 489102668Sgibbs flag = R_FIRST; 490102668Sgibbs while (symtable->seq(symtable, &key, &data, flag) == 0) { 491102668Sgibbs symbol_t *cursym; 49223925Sgibbs 493102668Sgibbs memcpy(&cursym, data.data, sizeof(cursym)); 494102668Sgibbs switch(cursym->type) { 495102668Sgibbs case REGISTER: 496102668Sgibbs case SCBLOC: 497102668Sgibbs case SRAMLOC: 498102668Sgibbs symlist_add(®isters, cursym, SYMLIST_SORT); 499102668Sgibbs break; 500102668Sgibbs case MASK: 501102668Sgibbs case FIELD: 502102668Sgibbs case ENUM: 503102668Sgibbs case ENUM_ENTRY: 504102668Sgibbs symlist_add(&masks, cursym, SYMLIST_SORT); 505102668Sgibbs break; 506102668Sgibbs case CONST: 507102668Sgibbs symlist_add(&constants, cursym, 508102668Sgibbs SYMLIST_INSERT_HEAD); 509102668Sgibbs break; 510102668Sgibbs case DOWNLOAD_CONST: 511102668Sgibbs symlist_add(&download_constants, cursym, 512102668Sgibbs SYMLIST_INSERT_HEAD); 513102668Sgibbs break; 514102668Sgibbs case ALIAS: 515102668Sgibbs symlist_add(&aliases, cursym, 516102668Sgibbs SYMLIST_INSERT_HEAD); 517102668Sgibbs break; 518102668Sgibbs case LABEL: 519102668Sgibbs if (cursym->info.linfo->exported == 0) 520102668Sgibbs break; 521102668Sgibbs symlist_add(&exported_labels, cursym, 522102668Sgibbs SYMLIST_INSERT_HEAD); 523102668Sgibbs break; 524102668Sgibbs default: 525102668Sgibbs break; 526102668Sgibbs } 527102668Sgibbs flag = R_NEXT; 528102668Sgibbs } 52923925Sgibbs 530102668Sgibbs /* Register dianostic functions/declarations first. */ 531102668Sgibbs aic_print_file_prologue(ofile); 532102668Sgibbs aic_print_reg_dump_types(ofile); 533102668Sgibbs aic_print_file_prologue(dfile); 534102668Sgibbs aic_print_include(dfile, stock_include_file); 535102668Sgibbs SLIST_FOREACH(curnode, ®isters, links) { 53623925Sgibbs 537102668Sgibbs switch(curnode->symbol->type) { 538102668Sgibbs case REGISTER: 539102668Sgibbs case SCBLOC: 540102668Sgibbs case SRAMLOC: 541102668Sgibbs { 542102668Sgibbs symlist_t *fields; 543102668Sgibbs symbol_node_t *fieldnode; 544102668Sgibbs int num_entries; 545102668Sgibbs 546102668Sgibbs num_entries = 0; 547102668Sgibbs fields = &curnode->symbol->info.rinfo->fields; 548102668Sgibbs SLIST_FOREACH(fieldnode, fields, links) { 549102668Sgibbs if (num_entries == 0) 550102668Sgibbs aic_print_reg_dump_start(dfile, 551102668Sgibbs curnode); 552109575Sgibbs else if (dfile != NULL) 553102668Sgibbs fputs(",\n", dfile); 554102668Sgibbs num_entries++; 555102668Sgibbs aic_print_reg_dump_entry(dfile, fieldnode); 55623925Sgibbs } 557102668Sgibbs aic_print_reg_dump_end(ofile, dfile, 558102668Sgibbs curnode, num_entries); 55923925Sgibbs } 560102668Sgibbs default: 561102668Sgibbs break; 562102668Sgibbs } 563102668Sgibbs } 56423925Sgibbs 565102668Sgibbs /* Fold in the masks and bits */ 566102668Sgibbs while (SLIST_FIRST(&masks) != NULL) { 567102668Sgibbs char *regname; 56823925Sgibbs 569102668Sgibbs curnode = SLIST_FIRST(&masks); 570102668Sgibbs SLIST_REMOVE_HEAD(&masks, links); 57123925Sgibbs 572102668Sgibbs regnode = SLIST_FIRST(&curnode->symbol->info.finfo->symrefs); 573102668Sgibbs regname = regnode->symbol->name; 574102668Sgibbs regnode = symlist_search(®isters, regname); 575102668Sgibbs SLIST_INSERT_AFTER(regnode, curnode, links); 576102668Sgibbs } 57723925Sgibbs 578102668Sgibbs /* Add the aliases */ 579102668Sgibbs while (SLIST_FIRST(&aliases) != NULL) { 580102668Sgibbs char *regname; 58123925Sgibbs 582102668Sgibbs curnode = SLIST_FIRST(&aliases); 583102668Sgibbs SLIST_REMOVE_HEAD(&aliases, links); 58423925Sgibbs 585102668Sgibbs regname = curnode->symbol->info.ainfo->parent->name; 586102668Sgibbs regnode = symlist_search(®isters, regname); 587102668Sgibbs SLIST_INSERT_AFTER(regnode, curnode, links); 588102668Sgibbs } 58923925Sgibbs 590102668Sgibbs /* Output generated #defines. */ 591102668Sgibbs while (SLIST_FIRST(®isters) != NULL) { 592102668Sgibbs u_int value; 593193244Sdelphij const char *tab_str; 594193244Sdelphij const char *tab_str2; 59523925Sgibbs 596102668Sgibbs curnode = SLIST_FIRST(®isters); 597102668Sgibbs SLIST_REMOVE_HEAD(®isters, links); 598102668Sgibbs switch(curnode->symbol->type) { 599102668Sgibbs case REGISTER: 600102668Sgibbs case SCBLOC: 601102668Sgibbs case SRAMLOC: 602102668Sgibbs fprintf(ofile, "\n"); 603102668Sgibbs value = curnode->symbol->info.rinfo->address; 604102668Sgibbs tab_str = "\t"; 605102668Sgibbs tab_str2 = "\t\t"; 606102668Sgibbs break; 607102668Sgibbs case ALIAS: 608102668Sgibbs { 609102668Sgibbs symbol_t *parent; 61023925Sgibbs 611102668Sgibbs parent = curnode->symbol->info.ainfo->parent; 612102668Sgibbs value = parent->info.rinfo->address; 613102668Sgibbs tab_str = "\t"; 614102668Sgibbs tab_str2 = "\t\t"; 615102668Sgibbs break; 61623925Sgibbs } 617102668Sgibbs case MASK: 618102668Sgibbs case FIELD: 619102668Sgibbs case ENUM: 620102668Sgibbs case ENUM_ENTRY: 621102668Sgibbs value = curnode->symbol->info.finfo->value; 622102668Sgibbs tab_str = "\t\t"; 623102668Sgibbs tab_str2 = "\t"; 624102668Sgibbs break; 625102668Sgibbs default: 626102668Sgibbs value = 0; /* Quiet compiler */ 627102668Sgibbs tab_str = NULL; 628102668Sgibbs tab_str2 = NULL; 629102668Sgibbs stop("symtable_dump: Invalid symbol type " 630102668Sgibbs "encountered", EX_SOFTWARE); 631102668Sgibbs break; 632102668Sgibbs } 633102668Sgibbs fprintf(ofile, "#define%s%-16s%s0x%02x\n", 634102668Sgibbs tab_str, curnode->symbol->name, tab_str2, 635102668Sgibbs value); 636102668Sgibbs free(curnode); 637102668Sgibbs } 638102668Sgibbs fprintf(ofile, "\n\n"); 63923925Sgibbs 640102668Sgibbs while (SLIST_FIRST(&constants) != NULL) { 64123925Sgibbs 642102668Sgibbs curnode = SLIST_FIRST(&constants); 643102668Sgibbs SLIST_REMOVE_HEAD(&constants, links); 644102668Sgibbs fprintf(ofile, "#define\t%-8s\t0x%02x\n", 645102668Sgibbs curnode->symbol->name, 646102668Sgibbs curnode->symbol->info.cinfo->value); 647102668Sgibbs free(curnode); 648102668Sgibbs } 64929897Sgibbs 650102668Sgibbs 651102668Sgibbs fprintf(ofile, "\n\n/* Downloaded Constant Definitions */\n"); 65229897Sgibbs 653102668Sgibbs for (i = 0; SLIST_FIRST(&download_constants) != NULL; i++) { 65429897Sgibbs 655102668Sgibbs curnode = SLIST_FIRST(&download_constants); 656102668Sgibbs SLIST_REMOVE_HEAD(&download_constants, links); 657102668Sgibbs fprintf(ofile, "#define\t%-8s\t0x%02x\n", 658102668Sgibbs curnode->symbol->name, 659102668Sgibbs curnode->symbol->info.cinfo->value); 660102668Sgibbs free(curnode); 661102668Sgibbs } 662102668Sgibbs fprintf(ofile, "#define\tDOWNLOAD_CONST_COUNT\t0x%02x\n", i); 66395376Sgibbs 664102668Sgibbs fprintf(ofile, "\n\n/* Exported Labels */\n"); 66595376Sgibbs 666102668Sgibbs while (SLIST_FIRST(&exported_labels) != NULL) { 66795376Sgibbs 668102668Sgibbs curnode = SLIST_FIRST(&exported_labels); 669102668Sgibbs SLIST_REMOVE_HEAD(&exported_labels, links); 670102668Sgibbs fprintf(ofile, "#define\tLABEL_%-8s\t0x%02x\n", 671102668Sgibbs curnode->symbol->name, 672102668Sgibbs curnode->symbol->info.linfo->address); 673102668Sgibbs free(curnode); 67423925Sgibbs } 67523925Sgibbs} 67623925Sgibbs 677