Mercurial > hg > index.cgi
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; |