2 * Aic7xxx SCSI host adapter firmware asssembler symbol table implementation
4 * Copyright (c) 1997 Justin T. Gibbs.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer,
12 * without modification, immediately at the beginning of the file.
13 * 2. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/types.h>
41 #include "aicasm_symbol.h"
52 new_symbol = (symbol_t *)malloc(sizeof(symbol_t));
53 if (new_symbol == NULL) {
54 perror("Unable to create new symbol");
57 memset(new_symbol, 0, sizeof(*new_symbol));
58 new_symbol->name = strdup(name);
59 new_symbol->type = UNINITIALIZED;
67 if (symtable != NULL) {
70 key.data = symbol->name;
71 key.size = strlen(symbol->name);
72 symtable->del(symtable, &key, /*flags*/0);
74 switch(symbol->type) {
78 if (symbol->info.rinfo != NULL)
79 free(symbol->info.rinfo);
82 if (symbol->info.ainfo != NULL)
83 free(symbol->info.ainfo);
87 if (symbol->info.minfo != NULL) {
88 symlist_free(&symbol->info.minfo->symrefs);
89 free(symbol->info.minfo);
94 if (symbol->info.cinfo != NULL)
95 free(symbol->info.cinfo);
98 if (symbol->info.linfo != NULL)
99 free(symbol->info.linfo);
112 symtable = dbopen(/*filename*/NULL,
113 O_CREAT | O_NONBLOCK | O_RDWR, /*mode*/0, DB_HASH,
116 if (symtable == NULL) {
117 perror("Symbol table creation failed");
126 if (symtable != NULL) {
130 while (symtable->seq(symtable, &key, &data, R_FIRST) == 0) {
131 symbol_t *stored_ptr;
133 memcpy(&stored_ptr, data.data, sizeof(stored_ptr));
134 symbol_delete(stored_ptr);
136 symtable->close(symtable);
141 * The semantics of get is to return an uninitialized symbol entry
148 symbol_t *stored_ptr;
153 key.data = (void *)name;
154 key.size = strlen(name);
156 if ((retval = symtable->get(symtable, &key, &data, /*flags*/0)) != 0) {
158 perror("Symbol table get operation failed");
161 } else if (retval == 1) {
162 /* Symbol wasn't found, so create a new one */
163 symbol_t *new_symbol;
165 new_symbol = symbol_create(name);
166 data.data = &new_symbol;
167 data.size = sizeof(new_symbol);
168 if (symtable->put(symtable, &key, &data,
170 perror("Symtable put failed");
175 perror("Unexpected return value from db get routine");
180 memcpy(&stored_ptr, data.data, sizeof(stored_ptr));
185 symlist_search(symlist, symname)
189 symbol_node_t *curnode;
191 curnode = symlist->slh_first;
192 while(curnode != NULL) {
193 if (strcmp(symname, curnode->symbol->name) == 0)
195 curnode = curnode->links.sle_next;
201 symlist_add(symlist, symbol, how)
206 symbol_node_t *newnode;
208 newnode = (symbol_node_t *)malloc(sizeof(symbol_node_t));
209 if (newnode == NULL) {
210 stop("symlist_add: Unable to malloc symbol_node", EX_SOFTWARE);
213 newnode->symbol = symbol;
214 if (how == SYMLIST_SORT) {
215 symbol_node_t *curnode;
219 switch(symbol->type) {
229 stop("symlist_add: Invalid symbol type for sorting",
234 curnode = symlist->slh_first;
236 || (mask && (curnode->symbol->info.minfo->mask >
237 newnode->symbol->info.minfo->mask))
238 || (!mask && (curnode->symbol->info.rinfo->address >
239 newnode->symbol->info.rinfo->address))) {
240 SLIST_INSERT_HEAD(symlist, newnode, links);
245 if (curnode->links.sle_next == NULL) {
246 SLIST_INSERT_AFTER(curnode, newnode,
252 cursymbol = curnode->links.sle_next->symbol;
253 if ((mask && (cursymbol->info.minfo->mask >
254 symbol->info.minfo->mask))
255 || (!mask &&(cursymbol->info.rinfo->address >
256 symbol->info.rinfo->address))){
257 SLIST_INSERT_AFTER(curnode, newnode,
262 curnode = curnode->links.sle_next;
265 SLIST_INSERT_HEAD(symlist, newnode, links);
270 symlist_free(symlist)
273 symbol_node_t *node1, *node2;
275 node1 = symlist->slh_first;
276 while (node1 != NULL) {
277 node2 = node1->links.sle_next;
285 symlist_merge(symlist_dest, symlist_src1, symlist_src2)
286 symlist_t *symlist_dest;
287 symlist_t *symlist_src1;
288 symlist_t *symlist_src2;
292 *symlist_dest = *symlist_src1;
293 while((node = symlist_src2->slh_first) != NULL) {
294 SLIST_REMOVE_HEAD(symlist_src2, links);
295 SLIST_INSERT_HEAD(symlist_dest, node, links);
298 /* These are now empty */
299 SLIST_INIT(symlist_src1);
300 SLIST_INIT(symlist_src2);
308 * Sort the registers by address with a simple insertion sort.
309 * Put bitmasks next to the first register that defines them.
310 * Put constants at the end.
315 symlist_t download_constants;
318 SLIST_INIT(®isters);
320 SLIST_INIT(&constants);
321 SLIST_INIT(&download_constants);
322 SLIST_INIT(&aliases);
324 if (symtable != NULL) {
329 while (symtable->seq(symtable, &key, &data, flag) == 0) {
332 memcpy(&cursym, data.data, sizeof(cursym));
333 switch(cursym->type) {
337 symlist_add(®isters, cursym, SYMLIST_SORT);
341 symlist_add(&masks, cursym, SYMLIST_SORT);
344 if (cursym->info.cinfo->define == FALSE) {
345 symlist_add(&constants, cursym,
346 SYMLIST_INSERT_HEAD);
350 symlist_add(&download_constants, cursym,
351 SYMLIST_INSERT_HEAD);
354 symlist_add(&aliases, cursym,
355 SYMLIST_INSERT_HEAD);
363 /* Put in the masks and bits */
364 while (masks.slh_first != NULL) {
365 symbol_node_t *curnode;
366 symbol_node_t *regnode;
369 curnode = masks.slh_first;
370 SLIST_REMOVE_HEAD(&masks, links);
373 curnode->symbol->info.minfo->symrefs.slh_first;
374 regname = regnode->symbol->name;
375 regnode = symlist_search(®isters, regname);
376 SLIST_INSERT_AFTER(regnode, curnode, links);
379 /* Add the aliases */
380 while (aliases.slh_first != NULL) {
381 symbol_node_t *curnode;
382 symbol_node_t *regnode;
385 curnode = aliases.slh_first;
386 SLIST_REMOVE_HEAD(&aliases, links);
388 regname = curnode->symbol->info.ainfo->parent->name;
389 regnode = symlist_search(®isters, regname);
390 SLIST_INSERT_AFTER(regnode, curnode, links);
393 /* Output what we have */
396 * DO NOT EDIT - This file is automatically generated.
398 while (registers.slh_first != NULL) {
399 symbol_node_t *curnode;
404 curnode = registers.slh_first;
405 SLIST_REMOVE_HEAD(®isters, links);
406 switch(curnode->symbol->type) {
410 fprintf(ofile, "\n");
411 value = curnode->symbol->info.rinfo->address;
419 parent = curnode->symbol->info.ainfo->parent;
420 value = parent->info.rinfo->address;
427 value = curnode->symbol->info.minfo->mask;
432 value = 0; /* Quiet compiler */
435 stop("symtable_dump: Invalid symbol type "
436 "encountered", EX_SOFTWARE);
439 fprintf(ofile, "#define%s%-16s%s0x%02x\n",
440 tab_str, curnode->symbol->name, tab_str2,
444 fprintf(ofile, "\n\n");
446 while (constants.slh_first != NULL) {
447 symbol_node_t *curnode;
449 curnode = constants.slh_first;
450 SLIST_REMOVE_HEAD(&constants, links);
451 fprintf(ofile, "#define\t%-8s\t0x%02x\n",
452 curnode->symbol->name,
453 curnode->symbol->info.cinfo->value);
458 fprintf(ofile, "\n\n/* Downloaded Constant Definitions */\n");
460 while (download_constants.slh_first != NULL) {
461 symbol_node_t *curnode;
463 curnode = download_constants.slh_first;
464 SLIST_REMOVE_HEAD(&download_constants, links);
465 fprintf(ofile, "#define\t%-8s\t0x%02x\n",
466 curnode->symbol->name,
467 curnode->symbol->info.cinfo->value);