aicasm_symbol.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:11k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Aic7xxx SCSI host adapter firmware asssembler symbol table implementation
  3.  *
  4.  * Copyright (c) 1997 Justin T. Gibbs.
  5.  * All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions, and the following disclaimer,
  12.  *    without modification.
  13.  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  14.  *    substantially similar to the "NO WARRANTY" disclaimer below
  15.  *    ("Disclaimer") and any redistribution must be conditioned upon
  16.  *    including a substantially similar Disclaimer requirement for further
  17.  *    binary redistribution.
  18.  * 3. Neither the names of the above-listed copyright holders nor the names
  19.  *    of any contributors may be used to endorse or promote products derived
  20.  *    from this software without specific prior written permission.
  21.  *
  22.  * Alternatively, this software may be distributed under the terms of the
  23.  * GNU General Public License ("GPL") version 2 as published by the Free
  24.  * Software Foundation.
  25.  *
  26.  * NO WARRANTY
  27.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  28.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  29.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  30.  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  31.  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  32.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  33.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  34.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  35.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  36.  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  37.  * POSSIBILITY OF SUCH DAMAGES.
  38.  *
  39.  * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_symbol.c#9 $
  40.  *
  41.  * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_symbol.c,v 1.11 2000/09/22 22:19:54 gibbs Exp $
  42.  */
  43. #include <sys/types.h>
  44. #ifdef __linux__
  45. #include "aicdb.h"
  46. #else
  47. #include <db.h>
  48. #endif
  49. #include <fcntl.h>
  50. #include <stdio.h>
  51. #include <stdlib.h>
  52. #include <string.h>
  53. #include <sysexits.h>
  54. #include "aicasm_symbol.h"
  55. #include "aicasm.h"
  56. static DB *symtable;
  57. symbol_t *
  58. symbol_create(char *name)
  59. {
  60. symbol_t *new_symbol;
  61. new_symbol = (symbol_t *)malloc(sizeof(symbol_t));
  62. if (new_symbol == NULL) {
  63. perror("Unable to create new symbol");
  64. exit(EX_SOFTWARE);
  65. }
  66. memset(new_symbol, 0, sizeof(*new_symbol));
  67. new_symbol->name = strdup(name);
  68. new_symbol->type = UNINITIALIZED;
  69. return (new_symbol);
  70. }
  71. void
  72. symbol_delete(symbol_t *symbol)
  73. {
  74. if (symtable != NULL) {
  75. DBT  key;
  76. key.data = symbol->name;
  77. key.size = strlen(symbol->name);
  78. symtable->del(symtable, &key, /*flags*/0);
  79. }
  80. switch(symbol->type) {
  81. case SCBLOC:
  82. case SRAMLOC:
  83. case REGISTER:
  84. if (symbol->info.rinfo != NULL)
  85. free(symbol->info.rinfo);
  86. break;
  87. case ALIAS:
  88. if (symbol->info.ainfo != NULL)
  89. free(symbol->info.ainfo);
  90. break;
  91. case MASK:
  92. case BIT:
  93. if (symbol->info.minfo != NULL) {
  94. symlist_free(&symbol->info.minfo->symrefs);
  95. free(symbol->info.minfo);
  96. }
  97. break;
  98. case DOWNLOAD_CONST:
  99. case CONST:
  100. if (symbol->info.cinfo != NULL)
  101. free(symbol->info.cinfo);
  102. break;
  103. case LABEL:
  104. if (symbol->info.linfo != NULL)
  105. free(symbol->info.linfo);
  106. break;
  107. case UNINITIALIZED:
  108. default:
  109. break;
  110. }
  111. free(symbol->name);
  112. free(symbol);
  113. }
  114. void
  115. symtable_open()
  116. {
  117. symtable = dbopen(/*filename*/NULL,
  118.   O_CREAT | O_NONBLOCK | O_RDWR, /*mode*/0, DB_HASH,
  119.   /*openinfo*/NULL);
  120. if (symtable == NULL) {
  121. perror("Symbol table creation failed");
  122. exit(EX_SOFTWARE);
  123. /* NOTREACHED */
  124. }
  125. }
  126. void
  127. symtable_close()
  128. {
  129. if (symtable != NULL) {
  130. DBT  key;
  131. DBT  data;
  132. while (symtable->seq(symtable, &key, &data, R_FIRST) == 0) {
  133. symbol_t *stored_ptr;
  134. memcpy(&stored_ptr, data.data, sizeof(stored_ptr));
  135. symbol_delete(stored_ptr);
  136. }
  137. symtable->close(symtable);
  138. }
  139. }
  140. /*
  141.  * The semantics of get is to return an uninitialized symbol entry
  142.  * if a lookup fails.
  143.  */
  144. symbol_t *
  145. symtable_get(char *name)
  146. {
  147. symbol_t *stored_ptr;
  148. DBT   key;
  149. DBT   data;
  150. int   retval;
  151. key.data = (void *)name;
  152. key.size = strlen(name);
  153. if ((retval = symtable->get(symtable, &key, &data, /*flags*/0)) != 0) {
  154. if (retval == -1) {
  155. perror("Symbol table get operation failed");
  156. exit(EX_SOFTWARE);
  157. /* NOTREACHED */
  158. } else if (retval == 1) {
  159. /* Symbol wasn't found, so create a new one */
  160. symbol_t *new_symbol;
  161. new_symbol = symbol_create(name);
  162. data.data = &new_symbol;
  163. data.size = sizeof(new_symbol);
  164. if (symtable->put(symtable, &key, &data,
  165.   /*flags*/0) !=0) {
  166. perror("Symtable put failed");
  167. exit(EX_SOFTWARE);
  168. }
  169. return (new_symbol);
  170. } else {
  171. perror("Unexpected return value from db get routine");
  172. exit(EX_SOFTWARE);
  173. /* NOTREACHED */
  174. }
  175. }
  176. memcpy(&stored_ptr, data.data, sizeof(stored_ptr));
  177. return (stored_ptr);
  178. }
  179. symbol_node_t *
  180. symlist_search(symlist_t *symlist, char *symname)
  181. {
  182. symbol_node_t *curnode;
  183. curnode = SLIST_FIRST(symlist);
  184. while(curnode != NULL) {
  185. if (strcmp(symname, curnode->symbol->name) == 0)
  186. break;
  187. curnode = SLIST_NEXT(curnode, links);
  188. }
  189. return (curnode);
  190. }
  191. void
  192. symlist_add(symlist_t *symlist, symbol_t *symbol, int how)
  193. {
  194. symbol_node_t *newnode;
  195. newnode = (symbol_node_t *)malloc(sizeof(symbol_node_t));
  196. if (newnode == NULL) {
  197. stop("symlist_add: Unable to malloc symbol_node", EX_SOFTWARE);
  198. /* NOTREACHED */
  199. }
  200. newnode->symbol = symbol;
  201. if (how == SYMLIST_SORT) {
  202. symbol_node_t *curnode;
  203. int mask;
  204. mask = FALSE;
  205. switch(symbol->type) {
  206. case REGISTER:
  207. case SCBLOC:
  208. case SRAMLOC:
  209. break;
  210. case BIT:
  211. case MASK:
  212. mask = TRUE;
  213. break;
  214. default:
  215. stop("symlist_add: Invalid symbol type for sorting",
  216.      EX_SOFTWARE);
  217. /* NOTREACHED */
  218. }
  219. curnode = SLIST_FIRST(symlist);
  220. if (curnode == NULL
  221.  || (mask && (curnode->symbol->info.minfo->mask >
  222.               newnode->symbol->info.minfo->mask))
  223.  || (!mask && (curnode->symbol->info.rinfo->address >
  224.                newnode->symbol->info.rinfo->address))) {
  225. SLIST_INSERT_HEAD(symlist, newnode, links);
  226. return;
  227. }
  228. while (1) {
  229. if (SLIST_NEXT(curnode, links) == NULL) {
  230. SLIST_INSERT_AFTER(curnode, newnode,
  231.    links);
  232. break;
  233. } else {
  234. symbol_t *cursymbol;
  235. cursymbol = SLIST_NEXT(curnode, links)->symbol;
  236. if ((mask && (cursymbol->info.minfo->mask >
  237.               symbol->info.minfo->mask))
  238.  || (!mask &&(cursymbol->info.rinfo->address >
  239.               symbol->info.rinfo->address))){
  240. SLIST_INSERT_AFTER(curnode, newnode,
  241.    links);
  242. break;
  243. }
  244. }
  245. curnode = SLIST_NEXT(curnode, links);
  246. }
  247. } else {
  248. SLIST_INSERT_HEAD(symlist, newnode, links);
  249. }
  250. }
  251. void
  252. symlist_free(symlist_t *symlist)
  253. {
  254. symbol_node_t *node1, *node2;
  255. node1 = SLIST_FIRST(symlist);
  256. while (node1 != NULL) {
  257. node2 = SLIST_NEXT(node1, links);
  258. free(node1);
  259. node1 = node2;
  260. }
  261. SLIST_INIT(symlist);
  262. }
  263. void
  264. symlist_merge(symlist_t *symlist_dest, symlist_t *symlist_src1,
  265.       symlist_t *symlist_src2)
  266. {
  267. symbol_node_t *node;
  268. *symlist_dest = *symlist_src1;
  269. while((node = SLIST_FIRST(symlist_src2)) != NULL) {
  270. SLIST_REMOVE_HEAD(symlist_src2, links);
  271. SLIST_INSERT_HEAD(symlist_dest, node, links);
  272. }
  273. /* These are now empty */
  274. SLIST_INIT(symlist_src1);
  275. SLIST_INIT(symlist_src2);
  276. }
  277. void
  278. symtable_dump(FILE *ofile)
  279. {
  280. /*
  281.  * Sort the registers by address with a simple insertion sort.
  282.  * Put bitmasks next to the first register that defines them.
  283.  * Put constants at the end.
  284.  */
  285. symlist_t registers;
  286. symlist_t masks;
  287. symlist_t constants;
  288. symlist_t download_constants;
  289. symlist_t aliases;
  290. SLIST_INIT(&registers);
  291. SLIST_INIT(&masks);
  292. SLIST_INIT(&constants);
  293. SLIST_INIT(&download_constants);
  294. SLIST_INIT(&aliases);
  295. if (symtable != NULL) {
  296. DBT  key;
  297. DBT  data;
  298. int  flag = R_FIRST;
  299. while (symtable->seq(symtable, &key, &data, flag) == 0) {
  300. symbol_t *cursym;
  301. memcpy(&cursym, data.data, sizeof(cursym));
  302. switch(cursym->type) {
  303. case REGISTER:
  304. case SCBLOC:
  305. case SRAMLOC:
  306. symlist_add(&registers, cursym, SYMLIST_SORT);
  307. break;
  308. case MASK:
  309. case BIT:
  310. symlist_add(&masks, cursym, SYMLIST_SORT);
  311. break;
  312. case CONST:
  313. if (cursym->info.cinfo->define == FALSE) {
  314. symlist_add(&constants, cursym,
  315.     SYMLIST_INSERT_HEAD);
  316. }
  317. break;
  318. case DOWNLOAD_CONST:
  319. symlist_add(&download_constants, cursym,
  320.     SYMLIST_INSERT_HEAD);
  321. break;
  322. case ALIAS:
  323. symlist_add(&aliases, cursym,
  324.     SYMLIST_INSERT_HEAD);
  325. break;
  326. default:
  327. break;
  328. }
  329. flag = R_NEXT;
  330. }
  331. /* Put in the masks and bits */
  332. while (SLIST_FIRST(&masks) != NULL) {
  333. symbol_node_t *curnode;
  334. symbol_node_t *regnode;
  335. char *regname;
  336. curnode = SLIST_FIRST(&masks);
  337. SLIST_REMOVE_HEAD(&masks, links);
  338. regnode =
  339.     SLIST_FIRST(&curnode->symbol->info.minfo->symrefs);
  340. regname = regnode->symbol->name;
  341. regnode = symlist_search(&registers, regname);
  342. SLIST_INSERT_AFTER(regnode, curnode, links);
  343. }
  344. /* Add the aliases */
  345. while (SLIST_FIRST(&aliases) != NULL) {
  346. symbol_node_t *curnode;
  347. symbol_node_t *regnode;
  348. char *regname;
  349. curnode = SLIST_FIRST(&aliases);
  350. SLIST_REMOVE_HEAD(&aliases, links);
  351. regname = curnode->symbol->info.ainfo->parent->name;
  352. regnode = symlist_search(&registers, regname);
  353. SLIST_INSERT_AFTER(regnode, curnode, links);
  354. }
  355. /* Output what we have */
  356. fprintf(ofile,
  357. "/*
  358.  * DO NOT EDIT - This file is automatically generated
  359.  *  from the following source files:
  360.  *
  361. %s */n", versions);
  362. while (SLIST_FIRST(&registers) != NULL) {
  363. symbol_node_t *curnode;
  364. u_int8_t value;
  365. char *tab_str;
  366. char *tab_str2;
  367. curnode = SLIST_FIRST(&registers);
  368. SLIST_REMOVE_HEAD(&registers, links);
  369. switch(curnode->symbol->type) {
  370. case REGISTER:
  371. case SCBLOC:
  372. case SRAMLOC:
  373. fprintf(ofile, "n");
  374. value = curnode->symbol->info.rinfo->address;
  375. tab_str = "t";
  376. tab_str2 = "tt";
  377. break;
  378. case ALIAS:
  379. {
  380. symbol_t *parent;
  381. parent = curnode->symbol->info.ainfo->parent;
  382. value = parent->info.rinfo->address;
  383. tab_str = "t";
  384. tab_str2 = "tt";
  385. break;
  386. }
  387. case MASK:
  388. case BIT:
  389. value = curnode->symbol->info.minfo->mask;
  390. tab_str = "tt";
  391. tab_str2 = "t";
  392. break;
  393. default:
  394. value = 0; /* Quiet compiler */
  395. tab_str = NULL;
  396. tab_str2 = NULL;
  397. stop("symtable_dump: Invalid symbol type "
  398.      "encountered", EX_SOFTWARE);
  399. break;
  400. }
  401. fprintf(ofile, "#define%s%-16s%s0x%02xn",
  402. tab_str, curnode->symbol->name, tab_str2,
  403. value);
  404. free(curnode);
  405. }
  406. fprintf(ofile, "nn");
  407. while (SLIST_FIRST(&constants) != NULL) {
  408. symbol_node_t *curnode;
  409. curnode = SLIST_FIRST(&constants);
  410. SLIST_REMOVE_HEAD(&constants, links);
  411. fprintf(ofile, "#definet%-8st0x%02xn",
  412. curnode->symbol->name,
  413. curnode->symbol->info.cinfo->value);
  414. free(curnode);
  415. }
  416. fprintf(ofile, "nn/* Downloaded Constant Definitions */n");
  417. while (SLIST_FIRST(&download_constants) != NULL) {
  418. symbol_node_t *curnode;
  419. curnode = SLIST_FIRST(&download_constants);
  420. SLIST_REMOVE_HEAD(&download_constants, links);
  421. fprintf(ofile, "#definet%-8st0x%02xn",
  422. curnode->symbol->name,
  423. curnode->symbol->info.cinfo->value);
  424. free(curnode);
  425. }
  426. }
  427. }