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;