comparison lwlink/link.c @ 258:ebda5c96665e

Improved stack handling for os9 target in lwlink Added "stack" as a valid symbol in the __os9 section. All instances of __os9 are now polled for "stack" symobls and the values added to the stack size set in the linker script. The stack size is then added to the final data size of the module. Also set a default minimum stack size of 32 bytes.
author William Astle <lost@l-w.ca>
date Thu, 31 Jan 2013 19:34:54 -0700
parents d5374e80dd04
children 7de7b14ebaee
comparison
equal deleted inserted replaced
257:d5374e80dd04 258:ebda5c96665e
688 fprintf(stderr, "Warning: multiple instances of section %s found; ignoring all of them which is probably not what you want\n", name); 688 fprintf(stderr, "Warning: multiple instances of section %s found; ignoring all of them which is probably not what you want\n", name);
689 } 689 }
690 return rval; 690 return rval;
691 } 691 }
692 692
693 void check_os9(void) 693 void foreach_section_aux(char *name, fileinfo_t *fn, void (*fnp)(section_t *s, void *arg), void *arg)
694 { 694 {
695 section_t *s; 695 int sn;
696
697 if (fn -> forced == 0)
698 return;
699
700 for (sn = 0; sn < fn -> nsections; sn++)
701 {
702 if (!strcmp(name, (char *)(fn -> sections[sn].name)))
703 {
704 (*fnp)(&(fn -> sections[sn]), arg);
705 }
706 }
707 for (sn = 0; sn < fn -> nsubs; sn++)
708 {
709 foreach_section_aux(name, fn -> subs[sn], fnp, arg);
710 }
711 }
712 void foreach_section(char *name, void (*fnp)(section_t *s, void *arg), void *arg)
713 {
714 int fn;
715
716 for (fn = 0; fn < ninputfiles; fn++)
717 {
718 foreach_section_aux(name, inputfiles[fn], fnp, arg);
719 }
720 }
721
722 struct check_os9_aux_s
723 {
724 int typeseen;
725 int attrseen;
726 int langseen;
727 int revseen;
728 int nameseen;
729 };
730
731 void check_os9_aux(section_t *s, void *arg)
732 {
733 struct check_os9_aux_s *st = arg;
696 symtab_t *sym; 734 symtab_t *sym;
697
698 s = find_section_by_name_once("__os9");
699 linkscript.name = outfile;
700
701 if (!s)
702 {
703 // use defaults if not found
704 return;
705 }
706 735
707 // this section is special 736 // this section is special
708 // several symbols may be defined as LOCAL symbols: 737 // several symbols may be defined as LOCAL symbols:
709 // type: module type 738 // type: module type
710 // lang: module language 739 // lang: module language
718 // the contents of the actual data to the first NUL 747 // the contents of the actual data to the first NUL
719 // is assumed to be the module name unless it is an empty string 748 // is assumed to be the module name unless it is an empty string
720 if (s -> codesize > 0 && (s -> flags & SECTION_BSS) == 0 && s -> code[0] != 0) 749 if (s -> codesize > 0 && (s -> flags & SECTION_BSS) == 0 && s -> code[0] != 0)
721 { 750 {
722 linkscript.name = (char *)(s -> code); 751 linkscript.name = (char *)(s -> code);
752 st -> nameseen++;
723 } 753 }
724 754
725 for (sym = s -> localsyms; sym; sym = sym -> next) 755 for (sym = s -> localsyms; sym; sym = sym -> next)
726 { 756 {
727 char *sm = (char *)(sym -> sym); 757 char *sm = (char *)(sym -> sym);
728 if (!strcasecmp(sm, "type")) 758 if (!strcasecmp(sm, "type"))
729 { 759 {
730 linkscript.modtype = sym -> offset; 760 linkscript.modtype = sym -> offset;
761 st -> typeseen++;
731 } 762 }
732 else if (!strcasecmp(sm, "lang")) 763 else if (!strcasecmp(sm, "lang"))
733 { 764 {
734 linkscript.modlang = sym -> offset; 765 linkscript.modlang = sym -> offset;
766 st -> langseen++;
735 } 767 }
736 else if (!strcasecmp(sm, "attr")) 768 else if (!strcasecmp(sm, "attr"))
737 { 769 {
738 linkscript.modattr = sym -> offset; 770 linkscript.modattr = sym -> offset;
771 st -> attrseen++;
739 } 772 }
740 else if (!strcasecmp(sm, "rev")) 773 else if (!strcasecmp(sm, "rev"))
741 { 774 {
742 linkscript.modrev = sym -> offset; 775 linkscript.modrev = sym -> offset;
743 } 776 st -> revseen++;
744 } 777 }
778 else if (!strcasecmp(sm, "stack"))
779 {
780 linkscript.stacksize += sym -> offset;
781 }
782 }
783 }
784
785 void check_os9(void)
786 {
787 struct check_os9_aux_s st = { 0 };
788
789 linkscript.name = outfile;
790 foreach_section("__os9", check_os9_aux, &st);
745 if (linkscript.modtype > 15) 791 if (linkscript.modtype > 15)
746 linkscript.modtype = linkscript.modtype >> 4; 792 linkscript.modtype = linkscript.modtype >> 4;
747 793
748 if (linkscript.modattr > 15) 794 if (linkscript.modattr > 15)
749 linkscript.modattr = linkscript.modattr >> 4; 795 linkscript.modattr = linkscript.modattr >> 4;
750 796
751 linkscript.modlang &= 15; 797 linkscript.modlang &= 15;
752 linkscript.modtype &= 15; 798 linkscript.modtype &= 15;
753 linkscript.modrev &= 15; 799 linkscript.modrev &= 15;
754 linkscript.modattr &= 15; 800 linkscript.modattr &= 15;
801
802 if (st.attrseen > 1 || st.typeseen > 1 ||
803 st.langseen > 1 || st.revseen > 1 ||
804 st.nameseen > 1
805 )
806 {
807 fprintf(stderr, "Warning: multiple instances of __os9 found with duplicate settings of type, lang, attr, rev, or module name.\n");
808 }
755 } 809 }
756 810
757 void resolve_padding(void) 811 void resolve_padding(void)
758 { 812 {
759 int sn; 813 int sn;