18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Aic7xxx SCSI host adapter firmware assembler symbol table implementation 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright (c) 1997 Justin T. Gibbs. 58c2ecf20Sopenharmony_ci * Copyright (c) 2002 Adaptec Inc. 68c2ecf20Sopenharmony_ci * All rights reserved. 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 98c2ecf20Sopenharmony_ci * modification, are permitted provided that the following conditions 108c2ecf20Sopenharmony_ci * are met: 118c2ecf20Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright 128c2ecf20Sopenharmony_ci * notice, this list of conditions, and the following disclaimer, 138c2ecf20Sopenharmony_ci * without modification. 148c2ecf20Sopenharmony_ci * 2. Redistributions in binary form must reproduce at minimum a disclaimer 158c2ecf20Sopenharmony_ci * substantially similar to the "NO WARRANTY" disclaimer below 168c2ecf20Sopenharmony_ci * ("Disclaimer") and any redistribution must be conditioned upon 178c2ecf20Sopenharmony_ci * including a substantially similar Disclaimer requirement for further 188c2ecf20Sopenharmony_ci * binary redistribution. 198c2ecf20Sopenharmony_ci * 3. Neither the names of the above-listed copyright holders nor the names 208c2ecf20Sopenharmony_ci * of any contributors may be used to endorse or promote products derived 218c2ecf20Sopenharmony_ci * from this software without specific prior written permission. 228c2ecf20Sopenharmony_ci * 238c2ecf20Sopenharmony_ci * Alternatively, this software may be distributed under the terms of the 248c2ecf20Sopenharmony_ci * GNU General Public License ("GPL") version 2 as published by the Free 258c2ecf20Sopenharmony_ci * Software Foundation. 268c2ecf20Sopenharmony_ci * 278c2ecf20Sopenharmony_ci * NO WARRANTY 288c2ecf20Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 298c2ecf20Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 308c2ecf20Sopenharmony_ci * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 318c2ecf20Sopenharmony_ci * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 328c2ecf20Sopenharmony_ci * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 338c2ecf20Sopenharmony_ci * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 348c2ecf20Sopenharmony_ci * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 358c2ecf20Sopenharmony_ci * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 368c2ecf20Sopenharmony_ci * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 378c2ecf20Sopenharmony_ci * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 388c2ecf20Sopenharmony_ci * POSSIBILITY OF SUCH DAMAGES. 398c2ecf20Sopenharmony_ci * 408c2ecf20Sopenharmony_ci * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#24 $ 418c2ecf20Sopenharmony_ci * 428c2ecf20Sopenharmony_ci * $FreeBSD$ 438c2ecf20Sopenharmony_ci */ 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci#include <sys/types.h> 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci#include "aicdb.h" 488c2ecf20Sopenharmony_ci#include <fcntl.h> 498c2ecf20Sopenharmony_ci#include <inttypes.h> 508c2ecf20Sopenharmony_ci#include <regex.h> 518c2ecf20Sopenharmony_ci#include <stdio.h> 528c2ecf20Sopenharmony_ci#include <stdlib.h> 538c2ecf20Sopenharmony_ci#include <string.h> 548c2ecf20Sopenharmony_ci#include <sysexits.h> 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci#include "aicasm_symbol.h" 578c2ecf20Sopenharmony_ci#include "aicasm.h" 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_cistatic DB *symtable; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_cisymbol_t * 628c2ecf20Sopenharmony_cisymbol_create(char *name) 638c2ecf20Sopenharmony_ci{ 648c2ecf20Sopenharmony_ci symbol_t *new_symbol; 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci new_symbol = (symbol_t *)malloc(sizeof(symbol_t)); 678c2ecf20Sopenharmony_ci if (new_symbol == NULL) { 688c2ecf20Sopenharmony_ci perror("Unable to create new symbol"); 698c2ecf20Sopenharmony_ci exit(EX_SOFTWARE); 708c2ecf20Sopenharmony_ci } 718c2ecf20Sopenharmony_ci memset(new_symbol, 0, sizeof(*new_symbol)); 728c2ecf20Sopenharmony_ci new_symbol->name = strdup(name); 738c2ecf20Sopenharmony_ci if (new_symbol->name == NULL) 748c2ecf20Sopenharmony_ci stop("Unable to strdup symbol name", EX_SOFTWARE); 758c2ecf20Sopenharmony_ci new_symbol->type = UNINITIALIZED; 768c2ecf20Sopenharmony_ci new_symbol->count = 1; 778c2ecf20Sopenharmony_ci return (new_symbol); 788c2ecf20Sopenharmony_ci} 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_civoid 818c2ecf20Sopenharmony_cisymbol_delete(symbol_t *symbol) 828c2ecf20Sopenharmony_ci{ 838c2ecf20Sopenharmony_ci if (symtable != NULL) { 848c2ecf20Sopenharmony_ci DBT key; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci key.data = symbol->name; 878c2ecf20Sopenharmony_ci key.size = strlen(symbol->name); 888c2ecf20Sopenharmony_ci symtable->del(symtable, &key, /*flags*/0); 898c2ecf20Sopenharmony_ci } 908c2ecf20Sopenharmony_ci switch(symbol->type) { 918c2ecf20Sopenharmony_ci case SCBLOC: 928c2ecf20Sopenharmony_ci case SRAMLOC: 938c2ecf20Sopenharmony_ci case REGISTER: 948c2ecf20Sopenharmony_ci if (symbol->info.rinfo != NULL) 958c2ecf20Sopenharmony_ci free(symbol->info.rinfo); 968c2ecf20Sopenharmony_ci break; 978c2ecf20Sopenharmony_ci case ALIAS: 988c2ecf20Sopenharmony_ci if (symbol->info.ainfo != NULL) 998c2ecf20Sopenharmony_ci free(symbol->info.ainfo); 1008c2ecf20Sopenharmony_ci break; 1018c2ecf20Sopenharmony_ci case MASK: 1028c2ecf20Sopenharmony_ci case FIELD: 1038c2ecf20Sopenharmony_ci case ENUM: 1048c2ecf20Sopenharmony_ci case ENUM_ENTRY: 1058c2ecf20Sopenharmony_ci if (symbol->info.finfo != NULL) { 1068c2ecf20Sopenharmony_ci symlist_free(&symbol->info.finfo->symrefs); 1078c2ecf20Sopenharmony_ci free(symbol->info.finfo); 1088c2ecf20Sopenharmony_ci } 1098c2ecf20Sopenharmony_ci break; 1108c2ecf20Sopenharmony_ci case DOWNLOAD_CONST: 1118c2ecf20Sopenharmony_ci case CONST: 1128c2ecf20Sopenharmony_ci if (symbol->info.cinfo != NULL) 1138c2ecf20Sopenharmony_ci free(symbol->info.cinfo); 1148c2ecf20Sopenharmony_ci break; 1158c2ecf20Sopenharmony_ci case LABEL: 1168c2ecf20Sopenharmony_ci if (symbol->info.linfo != NULL) 1178c2ecf20Sopenharmony_ci free(symbol->info.linfo); 1188c2ecf20Sopenharmony_ci break; 1198c2ecf20Sopenharmony_ci case UNINITIALIZED: 1208c2ecf20Sopenharmony_ci default: 1218c2ecf20Sopenharmony_ci break; 1228c2ecf20Sopenharmony_ci } 1238c2ecf20Sopenharmony_ci free(symbol->name); 1248c2ecf20Sopenharmony_ci free(symbol); 1258c2ecf20Sopenharmony_ci} 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_civoid 1288c2ecf20Sopenharmony_cisymtable_open() 1298c2ecf20Sopenharmony_ci{ 1308c2ecf20Sopenharmony_ci symtable = dbopen(/*filename*/NULL, 1318c2ecf20Sopenharmony_ci O_CREAT | O_NONBLOCK | O_RDWR, /*mode*/0, DB_HASH, 1328c2ecf20Sopenharmony_ci /*openinfo*/NULL); 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci if (symtable == NULL) { 1358c2ecf20Sopenharmony_ci perror("Symbol table creation failed"); 1368c2ecf20Sopenharmony_ci exit(EX_SOFTWARE); 1378c2ecf20Sopenharmony_ci /* NOTREACHED */ 1388c2ecf20Sopenharmony_ci } 1398c2ecf20Sopenharmony_ci} 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_civoid 1428c2ecf20Sopenharmony_cisymtable_close() 1438c2ecf20Sopenharmony_ci{ 1448c2ecf20Sopenharmony_ci if (symtable != NULL) { 1458c2ecf20Sopenharmony_ci DBT key; 1468c2ecf20Sopenharmony_ci DBT data; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci while (symtable->seq(symtable, &key, &data, R_FIRST) == 0) { 1498c2ecf20Sopenharmony_ci symbol_t *stored_ptr; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci memcpy(&stored_ptr, data.data, sizeof(stored_ptr)); 1528c2ecf20Sopenharmony_ci symbol_delete(stored_ptr); 1538c2ecf20Sopenharmony_ci } 1548c2ecf20Sopenharmony_ci symtable->close(symtable); 1558c2ecf20Sopenharmony_ci } 1568c2ecf20Sopenharmony_ci} 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci/* 1598c2ecf20Sopenharmony_ci * The semantics of get is to return an uninitialized symbol entry 1608c2ecf20Sopenharmony_ci * if a lookup fails. 1618c2ecf20Sopenharmony_ci */ 1628c2ecf20Sopenharmony_cisymbol_t * 1638c2ecf20Sopenharmony_cisymtable_get(char *name) 1648c2ecf20Sopenharmony_ci{ 1658c2ecf20Sopenharmony_ci symbol_t *stored_ptr; 1668c2ecf20Sopenharmony_ci DBT key; 1678c2ecf20Sopenharmony_ci DBT data; 1688c2ecf20Sopenharmony_ci int retval; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci key.data = (void *)name; 1718c2ecf20Sopenharmony_ci key.size = strlen(name); 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci if ((retval = symtable->get(symtable, &key, &data, /*flags*/0)) != 0) { 1748c2ecf20Sopenharmony_ci if (retval == -1) { 1758c2ecf20Sopenharmony_ci perror("Symbol table get operation failed"); 1768c2ecf20Sopenharmony_ci exit(EX_SOFTWARE); 1778c2ecf20Sopenharmony_ci /* NOTREACHED */ 1788c2ecf20Sopenharmony_ci } else if (retval == 1) { 1798c2ecf20Sopenharmony_ci /* Symbol wasn't found, so create a new one */ 1808c2ecf20Sopenharmony_ci symbol_t *new_symbol; 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci new_symbol = symbol_create(name); 1838c2ecf20Sopenharmony_ci data.data = &new_symbol; 1848c2ecf20Sopenharmony_ci data.size = sizeof(new_symbol); 1858c2ecf20Sopenharmony_ci if (symtable->put(symtable, &key, &data, 1868c2ecf20Sopenharmony_ci /*flags*/0) !=0) { 1878c2ecf20Sopenharmony_ci perror("Symtable put failed"); 1888c2ecf20Sopenharmony_ci exit(EX_SOFTWARE); 1898c2ecf20Sopenharmony_ci } 1908c2ecf20Sopenharmony_ci return (new_symbol); 1918c2ecf20Sopenharmony_ci } else { 1928c2ecf20Sopenharmony_ci perror("Unexpected return value from db get routine"); 1938c2ecf20Sopenharmony_ci exit(EX_SOFTWARE); 1948c2ecf20Sopenharmony_ci /* NOTREACHED */ 1958c2ecf20Sopenharmony_ci } 1968c2ecf20Sopenharmony_ci } 1978c2ecf20Sopenharmony_ci memcpy(&stored_ptr, data.data, sizeof(stored_ptr)); 1988c2ecf20Sopenharmony_ci stored_ptr->count++; 1998c2ecf20Sopenharmony_ci data.data = &stored_ptr; 2008c2ecf20Sopenharmony_ci if (symtable->put(symtable, &key, &data, /*flags*/0) !=0) { 2018c2ecf20Sopenharmony_ci perror("Symtable put failed"); 2028c2ecf20Sopenharmony_ci exit(EX_SOFTWARE); 2038c2ecf20Sopenharmony_ci } 2048c2ecf20Sopenharmony_ci return (stored_ptr); 2058c2ecf20Sopenharmony_ci} 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_cisymbol_node_t * 2088c2ecf20Sopenharmony_cisymlist_search(symlist_t *symlist, char *symname) 2098c2ecf20Sopenharmony_ci{ 2108c2ecf20Sopenharmony_ci symbol_node_t *curnode; 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci curnode = SLIST_FIRST(symlist); 2138c2ecf20Sopenharmony_ci while(curnode != NULL) { 2148c2ecf20Sopenharmony_ci if (strcmp(symname, curnode->symbol->name) == 0) 2158c2ecf20Sopenharmony_ci break; 2168c2ecf20Sopenharmony_ci curnode = SLIST_NEXT(curnode, links); 2178c2ecf20Sopenharmony_ci } 2188c2ecf20Sopenharmony_ci return (curnode); 2198c2ecf20Sopenharmony_ci} 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_civoid 2228c2ecf20Sopenharmony_cisymlist_add(symlist_t *symlist, symbol_t *symbol, int how) 2238c2ecf20Sopenharmony_ci{ 2248c2ecf20Sopenharmony_ci symbol_node_t *newnode; 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci newnode = (symbol_node_t *)malloc(sizeof(symbol_node_t)); 2278c2ecf20Sopenharmony_ci if (newnode == NULL) { 2288c2ecf20Sopenharmony_ci stop("symlist_add: Unable to malloc symbol_node", EX_SOFTWARE); 2298c2ecf20Sopenharmony_ci /* NOTREACHED */ 2308c2ecf20Sopenharmony_ci } 2318c2ecf20Sopenharmony_ci newnode->symbol = symbol; 2328c2ecf20Sopenharmony_ci if (how == SYMLIST_SORT) { 2338c2ecf20Sopenharmony_ci symbol_node_t *curnode; 2348c2ecf20Sopenharmony_ci int field; 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci field = FALSE; 2378c2ecf20Sopenharmony_ci switch(symbol->type) { 2388c2ecf20Sopenharmony_ci case REGISTER: 2398c2ecf20Sopenharmony_ci case SCBLOC: 2408c2ecf20Sopenharmony_ci case SRAMLOC: 2418c2ecf20Sopenharmony_ci break; 2428c2ecf20Sopenharmony_ci case FIELD: 2438c2ecf20Sopenharmony_ci case MASK: 2448c2ecf20Sopenharmony_ci case ENUM: 2458c2ecf20Sopenharmony_ci case ENUM_ENTRY: 2468c2ecf20Sopenharmony_ci field = TRUE; 2478c2ecf20Sopenharmony_ci break; 2488c2ecf20Sopenharmony_ci default: 2498c2ecf20Sopenharmony_ci stop("symlist_add: Invalid symbol type for sorting", 2508c2ecf20Sopenharmony_ci EX_SOFTWARE); 2518c2ecf20Sopenharmony_ci /* NOTREACHED */ 2528c2ecf20Sopenharmony_ci } 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci curnode = SLIST_FIRST(symlist); 2558c2ecf20Sopenharmony_ci if (curnode == NULL 2568c2ecf20Sopenharmony_ci || (field 2578c2ecf20Sopenharmony_ci && (curnode->symbol->type > newnode->symbol->type 2588c2ecf20Sopenharmony_ci || (curnode->symbol->type == newnode->symbol->type 2598c2ecf20Sopenharmony_ci && (curnode->symbol->info.finfo->value > 2608c2ecf20Sopenharmony_ci newnode->symbol->info.finfo->value)))) 2618c2ecf20Sopenharmony_ci || (!field && (curnode->symbol->info.rinfo->address > 2628c2ecf20Sopenharmony_ci newnode->symbol->info.rinfo->address))) { 2638c2ecf20Sopenharmony_ci SLIST_INSERT_HEAD(symlist, newnode, links); 2648c2ecf20Sopenharmony_ci return; 2658c2ecf20Sopenharmony_ci } 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci while (1) { 2688c2ecf20Sopenharmony_ci if (SLIST_NEXT(curnode, links) == NULL) { 2698c2ecf20Sopenharmony_ci SLIST_INSERT_AFTER(curnode, newnode, 2708c2ecf20Sopenharmony_ci links); 2718c2ecf20Sopenharmony_ci break; 2728c2ecf20Sopenharmony_ci } else { 2738c2ecf20Sopenharmony_ci symbol_t *cursymbol; 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci cursymbol = SLIST_NEXT(curnode, links)->symbol; 2768c2ecf20Sopenharmony_ci if ((field 2778c2ecf20Sopenharmony_ci && (cursymbol->type > symbol->type 2788c2ecf20Sopenharmony_ci || (cursymbol->type == symbol->type 2798c2ecf20Sopenharmony_ci && (cursymbol->info.finfo->value > 2808c2ecf20Sopenharmony_ci symbol->info.finfo->value)))) 2818c2ecf20Sopenharmony_ci || (!field 2828c2ecf20Sopenharmony_ci && (cursymbol->info.rinfo->address > 2838c2ecf20Sopenharmony_ci symbol->info.rinfo->address))) { 2848c2ecf20Sopenharmony_ci SLIST_INSERT_AFTER(curnode, newnode, 2858c2ecf20Sopenharmony_ci links); 2868c2ecf20Sopenharmony_ci break; 2878c2ecf20Sopenharmony_ci } 2888c2ecf20Sopenharmony_ci } 2898c2ecf20Sopenharmony_ci curnode = SLIST_NEXT(curnode, links); 2908c2ecf20Sopenharmony_ci } 2918c2ecf20Sopenharmony_ci } else { 2928c2ecf20Sopenharmony_ci SLIST_INSERT_HEAD(symlist, newnode, links); 2938c2ecf20Sopenharmony_ci } 2948c2ecf20Sopenharmony_ci} 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_civoid 2978c2ecf20Sopenharmony_cisymlist_free(symlist_t *symlist) 2988c2ecf20Sopenharmony_ci{ 2998c2ecf20Sopenharmony_ci symbol_node_t *node1, *node2; 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci node1 = SLIST_FIRST(symlist); 3028c2ecf20Sopenharmony_ci while (node1 != NULL) { 3038c2ecf20Sopenharmony_ci node2 = SLIST_NEXT(node1, links); 3048c2ecf20Sopenharmony_ci free(node1); 3058c2ecf20Sopenharmony_ci node1 = node2; 3068c2ecf20Sopenharmony_ci } 3078c2ecf20Sopenharmony_ci SLIST_INIT(symlist); 3088c2ecf20Sopenharmony_ci} 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_civoid 3118c2ecf20Sopenharmony_cisymlist_merge(symlist_t *symlist_dest, symlist_t *symlist_src1, 3128c2ecf20Sopenharmony_ci symlist_t *symlist_src2) 3138c2ecf20Sopenharmony_ci{ 3148c2ecf20Sopenharmony_ci symbol_node_t *node; 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_ci *symlist_dest = *symlist_src1; 3178c2ecf20Sopenharmony_ci while((node = SLIST_FIRST(symlist_src2)) != NULL) { 3188c2ecf20Sopenharmony_ci SLIST_REMOVE_HEAD(symlist_src2, links); 3198c2ecf20Sopenharmony_ci SLIST_INSERT_HEAD(symlist_dest, node, links); 3208c2ecf20Sopenharmony_ci } 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ci /* These are now empty */ 3238c2ecf20Sopenharmony_ci SLIST_INIT(symlist_src1); 3248c2ecf20Sopenharmony_ci SLIST_INIT(symlist_src2); 3258c2ecf20Sopenharmony_ci} 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_civoid 3288c2ecf20Sopenharmony_ciaic_print_file_prologue(FILE *ofile) 3298c2ecf20Sopenharmony_ci{ 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_ci if (ofile == NULL) 3328c2ecf20Sopenharmony_ci return; 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci fprintf(ofile, 3358c2ecf20Sopenharmony_ci"/*\n" 3368c2ecf20Sopenharmony_ci" * DO NOT EDIT - This file is automatically generated\n" 3378c2ecf20Sopenharmony_ci" * from the following source files:\n" 3388c2ecf20Sopenharmony_ci" *\n" 3398c2ecf20Sopenharmony_ci"%s */\n", 3408c2ecf20Sopenharmony_ci versions); 3418c2ecf20Sopenharmony_ci} 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_civoid 3448c2ecf20Sopenharmony_ciaic_print_include(FILE *dfile, char *include_file) 3458c2ecf20Sopenharmony_ci{ 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ci if (dfile == NULL) 3488c2ecf20Sopenharmony_ci return; 3498c2ecf20Sopenharmony_ci fprintf(dfile, "\n#include \"%s\"\n\n", include_file); 3508c2ecf20Sopenharmony_ci} 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_civoid 3538c2ecf20Sopenharmony_ciaic_print_reg_dump_types(FILE *ofile) 3548c2ecf20Sopenharmony_ci{ 3558c2ecf20Sopenharmony_ci if (ofile == NULL) 3568c2ecf20Sopenharmony_ci return; 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci fprintf(ofile, 3598c2ecf20Sopenharmony_ci"typedef int (%sreg_print_t)(u_int, u_int *, u_int);\n" 3608c2ecf20Sopenharmony_ci"typedef struct %sreg_parse_entry {\n" 3618c2ecf20Sopenharmony_ci" char *name;\n" 3628c2ecf20Sopenharmony_ci" uint8_t value;\n" 3638c2ecf20Sopenharmony_ci" uint8_t mask;\n" 3648c2ecf20Sopenharmony_ci"} %sreg_parse_entry_t;\n" 3658c2ecf20Sopenharmony_ci"\n", 3668c2ecf20Sopenharmony_ci prefix, prefix, prefix); 3678c2ecf20Sopenharmony_ci} 3688c2ecf20Sopenharmony_ci 3698c2ecf20Sopenharmony_cistatic void 3708c2ecf20Sopenharmony_ciaic_print_reg_dump_start(FILE *dfile, symbol_node_t *regnode) 3718c2ecf20Sopenharmony_ci{ 3728c2ecf20Sopenharmony_ci if (dfile == NULL) 3738c2ecf20Sopenharmony_ci return; 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ci fprintf(dfile, 3768c2ecf20Sopenharmony_ci"static const %sreg_parse_entry_t %s_parse_table[] = {\n", 3778c2ecf20Sopenharmony_ci prefix, 3788c2ecf20Sopenharmony_ci regnode->symbol->name); 3798c2ecf20Sopenharmony_ci} 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_cistatic void 3828c2ecf20Sopenharmony_ciaic_print_reg_dump_end(FILE *ofile, FILE *dfile, 3838c2ecf20Sopenharmony_ci symbol_node_t *regnode, u_int num_entries) 3848c2ecf20Sopenharmony_ci{ 3858c2ecf20Sopenharmony_ci char *lower_name; 3868c2ecf20Sopenharmony_ci char *letter; 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_ci lower_name = strdup(regnode->symbol->name); 3898c2ecf20Sopenharmony_ci if (lower_name == NULL) 3908c2ecf20Sopenharmony_ci stop("Unable to strdup symbol name", EX_SOFTWARE); 3918c2ecf20Sopenharmony_ci 3928c2ecf20Sopenharmony_ci for (letter = lower_name; *letter != '\0'; letter++) 3938c2ecf20Sopenharmony_ci *letter = tolower(*letter); 3948c2ecf20Sopenharmony_ci 3958c2ecf20Sopenharmony_ci if (dfile != NULL) { 3968c2ecf20Sopenharmony_ci if (num_entries != 0) 3978c2ecf20Sopenharmony_ci fprintf(dfile, 3988c2ecf20Sopenharmony_ci"\n" 3998c2ecf20Sopenharmony_ci"};\n" 4008c2ecf20Sopenharmony_ci"\n"); 4018c2ecf20Sopenharmony_ci 4028c2ecf20Sopenharmony_ci fprintf(dfile, 4038c2ecf20Sopenharmony_ci"int\n" 4048c2ecf20Sopenharmony_ci"%s%s_print(u_int regvalue, u_int *cur_col, u_int wrap)\n" 4058c2ecf20Sopenharmony_ci"{\n" 4068c2ecf20Sopenharmony_ci" return (%sprint_register(%s%s, %d, \"%s\",\n" 4078c2ecf20Sopenharmony_ci" 0x%02x, regvalue, cur_col, wrap));\n" 4088c2ecf20Sopenharmony_ci"}\n" 4098c2ecf20Sopenharmony_ci"\n", 4108c2ecf20Sopenharmony_ci prefix, 4118c2ecf20Sopenharmony_ci lower_name, 4128c2ecf20Sopenharmony_ci prefix, 4138c2ecf20Sopenharmony_ci num_entries != 0 ? regnode->symbol->name : "NULL", 4148c2ecf20Sopenharmony_ci num_entries != 0 ? "_parse_table" : "", 4158c2ecf20Sopenharmony_ci num_entries, 4168c2ecf20Sopenharmony_ci regnode->symbol->name, 4178c2ecf20Sopenharmony_ci regnode->symbol->info.rinfo->address); 4188c2ecf20Sopenharmony_ci } 4198c2ecf20Sopenharmony_ci 4208c2ecf20Sopenharmony_ci fprintf(ofile, 4218c2ecf20Sopenharmony_ci"#if AIC_DEBUG_REGISTERS\n" 4228c2ecf20Sopenharmony_ci"%sreg_print_t %s%s_print;\n" 4238c2ecf20Sopenharmony_ci"#else\n" 4248c2ecf20Sopenharmony_ci"#define %s%s_print(regvalue, cur_col, wrap) \\\n" 4258c2ecf20Sopenharmony_ci" %sprint_register(NULL, 0, \"%s\", 0x%02x, regvalue, cur_col, wrap)\n" 4268c2ecf20Sopenharmony_ci"#endif\n" 4278c2ecf20Sopenharmony_ci"\n", 4288c2ecf20Sopenharmony_ci prefix, 4298c2ecf20Sopenharmony_ci prefix, 4308c2ecf20Sopenharmony_ci lower_name, 4318c2ecf20Sopenharmony_ci prefix, 4328c2ecf20Sopenharmony_ci lower_name, 4338c2ecf20Sopenharmony_ci prefix, 4348c2ecf20Sopenharmony_ci regnode->symbol->name, 4358c2ecf20Sopenharmony_ci regnode->symbol->info.rinfo->address); 4368c2ecf20Sopenharmony_ci} 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_cistatic void 4398c2ecf20Sopenharmony_ciaic_print_reg_dump_entry(FILE *dfile, symbol_node_t *curnode) 4408c2ecf20Sopenharmony_ci{ 4418c2ecf20Sopenharmony_ci int num_tabs; 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_ci if (dfile == NULL) 4448c2ecf20Sopenharmony_ci return; 4458c2ecf20Sopenharmony_ci 4468c2ecf20Sopenharmony_ci fprintf(dfile, 4478c2ecf20Sopenharmony_ci" { \"%s\",", 4488c2ecf20Sopenharmony_ci curnode->symbol->name); 4498c2ecf20Sopenharmony_ci 4508c2ecf20Sopenharmony_ci num_tabs = 3 - (strlen(curnode->symbol->name) + 5) / 8; 4518c2ecf20Sopenharmony_ci 4528c2ecf20Sopenharmony_ci while (num_tabs-- > 0) 4538c2ecf20Sopenharmony_ci fputc('\t', dfile); 4548c2ecf20Sopenharmony_ci fprintf(dfile, "0x%02x, 0x%02x }", 4558c2ecf20Sopenharmony_ci curnode->symbol->info.finfo->value, 4568c2ecf20Sopenharmony_ci curnode->symbol->info.finfo->mask); 4578c2ecf20Sopenharmony_ci} 4588c2ecf20Sopenharmony_ci 4598c2ecf20Sopenharmony_civoid 4608c2ecf20Sopenharmony_cisymtable_dump(FILE *ofile, FILE *dfile) 4618c2ecf20Sopenharmony_ci{ 4628c2ecf20Sopenharmony_ci /* 4638c2ecf20Sopenharmony_ci * Sort the registers by address with a simple insertion sort. 4648c2ecf20Sopenharmony_ci * Put bitmasks next to the first register that defines them. 4658c2ecf20Sopenharmony_ci * Put constants at the end. 4668c2ecf20Sopenharmony_ci */ 4678c2ecf20Sopenharmony_ci symlist_t registers; 4688c2ecf20Sopenharmony_ci symlist_t masks; 4698c2ecf20Sopenharmony_ci symlist_t constants; 4708c2ecf20Sopenharmony_ci symlist_t download_constants; 4718c2ecf20Sopenharmony_ci symlist_t aliases; 4728c2ecf20Sopenharmony_ci symlist_t exported_labels; 4738c2ecf20Sopenharmony_ci symbol_node_t *curnode; 4748c2ecf20Sopenharmony_ci symbol_node_t *regnode; 4758c2ecf20Sopenharmony_ci DBT key; 4768c2ecf20Sopenharmony_ci DBT data; 4778c2ecf20Sopenharmony_ci int flag; 4788c2ecf20Sopenharmony_ci int reg_count = 0, reg_used = 0; 4798c2ecf20Sopenharmony_ci u_int i; 4808c2ecf20Sopenharmony_ci 4818c2ecf20Sopenharmony_ci if (symtable == NULL) 4828c2ecf20Sopenharmony_ci return; 4838c2ecf20Sopenharmony_ci 4848c2ecf20Sopenharmony_ci SLIST_INIT(®isters); 4858c2ecf20Sopenharmony_ci SLIST_INIT(&masks); 4868c2ecf20Sopenharmony_ci SLIST_INIT(&constants); 4878c2ecf20Sopenharmony_ci SLIST_INIT(&download_constants); 4888c2ecf20Sopenharmony_ci SLIST_INIT(&aliases); 4898c2ecf20Sopenharmony_ci SLIST_INIT(&exported_labels); 4908c2ecf20Sopenharmony_ci flag = R_FIRST; 4918c2ecf20Sopenharmony_ci while (symtable->seq(symtable, &key, &data, flag) == 0) { 4928c2ecf20Sopenharmony_ci symbol_t *cursym; 4938c2ecf20Sopenharmony_ci 4948c2ecf20Sopenharmony_ci memcpy(&cursym, data.data, sizeof(cursym)); 4958c2ecf20Sopenharmony_ci switch(cursym->type) { 4968c2ecf20Sopenharmony_ci case REGISTER: 4978c2ecf20Sopenharmony_ci case SCBLOC: 4988c2ecf20Sopenharmony_ci case SRAMLOC: 4998c2ecf20Sopenharmony_ci symlist_add(®isters, cursym, SYMLIST_SORT); 5008c2ecf20Sopenharmony_ci break; 5018c2ecf20Sopenharmony_ci case MASK: 5028c2ecf20Sopenharmony_ci case FIELD: 5038c2ecf20Sopenharmony_ci case ENUM: 5048c2ecf20Sopenharmony_ci case ENUM_ENTRY: 5058c2ecf20Sopenharmony_ci symlist_add(&masks, cursym, SYMLIST_SORT); 5068c2ecf20Sopenharmony_ci break; 5078c2ecf20Sopenharmony_ci case CONST: 5088c2ecf20Sopenharmony_ci symlist_add(&constants, cursym, 5098c2ecf20Sopenharmony_ci SYMLIST_INSERT_HEAD); 5108c2ecf20Sopenharmony_ci break; 5118c2ecf20Sopenharmony_ci case DOWNLOAD_CONST: 5128c2ecf20Sopenharmony_ci symlist_add(&download_constants, cursym, 5138c2ecf20Sopenharmony_ci SYMLIST_INSERT_HEAD); 5148c2ecf20Sopenharmony_ci break; 5158c2ecf20Sopenharmony_ci case ALIAS: 5168c2ecf20Sopenharmony_ci symlist_add(&aliases, cursym, 5178c2ecf20Sopenharmony_ci SYMLIST_INSERT_HEAD); 5188c2ecf20Sopenharmony_ci break; 5198c2ecf20Sopenharmony_ci case LABEL: 5208c2ecf20Sopenharmony_ci if (cursym->info.linfo->exported == 0) 5218c2ecf20Sopenharmony_ci break; 5228c2ecf20Sopenharmony_ci symlist_add(&exported_labels, cursym, 5238c2ecf20Sopenharmony_ci SYMLIST_INSERT_HEAD); 5248c2ecf20Sopenharmony_ci break; 5258c2ecf20Sopenharmony_ci default: 5268c2ecf20Sopenharmony_ci break; 5278c2ecf20Sopenharmony_ci } 5288c2ecf20Sopenharmony_ci flag = R_NEXT; 5298c2ecf20Sopenharmony_ci } 5308c2ecf20Sopenharmony_ci 5318c2ecf20Sopenharmony_ci /* Register dianostic functions/declarations first. */ 5328c2ecf20Sopenharmony_ci aic_print_file_prologue(ofile); 5338c2ecf20Sopenharmony_ci aic_print_reg_dump_types(ofile); 5348c2ecf20Sopenharmony_ci aic_print_file_prologue(dfile); 5358c2ecf20Sopenharmony_ci aic_print_include(dfile, stock_include_file); 5368c2ecf20Sopenharmony_ci SLIST_FOREACH(curnode, ®isters, links) { 5378c2ecf20Sopenharmony_ci 5388c2ecf20Sopenharmony_ci if (curnode->symbol->dont_generate_debug_code) 5398c2ecf20Sopenharmony_ci continue; 5408c2ecf20Sopenharmony_ci 5418c2ecf20Sopenharmony_ci switch(curnode->symbol->type) { 5428c2ecf20Sopenharmony_ci case REGISTER: 5438c2ecf20Sopenharmony_ci case SCBLOC: 5448c2ecf20Sopenharmony_ci case SRAMLOC: 5458c2ecf20Sopenharmony_ci { 5468c2ecf20Sopenharmony_ci symlist_t *fields; 5478c2ecf20Sopenharmony_ci symbol_node_t *fieldnode; 5488c2ecf20Sopenharmony_ci int num_entries; 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_ci num_entries = 0; 5518c2ecf20Sopenharmony_ci reg_count++; 5528c2ecf20Sopenharmony_ci if (curnode->symbol->count == 1) 5538c2ecf20Sopenharmony_ci break; 5548c2ecf20Sopenharmony_ci fields = &curnode->symbol->info.rinfo->fields; 5558c2ecf20Sopenharmony_ci SLIST_FOREACH(fieldnode, fields, links) { 5568c2ecf20Sopenharmony_ci if (num_entries == 0) 5578c2ecf20Sopenharmony_ci aic_print_reg_dump_start(dfile, 5588c2ecf20Sopenharmony_ci curnode); 5598c2ecf20Sopenharmony_ci else if (dfile != NULL) 5608c2ecf20Sopenharmony_ci fputs(",\n", dfile); 5618c2ecf20Sopenharmony_ci num_entries++; 5628c2ecf20Sopenharmony_ci aic_print_reg_dump_entry(dfile, fieldnode); 5638c2ecf20Sopenharmony_ci } 5648c2ecf20Sopenharmony_ci aic_print_reg_dump_end(ofile, dfile, 5658c2ecf20Sopenharmony_ci curnode, num_entries); 5668c2ecf20Sopenharmony_ci reg_used++; 5678c2ecf20Sopenharmony_ci } 5688c2ecf20Sopenharmony_ci default: 5698c2ecf20Sopenharmony_ci break; 5708c2ecf20Sopenharmony_ci } 5718c2ecf20Sopenharmony_ci } 5728c2ecf20Sopenharmony_ci fprintf(stderr, "%s: %d of %d register definitions used\n", appname, 5738c2ecf20Sopenharmony_ci reg_used, reg_count); 5748c2ecf20Sopenharmony_ci 5758c2ecf20Sopenharmony_ci /* Fold in the masks and bits */ 5768c2ecf20Sopenharmony_ci while (SLIST_FIRST(&masks) != NULL) { 5778c2ecf20Sopenharmony_ci char *regname; 5788c2ecf20Sopenharmony_ci 5798c2ecf20Sopenharmony_ci curnode = SLIST_FIRST(&masks); 5808c2ecf20Sopenharmony_ci SLIST_REMOVE_HEAD(&masks, links); 5818c2ecf20Sopenharmony_ci 5828c2ecf20Sopenharmony_ci regnode = SLIST_FIRST(&curnode->symbol->info.finfo->symrefs); 5838c2ecf20Sopenharmony_ci regname = regnode->symbol->name; 5848c2ecf20Sopenharmony_ci regnode = symlist_search(®isters, regname); 5858c2ecf20Sopenharmony_ci SLIST_INSERT_AFTER(regnode, curnode, links); 5868c2ecf20Sopenharmony_ci } 5878c2ecf20Sopenharmony_ci 5888c2ecf20Sopenharmony_ci /* Add the aliases */ 5898c2ecf20Sopenharmony_ci while (SLIST_FIRST(&aliases) != NULL) { 5908c2ecf20Sopenharmony_ci char *regname; 5918c2ecf20Sopenharmony_ci 5928c2ecf20Sopenharmony_ci curnode = SLIST_FIRST(&aliases); 5938c2ecf20Sopenharmony_ci SLIST_REMOVE_HEAD(&aliases, links); 5948c2ecf20Sopenharmony_ci 5958c2ecf20Sopenharmony_ci regname = curnode->symbol->info.ainfo->parent->name; 5968c2ecf20Sopenharmony_ci regnode = symlist_search(®isters, regname); 5978c2ecf20Sopenharmony_ci SLIST_INSERT_AFTER(regnode, curnode, links); 5988c2ecf20Sopenharmony_ci } 5998c2ecf20Sopenharmony_ci 6008c2ecf20Sopenharmony_ci /* Output generated #defines. */ 6018c2ecf20Sopenharmony_ci while (SLIST_FIRST(®isters) != NULL) { 6028c2ecf20Sopenharmony_ci symbol_node_t *curnode; 6038c2ecf20Sopenharmony_ci u_int value; 6048c2ecf20Sopenharmony_ci char *tab_str; 6058c2ecf20Sopenharmony_ci char *tab_str2; 6068c2ecf20Sopenharmony_ci 6078c2ecf20Sopenharmony_ci curnode = SLIST_FIRST(®isters); 6088c2ecf20Sopenharmony_ci SLIST_REMOVE_HEAD(®isters, links); 6098c2ecf20Sopenharmony_ci switch(curnode->symbol->type) { 6108c2ecf20Sopenharmony_ci case REGISTER: 6118c2ecf20Sopenharmony_ci case SCBLOC: 6128c2ecf20Sopenharmony_ci case SRAMLOC: 6138c2ecf20Sopenharmony_ci fprintf(ofile, "\n"); 6148c2ecf20Sopenharmony_ci value = curnode->symbol->info.rinfo->address; 6158c2ecf20Sopenharmony_ci tab_str = "\t"; 6168c2ecf20Sopenharmony_ci tab_str2 = "\t\t"; 6178c2ecf20Sopenharmony_ci break; 6188c2ecf20Sopenharmony_ci case ALIAS: 6198c2ecf20Sopenharmony_ci { 6208c2ecf20Sopenharmony_ci symbol_t *parent; 6218c2ecf20Sopenharmony_ci 6228c2ecf20Sopenharmony_ci parent = curnode->symbol->info.ainfo->parent; 6238c2ecf20Sopenharmony_ci value = parent->info.rinfo->address; 6248c2ecf20Sopenharmony_ci tab_str = "\t"; 6258c2ecf20Sopenharmony_ci tab_str2 = "\t\t"; 6268c2ecf20Sopenharmony_ci break; 6278c2ecf20Sopenharmony_ci } 6288c2ecf20Sopenharmony_ci case MASK: 6298c2ecf20Sopenharmony_ci case FIELD: 6308c2ecf20Sopenharmony_ci case ENUM: 6318c2ecf20Sopenharmony_ci case ENUM_ENTRY: 6328c2ecf20Sopenharmony_ci value = curnode->symbol->info.finfo->value; 6338c2ecf20Sopenharmony_ci tab_str = "\t\t"; 6348c2ecf20Sopenharmony_ci tab_str2 = "\t"; 6358c2ecf20Sopenharmony_ci break; 6368c2ecf20Sopenharmony_ci default: 6378c2ecf20Sopenharmony_ci value = 0; /* Quiet compiler */ 6388c2ecf20Sopenharmony_ci tab_str = NULL; 6398c2ecf20Sopenharmony_ci tab_str2 = NULL; 6408c2ecf20Sopenharmony_ci stop("symtable_dump: Invalid symbol type " 6418c2ecf20Sopenharmony_ci "encountered", EX_SOFTWARE); 6428c2ecf20Sopenharmony_ci break; 6438c2ecf20Sopenharmony_ci } 6448c2ecf20Sopenharmony_ci fprintf(ofile, "#define%s%-16s%s0x%02x\n", 6458c2ecf20Sopenharmony_ci tab_str, curnode->symbol->name, tab_str2, 6468c2ecf20Sopenharmony_ci value); 6478c2ecf20Sopenharmony_ci free(curnode); 6488c2ecf20Sopenharmony_ci } 6498c2ecf20Sopenharmony_ci fprintf(ofile, "\n\n"); 6508c2ecf20Sopenharmony_ci 6518c2ecf20Sopenharmony_ci while (SLIST_FIRST(&constants) != NULL) { 6528c2ecf20Sopenharmony_ci symbol_node_t *curnode; 6538c2ecf20Sopenharmony_ci 6548c2ecf20Sopenharmony_ci curnode = SLIST_FIRST(&constants); 6558c2ecf20Sopenharmony_ci SLIST_REMOVE_HEAD(&constants, links); 6568c2ecf20Sopenharmony_ci fprintf(ofile, "#define\t%-8s\t0x%02x\n", 6578c2ecf20Sopenharmony_ci curnode->symbol->name, 6588c2ecf20Sopenharmony_ci curnode->symbol->info.cinfo->value); 6598c2ecf20Sopenharmony_ci free(curnode); 6608c2ecf20Sopenharmony_ci } 6618c2ecf20Sopenharmony_ci 6628c2ecf20Sopenharmony_ci fprintf(ofile, "\n\n/* Downloaded Constant Definitions */\n"); 6638c2ecf20Sopenharmony_ci 6648c2ecf20Sopenharmony_ci for (i = 0; SLIST_FIRST(&download_constants) != NULL; i++) { 6658c2ecf20Sopenharmony_ci symbol_node_t *curnode; 6668c2ecf20Sopenharmony_ci 6678c2ecf20Sopenharmony_ci curnode = SLIST_FIRST(&download_constants); 6688c2ecf20Sopenharmony_ci SLIST_REMOVE_HEAD(&download_constants, links); 6698c2ecf20Sopenharmony_ci fprintf(ofile, "#define\t%-8s\t0x%02x\n", 6708c2ecf20Sopenharmony_ci curnode->symbol->name, 6718c2ecf20Sopenharmony_ci curnode->symbol->info.cinfo->value); 6728c2ecf20Sopenharmony_ci free(curnode); 6738c2ecf20Sopenharmony_ci } 6748c2ecf20Sopenharmony_ci fprintf(ofile, "#define\tDOWNLOAD_CONST_COUNT\t0x%02x\n", i); 6758c2ecf20Sopenharmony_ci 6768c2ecf20Sopenharmony_ci fprintf(ofile, "\n\n/* Exported Labels */\n"); 6778c2ecf20Sopenharmony_ci 6788c2ecf20Sopenharmony_ci while (SLIST_FIRST(&exported_labels) != NULL) { 6798c2ecf20Sopenharmony_ci symbol_node_t *curnode; 6808c2ecf20Sopenharmony_ci 6818c2ecf20Sopenharmony_ci curnode = SLIST_FIRST(&exported_labels); 6828c2ecf20Sopenharmony_ci SLIST_REMOVE_HEAD(&exported_labels, links); 6838c2ecf20Sopenharmony_ci fprintf(ofile, "#define\tLABEL_%-8s\t0x%02x\n", 6848c2ecf20Sopenharmony_ci curnode->symbol->name, 6858c2ecf20Sopenharmony_ci curnode->symbol->info.linfo->address); 6868c2ecf20Sopenharmony_ci free(curnode); 6878c2ecf20Sopenharmony_ci } 6888c2ecf20Sopenharmony_ci} 6898c2ecf20Sopenharmony_ci 690