Mercurial > hg-old > index.cgi
comparison src/output.c @ 85:918be0c02239
Started adding object target output
author | lost |
---|---|
date | Fri, 16 Jan 2009 05:14:49 +0000 |
parents | 6de358e7903f |
children | 033a328a10ae |
comparison
equal
deleted
inserted
replaced
84:e12edcfbebd5 | 85:918be0c02239 |
---|---|
28 #include <string.h> | 28 #include <string.h> |
29 #include <unistd.h> | 29 #include <unistd.h> |
30 #define __output_c_seen__ | 30 #define __output_c_seen__ |
31 //#include "instab.h" | 31 //#include "instab.h" |
32 #include "lwasm.h" | 32 #include "lwasm.h" |
33 #include "util.h" | |
33 | 34 |
34 void write_code_raw(asmstate_t *as, FILE *of); | 35 void write_code_raw(asmstate_t *as, FILE *of); |
35 void write_code_decb(asmstate_t *as, FILE *of); | 36 void write_code_decb(asmstate_t *as, FILE *of); |
36 void write_code_rawrel(asmstate_t *as, FILE *of); | 37 void write_code_rawrel(asmstate_t *as, FILE *of); |
38 void write_code_obj(asmstate_t *as, FILE *of); | |
37 | 39 |
38 // this prevents warnings about not using the return value of fwrite() | 40 // this prevents warnings about not using the return value of fwrite() |
39 #define writebytes(s, l, c, f) do { int r; r = fwrite((s), (l), (c), (f)); } while (0) | 41 #define writebytes(s, l, c, f) do { int r; r = fwrite((s), (l), (c), (f)); } while (0) |
40 | 42 |
41 void lwasm_output(asmstate_t *as) | 43 void lwasm_output(asmstate_t *as) |
67 break; | 69 break; |
68 | 70 |
69 case OUTPUT_RAWREL: | 71 case OUTPUT_RAWREL: |
70 write_code_rawrel(as, of); | 72 write_code_rawrel(as, of); |
71 break; | 73 break; |
72 | 74 |
75 case OUTPUT_OBJ: | |
76 write_code_obj(as, of); | |
77 break; | |
78 | |
73 default: | 79 default: |
74 fprintf(stderr, "BUG: unrecognized output format when generating output file\n"); | 80 fprintf(stderr, "BUG: unrecognized output format when generating output file\n"); |
75 fclose(of); | 81 fclose(of); |
76 unlink(as -> outfile); | 82 unlink(as -> outfile); |
77 return; | 83 return; |
178 outbuf[2] = 0x00; | 184 outbuf[2] = 0x00; |
179 outbuf[3] = (as -> execaddr >> 8) & 0xFF; | 185 outbuf[3] = (as -> execaddr >> 8) & 0xFF; |
180 outbuf[4] = (as -> execaddr) & 0xFF; | 186 outbuf[4] = (as -> execaddr) & 0xFF; |
181 writebytes(outbuf, 5, 1, of); | 187 writebytes(outbuf, 5, 1, of); |
182 } | 188 } |
189 | |
190 void write_code_obj_sbadd(sectiontab_t *s, unsigned char b) | |
191 { | |
192 if (s -> oblen >= s -> obsize) | |
193 { | |
194 s -> obytes = lwasm_realloc(s -> obytes, s -> obsize + 128); | |
195 s -> obsize += 128; | |
196 } | |
197 s -> obytes[s -> oblen] = b; | |
198 s -> oblen += 1; | |
199 } | |
200 | |
201 void write_code_obj(asmstate_t *as, FILE *of) | |
202 { | |
203 lwasm_line_t *l; | |
204 int i; | |
205 | |
206 // output the magic number and file header | |
207 writebytes("LWOBJ16\0", 8, 1, of); | |
208 | |
209 // run through the entire system and build the byte streams for each | |
210 // section; at the same time, generate a list of "local" symbols to | |
211 // output for each section | |
212 // NOTE: for "local" symbols, we will append \x01 and the ascii string | |
213 // of the context identifier (so sym in context 1 would be "sym\x011" | |
214 // we can do this because the linker can handle symbols with any | |
215 // character other than NUL. | |
216 // also we will generate a list of incomplete references for each | |
217 // section along with the actual definition that will be output | |
218 | |
219 // once all this information is generated, we will output each section | |
220 // to the file | |
221 | |
222 // NOTE: we build everything in memory then output it because the | |
223 // assembler accepts multiple instances of the same section but the | |
224 // linker expects only one instance of each section in the object file | |
225 // so we need to collect all the various pieces of a section together | |
226 // (also, the assembler treated multiple instances of the same section | |
227 // as continuations of previous sections so we would need to collect | |
228 // them together anyway. | |
229 | |
230 for (l = as -> lineshead; l; l = l -> next) | |
231 { | |
232 if (l -> sect) | |
233 { | |
234 // we're in a section - need to output some bytes | |
235 for (i = 0; i < l -> codelen; i++) | |
236 write_code_obj_sbadd(l -> sect, l -> bytes[i]); | |
237 for (i = 0; i < l -> nocodelen; i++) | |
238 write_code_obj_sbadd(l -> sect, 0); | |
239 | |
240 // do we have a "relocation"? If so, add a reference to the | |
241 // relocation table | |
242 if (l -> relocoff >= 0) | |
243 { | |
244 | |
245 } | |
246 } | |
247 } | |
248 } |