Mercurial > hg-old > index.cgi
annotate lwasm/symbol.c @ 405:7bcc50e828ff
Fixed up symbol table list to be more clear
author | lost@l-w.ca |
---|---|
date | Fri, 23 Jul 2010 18:58:20 -0600 |
parents | 027d7fbcdcfc |
children | 502fbc37ff4e |
rev | line source |
---|---|
342 | 1 /* |
2 symbol.c | |
3 | |
4 Copyright © 2010 William Astle | |
5 | |
6 This file is part of LWTOOLS. | |
7 | |
8 LWTOOLS is free software: you can redistribute it and/or modify it under the | |
9 terms of the GNU General Public License as published by the Free Software | |
10 Foundation, either version 3 of the License, or (at your option) any later | |
11 version. | |
12 | |
13 This program is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
16 more details. | |
17 | |
18 You should have received a copy of the GNU General Public License along with | |
19 this program. If not, see <http://www.gnu.org/licenses/>. | |
20 */ | |
21 | |
22 #include <config.h> | |
23 | |
390
027d7fbcdcfc
Basic symbol table output; needs work for non-constant symbols
lost@l-w.ca
parents:
389
diff
changeset
|
24 #include <stdio.h> |
342 | 25 #include <stdlib.h> |
26 #include <string.h> | |
27 | |
28 #include <lw_alloc.h> | |
29 #include <lw_expr.h> | |
370 | 30 #include <lw_string.h> |
342 | 31 |
32 #include "lwasm.h" | |
33 | |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
34 struct symtabe *register_symbol(asmstate_t *as, line_t *cl, char *sym, lw_expr_t val, int flags) |
342 | 35 { |
36 struct symtabe *se; | |
37 int islocal = 0; | |
38 int context = -1; | |
39 int version = -1; | |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
40 char *cp; |
342 | 41 |
389
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
374
diff
changeset
|
42 if (!(flags & symbol_flag_nocheck)) |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
43 { |
389
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
374
diff
changeset
|
44 if (*sym < 0x80 && !strchr(SSYMCHARS, *sym)) |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
374
diff
changeset
|
45 { |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
374
diff
changeset
|
46 lwasm_register_error(as, cl, "Bad symbol (%s)", sym); |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
374
diff
changeset
|
47 return NULL; |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
374
diff
changeset
|
48 } |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
49 |
389
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
374
diff
changeset
|
50 if ((*sym == '$' || *sym == '@') && (sym[1] >= '0' && sym[1] <= '9')) |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
374
diff
changeset
|
51 { |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
374
diff
changeset
|
52 lwasm_register_error(as, cl, "Bad symbol (%s)", sym); |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
374
diff
changeset
|
53 return NULL; |
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
374
diff
changeset
|
54 } |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
55 } |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
56 |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
57 for (cp = sym; *cp; cp++) |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
58 { |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
59 if (*cp == '@' || *cp == '?') |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
60 islocal = 1; |
360
7d91ab7ac7d6
Indexed stage 2; set line structure to track pragmas in effect for that line
lost@starbug
parents:
346
diff
changeset
|
61 if (*cp == '$' && !(CURPRAGMA(cl, PRAGMA_DOLLARNOTLOCAL))) |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
62 islocal = 1; |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
63 |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
64 // bad symbol |
389
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
374
diff
changeset
|
65 if (!(flags & symbol_flag_nocheck) && *cp < 0x80 && !strchr(SYMCHARS, *cp)) |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
66 { |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
67 lwasm_register_error(as, cl, "Bad symbol (%s)", sym); |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
68 return NULL; |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
69 } |
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
70 } |
342 | 71 |
72 if (islocal) | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
73 context = cl -> context; |
342 | 74 |
75 // first, look up symbol to see if it is already defined | |
76 for (se = as -> symtab.head; se; se = se -> next) | |
77 { | |
78 if (!strcmp(sym, se -> symbol)) | |
79 { | |
80 if (se -> context != context) | |
81 continue; | |
82 if ((flags & symbol_flag_set) && (se -> flags & symbol_flag_set)) | |
83 { | |
84 if (version < se -> version) | |
85 version = se -> version; | |
86 continue; | |
87 } | |
88 break; | |
89 } | |
90 } | |
389
fbb7bfed8076
Added in structure support and fixed up some warts in the listing code (by adding more warts)
lost@l-w.ca
parents:
374
diff
changeset
|
91 |
342 | 92 if (se) |
93 { | |
94 // multiply defined symbol | |
344
0215a0fbf61b
Added assembly error system and additional checks for symbol syntax
lost@starbug
parents:
342
diff
changeset
|
95 lwasm_register_error(as, cl, "Multiply defined symbol (%s)", sym); |
342 | 96 return NULL; |
97 } | |
98 | |
99 if (flags & symbol_flag_set) | |
100 { | |
101 version++; | |
102 } | |
103 | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
104 // symplify the symbol expression - replaces "SET" symbols with |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
105 // symbol table entries |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
106 lwasm_reduce_expr(as, val); |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
107 |
342 | 108 se = lw_alloc(sizeof(struct symtabe)); |
109 se -> next = as -> symtab.head; | |
110 as -> symtab.head = se; | |
111 se -> context = context; | |
112 se -> version = version; | |
113 se -> flags = flags; | |
114 se -> value = lw_expr_copy(val); | |
370 | 115 se -> symbol = lw_strdup(sym); |
374 | 116 se -> section = cl -> csect; |
342 | 117 return se; |
118 } | |
119 | |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
120 // for "SET" symbols, always returns the LAST definition of the |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
121 // symbol. This works because the lwasm_reduce_expr() call in |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
122 // register_symbol will ensure there are no lingering "var" references |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
123 // to the set symbol anywhere in the symbol table; they will all be |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
124 // converted to direct references |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
125 // NOTE: this means that for a forward reference to a SET symbol, |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
126 // the LAST definition will be the one used. |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
127 // This arrangement also ensures that any reference to the symbol |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
128 // itself inside a "set" definition will refer to the previous version |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
129 // of the symbol. |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
130 struct symtabe * lookup_symbol(asmstate_t *as, line_t *cl, char *sym) |
342 | 131 { |
363
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
132 int local = 0; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
133 struct symtabe *s, *s2; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
134 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
135 // check if this is a local symbol |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
136 if (strchr(sym, '@') || strchr(sym, '?')) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
137 local = 1; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
138 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
139 if (cl && !CURPRAGMA(cl, PRAGMA_DOLLARNOTLOCAL) && strchr(sym, '$')) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
140 local = 1; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
141 if (!cl && !(as -> pragmas & PRAGMA_DOLLARNOTLOCAL) && strchr(sym, '$')) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
142 local = 1; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
143 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
144 // cannot look up local symbol in global context!!!!! |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
145 if (!cl && local) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
146 return NULL; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
147 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
148 for (s = as -> symtab.head, s2 = NULL; s; s = s -> next) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
149 { |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
150 if (!strcmp(sym, s -> symbol)) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
151 { |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
152 if (local && s -> context != cl -> context) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
153 continue; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
154 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
155 if (s -> flags & symbol_flag_set) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
156 { |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
157 // look for highest version of symbol |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
158 if (s -> version > s2 -> version) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
159 s2 = s; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
160 continue; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
161 } |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
162 break; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
163 } |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
164 } |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
165 if (!s && s2) |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
166 s = s2; |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
167 |
d96c30e60ddf
Added pass2 and various supporting logic including symbol lookups
lost@starbug
parents:
360
diff
changeset
|
168 return s; |
342 | 169 } |
390
027d7fbcdcfc
Basic symbol table output; needs work for non-constant symbols
lost@l-w.ca
parents:
389
diff
changeset
|
170 |
405 | 171 struct listinfo |
172 { | |
173 sectiontab_t *sect; | |
174 asmstate_t *as; | |
175 int complex; | |
176 }; | |
177 | |
178 int list_symbols_test(lw_expr_t e, void *p) | |
179 { | |
180 struct listinfo *li = p; | |
181 | |
182 if (li -> complex) | |
183 return 0; | |
184 | |
185 if (lw_expr_istype(e, lw_expr_type_special)) | |
186 { | |
187 if (lw_expr_specint(e) == lwasm_expr_secbase) | |
188 { | |
189 if (li -> sect) | |
190 { | |
191 li -> complex = 1; | |
192 } | |
193 else | |
194 { | |
195 li -> sect = lw_expr_specptr(e); | |
196 } | |
197 } | |
198 } | |
199 return 0; | |
200 } | |
201 | |
390
027d7fbcdcfc
Basic symbol table output; needs work for non-constant symbols
lost@l-w.ca
parents:
389
diff
changeset
|
202 void list_symbols(asmstate_t *as, FILE *of) |
027d7fbcdcfc
Basic symbol table output; needs work for non-constant symbols
lost@l-w.ca
parents:
389
diff
changeset
|
203 { |
027d7fbcdcfc
Basic symbol table output; needs work for non-constant symbols
lost@l-w.ca
parents:
389
diff
changeset
|
204 struct symtabe *s; |
405 | 205 lw_expr_t te; |
206 struct listinfo li; | |
207 | |
208 li.as = as; | |
209 | |
390
027d7fbcdcfc
Basic symbol table output; needs work for non-constant symbols
lost@l-w.ca
parents:
389
diff
changeset
|
210 fprintf(of, "\nSymbol Table:\n"); |
027d7fbcdcfc
Basic symbol table output; needs work for non-constant symbols
lost@l-w.ca
parents:
389
diff
changeset
|
211 |
027d7fbcdcfc
Basic symbol table output; needs work for non-constant symbols
lost@l-w.ca
parents:
389
diff
changeset
|
212 for (s = as -> symtab.head; s; s = s -> next) |
027d7fbcdcfc
Basic symbol table output; needs work for non-constant symbols
lost@l-w.ca
parents:
389
diff
changeset
|
213 { |
405 | 214 lwasm_reduce_expr(as, s -> value); |
390
027d7fbcdcfc
Basic symbol table output; needs work for non-constant symbols
lost@l-w.ca
parents:
389
diff
changeset
|
215 fputc('[', of); |
027d7fbcdcfc
Basic symbol table output; needs work for non-constant symbols
lost@l-w.ca
parents:
389
diff
changeset
|
216 if (s -> flags & symbol_flag_set) |
027d7fbcdcfc
Basic symbol table output; needs work for non-constant symbols
lost@l-w.ca
parents:
389
diff
changeset
|
217 fputc('S', of); |
027d7fbcdcfc
Basic symbol table output; needs work for non-constant symbols
lost@l-w.ca
parents:
389
diff
changeset
|
218 else |
027d7fbcdcfc
Basic symbol table output; needs work for non-constant symbols
lost@l-w.ca
parents:
389
diff
changeset
|
219 fputc(' ', of); |
405 | 220 if (as -> output_format == OUTPUT_OBJ) |
221 { | |
222 if (lw_expr_istype(s -> value, lw_expr_type_int)) | |
223 fputc('c', of); | |
224 else | |
225 fputc('s', of); | |
226 } | |
227 if (s -> context < 0) | |
390
027d7fbcdcfc
Basic symbol table output; needs work for non-constant symbols
lost@l-w.ca
parents:
389
diff
changeset
|
228 fputc('G', of); |
027d7fbcdcfc
Basic symbol table output; needs work for non-constant symbols
lost@l-w.ca
parents:
389
diff
changeset
|
229 else |
405 | 230 fputc('L', of); |
231 | |
390
027d7fbcdcfc
Basic symbol table output; needs work for non-constant symbols
lost@l-w.ca
parents:
389
diff
changeset
|
232 fputc(']', of); |
027d7fbcdcfc
Basic symbol table output; needs work for non-constant symbols
lost@l-w.ca
parents:
389
diff
changeset
|
233 fputc(' ', of); |
027d7fbcdcfc
Basic symbol table output; needs work for non-constant symbols
lost@l-w.ca
parents:
389
diff
changeset
|
234 fprintf(of, "%-32s ", s -> symbol); |
405 | 235 |
236 te = lw_expr_copy(s -> value); | |
237 li.complex = 0; | |
238 li.sect = NULL; | |
239 lw_expr_testterms(te, list_symbols_test, &li); | |
240 if (li.sect) | |
241 { | |
242 as -> exportcheck = 1; | |
243 as -> csect = li.sect; | |
244 lwasm_reduce_expr(as, te); | |
245 as -> exportcheck = 0; | |
246 } | |
247 | |
248 if (lw_expr_istype(te, lw_expr_type_int)) | |
249 { | |
250 fprintf(of, "%04X", lw_expr_intval(te)); | |
251 if (li.sect) | |
252 { | |
253 fprintf(of, " (%s)", li.sect -> name); | |
254 } | |
255 fprintf(of, "\n"); | |
256 } | |
390
027d7fbcdcfc
Basic symbol table output; needs work for non-constant symbols
lost@l-w.ca
parents:
389
diff
changeset
|
257 else |
405 | 258 { |
259 fprintf(of, "<<incomplete>>\n"); | |
260 // fprintf(of, "%s\n", lw_expr_print(s -> value)); | |
261 } | |
262 lw_expr_destroy(te); | |
390
027d7fbcdcfc
Basic symbol table output; needs work for non-constant symbols
lost@l-w.ca
parents:
389
diff
changeset
|
263 } |
027d7fbcdcfc
Basic symbol table output; needs work for non-constant symbols
lost@l-w.ca
parents:
389
diff
changeset
|
264 } |