symrec.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. /*
  2. * Symbol table handling
  3. *
  4. * Copyright (C) 2001-2007 Michael Urman, Peter Johnson
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
  19. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  20. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  21. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  22. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  23. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  24. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  25. * POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #include "util.h"
  28. #include <limits.h>
  29. #include <ctype.h>
  30. #include "libyasm-stdint.h"
  31. #include "coretype.h"
  32. #include "valparam.h"
  33. #include "hamt.h"
  34. #include "assocdat.h"
  35. #include "errwarn.h"
  36. #include "intnum.h"
  37. #include "floatnum.h"
  38. #include "expr.h"
  39. #include "symrec.h"
  40. #include "bytecode.h"
  41. #include "section.h"
  42. #include "objfmt.h"
  43. typedef enum {
  44. SYM_UNKNOWN, /* for unknown type (COMMON/EXTERN) */
  45. SYM_EQU, /* for EQU defined symbols (expressions) */
  46. SYM_LABEL, /* for labels */
  47. SYM_CURPOS, /* for labels representing the current
  48. assembly position */
  49. SYM_SPECIAL /* for special symbols that need to be in
  50. the symbol table but otherwise have no
  51. purpose */
  52. } sym_type;
  53. struct yasm_symrec {
  54. char *name;
  55. sym_type type;
  56. yasm_sym_status status;
  57. yasm_sym_vis visibility;
  58. unsigned long def_line; /* line where symbol was first defined */
  59. unsigned long decl_line; /* line where symbol was first declared */
  60. unsigned long use_line; /* line where symbol was first used */
  61. union {
  62. yasm_expr *expn; /* equ value */
  63. /* bytecode immediately preceding a label */
  64. /*@dependent@*/ yasm_bytecode *precbc;
  65. } value;
  66. unsigned int size; /* 0 if not user-defined */
  67. const char *segment; /* for segmented systems like DOS */
  68. /* associated data; NULL if none */
  69. /*@null@*/ /*@only@*/ yasm__assoc_data *assoc_data;
  70. };
  71. /* Linked list of symbols not in the symbol table. */
  72. typedef struct non_table_symrec_s {
  73. /*@reldef@*/ SLIST_ENTRY(non_table_symrec_s) link;
  74. /*@owned@*/ yasm_symrec *rec;
  75. } non_table_symrec;
  76. struct yasm_symtab {
  77. /* The symbol table: a hash array mapped trie (HAMT). */
  78. /*@only@*/ HAMT *sym_table;
  79. /* Symbols not in the table */
  80. SLIST_HEAD(nontablesymhead_s, non_table_symrec_s) non_table_syms;
  81. int case_sensitive;
  82. };
  83. static void
  84. objext_valparams_destroy(void *data)
  85. {
  86. yasm_vps_destroy((yasm_valparamhead *)data);
  87. }
  88. static void
  89. objext_valparams_print(void *data, FILE *f, int indent_level)
  90. {
  91. yasm_vps_print((yasm_valparamhead *)data, f);
  92. }
  93. static yasm_assoc_data_callback objext_valparams_cb = {
  94. objext_valparams_destroy,
  95. objext_valparams_print
  96. };
  97. static void
  98. common_size_destroy(void *data)
  99. {
  100. yasm_expr **e = (yasm_expr **)data;
  101. yasm_expr_destroy(*e);
  102. yasm_xfree(data);
  103. }
  104. static void
  105. common_size_print(void *data, FILE *f, int indent_level)
  106. {
  107. yasm_expr **e = (yasm_expr **)data;
  108. yasm_expr_print(*e, f);
  109. }
  110. static yasm_assoc_data_callback common_size_cb = {
  111. common_size_destroy,
  112. common_size_print
  113. };
  114. yasm_symtab *
  115. yasm_symtab_create(void)
  116. {
  117. yasm_symtab *symtab = yasm_xmalloc(sizeof(yasm_symtab));
  118. symtab->sym_table = HAMT_create(0, yasm_internal_error_);
  119. SLIST_INIT(&symtab->non_table_syms);
  120. symtab->case_sensitive = 1;
  121. return symtab;
  122. }
  123. void
  124. yasm_symtab_set_case_sensitive(yasm_symtab *symtab, int sensitive)
  125. {
  126. symtab->case_sensitive = sensitive;
  127. }
  128. static void
  129. symrec_destroy_one(/*@only@*/ void *d)
  130. {
  131. yasm_symrec *sym = d;
  132. yasm_xfree(sym->name);
  133. if (sym->type == SYM_EQU && (sym->status & YASM_SYM_VALUED))
  134. yasm_expr_destroy(sym->value.expn);
  135. yasm__assoc_data_destroy(sym->assoc_data);
  136. yasm_xfree(sym);
  137. }
  138. static /*@partial@*/ yasm_symrec *
  139. symrec_new_common(/*@keep@*/ char *name, int case_sensitive)
  140. {
  141. yasm_symrec *rec = yasm_xmalloc(sizeof(yasm_symrec));
  142. if (!case_sensitive) {
  143. char *c;
  144. for (c=name; *c; c++)
  145. *c = tolower(*c);
  146. }
  147. rec->name = name;
  148. rec->type = SYM_UNKNOWN;
  149. rec->def_line = 0;
  150. rec->decl_line = 0;
  151. rec->use_line = 0;
  152. rec->visibility = YASM_SYM_LOCAL;
  153. rec->size = 0;
  154. rec->segment = NULL;
  155. rec->assoc_data = NULL;
  156. return rec;
  157. }
  158. static /*@partial@*/ /*@dependent@*/ yasm_symrec *
  159. symtab_get_or_new_in_table(yasm_symtab *symtab, /*@only@*/ char *name)
  160. {
  161. yasm_symrec *rec = symrec_new_common(name, symtab->case_sensitive);
  162. int replace = 0;
  163. rec->status = YASM_SYM_NOSTATUS;
  164. if (!symtab->case_sensitive) {
  165. char *c;
  166. for (c=name; *c; c++)
  167. *c = tolower(*c);
  168. }
  169. return HAMT_insert(symtab->sym_table, name, rec, &replace,
  170. symrec_destroy_one);
  171. }
  172. static /*@partial@*/ /*@dependent@*/ yasm_symrec *
  173. symtab_get_or_new_not_in_table(yasm_symtab *symtab, /*@only@*/ char *name)
  174. {
  175. non_table_symrec *sym = yasm_xmalloc(sizeof(non_table_symrec));
  176. sym->rec = symrec_new_common(name, symtab->case_sensitive);
  177. sym->rec->status = YASM_SYM_NOTINTABLE;
  178. SLIST_INSERT_HEAD(&symtab->non_table_syms, sym, link);
  179. return sym->rec;
  180. }
  181. /* create a new symrec */
  182. /*@-freshtrans -mustfree@*/
  183. static /*@partial@*/ /*@dependent@*/ yasm_symrec *
  184. symtab_get_or_new(yasm_symtab *symtab, const char *name, int in_table)
  185. {
  186. char *symname = yasm__xstrdup(name);
  187. if (in_table)
  188. return symtab_get_or_new_in_table(symtab, symname);
  189. else
  190. return symtab_get_or_new_not_in_table(symtab, symname);
  191. }
  192. /*@=freshtrans =mustfree@*/
  193. int
  194. yasm_symtab_traverse(yasm_symtab *symtab, void *d,
  195. int (*func) (yasm_symrec *sym, void *d))
  196. {
  197. return HAMT_traverse(symtab->sym_table, d, (int (*) (void *, void *))func);
  198. }
  199. const yasm_symtab_iter *
  200. yasm_symtab_first(const yasm_symtab *symtab)
  201. {
  202. return (const yasm_symtab_iter *)HAMT_first(symtab->sym_table);
  203. }
  204. /*@null@*/ const yasm_symtab_iter *
  205. yasm_symtab_next(const yasm_symtab_iter *prev)
  206. {
  207. return (const yasm_symtab_iter *)HAMT_next((const HAMTEntry *)prev);
  208. }
  209. yasm_symrec *
  210. yasm_symtab_iter_value(const yasm_symtab_iter *cur)
  211. {
  212. return (yasm_symrec *)HAMTEntry_get_data((const HAMTEntry *)cur);
  213. }
  214. yasm_symrec *
  215. yasm_symtab_abs_sym(yasm_symtab *symtab)
  216. {
  217. yasm_symrec *rec = symtab_get_or_new(symtab, "", 1);
  218. rec->def_line = 0;
  219. rec->decl_line = 0;
  220. rec->use_line = 0;
  221. rec->type = SYM_EQU;
  222. rec->value.expn =
  223. yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(0)), 0);
  224. rec->status |= YASM_SYM_DEFINED|YASM_SYM_VALUED|YASM_SYM_USED;
  225. return rec;
  226. }
  227. yasm_symrec *
  228. yasm_symtab_use(yasm_symtab *symtab, const char *name, unsigned long line)
  229. {
  230. yasm_symrec *rec = symtab_get_or_new(symtab, name, 1);
  231. if (rec->use_line == 0)
  232. rec->use_line = line; /* set line number of first use */
  233. rec->status |= YASM_SYM_USED;
  234. return rec;
  235. }
  236. yasm_symrec *
  237. yasm_symtab_get(yasm_symtab *symtab, const char *name)
  238. {
  239. if (!symtab->case_sensitive) {
  240. char *_name = yasm__xstrdup(name);
  241. char *c;
  242. yasm_symrec *ret;
  243. for (c=_name; *c; c++)
  244. *c = tolower(*c);
  245. ret = HAMT_search(symtab->sym_table, _name);
  246. yasm_xfree(_name);
  247. return ret;
  248. } else
  249. return HAMT_search(symtab->sym_table, name);
  250. }
  251. static /*@dependent@*/ yasm_symrec *
  252. symtab_define(yasm_symtab *symtab, const char *name, sym_type type,
  253. int in_table, unsigned long line)
  254. {
  255. yasm_symrec *rec = symtab_get_or_new(symtab, name, in_table);
  256. /* Has it been defined before (either by DEFINED or COMMON/EXTERN)? */
  257. if (rec->status & YASM_SYM_DEFINED) {
  258. yasm_error_set_xref(rec->def_line!=0 ? rec->def_line : rec->decl_line,
  259. N_("`%s' previously defined here"), name);
  260. yasm_error_set(YASM_ERROR_GENERAL, N_("redefinition of `%s'"),
  261. name);
  262. } else {
  263. if (rec->visibility & YASM_SYM_EXTERN)
  264. yasm_warn_set(YASM_WARN_GENERAL,
  265. N_("`%s' both defined and declared extern"), name);
  266. rec->def_line = line; /* set line number of definition */
  267. rec->type = type;
  268. rec->status |= YASM_SYM_DEFINED;
  269. rec->size = 0;
  270. rec->segment = NULL;
  271. }
  272. return rec;
  273. }
  274. yasm_symrec *
  275. yasm_symtab_define_equ(yasm_symtab *symtab, const char *name, yasm_expr *e,
  276. unsigned long line)
  277. {
  278. yasm_symrec *rec = symtab_define(symtab, name, SYM_EQU, 1, line);
  279. if (yasm_error_occurred())
  280. return rec;
  281. rec->value.expn = e;
  282. rec->status |= YASM_SYM_VALUED;
  283. return rec;
  284. }
  285. yasm_symrec *
  286. yasm_symtab_define_label(yasm_symtab *symtab, const char *name,
  287. yasm_bytecode *precbc, int in_table,
  288. unsigned long line)
  289. {
  290. yasm_symrec *rec = symtab_define(symtab, name, SYM_LABEL, in_table, line);
  291. if (yasm_error_occurred())
  292. return rec;
  293. rec->value.precbc = precbc;
  294. if (in_table && precbc)
  295. yasm_bc__add_symrec(precbc, rec);
  296. return rec;
  297. }
  298. yasm_symrec *
  299. yasm_symtab_define_curpos(yasm_symtab *symtab, const char *name,
  300. yasm_bytecode *precbc, unsigned long line)
  301. {
  302. yasm_symrec *rec = symtab_define(symtab, name, SYM_CURPOS, 0, line);
  303. if (yasm_error_occurred())
  304. return rec;
  305. rec->value.precbc = precbc;
  306. return rec;
  307. }
  308. yasm_symrec *
  309. yasm_symtab_define_special(yasm_symtab *symtab, const char *name,
  310. yasm_sym_vis vis)
  311. {
  312. yasm_symrec *rec = symtab_define(symtab, name, SYM_SPECIAL, 1, 0);
  313. if (yasm_error_occurred())
  314. return rec;
  315. rec->status |= YASM_SYM_VALUED;
  316. rec->visibility = vis;
  317. return rec;
  318. }
  319. yasm_symrec *
  320. yasm_symtab_declare(yasm_symtab *symtab, const char *name, yasm_sym_vis vis,
  321. unsigned long line)
  322. {
  323. yasm_symrec *rec = symtab_get_or_new(symtab, name, 1);
  324. yasm_symrec_declare(rec, vis, line);
  325. return rec;
  326. }
  327. void
  328. yasm_symrec_declare(yasm_symrec *rec, yasm_sym_vis vis, unsigned long line)
  329. {
  330. /* Allowable combinations:
  331. * Existing State-------------- vis New State-------------------
  332. * DEFINED GLOBAL COMMON EXTERN GCE DEFINED GLOBAL COMMON EXTERN
  333. * 0 - 0 0 GCE 0 G C E
  334. * 0 - 0 1 GE 0 G 0 E
  335. * 0 - 1 0 GC 0 G C 0
  336. * X 0 - 1 1
  337. * 1 - 0 0 G 1 G 0 0
  338. * X 1 - - 1
  339. * X 1 - 1 -
  340. */
  341. if ((vis == YASM_SYM_GLOBAL) ||
  342. (!(rec->status & YASM_SYM_DEFINED) &&
  343. (!(rec->visibility & (YASM_SYM_COMMON | YASM_SYM_EXTERN)) ||
  344. ((rec->visibility & YASM_SYM_COMMON) && (vis == YASM_SYM_COMMON)) ||
  345. ((rec->visibility & YASM_SYM_EXTERN) && (vis == YASM_SYM_EXTERN))))) {
  346. rec->decl_line = line;
  347. rec->visibility |= vis;
  348. } else
  349. yasm_error_set(YASM_ERROR_GENERAL,
  350. N_("duplicate definition of `%s'; first defined on line %lu"),
  351. rec->name, rec->def_line!=0 ? rec->def_line : rec->decl_line);
  352. }
  353. typedef struct symtab_finalize_info {
  354. unsigned long firstundef_line;
  355. int undef_extern;
  356. yasm_errwarns *errwarns;
  357. } symtab_finalize_info;
  358. static int
  359. symtab_parser_finalize_checksym(yasm_symrec *sym, /*@null@*/ void *d)
  360. {
  361. symtab_finalize_info *info = (symtab_finalize_info *)d;
  362. /* error if a symbol is used but never defined or extern/common declared */
  363. if ((sym->status & YASM_SYM_USED) && !(sym->status & YASM_SYM_DEFINED) &&
  364. !(sym->visibility & (YASM_SYM_EXTERN | YASM_SYM_COMMON))) {
  365. if (info->undef_extern)
  366. sym->visibility |= YASM_SYM_EXTERN;
  367. else {
  368. yasm_error_set(YASM_ERROR_GENERAL,
  369. N_("undefined symbol `%s' (first use)"), sym->name);
  370. yasm_errwarn_propagate(info->errwarns, sym->use_line);
  371. if (sym->use_line < info->firstundef_line)
  372. info->firstundef_line = sym->use_line;
  373. }
  374. }
  375. return 0;
  376. }
  377. void
  378. yasm_symtab_parser_finalize(yasm_symtab *symtab, int undef_extern,
  379. yasm_errwarns *errwarns)
  380. {
  381. symtab_finalize_info info;
  382. info.firstundef_line = ULONG_MAX;
  383. info.undef_extern = undef_extern;
  384. info.errwarns = errwarns;
  385. yasm_symtab_traverse(symtab, &info, symtab_parser_finalize_checksym);
  386. if (info.firstundef_line < ULONG_MAX) {
  387. yasm_error_set(YASM_ERROR_GENERAL,
  388. N_(" (Each undefined symbol is reported only once.)"));
  389. yasm_errwarn_propagate(errwarns, info.firstundef_line);
  390. }
  391. }
  392. void
  393. yasm_symtab_destroy(yasm_symtab *symtab)
  394. {
  395. HAMT_destroy(symtab->sym_table, symrec_destroy_one);
  396. while (!SLIST_EMPTY(&symtab->non_table_syms)) {
  397. non_table_symrec *sym = SLIST_FIRST(&symtab->non_table_syms);
  398. SLIST_REMOVE_HEAD(&symtab->non_table_syms, link);
  399. symrec_destroy_one(sym->rec);
  400. yasm_xfree(sym);
  401. }
  402. yasm_xfree(symtab);
  403. }
  404. typedef struct symrec_print_data {
  405. FILE *f;
  406. int indent_level;
  407. } symrec_print_data;
  408. /*@+voidabstract@*/
  409. static int
  410. symrec_print_wrapper(yasm_symrec *sym, /*@null@*/ void *d)
  411. {
  412. symrec_print_data *data = (symrec_print_data *)d;
  413. assert(data != NULL);
  414. fprintf(data->f, "%*sSymbol `%s'\n", data->indent_level, "", sym->name);
  415. yasm_symrec_print(sym, data->f, data->indent_level+1);
  416. return 0;
  417. }
  418. void
  419. yasm_symtab_print(yasm_symtab *symtab, FILE *f, int indent_level)
  420. {
  421. symrec_print_data data;
  422. data.f = f;
  423. data.indent_level = indent_level;
  424. yasm_symtab_traverse(symtab, &data, symrec_print_wrapper);
  425. }
  426. /*@=voidabstract@*/
  427. const char *
  428. yasm_symrec_get_name(const yasm_symrec *sym)
  429. {
  430. return sym->name;
  431. }
  432. char *
  433. yasm_symrec_get_global_name(const yasm_symrec *sym, const yasm_object *object)
  434. {
  435. if (sym->visibility & (YASM_SYM_GLOBAL|YASM_SYM_COMMON|YASM_SYM_EXTERN)) {
  436. char *name = yasm_xmalloc(strlen(object->global_prefix) +
  437. strlen(sym->name) +
  438. strlen(object->global_suffix) + 1);
  439. strcpy(name, object->global_prefix);
  440. strcat(name, sym->name);
  441. strcat(name, object->global_suffix);
  442. return name;
  443. }
  444. return yasm__xstrdup(sym->name);
  445. }
  446. yasm_sym_vis
  447. yasm_symrec_get_visibility(const yasm_symrec *sym)
  448. {
  449. return sym->visibility;
  450. }
  451. yasm_sym_status
  452. yasm_symrec_get_status(const yasm_symrec *sym)
  453. {
  454. return sym->status;
  455. }
  456. unsigned long
  457. yasm_symrec_get_def_line(const yasm_symrec *sym)
  458. {
  459. return sym->def_line;
  460. }
  461. unsigned long
  462. yasm_symrec_get_decl_line(const yasm_symrec *sym)
  463. {
  464. return sym->decl_line;
  465. }
  466. unsigned long
  467. yasm_symrec_get_use_line(const yasm_symrec *sym)
  468. {
  469. return sym->use_line;
  470. }
  471. const yasm_expr *
  472. yasm_symrec_get_equ(const yasm_symrec *sym)
  473. {
  474. if (sym->type == SYM_EQU && (sym->status & YASM_SYM_VALUED))
  475. return sym->value.expn;
  476. return (const yasm_expr *)NULL;
  477. }
  478. int
  479. yasm_symrec_get_label(const yasm_symrec *sym,
  480. yasm_symrec_get_label_bytecodep *precbc)
  481. {
  482. if (!(sym->type == SYM_LABEL || sym->type == SYM_CURPOS)
  483. || !sym->value.precbc) {
  484. *precbc = (yasm_symrec_get_label_bytecodep)0xDEADBEEF;
  485. return 0;
  486. }
  487. *precbc = sym->value.precbc;
  488. return 1;
  489. }
  490. void
  491. yasm_symrec_set_size(yasm_symrec *sym, int size)
  492. {
  493. sym->size = size;
  494. }
  495. int
  496. yasm_symrec_get_size(const yasm_symrec *sym)
  497. {
  498. return sym->size;
  499. }
  500. void
  501. yasm_symrec_set_segment(yasm_symrec *sym, const char *segment)
  502. {
  503. sym->segment = segment;
  504. }
  505. const char *
  506. yasm_symrec_get_segment(const yasm_symrec *sym)
  507. {
  508. return sym->segment;
  509. }
  510. int
  511. yasm_symrec_is_abs(const yasm_symrec *sym)
  512. {
  513. return (sym->def_line == 0 && sym->type == SYM_EQU &&
  514. sym->name[0] == '\0');
  515. }
  516. int
  517. yasm_symrec_is_special(const yasm_symrec *sym)
  518. {
  519. return (sym->type == SYM_SPECIAL);
  520. }
  521. int
  522. yasm_symrec_is_curpos(const yasm_symrec *sym)
  523. {
  524. return (sym->type == SYM_CURPOS);
  525. }
  526. void
  527. yasm_symrec_set_objext_valparams(yasm_symrec *sym,
  528. /*@only@*/ yasm_valparamhead *objext_valparams)
  529. {
  530. yasm_symrec_add_data(sym, &objext_valparams_cb, objext_valparams);
  531. }
  532. yasm_valparamhead *
  533. yasm_symrec_get_objext_valparams(yasm_symrec *sym)
  534. {
  535. return yasm_symrec_get_data(sym, &objext_valparams_cb);
  536. }
  537. void
  538. yasm_symrec_set_common_size(yasm_symrec *sym,
  539. /*@only@*/ yasm_expr *common_size)
  540. {
  541. yasm_expr **ep = yasm_xmalloc(sizeof(yasm_expr *));
  542. *ep = common_size;
  543. yasm_symrec_add_data(sym, &common_size_cb, ep);
  544. }
  545. yasm_expr **
  546. yasm_symrec_get_common_size(yasm_symrec *sym)
  547. {
  548. return (yasm_expr **)yasm_symrec_get_data(sym, &common_size_cb);
  549. }
  550. void *
  551. yasm_symrec_get_data(yasm_symrec *sym,
  552. const yasm_assoc_data_callback *callback)
  553. {
  554. return yasm__assoc_data_get(sym->assoc_data, callback);
  555. }
  556. void
  557. yasm_symrec_add_data(yasm_symrec *sym,
  558. const yasm_assoc_data_callback *callback, void *data)
  559. {
  560. sym->assoc_data = yasm__assoc_data_add(sym->assoc_data, callback, data);
  561. }
  562. void
  563. yasm_symrec_print(const yasm_symrec *sym, FILE *f, int indent_level)
  564. {
  565. switch (sym->type) {
  566. case SYM_UNKNOWN:
  567. fprintf(f, "%*s-Unknown (Common/Extern)-\n", indent_level, "");
  568. break;
  569. case SYM_EQU:
  570. fprintf(f, "%*s_EQU_\n", indent_level, "");
  571. fprintf(f, "%*sExpn=", indent_level, "");
  572. if (sym->status & YASM_SYM_VALUED)
  573. yasm_expr_print(sym->value.expn, f);
  574. else
  575. fprintf(f, "***UNVALUED***");
  576. fprintf(f, "\n");
  577. break;
  578. case SYM_LABEL:
  579. case SYM_CURPOS:
  580. fprintf(f, "%*s_%s_\n%*sSection:\n", indent_level, "",
  581. sym->type == SYM_LABEL ? "Label" : "CurPos",
  582. indent_level, "");
  583. yasm_section_print(yasm_bc_get_section(sym->value.precbc), f,
  584. indent_level+1, 0);
  585. fprintf(f, "%*sPreceding bytecode:\n", indent_level, "");
  586. yasm_bc_print(sym->value.precbc, f, indent_level+1);
  587. break;
  588. case SYM_SPECIAL:
  589. fprintf(f, "%*s-Special-\n", indent_level, "");
  590. break;
  591. }
  592. fprintf(f, "%*sStatus=", indent_level, "");
  593. if (sym->status == YASM_SYM_NOSTATUS)
  594. fprintf(f, "None\n");
  595. else {
  596. if (sym->status & YASM_SYM_USED)
  597. fprintf(f, "Used,");
  598. if (sym->status & YASM_SYM_DEFINED)
  599. fprintf(f, "Defined,");
  600. if (sym->status & YASM_SYM_VALUED)
  601. fprintf(f, "Valued,");
  602. if (sym->status & YASM_SYM_NOTINTABLE)
  603. fprintf(f, "Not in Table,");
  604. fprintf(f, "\n");
  605. }
  606. fprintf(f, "%*sVisibility=", indent_level, "");
  607. if (sym->visibility == YASM_SYM_LOCAL)
  608. fprintf(f, "Local\n");
  609. else {
  610. if (sym->visibility & YASM_SYM_GLOBAL)
  611. fprintf(f, "Global,");
  612. if (sym->visibility & YASM_SYM_COMMON)
  613. fprintf(f, "Common,");
  614. if (sym->visibility & YASM_SYM_EXTERN)
  615. fprintf(f, "Extern,");
  616. fprintf(f, "\n");
  617. }
  618. if (sym->assoc_data) {
  619. fprintf(f, "%*sAssociated data:\n", indent_level, "");
  620. yasm__assoc_data_print(sym->assoc_data, f, indent_level+1);
  621. }
  622. fprintf(f, "%*sLine Index (Defined)=%lu\n", indent_level, "",
  623. sym->def_line);
  624. fprintf(f, "%*sLine Index (Declared)=%lu\n", indent_level, "",
  625. sym->decl_line);
  626. fprintf(f, "%*sLine Index (Used)=%lu\n", indent_level, "", sym->use_line);
  627. }