root/dev/microcode/aic7xxx/aicasm_symbol.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. symbol_create
  2. symbol_delete
  3. symtable_open
  4. symtable_close
  5. symtable_get
  6. symlist_search
  7. symlist_add
  8. symlist_free
  9. symlist_merge
  10. aic_print_file_prologue
  11. aic_print_include
  12. aic_print_reg_dump_types
  13. aic_print_reg_dump_start
  14. aic_print_reg_dump_end
  15. aic_print_reg_dump_entry
  16. symtable_dump

    1 /* $OpenBSD: aicasm_symbol.c,v 1.9 2003/12/24 23:27:55 krw Exp $ */
    2 /*      $NetBSD: aicasm_symbol.c,v 1.4 2003/07/14 15:42:40 lukem Exp $  */
    3 
    4 /*
    5  * Aic7xxx SCSI host adapter firmware asssembler symbol table implementation
    6  *
    7  * Copyright (c) 1997 Justin T. Gibbs.
    8  * Copyright (c) 2002 Adaptec Inc.
    9  * All rights reserved.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions, and the following disclaimer,
   16  *    without modification.
   17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
   18  *    substantially similar to the "NO WARRANTY" disclaimer below
   19  *    ("Disclaimer") and any redistribution must be conditioned upon
   20  *    including a substantially similar Disclaimer requirement for further
   21  *    binary redistribution.
   22  * 3. Neither the names of the above-listed copyright holders nor the names
   23  *    of any contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * Alternatively, this software may be distributed under the terms of the
   27  * GNU General Public License ("GPL") version 2 as published by the Free
   28  * Software Foundation.
   29  *
   30  * NO WARRANTY
   31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
   34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
   40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   41  * POSSIBILITY OF SUCH DAMAGES.
   42  *
   43  * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_symbol.c,v 1.23 2003/01/20 18:01:37 gibbs Exp $
   44  */
   45 
   46 #include <sys/cdefs.h>
   47 /* __RCSID("$NetBSD: aicasm_symbol.c,v 1.4 2003/07/14 15:42:40 lukem Exp $"); */
   48 
   49 #include <sys/types.h>
   50 
   51 #ifdef __linux__
   52 #include "aicdb.h"
   53 #else
   54 #include <db.h>
   55 #endif
   56 #include <fcntl.h>
   57 #include <inttypes.h>
   58 #include <regex.h>
   59 #include <stdio.h>
   60 #include <stdlib.h>
   61 #include <string.h>
   62 #include <sysexits.h>
   63 
   64 #include "aicasm_symbol.h"
   65 #include "aicasm.h"
   66 
   67 static DB *symtable;
   68 
   69 symbol_t *
   70 symbol_create(char *name)
   71 {
   72         symbol_t *new_symbol;
   73 
   74         new_symbol = (symbol_t *)malloc(sizeof(symbol_t));
   75         if (new_symbol == NULL) {
   76                 perror("Unable to create new symbol");
   77                 exit(EX_SOFTWARE);
   78         }
   79         memset(new_symbol, 0, sizeof(*new_symbol));
   80         new_symbol->name = strdup(name);
   81         if (new_symbol->name == NULL)
   82                  stop("Unable to strdup symbol name", EX_SOFTWARE);
   83         new_symbol->type = UNINITIALIZED;
   84         return (new_symbol);
   85 }
   86 
   87 void
   88 symbol_delete(symbol_t *symbol)
   89 {
   90         if (symtable != NULL) {
   91                 DBT      key;
   92 
   93                 key.data = symbol->name;
   94                 key.size = strlen(symbol->name);
   95                 symtable->del(symtable, &key, /*flags*/0);
   96         }
   97         switch(symbol->type) {
   98         case SCBLOC:
   99         case SRAMLOC:
  100         case REGISTER:
  101                 if (symbol->info.rinfo != NULL)
  102                         free(symbol->info.rinfo);
  103                 break;
  104         case ALIAS:
  105                 if (symbol->info.ainfo != NULL)
  106                         free(symbol->info.ainfo);
  107                 break;
  108         case MASK:
  109         case FIELD:
  110         case ENUM:
  111         case ENUM_ENTRY:
  112                 if (symbol->info.finfo != NULL) {
  113                         symlist_free(&symbol->info.finfo->symrefs);
  114                         free(symbol->info.finfo);
  115                 }
  116                 break;
  117         case DOWNLOAD_CONST:
  118         case CONST:
  119                 if (symbol->info.cinfo != NULL)
  120                         free(symbol->info.cinfo);
  121                 break;
  122         case LABEL:
  123                 if (symbol->info.linfo != NULL)
  124                         free(symbol->info.linfo);
  125                 break;
  126         case UNINITIALIZED:
  127         default:
  128                 break;
  129         }
  130         free(symbol->name);
  131         free(symbol);
  132 }
  133 
  134 void
  135 symtable_open()
  136 {
  137         symtable = dbopen(/*filename*/NULL,
  138                           O_CREAT | O_NONBLOCK | O_RDWR, /*mode*/0, DB_HASH,
  139                           /*openinfo*/NULL);
  140 
  141         if (symtable == NULL) {
  142                 perror("Symbol table creation failed");
  143                 exit(EX_SOFTWARE);
  144                 /* NOTREACHED */
  145         }
  146 }
  147 
  148 void
  149 symtable_close()
  150 {
  151         if (symtable != NULL) {
  152                 DBT      key;
  153                 DBT      data;
  154 
  155                 while (symtable->seq(symtable, &key, &data, R_FIRST) == 0) {
  156                         symbol_t *stored_ptr;
  157 
  158                         memcpy(&stored_ptr, data.data, sizeof(stored_ptr));
  159                         symbol_delete(stored_ptr);
  160                 }
  161                 symtable->close(symtable);
  162         }
  163 }
  164 
  165 /*
  166  * The semantics of get is to return an uninitialized symbol entry
  167  * if a lookup fails.
  168  */
  169 symbol_t *
  170 symtable_get(char *name)
  171 {
  172         symbol_t *stored_ptr;
  173         DBT       key;
  174         DBT       data;
  175         int       retval;
  176 
  177         key.data = (void *)name;
  178         key.size = strlen(name);
  179 
  180         if ((retval = symtable->get(symtable, &key, &data, /*flags*/0)) != 0) {
  181                 if (retval == -1) {
  182                         perror("Symbol table get operation failed");
  183                         exit(EX_SOFTWARE);
  184                         /* NOTREACHED */
  185                 } else if (retval == 1) {
  186                         /* Symbol wasn't found, so create a new one */
  187                         symbol_t *new_symbol;
  188 
  189                         new_symbol = symbol_create(name);
  190                         data.data = &new_symbol;
  191                         data.size = sizeof(new_symbol);
  192                         if (symtable->put(symtable, &key, &data,
  193                                           /*flags*/0) !=0) {
  194                                 perror("Symtable put failed");
  195                                 exit(EX_SOFTWARE);
  196                         }
  197                         return (new_symbol);
  198                 } else {
  199                         perror("Unexpected return value from db get routine");
  200                         exit(EX_SOFTWARE);
  201                         /* NOTREACHED */
  202                 }
  203         }
  204         memcpy(&stored_ptr, data.data, sizeof(stored_ptr));
  205         return (stored_ptr);
  206 }
  207 
  208 symbol_node_t *
  209 symlist_search(symlist_t *symlist, char *symname)
  210 {
  211         symbol_node_t *curnode;
  212 
  213         curnode = SLIST_FIRST(symlist);
  214         while(curnode != NULL) {
  215                 if (strcmp(symname, curnode->symbol->name) == 0)
  216                         break;
  217                 curnode = SLIST_NEXT(curnode, links);
  218         }
  219         return (curnode);
  220 }
  221 
  222 void
  223 symlist_add(symlist_t *symlist, symbol_t *symbol, int how)
  224 {
  225         symbol_node_t *newnode;
  226 
  227         newnode = (symbol_node_t *)malloc(sizeof(symbol_node_t));
  228         if (newnode == NULL) {
  229                 stop("symlist_add: Unable to malloc symbol_node", EX_SOFTWARE);
  230                 /* NOTREACHED */
  231         }
  232         newnode->symbol = symbol;
  233         if (how == SYMLIST_SORT) {
  234                 symbol_node_t *curnode;
  235                 int field;
  236 
  237                 field = FALSE;
  238                 switch(symbol->type) {
  239                 case REGISTER:
  240                 case SCBLOC:
  241                 case SRAMLOC:
  242                         break;
  243                 case FIELD:
  244                 case MASK:
  245                 case ENUM:
  246                 case ENUM_ENTRY:
  247                         field = TRUE;
  248                         break;
  249                 default:
  250                         stop("symlist_add: Invalid symbol type for sorting",
  251                              EX_SOFTWARE);
  252                         /* NOTREACHED */
  253                 }
  254 
  255                 curnode = SLIST_FIRST(symlist);
  256                 if (curnode == NULL
  257                  || (field
  258                   && (curnode->symbol->type > newnode->symbol->type
  259                    || (curnode->symbol->type == newnode->symbol->type
  260                     && (curnode->symbol->info.finfo->value >
  261                         newnode->symbol->info.finfo->value))))
  262                  || (!field && (curnode->symbol->info.rinfo->address >
  263                                newnode->symbol->info.rinfo->address))) {
  264                         SLIST_INSERT_HEAD(symlist, newnode, links);
  265                         return;
  266                 }
  267 
  268                 while (1) {
  269                         if (SLIST_NEXT(curnode, links) == NULL) {
  270                                 SLIST_INSERT_AFTER(curnode, newnode,
  271                                                    links);
  272                                 break;
  273                         } else {
  274                                 symbol_t *cursymbol;
  275 
  276                                 cursymbol = SLIST_NEXT(curnode, links)->symbol;
  277                                 if ((field
  278                                   && (cursymbol->type > symbol->type
  279                                    || (cursymbol->type == symbol->type
  280                                     && (cursymbol->info.finfo->value >
  281                                         symbol->info.finfo->value))))
  282                                  || (!field
  283                                    && (cursymbol->info.rinfo->address >
  284                                        symbol->info.rinfo->address))) {
  285                                         SLIST_INSERT_AFTER(curnode, newnode,
  286                                                            links);
  287                                         break;
  288                                 }
  289                         }
  290                         curnode = SLIST_NEXT(curnode, links);
  291                 }
  292         } else {
  293                 SLIST_INSERT_HEAD(symlist, newnode, links);
  294         }
  295 }
  296 
  297 void
  298 symlist_free(symlist_t *symlist)
  299 {
  300         symbol_node_t *node1, *node2;
  301 
  302         node1 = SLIST_FIRST(symlist);
  303         while (node1 != NULL) {
  304                 node2 = SLIST_NEXT(node1, links);
  305                 free(node1);
  306                 node1 = node2;
  307         }
  308         SLIST_INIT(symlist);
  309 }
  310 
  311 void
  312 symlist_merge(symlist_t *symlist_dest, symlist_t *symlist_src1,
  313               symlist_t *symlist_src2)
  314 {
  315         symbol_node_t *node;
  316 
  317         *symlist_dest = *symlist_src1;
  318         while((node = SLIST_FIRST(symlist_src2)) != NULL) {
  319                 SLIST_REMOVE_HEAD(symlist_src2, links);
  320                 SLIST_INSERT_HEAD(symlist_dest, node, links);
  321         }
  322 
  323         /* These are now empty */
  324         SLIST_INIT(symlist_src1);
  325         SLIST_INIT(symlist_src2);
  326 }
  327 
  328 void
  329 aic_print_file_prologue(FILE *ofile)
  330 {
  331 
  332         if (ofile == NULL)
  333                 return;
  334 
  335         fprintf(ofile,
  336 "/*\n"
  337 " * DO NOT EDIT - This file is automatically generated\n"
  338 " *              from the following source files:\n"
  339 " *\n"
  340 "%s */\n",
  341                 versions);
  342 }
  343 
  344 void
  345 aic_print_include(FILE *dfile, char *include_file)
  346 {
  347 
  348         if (dfile == NULL)
  349                 return;
  350         fprintf(dfile, "\n#include \"%s\"\n\n", include_file);
  351 }
  352 
  353 void
  354 aic_print_reg_dump_types(FILE *ofile)
  355 {
  356         if (ofile == NULL)
  357                 return;
  358                 
  359         fprintf(ofile,
  360 "typedef int (%sreg_print_t)(u_int, u_int *, u_int);\n"
  361 "typedef struct %sreg_parse_entry {\n"
  362 "       char    *name;\n"
  363 "       uint8_t  value;\n"
  364 "       uint8_t  mask;\n"
  365 "} %sreg_parse_entry_t;\n"
  366 "\n",
  367                 prefix, prefix, prefix);
  368 }
  369 
  370 static void
  371 aic_print_reg_dump_start(FILE *dfile, symbol_node_t *regnode)
  372 {
  373         if (dfile == NULL)
  374                 return;
  375 
  376         fprintf(dfile,
  377 "static %sreg_parse_entry_t %s_parse_table[] = {\n",
  378                 prefix,
  379                 regnode->symbol->name);
  380 }
  381 
  382 static void
  383 aic_print_reg_dump_end(FILE *ofile, FILE *dfile,
  384                        symbol_node_t *regnode, u_int num_entries)
  385 {
  386         char *lower_name;
  387         char *letter;
  388 
  389         lower_name = strdup(regnode->symbol->name);
  390         if (lower_name == NULL)
  391                  stop("Unable to strdup symbol name", EX_SOFTWARE);
  392         
  393         for (letter = lower_name; *letter != '\0'; letter++)
  394                 *letter = tolower(*letter);
  395 
  396         if (dfile != NULL) {
  397                 if (num_entries != 0)
  398                         fprintf(dfile,
  399 "\n"
  400 "};\n"
  401 "\n");
  402 
  403                 fprintf(dfile,
  404 "int\n"
  405 "%s%s_print(u_int regvalue, u_int *cur_col, u_int wrap)\n"
  406 "{\n"
  407 "       return (%sprint_register(%s%s, %d, \"%s\",\n"
  408 "           0x%02x, regvalue, cur_col, wrap));\n"
  409 "}\n"
  410 "\n",
  411                         prefix,
  412                         lower_name,
  413                         prefix,
  414                         num_entries != 0 ? regnode->symbol->name : "NULL",
  415                         num_entries != 0 ? "_parse_table" : "",
  416                         num_entries,
  417                         regnode->symbol->name,
  418                         regnode->symbol->info.rinfo->address);
  419         }
  420 
  421         fprintf(ofile,
  422 "#if AIC_DEBUG_REGISTERS\n"
  423 "%sreg_print_t %s%s_print;\n"
  424 "#else\n"
  425 "#define %s%s_print(regvalue, cur_col, wrap) \\\n"
  426 "    %sprint_register(NULL, 0, \"%s\", 0x%02x, regvalue, cur_col, wrap)\n"
  427 "#endif\n"
  428 "\n",
  429                 prefix,
  430                 prefix,
  431                 lower_name,
  432                 prefix,
  433                 lower_name,
  434                 prefix,
  435                 regnode->symbol->name,
  436                 regnode->symbol->info.rinfo->address);
  437 }
  438 
  439 static void
  440 aic_print_reg_dump_entry(FILE *dfile, symbol_node_t *curnode)
  441 {
  442         int num_tabs;
  443 
  444         if (dfile == NULL)
  445                 return;
  446 
  447         fprintf(dfile,
  448 "       { \"%s\",",
  449                 curnode->symbol->name);
  450 
  451         num_tabs = 3 - (strlen(curnode->symbol->name) + 5) / 8;
  452 
  453         while (num_tabs-- > 0)
  454                 fputc('\t', dfile);
  455         fprintf(dfile, "0x%02x, 0x%02x }",
  456                 curnode->symbol->info.finfo->value,
  457                 curnode->symbol->info.finfo->mask);
  458 }
  459 
  460 void
  461 symtable_dump(FILE *ofile, FILE *dfile)
  462 {
  463         /*
  464          * Sort the registers by address with a simple insertion sort.
  465          * Put bitmasks next to the first register that defines them.
  466          * Put constants at the end.
  467          */
  468         symlist_t        registers;
  469         symlist_t        masks;
  470         symlist_t        constants;
  471         symlist_t        download_constants;
  472         symlist_t        aliases;
  473         symlist_t        exported_labels;
  474         symbol_node_t   *curnode;
  475         symbol_node_t   *regnode;
  476         DBT              key;
  477         DBT              data;
  478         int              flag;
  479         u_int            i;
  480 
  481         if (symtable == NULL)
  482                 return;
  483 
  484         SLIST_INIT(&registers);
  485         SLIST_INIT(&masks);
  486         SLIST_INIT(&constants);
  487         SLIST_INIT(&download_constants);
  488         SLIST_INIT(&aliases);
  489         SLIST_INIT(&exported_labels);
  490         flag = R_FIRST;
  491         while (symtable->seq(symtable, &key, &data, flag) == 0) {
  492                 symbol_t *cursym;
  493 
  494                 memcpy(&cursym, data.data, sizeof(cursym));
  495                 switch(cursym->type) {
  496                 case REGISTER:
  497                 case SCBLOC:
  498                 case SRAMLOC:
  499                         symlist_add(&registers, cursym, SYMLIST_SORT);
  500                         break;
  501                 case MASK:
  502                 case FIELD:
  503                 case ENUM:
  504                 case ENUM_ENTRY:
  505                         symlist_add(&masks, cursym, SYMLIST_SORT);
  506                         break;
  507                 case CONST:
  508                         symlist_add(&constants, cursym,
  509                                     SYMLIST_INSERT_HEAD);
  510                         break;
  511                 case DOWNLOAD_CONST:
  512                         symlist_add(&download_constants, cursym,
  513                                     SYMLIST_INSERT_HEAD);
  514                         break;
  515                 case ALIAS:
  516                         symlist_add(&aliases, cursym,
  517                                     SYMLIST_INSERT_HEAD);
  518                         break;
  519                 case LABEL:
  520                         if (cursym->info.linfo->exported == 0)
  521                                 break;
  522                         symlist_add(&exported_labels, cursym,
  523                                     SYMLIST_INSERT_HEAD);
  524                         break;
  525                 default:
  526                         break;
  527                 }
  528                 flag = R_NEXT;
  529         }
  530 
  531         /* Register dianostic functions/declarations first. */
  532         aic_print_file_prologue(ofile);
  533         aic_print_reg_dump_types(ofile);
  534         aic_print_file_prologue(dfile);
  535         aic_print_include(dfile, stock_include_file);
  536         SLIST_FOREACH(curnode, &registers, links) {
  537 
  538                 switch(curnode->symbol->type) {
  539                 case REGISTER:
  540                 case SCBLOC:
  541                 case SRAMLOC:
  542                 {
  543                         symlist_t       *fields;
  544                         symbol_node_t   *fieldnode;
  545                         int              num_entries;
  546 
  547                         num_entries = 0;
  548                         fields = &curnode->symbol->info.rinfo->fields;
  549                         SLIST_FOREACH(fieldnode, fields, links) {
  550                                 if (num_entries == 0)
  551                                         aic_print_reg_dump_start(dfile,
  552                                                                  curnode);
  553                                 else if (dfile != NULL)
  554                                         fputs(",\n", dfile);
  555                                 num_entries++;
  556                                 aic_print_reg_dump_entry(dfile, fieldnode);
  557                         }
  558                         aic_print_reg_dump_end(ofile, dfile,
  559                                                curnode, num_entries);
  560                 }
  561                 default:
  562                         break;
  563                 }
  564         }
  565 
  566         /* Fold in the masks and bits */
  567         while (SLIST_FIRST(&masks) != NULL) {
  568                 char *regname;
  569 
  570                 curnode = SLIST_FIRST(&masks);
  571                 SLIST_REMOVE_HEAD(&masks, links);
  572 
  573                 regnode = SLIST_FIRST(&curnode->symbol->info.finfo->symrefs);
  574                 regname = regnode->symbol->name;
  575                 regnode = symlist_search(&registers, regname);
  576                 SLIST_INSERT_AFTER(regnode, curnode, links);
  577         }
  578 
  579         /* Add the aliases */
  580         while (SLIST_FIRST(&aliases) != NULL) {
  581                 char *regname;
  582 
  583                 curnode = SLIST_FIRST(&aliases);
  584                 SLIST_REMOVE_HEAD(&aliases, links);
  585 
  586                 regname = curnode->symbol->info.ainfo->parent->name;
  587                 regnode = symlist_search(&registers, regname);
  588                 SLIST_INSERT_AFTER(regnode, curnode, links);
  589         }
  590 
  591         /* Output generated #defines. */
  592         while (SLIST_FIRST(&registers) != NULL) {
  593                 symbol_node_t *curnode;
  594                 u_int value;
  595                 char *tab_str;
  596                 char *tab_str2;
  597 
  598                 curnode = SLIST_FIRST(&registers);
  599                 SLIST_REMOVE_HEAD(&registers, links);
  600                 switch(curnode->symbol->type) {
  601                 case REGISTER:
  602                 case SCBLOC:
  603                 case SRAMLOC:
  604                         fprintf(ofile, "\n");
  605                         value = curnode->symbol->info.rinfo->address;
  606                         tab_str = "\t";
  607                         tab_str2 = "\t\t";
  608                         break;
  609                 case ALIAS:
  610                 {
  611                         symbol_t *parent;
  612 
  613                         parent = curnode->symbol->info.ainfo->parent;
  614                         value = parent->info.rinfo->address;
  615                         tab_str = "\t";
  616                         tab_str2 = "\t\t";
  617                         break;
  618                 }
  619                 case MASK:
  620                 case FIELD:
  621                 case ENUM:
  622                 case ENUM_ENTRY:
  623                         value = curnode->symbol->info.finfo->value;
  624                         tab_str = "\t\t";
  625                         tab_str2 = "\t";
  626                         break;
  627                 default:
  628                         value = 0; /* Quiet compiler */
  629                         tab_str = NULL;
  630                         tab_str2 = NULL;
  631                         stop("symtable_dump: Invalid symbol type "
  632                              "encountered", EX_SOFTWARE);
  633                         break;
  634                 }
  635                 fprintf(ofile, "#define%s%-16s%s0x%02x\n",
  636                         tab_str, curnode->symbol->name, tab_str2,
  637                         value);
  638                 free(curnode);
  639         }
  640         fprintf(ofile, "\n\n");
  641 
  642         while (SLIST_FIRST(&constants) != NULL) {
  643                 symbol_node_t *curnode;
  644 
  645                 curnode = SLIST_FIRST(&constants);
  646                 SLIST_REMOVE_HEAD(&constants, links);
  647                 fprintf(ofile, "#define\t%-8s\t0x%02x\n",
  648                         curnode->symbol->name,
  649                         curnode->symbol->info.cinfo->value);
  650                 free(curnode);
  651         }
  652 
  653         
  654         fprintf(ofile, "\n\n/* Downloaded Constant Definitions */\n");
  655 
  656         for (i = 0; SLIST_FIRST(&download_constants) != NULL; i++) {
  657                 symbol_node_t *curnode;
  658 
  659                 curnode = SLIST_FIRST(&download_constants);
  660                 SLIST_REMOVE_HEAD(&download_constants, links);
  661                 fprintf(ofile, "#define\t%-8s\t0x%02x\n",
  662                         curnode->symbol->name,
  663                         curnode->symbol->info.cinfo->value);
  664                 free(curnode);
  665         }
  666         fprintf(ofile, "#define\tDOWNLOAD_CONST_COUNT\t0x%02x\n", i);
  667 
  668         fprintf(ofile, "\n\n/* Exported Labels */\n");
  669 
  670         while (SLIST_FIRST(&exported_labels) != NULL) {
  671                 symbol_node_t *curnode;
  672 
  673                 curnode = SLIST_FIRST(&exported_labels);
  674                 SLIST_REMOVE_HEAD(&exported_labels, links);
  675                 fprintf(ofile, "#define\tLABEL_%-8s\t0x%02x\n",
  676                         curnode->symbol->name,
  677                         curnode->symbol->info.linfo->address);
  678                 free(curnode);
  679         }
  680 }
  681 

/* [<][>][^][v][top][bottom][index][help] */