From: Tormod Volden Date: Thu, 16 Apr 2015 22:00:19 +0000 (+0200) Subject: 6809 Fix syscall glue for variadic functions X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=5736885db2ba7d0d3d5487c5502c9a56123c4710;p=FUZIX.git 6809 Fix syscall glue for variadic functions gcc6809 uses a fastcall calling convention with the first argument in X, the second and up on the stack. However, variadic functions get all the arguments on the stack. We therefore mangle the stack for these functions so that they appear as fastcall to the kernel. Signed-off-by: Tormod Volden --- diff --git a/Library/libs/fuzix6809/syscall6809.s b/Library/libs/fuzix6809/syscall6809.s index a8c906da..0f284d37 100644 --- a/Library/libs/fuzix6809/syscall6809.s +++ b/Library/libs/fuzix6809/syscall6809.s @@ -1,4 +1,5 @@ .globl __syscall + .globl __syscall_mangled .globl _errno .area .text @@ -10,3 +11,14 @@ __syscall: error: std _errno ; X is -1 rts + +; for variadic functions: +; compensate for the 1st argument that we removed +__syscall_mangled: + swi + beq noerr + std _errno +noerr: + puls d ; get return address + pshs d,x ; inject a word on stack + rts diff --git a/Library/tools/syscall_6809.c b/Library/tools/syscall_6809.c index f310978c..cd4d93ab 100644 --- a/Library/tools/syscall_6809.c +++ b/Library/tools/syscall_6809.c @@ -18,11 +18,23 @@ static void write_call(int n) perror(namebuf); exit(1); } - fprintf(fp, "\t.area .text\n\n"); - fprintf(fp, "\t.globl __syscall\n"); - fprintf(fp, "\t.globl _%s\n\n", syscall_name[n]); - fprintf(fp, "_%s:\n\tldd #%d\n", syscall_name[n], n); - fprintf(fp, "\tjmp __syscall\n"); + fprintf(fp, "\t.area .text\n\n" + "\t.globl __syscall\n" + "\t.globl __syscall_mangled\n" + "\t.globl _%1$s\n\n" + "_%1$s:\n", syscall_name[n]); + if (syscall_args[n] == VARARGS) { + /* Mangle into fastcall like the others: */ + /* get return address and X (first argument) */ + /* then put return address back */ + fprintf(fp, "\tpuls d,x\n" + "\tpshs d\n" + "\tldd #%d\n" + "\tjmp __syscall_mangled\n", n); + } else { + fprintf(fp, "\tldd #%d\n" + "\tjmp __syscall\n", n); + } fclose(fp); }