# HG changeset patch # User William Astle # Date 1359686094 25200 # Node ID ebda5c96665e09729db3b6c04cedce3fbb941157 # Parent d5374e80dd04ff75281bd581bed47d23b5406697 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. diff -r d5374e80dd04 -r ebda5c96665e lwlink/link.c --- a/lwlink/link.c Thu Jan 31 16:28:41 2013 -0700 +++ b/lwlink/link.c Thu Jan 31 19:34:54 2013 -0700 @@ -690,19 +690,48 @@ return rval; } -void check_os9(void) +void foreach_section_aux(char *name, fileinfo_t *fn, void (*fnp)(section_t *s, void *arg), void *arg) { - section_t *s; - symtab_t *sym; + int sn; - s = find_section_by_name_once("__os9"); - linkscript.name = outfile; + if (fn -> forced == 0) + return; + + for (sn = 0; sn < fn -> nsections; sn++) + { + if (!strcmp(name, (char *)(fn -> sections[sn].name))) + { + (*fnp)(&(fn -> sections[sn]), arg); + } + } + for (sn = 0; sn < fn -> nsubs; sn++) + { + foreach_section_aux(name, fn -> subs[sn], fnp, arg); + } +} +void foreach_section(char *name, void (*fnp)(section_t *s, void *arg), void *arg) +{ + int fn; - if (!s) + for (fn = 0; fn < ninputfiles; fn++) { - // use defaults if not found - return; - } + foreach_section_aux(name, inputfiles[fn], fnp, arg); + } +} + +struct check_os9_aux_s +{ + int typeseen; + int attrseen; + int langseen; + int revseen; + int nameseen; +}; + +void check_os9_aux(section_t *s, void *arg) +{ + struct check_os9_aux_s *st = arg; + symtab_t *sym; // this section is special // several symbols may be defined as LOCAL symbols: @@ -720,6 +749,7 @@ if (s -> codesize > 0 && (s -> flags & SECTION_BSS) == 0 && s -> code[0] != 0) { linkscript.name = (char *)(s -> code); + st -> nameseen++; } for (sym = s -> localsyms; sym; sym = sym -> next) @@ -728,20 +758,36 @@ if (!strcasecmp(sm, "type")) { linkscript.modtype = sym -> offset; + st -> typeseen++; } else if (!strcasecmp(sm, "lang")) { linkscript.modlang = sym -> offset; + st -> langseen++; } else if (!strcasecmp(sm, "attr")) { linkscript.modattr = sym -> offset; + st -> attrseen++; } else if (!strcasecmp(sm, "rev")) { linkscript.modrev = sym -> offset; + st -> revseen++; + } + else if (!strcasecmp(sm, "stack")) + { + linkscript.stacksize += sym -> offset; } } +} + +void check_os9(void) +{ + struct check_os9_aux_s st = { 0 }; + + linkscript.name = outfile; + foreach_section("__os9", check_os9_aux, &st); if (linkscript.modtype > 15) linkscript.modtype = linkscript.modtype >> 4; @@ -752,6 +798,14 @@ linkscript.modtype &= 15; linkscript.modrev &= 15; linkscript.modattr &= 15; + + if (st.attrseen > 1 || st.typeseen > 1 || + st.langseen > 1 || st.revseen > 1 || + st.nameseen > 1 + ) + { + fprintf(stderr, "Warning: multiple instances of __os9 found with duplicate settings of type, lang, attr, rev, or module name.\n"); + } } void resolve_padding(void) diff -r d5374e80dd04 -r ebda5c96665e lwlink/output.c --- a/lwlink/output.c Thu Jan 31 16:28:41 2013 -0700 +++ b/lwlink/output.c Thu Jan 31 19:34:54 2013 -0700 @@ -262,6 +262,7 @@ } codedatasize += sectlist[sn].ptr -> codesize; } + bsssize += linkscript.stacksize; // now bss size is the data size for the module // and codesize is the length of the module minus the module header diff -r d5374e80dd04 -r ebda5c96665e lwlink/script.c --- a/lwlink/script.c Thu Jan 31 16:28:41 2013 -0700 +++ b/lwlink/script.c Thu Jan 31 19:34:54 2013 -0700 @@ -43,6 +43,7 @@ "section .data\n" "section bss,bss load 0000\n" "section .bss,bss\n" + "stacksize 32\n" "entry __start\n" ;