Mercurial > hg-old > index.cgi
comparison src/output.c @ 91:718998b673ee
Added incomplete references to object output and added support for section base terms in expression handler
author | lost |
---|---|
date | Sat, 17 Jan 2009 05:56:40 +0000 |
parents | 6460a1fb5f1f |
children |
comparison
equal
deleted
inserted
replaced
90:6097cb1486f8 | 91:718998b673ee |
---|---|
201 void write_code_obj(asmstate_t *as, FILE *of) | 201 void write_code_obj(asmstate_t *as, FILE *of) |
202 { | 202 { |
203 lwasm_line_t *l; | 203 lwasm_line_t *l; |
204 sectiontab_t *s; | 204 sectiontab_t *s; |
205 lwasm_symbol_ent_t *se; | 205 lwasm_symbol_ent_t *se; |
206 export_list_t *ex; | |
207 section_reloc_list_t *re; | |
208 lwasm_expr_stack_node_t *sn; | |
206 | 209 |
207 int i; | 210 int i; |
208 unsigned char buf[16]; | 211 unsigned char buf[16]; |
209 | 212 |
210 // output the magic number and file header | 213 // output the magic number and file header |
244 | 247 |
245 // do we have a "relocation"? If so, add a reference to the | 248 // do we have a "relocation"? If so, add a reference to the |
246 // relocation table | 249 // relocation table |
247 if (l -> relocoff >= 0) | 250 if (l -> relocoff >= 0) |
248 { | 251 { |
249 section_reloc_list_t *re; | |
250 | |
251 // build the relocation reference for the linker | 252 // build the relocation reference for the linker |
252 re = lwasm_alloc(sizeof(section_reloc_list_t)); | 253 re = lwasm_alloc(sizeof(section_reloc_list_t)); |
253 re -> next = l -> sect -> rl; | 254 re -> next = l -> sect -> rl; |
254 l -> sect -> rl = re; | 255 l -> sect -> rl = re; |
255 | 256 |
256 re -> offset = l -> codeaddr + l -> relocoff; | 257 re -> offset = l -> codeaddr + l -> relocoff; |
257 re -> expr = l -> exprs[0]; | 258 re -> expr = l -> exprs[0]; |
259 re -> context = l -> context; | |
258 } | 260 } |
259 } | 261 } |
260 } | 262 } |
261 | 263 |
262 // run through the sections | 264 // run through the sections |
302 writebytes(buf, 2, 1, of); | 304 writebytes(buf, 2, 1, of); |
303 } | 305 } |
304 // flag end of local symbol table - "" is NOT an error | 306 // flag end of local symbol table - "" is NOT an error |
305 writebytes("", 1, 1, of); | 307 writebytes("", 1, 1, of); |
306 | 308 |
309 // now the exports | |
310 for (ex = s -> exports; ex; ex = ex -> next) | |
311 { | |
312 writebytes(ex -> sym, strlen(ex -> sym) + 1, 1, of); | |
313 buf[0] = (ex -> offset >> 8) & 0xff; | |
314 buf[1] = ex -> offset & 0xff; | |
315 writebytes(buf, 2, 1, of); | |
316 } | |
317 | |
318 // flag end of exported symbols - "" is NOT an error | |
319 writebytes("", 1, 1, of); | |
320 | |
321 // now output the "incomplete references" | |
322 // this being the most complex bit | |
323 for (re = s -> rl; re; re = re -> next) | |
324 { | |
325 if (re -> expr == NULL) | |
326 { | |
327 // this is an error but we'll simply ignore it | |
328 // and not output this expression | |
329 continue; | |
330 } | |
331 | |
332 // work through each term in the expression and output | |
333 // the proper equivalent to the object file | |
334 for (sn = re -> expr -> head; sn; sn = sn -> next) | |
335 { | |
336 switch (sn -> term -> term_type) | |
337 { | |
338 case LWASM_TERM_OPER: | |
339 buf[0] = 0x04; | |
340 buf[1] = sn -> term -> value; | |
341 writebytes(buf, 2, 1, of); | |
342 break; | |
343 | |
344 case LWASM_TERM_INT: | |
345 buf[0] = 0x01; | |
346 buf[1] = (sn -> term -> value >> 8) & 0xff; | |
347 buf[2] = sn -> term -> value & 0xff; | |
348 writebytes(buf, 3, 1, of); | |
349 break; | |
350 | |
351 case LWASM_TERM_SECBASE: | |
352 writebytes("\x05", 1, 1, of); | |
353 break; | |
354 | |
355 case LWASM_TERM_SYM: | |
356 // now for the ugly part - resolve a symbol reference | |
357 // and determine whether it's internal, external, or | |
358 // a section base | |
359 se = lwasm_find_symbol(as, sn -> term -> symbol, re -> context); | |
360 if (!se) | |
361 se = lwasm_find_symbol(as, sn -> term -> symbol, -1); | |
362 if (!se || se -> flags & SYMBOL_EXTERN) | |
363 { | |
364 // not found - assume external reference | |
365 // found but flagged external - handle it | |
366 writebytes("\x02", 1, 1, of); | |
367 writebytes(se -> sym, strlen(se -> sym) + 1, 1, of); | |
368 break; | |
369 } | |
370 // a local symbol reference here | |
371 writebytes("\x03", 1, 1, of); | |
372 writebytes(se -> sym, strlen(se -> sym), 1, of); | |
373 if (se -> context >= 0) | |
374 { | |
375 writebytes("\x01", 1, 1, of); | |
376 sprintf(buf, "%d", se -> context); | |
377 writebytes(buf, strlen(buf), 1, of); | |
378 } | |
379 writebytes("", 1, 1, of); | |
380 break; | |
381 | |
382 default: | |
383 // unrecognized term type - replace with integer 0 | |
384 buf[0] = 0x01; | |
385 buf[1] = 0x00; | |
386 buf[2] = 0x00; | |
387 writebytes(buf, 3, 1, of); | |
388 break; | |
389 } | |
390 } | |
391 | |
392 // flag end of expressions | |
393 writebytes("", 1, 1, of); | |
394 | |
395 // write the offset | |
396 buf[0] = (re -> offset >> 8) & 0xff; | |
397 buf[1] = re -> offset & 0xff; | |
398 writebytes(buf, 2, 1, of); | |
399 } | |
400 // flag end of incomplete references list | |
401 writebytes("", 1, 1, of); | |
402 | |
307 // now blast out the code | 403 // now blast out the code |
308 | 404 |
309 // length | 405 // length |
310 buf[0] = s -> oblen >> 8 & 0xff; | 406 buf[0] = s -> oblen >> 8 & 0xff; |
311 buf[1] = s -> oblen & 0xff; | 407 buf[1] = s -> oblen & 0xff; |