syscall68000: Special fork handling
authorAlan Cox <alan@linux.intel.com>
Thu, 20 Oct 2016 16:43:29 +0000 (17:43 +0100)
committerAlan Cox <alan@linux.intel.com>
Thu, 20 Oct 2016 16:43:29 +0000 (17:43 +0100)
Library/libs/fuzix68000/syscall__fork.S
Library/tools/syscall_68000.c

index 8413516..d22f64e 100644 (file)
@@ -4,14 +4,17 @@
 
 _fork:
 .mri 1
-       movem.l d2-d7/a2-a6,-(sp)
+       move.l 4(sp),d1
+       movem.l d0-d7/a2-a6,-(sp)
        move.w #32,d0
        trap #14
        ext.l d1
        bne _error
+       addq #8,sp
        movem.l (sp)+,d2-d7/a2-a6
        rts
 _error:
        move.l d1,errno
+       addq #8,sp
        movem.l (sp)+,d2-d7/a2-a6
        rts
index b6ff5b9..877e040 100644 (file)
@@ -21,9 +21,12 @@ static void write_call(int n)
   }
   /*
    *   We define _fork() as trashing all the registers except the return
-   *   values and a7. This little userspace ick here allows us to avoid saving
+   *   values a5 and a7. The userspace ick here allows us to avoid saving
    *   all the registers on syscall entry just in case we are doing a fork and
    *   have multiple udata blocks.
+   *
+   *   Note: this does mean if you want a register global you need to use a5
+   *   or ensure you never take a signal in the fork() area - doable but ugly.
    */
   if (strcmp(syscall_name[n], "_fork") == 0)
     saves = 1;
@@ -32,8 +35,11 @@ static void write_call(int n)
              "\t.globl %1$s\n\n"
              "%1$s:\n", syscall_name[n]);
   fprintf(fp, ".mri 1\n");
+  /* If saving we build a valid stack frame for the syscall below the saves
+     using d0/d1 - d0 is the non-existent return address, d1 is the argument */
   if (saves)
-    fprintf(fp, "\tmovem.l d2-d7/a2-a6,-(sp)\n");
+    fprintf(fp, "\tmove.l 4(sp),d1\n"
+                "\tmovem.l d0-d7/a2-a6,-(sp)\n");
   fprintf(fp, "\tmove.w #%d,d0\n"
              "\ttrap #14\n", n);
   /* ext is the same speed as tst so we might as well do the ext in case
@@ -43,13 +49,15 @@ static void write_call(int n)
   fprintf(fp, "\text.l d1\n"
               "\tbne _error\n");
   if (saves)
-    fprintf(fp, "\tmovem.l (sp)+,d2-d7/a2-a6\n");
+    fprintf(fp, "\taddq #8,sp\n"
+                "\tmovem.l (sp)+,d2-d7/a2-a6\n");
 
   fprintf(fp, "\trts\n"
               "_error:\n"
               "\tmove.l d1,errno\n");
   if (saves)
-    fprintf(fp, "\tmovem.l (sp)+,d2-d7/a2-a6\n");
+    fprintf(fp, "\taddq #8,sp\n"
+                "\tmovem.l (sp)+,d2-d7/a2-a6\n");
   fprintf(fp, "\trts\n");
   fclose(fp);
 }