annotate src/output.c @ 88:6460a1fb5f1f

Checkpoint: object format output
author lost
date Sat, 17 Jan 2009 04:37:40 +0000
parents 41ff4686b46b
children 718998b673ee
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
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
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
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 */
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
23
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
24 //#include <ctype.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
25 #include <errno.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
26 #include <stdio.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
27 //#include <stdlib.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
28 #include <string.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
29 #include <unistd.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
30 #define __output_c_seen__
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
31 //#include "instab.h"
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
32 #include "lwasm.h"
85
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
33 #include "util.h"
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
34
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
35 void write_code_raw(asmstate_t *as, FILE *of);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
36 void write_code_decb(asmstate_t *as, FILE *of);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
37 void write_code_rawrel(asmstate_t *as, FILE *of);
85
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
38 void write_code_obj(asmstate_t *as, FILE *of);
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
39
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
40 // 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
41 #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
42
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
43 void lwasm_output(asmstate_t *as)
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
44 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
45 FILE *of;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
46
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
47 if (as -> errorcount > 0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
48 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
49 fprintf(stderr, "Not doing output due to assembly errors.\n");
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
50 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
51 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
52
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
53 of = fopen(as -> outfile, "wb");
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
54 if (!of)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
55 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
56 fprintf(stderr, "Cannot open '%s' for output", as -> outfile);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
57 perror("");
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
58 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
59 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
60
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
61 switch (as -> outformat)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
62 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
63 case OUTPUT_RAW:
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
64 write_code_raw(as, of);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
65 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
66
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
67 case OUTPUT_DECB:
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
68 write_code_decb(as, of);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
69 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
70
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
71 case OUTPUT_RAWREL:
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
72 write_code_rawrel(as, of);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
73 break;
85
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
74
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
75 case OUTPUT_OBJ:
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
76 write_code_obj(as, of);
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
77 break;
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
78
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
79 default:
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
80 fprintf(stderr, "BUG: unrecognized output format when generating output file\n");
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
81 fclose(of);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
82 unlink(as -> outfile);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
83 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
84 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
85
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
86 fclose(of);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
87 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
88
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
89 /*
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
90 rawrel output treats an ORG directive as an offset from the start of the
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
91 file. Undefined results will occur if an ORG directive moves the output
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
92 pointer backward. This particular implementation uses "fseek" to handle
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
93 ORG requests and to skip over RMBs.
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
94
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
95 This simple brain damanged method simply does an fseek before outputting
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
96 each instruction.
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
97 */
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
98 void write_code_rawrel(asmstate_t *as, FILE *of)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
99 {
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
100 lwasm_line_t *cl;
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
101
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
102 for (cl = as -> lineshead; cl; cl = cl -> next)
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
103 {
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
104 if (cl -> codelen == 0)
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
105 continue;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
106
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
107 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
108 writebytes(cl -> bytes, cl -> codelen, 1, of);
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
109 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
110 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
111
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
112 /*
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
113 raw merely writes all the bytes directly to the file as is. ORG is just a
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
114 reference for the assembler to handle absolute references. Multiple ORG
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
115 statements will produce mostly useless results
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
116 */
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
117 void write_code_raw(asmstate_t *as, FILE *of)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
118 {
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
119 lwasm_line_t *cl;
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
120
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
121 for (cl = as -> lineshead; cl; cl = cl -> next)
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
122 {
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
123 if (cl -> nocodelen)
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
124 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
125 int i;
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
126 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
127 writebytes("\0", 1, 1, of);
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
128 continue;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
129 }
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
130 writebytes(cl -> bytes, cl -> codelen, 1, of);
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
131 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
132 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
133
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
134 void write_code_decb(asmstate_t *as, FILE *of)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
135 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
136 long preambloc;
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
137 lwasm_line_t *cl;
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
138 int blocklen = -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
139 int nextcalc = -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
140 unsigned char outbuf[5];
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
141
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
142 for (cl = as -> lineshead; cl; cl = cl -> next)
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
143 {
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
144 if (cl -> nocodelen)
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
145 continue;
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
146 if (cl -> codeaddr != nextcalc && cl -> codelen > 0)
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
147 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
148 // need preamble here
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
149 if (blocklen > 0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
150 {
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
151 // update previous preamble if needed
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
152 fseek(of, preambloc, SEEK_SET);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
153 outbuf[0] = (blocklen >> 8) & 0xFF;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
154 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
155 writebytes(outbuf, 2, 1, of);
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
156 fseek(of, 0, SEEK_END);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
157 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
158 blocklen = 0;
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
159 nextcalc = cl -> codeaddr;
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
160 outbuf[0] = 0x00;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
161 outbuf[1] = 0x00;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
162 outbuf[2] = 0x00;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
163 outbuf[3] = (nextcalc >> 8) & 0xFF;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
164 outbuf[4] = nextcalc & 0xFF;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
165 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
166 writebytes(outbuf, 5, 1, of);
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
167 }
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
168 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
169 writebytes(cl -> bytes, cl -> codelen, 1, of);
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
170 blocklen += cl -> codelen;
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
171 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
172 if (blocklen > 0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
173 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
174 fseek(of, preambloc, SEEK_SET);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
175 outbuf[0] = (blocklen >> 8) & 0xFF;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
176 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
177 writebytes(outbuf, 2, 1, of);
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
178 fseek(of, 0, SEEK_END);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
179 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
180
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
181 // now write postamble
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
182 outbuf[0] = 0xFF;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
183 outbuf[1] = 0x00;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
184 outbuf[2] = 0x00;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
185 outbuf[3] = (as -> execaddr >> 8) & 0xFF;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
186 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
187 writebytes(outbuf, 5, 1, of);
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
188 }
85
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
189
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
190 void write_code_obj_sbadd(sectiontab_t *s, unsigned char b)
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
191 {
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
192 if (s -> oblen >= s -> obsize)
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
193 {
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
194 s -> obytes = lwasm_realloc(s -> obytes, s -> obsize + 128);
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
195 s -> obsize += 128;
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
196 }
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
197 s -> obytes[s -> oblen] = b;
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
198 s -> oblen += 1;
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
199 }
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
200
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
201 void write_code_obj(asmstate_t *as, FILE *of)
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
202 {
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
203 lwasm_line_t *l;
87
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
204 sectiontab_t *s;
88
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
205 lwasm_symbol_ent_t *se;
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
206
85
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
207 int i;
87
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
208 unsigned char buf[16];
85
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
209
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
210 // output the magic number and file header
87
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
211 // the 8 is NOT an error
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
212 writebytes("LWOBJ16", 8, 1, of);
85
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
213
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
214 // run through the entire system and build the byte streams for each
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
215 // section; at the same time, generate a list of "local" symbols to
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
216 // output for each section
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
217 // NOTE: for "local" symbols, we will append \x01 and the ascii string
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
218 // of the context identifier (so sym in context 1 would be "sym\x011"
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
219 // we can do this because the linker can handle symbols with any
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
220 // character other than NUL.
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
221 // also we will generate a list of incomplete references for each
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
222 // section along with the actual definition that will be output
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
223
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
224 // once all this information is generated, we will output each section
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
225 // to the file
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
226
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
227 // NOTE: we build everything in memory then output it because the
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
228 // assembler accepts multiple instances of the same section but the
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
229 // linker expects only one instance of each section in the object file
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
230 // so we need to collect all the various pieces of a section together
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
231 // (also, the assembler treated multiple instances of the same section
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
232 // as continuations of previous sections so we would need to collect
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
233 // them together anyway.
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
234
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
235 for (l = as -> lineshead; l; l = l -> next)
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
236 {
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
237 if (l -> sect)
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
238 {
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
239 // we're in a section - need to output some bytes
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
240 for (i = 0; i < l -> codelen; i++)
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
241 write_code_obj_sbadd(l -> sect, l -> bytes[i]);
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
242 for (i = 0; i < l -> nocodelen; i++)
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
243 write_code_obj_sbadd(l -> sect, 0);
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
244
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
245 // do we have a "relocation"? If so, add a reference to the
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
246 // relocation table
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
247 if (l -> relocoff >= 0)
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
248 {
86
033a328a10ae Checkpoint: object target output
lost
parents: 85
diff changeset
249 section_reloc_list_t *re;
033a328a10ae Checkpoint: object target output
lost
parents: 85
diff changeset
250
033a328a10ae Checkpoint: object target output
lost
parents: 85
diff changeset
251 // build the relocation reference for the linker
033a328a10ae Checkpoint: object target output
lost
parents: 85
diff changeset
252 re = lwasm_alloc(sizeof(section_reloc_list_t));
033a328a10ae Checkpoint: object target output
lost
parents: 85
diff changeset
253 re -> next = l -> sect -> rl;
033a328a10ae Checkpoint: object target output
lost
parents: 85
diff changeset
254 l -> sect -> rl = re;
033a328a10ae Checkpoint: object target output
lost
parents: 85
diff changeset
255
033a328a10ae Checkpoint: object target output
lost
parents: 85
diff changeset
256 re -> offset = l -> codeaddr + l -> relocoff;
033a328a10ae Checkpoint: object target output
lost
parents: 85
diff changeset
257 re -> expr = l -> exprs[0];
85
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
258 }
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
259 }
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
260 }
87
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
261
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
262 // run through the sections
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
263 for (s = as -> sections; s; s = s -> next)
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
264 {
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
265 // write the name
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
266 writebytes(s -> name, strlen(s -> name) + 1, 1, of);
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
267
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
268 // write the flags
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
269 if (s -> flags & SECTION_BSS)
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
270 writebytes("\x01", 1, 1, of);
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
271
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
272 // indicate end of flags - the "" is NOT an error
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
273 writebytes("", 1, 1, of);
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
274
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
275
88
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
276 // now the local symbols
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
277 for (se = as -> symhead; se; se = se -> next)
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
278 {
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
279 // ignore symbols not in this section
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
280 if (se -> sect != s)
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
281 continue;
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
282
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
283 if (se -> flags & SYMBOL_SET)
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
284 continue;
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
285
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
286 if (se -> flags & SYMBOL_EXTERN)
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
287 continue;
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
288
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
289 writebytes(se -> sym, strlen(se -> sym), 1, of);
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
290 if (se -> context >= 0)
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
291 {
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
292 writebytes("\x01", 1, 1, of);
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
293 sprintf(buf, "%d", se -> context);
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
294 writebytes(buf, strlen(buf), 1, of);
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
295 }
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
296 // the "" is NOT an error
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
297 writebytes("", 1, 1, of);
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
298
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
299 // write the address
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
300 buf[0] = (se -> value >> 8) & 0xff;
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
301 buf[1] = se -> value & 0xff;
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
302 writebytes(buf, 2, 1, of);
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
303 }
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
304 // flag end of local symbol table - "" is NOT an error
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
305 writebytes("", 1, 1, of);
6460a1fb5f1f Checkpoint: object format output
lost
parents: 87
diff changeset
306
87
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
307 // now blast out the code
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
308
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
309 // length
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
310 buf[0] = s -> oblen >> 8 & 0xff;
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
311 buf[1] = s -> oblen & 0xff;
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
312 writebytes(buf, 2, 1, of);
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
313
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
314 if (!(s -> flags & SECTION_BSS))
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
315 {
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
316 writebytes(s -> obytes, s -> oblen, 1, of);
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
317 }
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
318 }
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
319
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
320 // flag no more sections
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
321 // the "" is NOT an error
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
322 writebytes("", 1, 1, of);
85
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
323 }