aicasm_symbol.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:12k
源码类别:

Linux/Unix编程

开发平台:

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#13 $
  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 <regex.h>
  51. #include <stdio.h>
  52. #include <stdlib.h>
  53. #include <string.h>
  54. #include <sysexits.h>
  55. #include "aicasm_symbol.h"
  56. #include "aicasm.h"
  57. static DB *symtable;
  58. symbol_t *
  59. symbol_create(char *name)
  60. {
  61. symbol_t *new_symbol;
  62. new_symbol = (symbol_t *)malloc(sizeof(symbol_t));
  63. if (new_symbol == NULL) {
  64. perror("Unable to create new symbol");
  65. exit(EX_SOFTWARE);
  66. }
  67. memset(new_symbol, 0, sizeof(*new_symbol));
  68. new_symbol->name = strdup(name);
  69. new_symbol->type = UNINITIALIZED;
  70. return (new_symbol);
  71. }
  72. void
  73. symbol_delete(symbol_t *symbol)
  74. {
  75. if (symtable != NULL) {
  76. DBT  key;
  77. key.data = symbol->name;
  78. key.size = strlen(symbol->name);
  79. symtable->del(symtable, &key, /*flags*/0);
  80. }
  81. switch(symbol->type) {
  82. case SCBLOC:
  83. case SRAMLOC:
  84. case REGISTER:
  85. if (symbol->info.rinfo != NULL)
  86. free(symbol->info.rinfo);
  87. break;
  88. case ALIAS:
  89. if (symbol->info.ainfo != NULL)
  90. free(symbol->info.ainfo);
  91. break;
  92. case MASK:
  93. case BIT:
  94. if (symbol->info.minfo != NULL) {
  95. symlist_free(&symbol->info.minfo->symrefs);
  96. free(symbol->info.minfo);
  97. }
  98. break;
  99. case DOWNLOAD_CONST:
  100. case CONST:
  101. if (symbol->info.cinfo != NULL)
  102. free(symbol->info.cinfo);
  103. break;
  104. case LABEL:
  105. if (symbol->info.linfo != NULL)
  106. free(symbol->info.linfo);
  107. break;
  108. case UNINITIALIZED:
  109. default:
  110. break;
  111. }
  112. free(symbol->name);
  113. free(symbol);
  114. }
  115. void
  116. symtable_open()
  117. {
  118. symtable = dbopen(/*filename*/NULL,
  119.   O_CREAT | O_NONBLOCK | O_RDWR, /*mode*/0, DB_HASH,
  120.   /*openinfo*/NULL);
  121. if (symtable == NULL) {
  122. perror("Symbol table creation failed");
  123. exit(EX_SOFTWARE);
  124. /* NOTREACHED */
  125. }
  126. }
  127. void
  128. symtable_close()
  129. {
  130. if (symtable != NULL) {
  131. DBT  key;
  132. DBT  data;
  133. while (symtable->seq(symtable, &key, &data, R_FIRST) == 0) {
  134. symbol_t *stored_ptr;
  135. memcpy(&stored_ptr, data.data, sizeof(stored_ptr));
  136. symbol_delete(stored_ptr);
  137. }
  138. symtable->close(symtable);
  139. }
  140. }
  141. /*
  142.  * The semantics of get is to return an uninitialized symbol entry
  143.  * if a lookup fails.
  144.  */
  145. symbol_t *
  146. symtable_get(char *name)
  147. {
  148. symbol_t *stored_ptr;
  149. DBT   key;
  150. DBT   data;
  151. int   retval;
  152. key.data = (void *)name;
  153. key.size = strlen(name);
  154. if ((retval = symtable->get(symtable, &key, &data, /*flags*/0)) != 0) {
  155. if (retval == -1) {
  156. perror("Symbol table get operation failed");
  157. exit(EX_SOFTWARE);
  158. /* NOTREACHED */
  159. } else if (retval == 1) {
  160. /* Symbol wasn't found, so create a new one */
  161. symbol_t *new_symbol;
  162. new_symbol = symbol_create(name);
  163. data.data = &new_symbol;
  164. data.size = sizeof(new_symbol);
  165. if (symtable->put(symtable, &key, &data,
  166.   /*flags*/0) !=0) {
  167. perror("Symtable put failed");
  168. exit(EX_SOFTWARE);
  169. }
  170. return (new_symbol);
  171. } else {
  172. perror("Unexpected return value from db get routine");
  173. exit(EX_SOFTWARE);
  174. /* NOTREACHED */
  175. }
  176. }
  177. memcpy(&stored_ptr, data.data, sizeof(stored_ptr));
  178. return (stored_ptr);
  179. }
  180. symbol_node_t *
  181. symlist_search(symlist_t *symlist, char *symname)
  182. {
  183. symbol_node_t *curnode;
  184. curnode = SLIST_FIRST(symlist);
  185. while(curnode != NULL) {
  186. if (strcmp(symname, curnode->symbol->name) == 0)
  187. break;
  188. curnode = SLIST_NEXT(curnode, links);
  189. }
  190. return (curnode);
  191. }
  192. void
  193. symlist_add(symlist_t *symlist, symbol_t *symbol, int how)
  194. {
  195. symbol_node_t *newnode;
  196. newnode = (symbol_node_t *)malloc(sizeof(symbol_node_t));
  197. if (newnode == NULL) {
  198. stop("symlist_add: Unable to malloc symbol_node", EX_SOFTWARE);
  199. /* NOTREACHED */
  200. }
  201. newnode->symbol = symbol;
  202. if (how == SYMLIST_SORT) {
  203. symbol_node_t *curnode;
  204. int mask;
  205. mask = FALSE;
  206. switch(symbol->type) {
  207. case REGISTER:
  208. case SCBLOC:
  209. case SRAMLOC:
  210. break;
  211. case BIT:
  212. case MASK:
  213. mask = TRUE;
  214. break;
  215. default:
  216. stop("symlist_add: Invalid symbol type for sorting",
  217.      EX_SOFTWARE);
  218. /* NOTREACHED */
  219. }
  220. curnode = SLIST_FIRST(symlist);
  221. if (curnode == NULL
  222.  || (mask && (curnode->symbol->info.minfo->mask >
  223.               newnode->symbol->info.minfo->mask))
  224.  || (!mask && (curnode->symbol->info.rinfo->address >
  225.                newnode->symbol->info.rinfo->address))) {
  226. SLIST_INSERT_HEAD(symlist, newnode, links);
  227. return;
  228. }
  229. while (1) {
  230. if (SLIST_NEXT(curnode, links) == NULL) {
  231. SLIST_INSERT_AFTER(curnode, newnode,
  232.    links);
  233. break;
  234. } else {
  235. symbol_t *cursymbol;
  236. cursymbol = SLIST_NEXT(curnode, links)->symbol;
  237. if ((mask && (cursymbol->info.minfo->mask >
  238.               symbol->info.minfo->mask))
  239.  || (!mask &&(cursymbol->info.rinfo->address >
  240.               symbol->info.rinfo->address))){
  241. SLIST_INSERT_AFTER(curnode, newnode,
  242.    links);
  243. break;
  244. }
  245. }
  246. curnode = SLIST_NEXT(curnode, links);
  247. }
  248. } else {
  249. SLIST_INSERT_HEAD(symlist, newnode, links);
  250. }
  251. }
  252. void
  253. symlist_free(symlist_t *symlist)
  254. {
  255. symbol_node_t *node1, *node2;
  256. node1 = SLIST_FIRST(symlist);
  257. while (node1 != NULL) {
  258. node2 = SLIST_NEXT(node1, links);
  259. free(node1);
  260. node1 = node2;
  261. }
  262. SLIST_INIT(symlist);
  263. }
  264. void
  265. symlist_merge(symlist_t *symlist_dest, symlist_t *symlist_src1,
  266.       symlist_t *symlist_src2)
  267. {
  268. symbol_node_t *node;
  269. *symlist_dest = *symlist_src1;
  270. while((node = SLIST_FIRST(symlist_src2)) != NULL) {
  271. SLIST_REMOVE_HEAD(symlist_src2, links);
  272. SLIST_INSERT_HEAD(symlist_dest, node, links);
  273. }
  274. /* These are now empty */
  275. SLIST_INIT(symlist_src1);
  276. SLIST_INIT(symlist_src2);
  277. }
  278. void
  279. symtable_dump(FILE *ofile)
  280. {
  281. /*
  282.  * Sort the registers by address with a simple insertion sort.
  283.  * Put bitmasks next to the first register that defines them.
  284.  * Put constants at the end.
  285.  */
  286. symlist_t registers;
  287. symlist_t masks;
  288. symlist_t constants;
  289. symlist_t download_constants;
  290. symlist_t aliases;
  291. symlist_t exported_labels;
  292. u_int   i;
  293. SLIST_INIT(&registers);
  294. SLIST_INIT(&masks);
  295. SLIST_INIT(&constants);
  296. SLIST_INIT(&download_constants);
  297. SLIST_INIT(&aliases);
  298. SLIST_INIT(&exported_labels);
  299. if (symtable != NULL) {
  300. DBT  key;
  301. DBT  data;
  302. int  flag = R_FIRST;
  303. while (symtable->seq(symtable, &key, &data, flag) == 0) {
  304. symbol_t *cursym;
  305. memcpy(&cursym, data.data, sizeof(cursym));
  306. switch(cursym->type) {
  307. case REGISTER:
  308. case SCBLOC:
  309. case SRAMLOC:
  310. symlist_add(&registers, cursym, SYMLIST_SORT);
  311. break;
  312. case MASK:
  313. case BIT:
  314. symlist_add(&masks, cursym, SYMLIST_SORT);
  315. break;
  316. case CONST:
  317. symlist_add(&constants, cursym,
  318.     SYMLIST_INSERT_HEAD);
  319. break;
  320. case DOWNLOAD_CONST:
  321. symlist_add(&download_constants, cursym,
  322.     SYMLIST_INSERT_HEAD);
  323. break;
  324. case ALIAS:
  325. symlist_add(&aliases, cursym,
  326.     SYMLIST_INSERT_HEAD);
  327. break;
  328. case LABEL:
  329. if (cursym->info.linfo->exported == 0)
  330. break;
  331. symlist_add(&exported_labels, cursym,
  332.     SYMLIST_INSERT_HEAD);
  333. break;
  334. default:
  335. break;
  336. }
  337. flag = R_NEXT;
  338. }
  339. /* Put in the masks and bits */
  340. while (SLIST_FIRST(&masks) != NULL) {
  341. symbol_node_t *curnode;
  342. symbol_node_t *regnode;
  343. char *regname;
  344. curnode = SLIST_FIRST(&masks);
  345. SLIST_REMOVE_HEAD(&masks, links);
  346. regnode =
  347.     SLIST_FIRST(&curnode->symbol->info.minfo->symrefs);
  348. regname = regnode->symbol->name;
  349. regnode = symlist_search(&registers, regname);
  350. SLIST_INSERT_AFTER(regnode, curnode, links);
  351. }
  352. /* Add the aliases */
  353. while (SLIST_FIRST(&aliases) != NULL) {
  354. symbol_node_t *curnode;
  355. symbol_node_t *regnode;
  356. char *regname;
  357. curnode = SLIST_FIRST(&aliases);
  358. SLIST_REMOVE_HEAD(&aliases, links);
  359. regname = curnode->symbol->info.ainfo->parent->name;
  360. regnode = symlist_search(&registers, regname);
  361. SLIST_INSERT_AFTER(regnode, curnode, links);
  362. }
  363. /* Output what we have */
  364. fprintf(ofile,
  365. "/*
  366.  * DO NOT EDIT - This file is automatically generated
  367.  *  from the following source files:
  368.  *
  369. %s */n", versions);
  370. while (SLIST_FIRST(&registers) != NULL) {
  371. symbol_node_t *curnode;
  372. u_int value;
  373. char *tab_str;
  374. char *tab_str2;
  375. curnode = SLIST_FIRST(&registers);
  376. SLIST_REMOVE_HEAD(&registers, links);
  377. switch(curnode->symbol->type) {
  378. case REGISTER:
  379. case SCBLOC:
  380. case SRAMLOC:
  381. fprintf(ofile, "n");
  382. value = curnode->symbol->info.rinfo->address;
  383. tab_str = "t";
  384. tab_str2 = "tt";
  385. break;
  386. case ALIAS:
  387. {
  388. symbol_t *parent;
  389. parent = curnode->symbol->info.ainfo->parent;
  390. value = parent->info.rinfo->address;
  391. tab_str = "t";
  392. tab_str2 = "tt";
  393. break;
  394. }
  395. case MASK:
  396. case BIT:
  397. value = curnode->symbol->info.minfo->mask;
  398. tab_str = "tt";
  399. tab_str2 = "t";
  400. break;
  401. default:
  402. value = 0; /* Quiet compiler */
  403. tab_str = NULL;
  404. tab_str2 = NULL;
  405. stop("symtable_dump: Invalid symbol type "
  406.      "encountered", EX_SOFTWARE);
  407. break;
  408. }
  409. fprintf(ofile, "#define%s%-16s%s0x%02xn",
  410. tab_str, curnode->symbol->name, tab_str2,
  411. value);
  412. free(curnode);
  413. }
  414. fprintf(ofile, "nn");
  415. while (SLIST_FIRST(&constants) != NULL) {
  416. symbol_node_t *curnode;
  417. curnode = SLIST_FIRST(&constants);
  418. SLIST_REMOVE_HEAD(&constants, links);
  419. fprintf(ofile, "#definet%-8st0x%02xn",
  420. curnode->symbol->name,
  421. curnode->symbol->info.cinfo->value);
  422. free(curnode);
  423. }
  424. fprintf(ofile, "nn/* Downloaded Constant Definitions */n");
  425. for (i = 0; SLIST_FIRST(&download_constants) != NULL; i++) {
  426. symbol_node_t *curnode;
  427. curnode = SLIST_FIRST(&download_constants);
  428. SLIST_REMOVE_HEAD(&download_constants, links);
  429. fprintf(ofile, "#definet%-8st0x%02xn",
  430. curnode->symbol->name,
  431. curnode->symbol->info.cinfo->value);
  432. free(curnode);
  433. }
  434. fprintf(ofile, "#definetDOWNLOAD_CONST_COUNTt0x%02xn", i);
  435. fprintf(ofile, "nn/* Exported Labels */n");
  436. while (SLIST_FIRST(&exported_labels) != NULL) {
  437. symbol_node_t *curnode;
  438. curnode = SLIST_FIRST(&exported_labels);
  439. SLIST_REMOVE_HEAD(&exported_labels, links);
  440. fprintf(ofile, "#definetLABEL_%-8st0x%02xn",
  441. curnode->symbol->name,
  442. curnode->symbol->info.linfo->address);
  443. free(curnode);
  444. }
  445. }
  446. }