comparison lwlink/link.c @ 148:08fb11004df9

Initial pass at OS9 module support for lwlink
author lost@l-w.ca
date Fri, 26 Aug 2011 23:26:00 -0600
parents fdc11ef4115b
children 729a9c70934e
comparison
equal deleted inserted replaced
147:9cf1796259b2 148:08fb11004df9
27 27
28 #include <lw_alloc.h> 28 #include <lw_alloc.h>
29 29
30 #include "expr.h" 30 #include "expr.h"
31 #include "lwlink.h" 31 #include "lwlink.h"
32
33 void check_os9(void);
32 34
33 struct section_list *sectlist = NULL; 35 struct section_list *sectlist = NULL;
34 int nsects = 0; 36 int nsects = 0;
35 static int nforced = 0; 37 static int nforced = 0;
36 38
388 } 390 }
389 } 391 }
390 392
391 if (symerr) 393 if (symerr)
392 exit(1); 394 exit(1);
395
396 if (outformat == OUTPUT_OS9)
397 check_os9();
393 } 398 }
394 399
395 /* 400 /*
396 This is just a pared down version of the algo for resolving references. 401 This is just a pared down version of the algo for resolving references.
397 */ 402 */
458 continue; 463 continue;
459 464
460 fprintf(stderr, "Warning: %s (%d) does not resolve any symbols\n", inputfiles[fn] -> filename, fn); 465 fprintf(stderr, "Warning: %s (%d) does not resolve any symbols\n", inputfiles[fn] -> filename, fn);
461 } 466 }
462 } 467 }
468 void find_section_by_name_once_aux(char *name, fileinfo_t *fn, section_t **rval, int *found);
469 void find_section_by_name_once_aux(char *name, fileinfo_t *fn, section_t **rval, int *found)
470 {
471 int sn;
472
473 if (fn -> forced == 0)
474 return;
475
476 for (sn = 0; sn < fn -> nsections; sn++)
477 {
478 if (!strcmp(name, (char *)(fn -> sections[sn].name)))
479 {
480 (*found)++;
481 *rval = &(fn -> sections[sn]);
482 }
483 }
484 for (sn = 0; sn < fn -> nsubs; sn++)
485 {
486 find_section_by_name_once_aux(name, fn -> subs[sn], rval, found);
487 }
488 }
489
490 section_t *find_section_by_name_once(char *name)
491 {
492 int fn;
493 int found = 0;
494 section_t *rval = NULL;
495
496 for (fn = 0; fn < ninputfiles; fn++)
497 {
498 find_section_by_name_once_aux(name, inputfiles[fn], &rval, &found);
499 }
500 if (found != 1)
501 {
502 rval = NULL;
503 fprintf(stderr, "Warning: multiple instances of section %s found; ignoring all of them which is probably not what you want\n", name);
504 }
505 return rval;
506 }
507
508 void check_os9(void)
509 {
510 section_t *s;
511 symtab_t *sym;
512
513 s = find_section_by_name_once("__os9");
514 linkscript.name = outfile;
515
516 if (!s)
517 {
518 // use defaults if not found
519 return;
520 }
521
522 // this section is special
523 // several symbols may be defined as LOCAL symbols:
524 // type: module type
525 // lang: module language
526 // attr: module attributes
527 // rev: module revision
528 //
529 // the symbols are not case sensitive
530 //
531 // any unrecognized symbols are ignored
532
533 // the contents of the actual data to the first NUL
534 // is assumed to be the module name unless it is an empty string
535 if (s -> codesize > 0 && (s -> flags & SECTION_BSS) == 0 && s -> code[0] != 0)
536 {
537 linkscript.name = (char *)(s -> code);
538 }
539
540 for (sym = s -> localsyms; s; sym = sym -> next)
541 {
542 char *sm = (char *)(sym -> sym);
543 if (!strcasecmp(sm, "type"))
544 {
545 linkscript.modtype = sym -> offset;
546 }
547 else if (!strcasecmp(sm, "lang"))
548 {
549 linkscript.modlang = sym -> offset;
550 }
551 else if (!strcasecmp(sm, "attr"))
552 {
553 linkscript.modlang = sym -> offset;
554 }
555 else if (!strcasecmp(sm, "rev"))
556 {
557 linkscript.modrev = sym -> offset;
558 }
559 }
560 if (linkscript.modtype > 15)
561 linkscript.modtype = linkscript.modtype >> 4;
562
563 if (linkscript.modattr > 15)
564 linkscript.modattr = linkscript.modattr >> 4;
565
566 linkscript.modlang &= 15;
567 linkscript.modtype &= 15;
568 linkscript.modrev &= 15;
569 linkscript.modattr &= 15;
570 }