annotate src/output.c @ 87:41ff4686b46b

Checkpoint: object format output
author lost
date Sat, 17 Jan 2009 02:59:24 +0000
parents 033a328a10ae
children 6460a1fb5f1f
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;
85
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
205 int i;
87
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
206 unsigned char buf[16];
85
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
207
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
208 // output the magic number and file header
87
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
209 // the 8 is NOT an error
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
210 writebytes("LWOBJ16", 8, 1, of);
85
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
211
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
212 // run through the entire system and build the byte streams for each
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
213 // section; at the same time, generate a list of "local" symbols to
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
214 // output for each section
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
215 // NOTE: for "local" symbols, we will append \x01 and the ascii string
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
216 // of the context identifier (so sym in context 1 would be "sym\x011"
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
217 // we can do this because the linker can handle symbols with any
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
218 // character other than NUL.
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
219 // also we will generate a list of incomplete references for each
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
220 // section along with the actual definition that will be output
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
221
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
222 // once all this information is generated, we will output each section
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
223 // to the file
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
224
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
225 // NOTE: we build everything in memory then output it because the
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
226 // assembler accepts multiple instances of the same section but the
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
227 // linker expects only one instance of each section in the object file
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
228 // so we need to collect all the various pieces of a section together
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
229 // (also, the assembler treated multiple instances of the same section
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
230 // as continuations of previous sections so we would need to collect
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
231 // them together anyway.
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
232
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
233 for (l = as -> lineshead; l; l = l -> next)
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
234 {
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
235 if (l -> sect)
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
236 {
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
237 // we're in a section - need to output some bytes
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
238 for (i = 0; i < l -> codelen; i++)
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
239 write_code_obj_sbadd(l -> sect, l -> bytes[i]);
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
240 for (i = 0; i < l -> nocodelen; i++)
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
241 write_code_obj_sbadd(l -> sect, 0);
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
242
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
243 // do we have a "relocation"? If so, add a reference to the
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
244 // relocation table
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
245 if (l -> relocoff >= 0)
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
246 {
86
033a328a10ae Checkpoint: object target output
lost
parents: 85
diff changeset
247 section_reloc_list_t *re;
033a328a10ae Checkpoint: object target output
lost
parents: 85
diff changeset
248
033a328a10ae Checkpoint: object target output
lost
parents: 85
diff changeset
249 // build the relocation reference for the linker
033a328a10ae Checkpoint: object target output
lost
parents: 85
diff changeset
250 re = lwasm_alloc(sizeof(section_reloc_list_t));
033a328a10ae Checkpoint: object target output
lost
parents: 85
diff changeset
251 re -> next = l -> sect -> rl;
033a328a10ae Checkpoint: object target output
lost
parents: 85
diff changeset
252 l -> sect -> rl = re;
033a328a10ae Checkpoint: object target output
lost
parents: 85
diff changeset
253
033a328a10ae Checkpoint: object target output
lost
parents: 85
diff changeset
254 re -> offset = l -> codeaddr + l -> relocoff;
033a328a10ae Checkpoint: object target output
lost
parents: 85
diff changeset
255 re -> expr = l -> exprs[0];
85
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
256 }
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
257 }
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
258 }
87
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
259
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
260 // run through the sections
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
261 for (s = as -> sections; s; s = s -> next)
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
262 {
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
263 // write the name
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
264 writebytes(s -> name, strlen(s -> name) + 1, 1, of);
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
265
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
266 // write the flags
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
267 if (s -> flags & SECTION_BSS)
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
268 writebytes("\x01", 1, 1, of);
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
269
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
270 // indicate end of flags - the "" is NOT an error
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
271 writebytes("", 1, 1, of);
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
272
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
273
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
274 // now blast out the code
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
275
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
276 // length
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
277 buf[0] = s -> oblen >> 8 & 0xff;
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
278 buf[1] = s -> oblen & 0xff;
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
279 writebytes(buf, 2, 1, of);
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
280
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
281 if (!(s -> flags & SECTION_BSS))
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
282 {
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
283 writebytes(s -> obytes, s -> oblen, 1, of);
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
284 }
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
285 }
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
286
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
287 // flag no more sections
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
288 // the "" is NOT an error
41ff4686b46b Checkpoint: object format output
lost
parents: 86
diff changeset
289 writebytes("", 1, 1, of);
85
918be0c02239 Started adding object target output
lost
parents: 48
diff changeset
290 }