Mercurial > hg-old > index.cgi
annotate lwasm/output.c @ 236:a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
author | lost |
---|---|
date | Fri, 14 Aug 2009 03:22:26 +0000 |
parents | bae1e3ecdce1 |
children | f9f01a499525 |
rev | line source |
---|---|
0 | 1 /* |
4
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
2 output.c |
46 | 3 Copyright © 2009 William Astle |
4
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
4 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
5 This file is part of LWASM. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
6 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
7 LWASM is free software: you can redistribute it and/or modify it under the |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
8 terms of the GNU General Public License as published by the Free Software |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
9 Foundation, either version 3 of the License, or (at your option) any later |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
10 version. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
11 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
12 This program is distributed in the hope that it will be useful, but WITHOUT |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
15 more details. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
16 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
17 You should have received a copy of the GNU General Public License along with |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
18 this program. If not, see <http://www.gnu.org/licenses/>. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
19 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
20 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
21 Contains the code for actually outputting the assembled code |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
22 */ |
212 | 23 #include <config.h> |
0 | 24 //#include <ctype.h> |
25 #include <errno.h> | |
26 #include <stdio.h> | |
27 //#include <stdlib.h> | |
28 #include <string.h> | |
29 #include <unistd.h> | |
30 #define __output_c_seen__ | |
31 //#include "instab.h" | |
32 #include "lwasm.h" | |
85 | 33 #include "util.h" |
0 | 34 |
35 void write_code_raw(asmstate_t *as, FILE *of); | |
36 void write_code_decb(asmstate_t *as, FILE *of); | |
37 void write_code_rawrel(asmstate_t *as, FILE *of); | |
85 | 38 void write_code_obj(asmstate_t *as, FILE *of); |
236
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
39 void write_code_os9(asmstate_t *as, FILE *of); |
0 | 40 |
48
6de358e7903f
Cleaned up warnings about the return value of fwrite() being ignored (it still is but now there's no warning)
lost
parents:
46
diff
changeset
|
41 // this prevents warnings about not using the return value of fwrite() |
6de358e7903f
Cleaned up warnings about the return value of fwrite() being ignored (it still is but now there's no warning)
lost
parents:
46
diff
changeset
|
42 #define writebytes(s, l, c, f) do { int r; r = fwrite((s), (l), (c), (f)); } while (0) |
6de358e7903f
Cleaned up warnings about the return value of fwrite() being ignored (it still is but now there's no warning)
lost
parents:
46
diff
changeset
|
43 |
46 | 44 void lwasm_output(asmstate_t *as) |
0 | 45 { |
46 FILE *of; | |
47 | |
48 if (as -> errorcount > 0) | |
49 { | |
50 fprintf(stderr, "Not doing output due to assembly errors.\n"); | |
51 return; | |
52 } | |
53 | |
54 of = fopen(as -> outfile, "wb"); | |
55 if (!of) | |
56 { | |
57 fprintf(stderr, "Cannot open '%s' for output", as -> outfile); | |
58 perror(""); | |
59 return; | |
60 } | |
61 | |
62 switch (as -> outformat) | |
63 { | |
64 case OUTPUT_RAW: | |
65 write_code_raw(as, of); | |
66 break; | |
67 | |
68 case OUTPUT_DECB: | |
69 write_code_decb(as, of); | |
70 break; | |
71 | |
72 case OUTPUT_RAWREL: | |
73 write_code_rawrel(as, of); | |
74 break; | |
85 | 75 |
76 case OUTPUT_OBJ: | |
77 write_code_obj(as, of); | |
78 break; | |
79 | |
236
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
80 case OUTPUT_OS9: |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
81 write_code_os9(as, of); |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
82 break; |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
83 |
0 | 84 default: |
85 fprintf(stderr, "BUG: unrecognized output format when generating output file\n"); | |
86 fclose(of); | |
87 unlink(as -> outfile); | |
88 return; | |
89 } | |
90 | |
91 fclose(of); | |
92 } | |
93 | |
94 /* | |
95 rawrel output treats an ORG directive as an offset from the start of the | |
96 file. Undefined results will occur if an ORG directive moves the output | |
97 pointer backward. This particular implementation uses "fseek" to handle | |
98 ORG requests and to skip over RMBs. | |
99 | |
100 This simple brain damanged method simply does an fseek before outputting | |
101 each instruction. | |
102 */ | |
103 void write_code_rawrel(asmstate_t *as, FILE *of) | |
104 { | |
46 | 105 lwasm_line_t *cl; |
0 | 106 |
46 | 107 for (cl = as -> lineshead; cl; cl = cl -> next) |
0 | 108 { |
46 | 109 if (cl -> codelen == 0) |
0 | 110 continue; |
111 | |
46 | 112 fseek(of, cl -> codeaddr, SEEK_SET); |
48
6de358e7903f
Cleaned up warnings about the return value of fwrite() being ignored (it still is but now there's no warning)
lost
parents:
46
diff
changeset
|
113 writebytes(cl -> bytes, cl -> codelen, 1, of); |
0 | 114 } |
115 } | |
116 | |
117 /* | |
118 raw merely writes all the bytes directly to the file as is. ORG is just a | |
119 reference for the assembler to handle absolute references. Multiple ORG | |
120 statements will produce mostly useless results | |
121 */ | |
122 void write_code_raw(asmstate_t *as, FILE *of) | |
123 { | |
46 | 124 lwasm_line_t *cl; |
0 | 125 |
46 | 126 for (cl = as -> lineshead; cl; cl = cl -> next) |
0 | 127 { |
46 | 128 if (cl -> nocodelen) |
0 | 129 { |
130 int i; | |
46 | 131 for (i = 0; i < cl -> nocodelen; i++) |
48
6de358e7903f
Cleaned up warnings about the return value of fwrite() being ignored (it still is but now there's no warning)
lost
parents:
46
diff
changeset
|
132 writebytes("\0", 1, 1, of); |
0 | 133 continue; |
134 } | |
48
6de358e7903f
Cleaned up warnings about the return value of fwrite() being ignored (it still is but now there's no warning)
lost
parents:
46
diff
changeset
|
135 writebytes(cl -> bytes, cl -> codelen, 1, of); |
0 | 136 } |
137 } | |
138 | |
236
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
139 |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
140 /* |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
141 OS9 target also just writes all the bytes in order. No need for anything |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
142 else. |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
143 */ |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
144 void write_code_os9(asmstate_t *as, FILE *of) |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
145 { |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
146 lwasm_line_t *cl; |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
147 |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
148 for (cl = as -> lineshead; cl; cl = cl -> next) |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
149 { |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
150 if (cl -> inmod == 0) |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
151 continue; |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
152 if (cl -> nocodelen) |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
153 { |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
154 int i; |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
155 for (i = 0; i < cl -> nocodelen; i++) |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
156 writebytes("\0", 1, 1, of); |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
157 continue; |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
158 } |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
159 writebytes(cl -> bytes, cl -> codelen, 1, of); |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
160 } |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
161 } |
a58f49a77441
Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
lost
parents:
212
diff
changeset
|
162 |
0 | 163 void write_code_decb(asmstate_t *as, FILE *of) |
164 { | |
165 long preambloc; | |
46 | 166 lwasm_line_t *cl; |
0 | 167 int blocklen = -1; |
168 int nextcalc = -1; | |
169 unsigned char outbuf[5]; | |
170 | |
46 | 171 for (cl = as -> lineshead; cl; cl = cl -> next) |
0 | 172 { |
46 | 173 if (cl -> nocodelen) |
0 | 174 continue; |
46 | 175 if (cl -> codeaddr != nextcalc && cl -> codelen > 0) |
0 | 176 { |
177 // need preamble here | |
178 if (blocklen > 0) | |
179 { | |
46 | 180 // update previous preamble if needed |
0 | 181 fseek(of, preambloc, SEEK_SET); |
182 outbuf[0] = (blocklen >> 8) & 0xFF; | |
183 outbuf[1] = blocklen & 0xFF; | |
48
6de358e7903f
Cleaned up warnings about the return value of fwrite() being ignored (it still is but now there's no warning)
lost
parents:
46
diff
changeset
|
184 writebytes(outbuf, 2, 1, of); |
0 | 185 fseek(of, 0, SEEK_END); |
186 } | |
187 blocklen = 0; | |
46 | 188 nextcalc = cl -> codeaddr; |
0 | 189 outbuf[0] = 0x00; |
190 outbuf[1] = 0x00; | |
191 outbuf[2] = 0x00; | |
192 outbuf[3] = (nextcalc >> 8) & 0xFF; | |
193 outbuf[4] = nextcalc & 0xFF; | |
194 preambloc = ftell(of) + 1; | |
48
6de358e7903f
Cleaned up warnings about the return value of fwrite() being ignored (it still is but now there's no warning)
lost
parents:
46
diff
changeset
|
195 writebytes(outbuf, 5, 1, of); |
0 | 196 } |
46 | 197 nextcalc += cl -> codelen; |
48
6de358e7903f
Cleaned up warnings about the return value of fwrite() being ignored (it still is but now there's no warning)
lost
parents:
46
diff
changeset
|
198 writebytes(cl -> bytes, cl -> codelen, 1, of); |
46 | 199 blocklen += cl -> codelen; |
0 | 200 } |
201 if (blocklen > 0) | |
202 { | |
203 fseek(of, preambloc, SEEK_SET); | |
204 outbuf[0] = (blocklen >> 8) & 0xFF; | |
205 outbuf[1] = blocklen & 0xFF; | |
48
6de358e7903f
Cleaned up warnings about the return value of fwrite() being ignored (it still is but now there's no warning)
lost
parents:
46
diff
changeset
|
206 writebytes(outbuf, 2, 1, of); |
0 | 207 fseek(of, 0, SEEK_END); |
208 } | |
209 | |
210 // now write postamble | |
211 outbuf[0] = 0xFF; | |
212 outbuf[1] = 0x00; | |
213 outbuf[2] = 0x00; | |
214 outbuf[3] = (as -> execaddr >> 8) & 0xFF; | |
215 outbuf[4] = (as -> execaddr) & 0xFF; | |
48
6de358e7903f
Cleaned up warnings about the return value of fwrite() being ignored (it still is but now there's no warning)
lost
parents:
46
diff
changeset
|
216 writebytes(outbuf, 5, 1, of); |
0 | 217 } |
85 | 218 |
219 void write_code_obj_sbadd(sectiontab_t *s, unsigned char b) | |
220 { | |
221 if (s -> oblen >= s -> obsize) | |
222 { | |
223 s -> obytes = lwasm_realloc(s -> obytes, s -> obsize + 128); | |
224 s -> obsize += 128; | |
225 } | |
226 s -> obytes[s -> oblen] = b; | |
227 s -> oblen += 1; | |
228 } | |
229 | |
230 void write_code_obj(asmstate_t *as, FILE *of) | |
231 { | |
232 lwasm_line_t *l; | |
87 | 233 sectiontab_t *s; |
88 | 234 lwasm_symbol_ent_t *se; |
91
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
235 export_list_t *ex; |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
236 section_reloc_list_t *re; |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
237 lwasm_expr_stack_node_t *sn; |
88 | 238 |
85 | 239 int i; |
87 | 240 unsigned char buf[16]; |
85 | 241 |
242 // output the magic number and file header | |
87 | 243 // the 8 is NOT an error |
244 writebytes("LWOBJ16", 8, 1, of); | |
85 | 245 |
246 // run through the entire system and build the byte streams for each | |
247 // section; at the same time, generate a list of "local" symbols to | |
248 // output for each section | |
249 // NOTE: for "local" symbols, we will append \x01 and the ascii string | |
250 // of the context identifier (so sym in context 1 would be "sym\x011" | |
251 // we can do this because the linker can handle symbols with any | |
252 // character other than NUL. | |
253 // also we will generate a list of incomplete references for each | |
254 // section along with the actual definition that will be output | |
255 | |
256 // once all this information is generated, we will output each section | |
257 // to the file | |
258 | |
259 // NOTE: we build everything in memory then output it because the | |
260 // assembler accepts multiple instances of the same section but the | |
261 // linker expects only one instance of each section in the object file | |
262 // so we need to collect all the various pieces of a section together | |
263 // (also, the assembler treated multiple instances of the same section | |
264 // as continuations of previous sections so we would need to collect | |
265 // them together anyway. | |
266 | |
267 for (l = as -> lineshead; l; l = l -> next) | |
268 { | |
269 if (l -> sect) | |
270 { | |
271 // we're in a section - need to output some bytes | |
272 for (i = 0; i < l -> codelen; i++) | |
273 write_code_obj_sbadd(l -> sect, l -> bytes[i]); | |
274 for (i = 0; i < l -> nocodelen; i++) | |
275 write_code_obj_sbadd(l -> sect, 0); | |
276 | |
277 // do we have a "relocation"? If so, add a reference to the | |
278 // relocation table | |
279 if (l -> relocoff >= 0) | |
280 { | |
86 | 281 // build the relocation reference for the linker |
282 re = lwasm_alloc(sizeof(section_reloc_list_t)); | |
283 re -> next = l -> sect -> rl; | |
284 l -> sect -> rl = re; | |
285 | |
286 re -> offset = l -> codeaddr + l -> relocoff; | |
287 re -> expr = l -> exprs[0]; | |
91
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
288 re -> context = l -> context; |
204
048ebb85f6ef
Added 8 bit external references for base page addressing mode
lost
parents:
151
diff
changeset
|
289 re -> relocsize = 2; |
048ebb85f6ef
Added 8 bit external references for base page addressing mode
lost
parents:
151
diff
changeset
|
290 if (l -> reloc8bit) |
048ebb85f6ef
Added 8 bit external references for base page addressing mode
lost
parents:
151
diff
changeset
|
291 re -> relocsize = 1; |
85 | 292 } |
293 } | |
294 } | |
87 | 295 |
296 // run through the sections | |
297 for (s = as -> sections; s; s = s -> next) | |
298 { | |
299 // write the name | |
300 writebytes(s -> name, strlen(s -> name) + 1, 1, of); | |
301 | |
302 // write the flags | |
303 if (s -> flags & SECTION_BSS) | |
304 writebytes("\x01", 1, 1, of); | |
305 | |
306 // indicate end of flags - the "" is NOT an error | |
307 writebytes("", 1, 1, of); | |
308 | |
309 | |
88 | 310 // now the local symbols |
311 for (se = as -> symhead; se; se = se -> next) | |
312 { | |
313 // ignore symbols not in this section | |
314 if (se -> sect != s) | |
315 continue; | |
316 | |
317 if (se -> flags & SYMBOL_SET) | |
318 continue; | |
319 | |
320 if (se -> flags & SYMBOL_EXTERN) | |
321 continue; | |
322 | |
323 writebytes(se -> sym, strlen(se -> sym), 1, of); | |
324 if (se -> context >= 0) | |
325 { | |
326 writebytes("\x01", 1, 1, of); | |
327 sprintf(buf, "%d", se -> context); | |
328 writebytes(buf, strlen(buf), 1, of); | |
329 } | |
330 // the "" is NOT an error | |
331 writebytes("", 1, 1, of); | |
332 | |
333 // write the address | |
334 buf[0] = (se -> value >> 8) & 0xff; | |
335 buf[1] = se -> value & 0xff; | |
336 writebytes(buf, 2, 1, of); | |
337 } | |
338 // flag end of local symbol table - "" is NOT an error | |
339 writebytes("", 1, 1, of); | |
340 | |
91
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
341 // now the exports |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
342 for (ex = s -> exports; ex; ex = ex -> next) |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
343 { |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
344 writebytes(ex -> sym, strlen(ex -> sym) + 1, 1, of); |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
345 buf[0] = (ex -> offset >> 8) & 0xff; |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
346 buf[1] = ex -> offset & 0xff; |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
347 writebytes(buf, 2, 1, of); |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
348 } |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
349 |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
350 // flag end of exported symbols - "" is NOT an error |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
351 writebytes("", 1, 1, of); |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
352 |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
353 // now output the "incomplete references" |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
354 // this being the most complex bit |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
355 for (re = s -> rl; re; re = re -> next) |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
356 { |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
357 if (re -> expr == NULL) |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
358 { |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
359 // this is an error but we'll simply ignore it |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
360 // and not output this expression |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
361 continue; |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
362 } |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
363 |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
364 // work through each term in the expression and output |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
365 // the proper equivalent to the object file |
204
048ebb85f6ef
Added 8 bit external references for base page addressing mode
lost
parents:
151
diff
changeset
|
366 if (re -> relocsize == 1) |
048ebb85f6ef
Added 8 bit external references for base page addressing mode
lost
parents:
151
diff
changeset
|
367 { |
048ebb85f6ef
Added 8 bit external references for base page addressing mode
lost
parents:
151
diff
changeset
|
368 // flag an 8 bit relocation (low 8 bits will be used) |
048ebb85f6ef
Added 8 bit external references for base page addressing mode
lost
parents:
151
diff
changeset
|
369 buf[0] = 0xFF; |
048ebb85f6ef
Added 8 bit external references for base page addressing mode
lost
parents:
151
diff
changeset
|
370 buf[1] = 0x01; |
048ebb85f6ef
Added 8 bit external references for base page addressing mode
lost
parents:
151
diff
changeset
|
371 writebytes(buf, 2, 1, of); |
048ebb85f6ef
Added 8 bit external references for base page addressing mode
lost
parents:
151
diff
changeset
|
372 } |
91
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
373 for (sn = re -> expr -> head; sn; sn = sn -> next) |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
374 { |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
375 switch (sn -> term -> term_type) |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
376 { |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
377 case LWASM_TERM_OPER: |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
378 buf[0] = 0x04; |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
379 buf[1] = sn -> term -> value; |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
380 writebytes(buf, 2, 1, of); |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
381 break; |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
382 |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
383 case LWASM_TERM_INT: |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
384 buf[0] = 0x01; |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
385 buf[1] = (sn -> term -> value >> 8) & 0xff; |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
386 buf[2] = sn -> term -> value & 0xff; |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
387 writebytes(buf, 3, 1, of); |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
388 break; |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
389 |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
390 case LWASM_TERM_SECBASE: |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
391 writebytes("\x05", 1, 1, of); |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
392 break; |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
393 |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
394 case LWASM_TERM_SYM: |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
395 // now for the ugly part - resolve a symbol reference |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
396 // and determine whether it's internal, external, or |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
397 // a section base |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
398 se = lwasm_find_symbol(as, sn -> term -> symbol, re -> context); |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
399 if (!se) |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
400 se = lwasm_find_symbol(as, sn -> term -> symbol, -1); |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
401 if (!se || se -> flags & SYMBOL_EXTERN) |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
402 { |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
403 // not found - assume external reference |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
404 // found but flagged external - handle it |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
405 writebytes("\x02", 1, 1, of); |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
406 writebytes(se -> sym, strlen(se -> sym) + 1, 1, of); |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
407 break; |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
408 } |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
409 // a local symbol reference here |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
410 writebytes("\x03", 1, 1, of); |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
411 writebytes(se -> sym, strlen(se -> sym), 1, of); |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
412 if (se -> context >= 0) |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
413 { |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
414 writebytes("\x01", 1, 1, of); |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
415 sprintf(buf, "%d", se -> context); |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
416 writebytes(buf, strlen(buf), 1, of); |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
417 } |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
418 writebytes("", 1, 1, of); |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
419 break; |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
420 |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
421 default: |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
422 // unrecognized term type - replace with integer 0 |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
423 buf[0] = 0x01; |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
424 buf[1] = 0x00; |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
425 buf[2] = 0x00; |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
426 writebytes(buf, 3, 1, of); |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
427 break; |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
428 } |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
429 } |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
430 |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
431 // flag end of expressions |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
432 writebytes("", 1, 1, of); |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
433 |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
434 // write the offset |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
435 buf[0] = (re -> offset >> 8) & 0xff; |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
436 buf[1] = re -> offset & 0xff; |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
437 writebytes(buf, 2, 1, of); |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
438 } |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
439 // flag end of incomplete references list |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
440 writebytes("", 1, 1, of); |
718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
lost
parents:
88
diff
changeset
|
441 |
87 | 442 // now blast out the code |
443 | |
444 // length | |
445 buf[0] = s -> oblen >> 8 & 0xff; | |
446 buf[1] = s -> oblen & 0xff; | |
447 writebytes(buf, 2, 1, of); | |
448 | |
449 if (!(s -> flags & SECTION_BSS)) | |
450 { | |
451 writebytes(s -> obytes, s -> oblen, 1, of); | |
452 } | |
453 } | |
454 | |
455 // flag no more sections | |
456 // the "" is NOT an error | |
457 writebytes("", 1, 1, of); | |
85 | 458 } |