xref: /freebsd/sys/dev/aic7xxx/aicasm/aicasm_symbol.c (revision 34db47a9dbc76c09019e2bfa37d23e28e477a506)
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(&registers);
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(&registers, 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, &registers, 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(&registers, 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(&registers, 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(&registers) != 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(&registers);
599c5cb3888SJustin T. Gibbs 		SLIST_REMOVE_HEAD(&registers, 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