mlibc: GNU Gcc support: setjmp, longjmp.
* stage0/x86.M1 (jmp____*%ebx): New macro. (mov____0x8(%ebp),%ebp): New macro. (mov____0x8(%ebp),%esp): New macro. * include/setjmp.h (jmp_buf): Redefine as struct. * lib/libc-mes+tcc.c (longjmp, setjmp): Implement. * scaffold/tests/80-setjmp.c: Test it. * make.scm ("80-setjmp"): Build it. * .gitignore: Ignore *.tcc-guile.
This commit is contained in:
parent
83f2a55c2c
commit
e8884d83e1
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -18,6 +18,7 @@
|
||||||
*.mini-hex2
|
*.mini-hex2
|
||||||
*.mlibc-gcc
|
*.mlibc-gcc
|
||||||
*.mlibc-o
|
*.mlibc-o
|
||||||
|
*.tcc-guile
|
||||||
!/stage0/*
|
!/stage0/*
|
||||||
!/stage0/*.c
|
!/stage0/*.c
|
||||||
/stage0/exit-42.*
|
/stage0/exit-42.*
|
||||||
|
@ -48,3 +49,4 @@
|
||||||
/doc/fosdem/fosdem.tex
|
/doc/fosdem/fosdem.tex
|
||||||
/doc/fosdem/fosdem.toc
|
/doc/fosdem/fosdem.toc
|
||||||
/doc/fosdem/fosdem.*vrb
|
/doc/fosdem/fosdem.*vrb
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,20 @@
|
||||||
#include_next <setjmp.h>
|
#include_next <setjmp.h>
|
||||||
#else // ! (__GNUC__ && POSIX)
|
#else // ! (__GNUC__ && POSIX)
|
||||||
|
|
||||||
typedef int jmp_buf;
|
typedef struct
|
||||||
|
{
|
||||||
|
int __bp;
|
||||||
|
int __pc;
|
||||||
|
int __sp;
|
||||||
|
} __jmp_buf;
|
||||||
|
typedef __jmp_buf jmp_buf[1];
|
||||||
|
|
||||||
|
#if __MESC__
|
||||||
|
__jmp_buf buf[1];
|
||||||
|
#else
|
||||||
|
jmp_buf buf;
|
||||||
|
#endif
|
||||||
|
|
||||||
void longjmp (jmp_buf env, int val);
|
void longjmp (jmp_buf env, int val);
|
||||||
int setjmp (jmp_buf env);
|
int setjmp (jmp_buf env);
|
||||||
|
|
||||||
|
|
|
@ -184,7 +184,27 @@ localtime (time_t const *timep)
|
||||||
void
|
void
|
||||||
longjmp (jmp_buf env, int val)
|
longjmp (jmp_buf env, int val)
|
||||||
{
|
{
|
||||||
eputs ("longjmp stub\n");
|
val = val == 0 ? 1 : val;
|
||||||
|
#if __MESC__
|
||||||
|
asm ("mov____0x8(%ebp),%eax !0x0c"); // val
|
||||||
|
asm ("mov____0x8(%ebp),%ebp !0x08"); // env*
|
||||||
|
|
||||||
|
asm ("mov____0x8(%ebp),%ebx !0x4"); // env.__pc
|
||||||
|
asm ("mov____0x8(%ebp),%esp !0x8"); // env.__sp
|
||||||
|
asm ("mov____0x8(%ebp),%ebp !0x0"); // env.__bp
|
||||||
|
asm ("jmp____*%ebx");
|
||||||
|
#else
|
||||||
|
asm ("mov 0xc(%ebp),%eax\n\t" // val
|
||||||
|
"mov 0x8(%ebp),%ebp\n\t" // env*
|
||||||
|
|
||||||
|
"mov 0x4(%ebp),%ebx\n\t" // env->__pc
|
||||||
|
"mov 0x8(%ebp),%esp\n\t" // env->__sp
|
||||||
|
"mov 0x0(%ebp),%ebp\n\t" // env->__bp
|
||||||
|
"jmp *%ebx\n\t" // jmp *PC
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
// not reached
|
||||||
|
exit (42);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
@ -235,10 +255,36 @@ remove (char const *file_name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
int
|
||||||
|
setjmp_debug (jmp_buf env, int val)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
#if 1
|
||||||
|
i = env->__bp;
|
||||||
|
i = env->__pc;
|
||||||
|
i = env->__sp;
|
||||||
|
#else
|
||||||
|
i = env[0].__bp;
|
||||||
|
i = env[0].__pc;
|
||||||
|
i = env[0].__sp;
|
||||||
|
#endif
|
||||||
|
return val == 0 ? 1 : val;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __MESC__
|
||||||
|
int
|
||||||
|
setjmp (__jmp_buf *env)
|
||||||
|
#else
|
||||||
int
|
int
|
||||||
setjmp (jmp_buf env)
|
setjmp (jmp_buf env)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
eputs ("setjmp stub\n");
|
int *p = (int*)&env;
|
||||||
|
env[0].__bp = p[-2];
|
||||||
|
env[0].__pc = p[-1];
|
||||||
|
env[0].__sp = (int)&env;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
make.scm
10
make.scm
|
@ -128,6 +128,7 @@ exec ${GUILE-guile} --no-auto-compile -L . -L guile -C . -C guile -s "$0" ${1+"$
|
||||||
(add-target (bin.mescc (string-append "scaffold/tests/" name ".c") #:libc libc #:includes includes))
|
(add-target (bin.mescc (string-append "scaffold/tests/" name ".c") #:libc libc #:includes includes))
|
||||||
(add-target (check (string-append "scaffold/tests/" name "." (cond ((not libc) "0-")
|
(add-target (check (string-append "scaffold/tests/" name "." (cond ((not libc) "0-")
|
||||||
((eq? libc mini-libc-mes.hex2) "mini-")
|
((eq? libc mini-libc-mes.hex2) "mini-")
|
||||||
|
((eq? libc libc-mes+tcc.hex2) "tcc-")
|
||||||
(else "")) "guile") #:exit exit)))
|
(else "")) "guile") #:exit exit)))
|
||||||
|
|
||||||
(add-target (compile.gcc "lib/crt1.c" #:libc #f))
|
(add-target (compile.gcc "lib/crt1.c" #:libc #f))
|
||||||
|
@ -253,6 +254,15 @@ exec ${GUILE-guile} --no-auto-compile -L . -L guile -C . -C guile -s "$0" ${1+"$
|
||||||
|
|
||||||
(add-target (group "check-scaffold-tests" #:dependencies (filter (target-prefix? "check-scaffold/tests") %targets)))
|
(add-target (group "check-scaffold-tests" #:dependencies (filter (target-prefix? "check-scaffold/tests") %targets)))
|
||||||
|
|
||||||
|
;; tests/80: and beyond tinycc; building GNU GCC and dependencies
|
||||||
|
(for-each
|
||||||
|
(cut add-scaffold-test <> #:libc libc-mes+tcc.hex2 #:libc-gcc libc-gcc+tcc.mlibc-o)
|
||||||
|
'("80-setjmp"))
|
||||||
|
|
||||||
|
(add-target (group "check-scaffold-tests/8" #:dependencies (filter (target-prefix? "check-scaffold/tests/8") %targets)))
|
||||||
|
|
||||||
|
(add-target (group "check-scaffold-tests" #:dependencies (filter (target-prefix? "check-scaffold/tests") %targets)))
|
||||||
|
|
||||||
(add-target (cpp.mescc "lib/libc-mes+tcc.c"))
|
(add-target (cpp.mescc "lib/libc-mes+tcc.c"))
|
||||||
(add-target (compile.mescc "lib/libc-mes+tcc.c"))
|
(add-target (compile.mescc "lib/libc-mes+tcc.c"))
|
||||||
|
|
||||||
|
|
58
scaffold/tests/80-setjmp.c
Normal file
58
scaffold/tests/80-setjmp.c
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/* -*-comment-start: "//";comment-end:""-*-
|
||||||
|
* Mes --- Maxwell Equations of Software
|
||||||
|
* Copyright © 2017 Jan Nieuwenhuizen <janneke@gnu.org>
|
||||||
|
*
|
||||||
|
* This file is part of Mes.
|
||||||
|
*
|
||||||
|
* Mes is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* Mes is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Mes. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "30-test.i"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
|
||||||
|
int foo;
|
||||||
|
|
||||||
|
void
|
||||||
|
second()
|
||||||
|
{
|
||||||
|
if (foo++) exit (1);
|
||||||
|
printf ("second\n"); // prints
|
||||||
|
longjmp (buf,1); // jumps back to where setjmp was called - making setjmp now return 1
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
first ()
|
||||||
|
{
|
||||||
|
second ();
|
||||||
|
printf ("first\n"); // does not print
|
||||||
|
exit (2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
test ()
|
||||||
|
{
|
||||||
|
if (!setjmp (buf))
|
||||||
|
first (); // when executed, setjmp returned 0
|
||||||
|
else // when longjmp jumps back, setjmp returns 1
|
||||||
|
{
|
||||||
|
printf ("main\n"); // prints
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 3;
|
||||||
|
}
|
|
@ -51,8 +51,8 @@ DEFINE cmp____%al,%dl 38c2
|
||||||
DEFINE cmp____%edx,%eax 39d0
|
DEFINE cmp____%edx,%eax 39d0
|
||||||
DEFINE hlt f4
|
DEFINE hlt f4
|
||||||
DEFINE idiv___%ebx f7fb
|
DEFINE idiv___%ebx f7fb
|
||||||
DEFINE int____$0x80 cd80
|
|
||||||
DEFINE int cd
|
DEFINE int cd
|
||||||
|
DEFINE int____$0x80 cd80
|
||||||
DEFINE je32 0f84
|
DEFINE je32 0f84
|
||||||
DEFINE je8 74
|
DEFINE je8 74
|
||||||
DEFINE jg32 0f8f
|
DEFINE jg32 0f8f
|
||||||
|
@ -60,6 +60,7 @@ DEFINE jge32 0f8d
|
||||||
DEFINE jl32 0f8c
|
DEFINE jl32 0f8c
|
||||||
DEFINE jle32 0f8e
|
DEFINE jle32 0f8e
|
||||||
DEFINE jmp32 e9
|
DEFINE jmp32 e9
|
||||||
|
DEFINE jmp____*%ebx ffe3
|
||||||
DEFINE jne32 0f85
|
DEFINE jne32 0f85
|
||||||
DEFINE lahf 9f
|
DEFINE lahf 9f
|
||||||
DEFINE lea____0x32(%ebp),%eax 8d85
|
DEFINE lea____0x32(%ebp),%eax 8d85
|
||||||
|
@ -128,9 +129,11 @@ DEFINE mov____0x8(%eax),%eax 8b40
|
||||||
DEFINE mov____0x8(%eax),%ebx 8b58
|
DEFINE mov____0x8(%eax),%ebx 8b58
|
||||||
DEFINE mov____0x8(%eax),%ecx 8b48
|
DEFINE mov____0x8(%eax),%ecx 8b48
|
||||||
DEFINE mov____0x8(%ebp),%eax 8b45
|
DEFINE mov____0x8(%ebp),%eax 8b45
|
||||||
|
DEFINE mov____0x8(%ebp),%ebp 8b6d
|
||||||
DEFINE mov____0x8(%ebp),%ebx 8b5d
|
DEFINE mov____0x8(%ebp),%ebx 8b5d
|
||||||
DEFINE mov____0x8(%ebp),%ecx 8b4d
|
DEFINE mov____0x8(%ebp),%ecx 8b4d
|
||||||
DEFINE mov____0x8(%ebp),%edx 8b55
|
DEFINE mov____0x8(%ebp),%edx 8b55
|
||||||
|
DEFINE mov____0x8(%ebp),%esp 8b65
|
||||||
DEFINE movzbl_%al,%eax 0fb6c0
|
DEFINE movzbl_%al,%eax 0fb6c0
|
||||||
DEFINE movzbl_%dl,%edx 0fb6d2
|
DEFINE movzbl_%dl,%edx 0fb6d2
|
||||||
DEFINE movzbl_(%eax),%eax 0fb600
|
DEFINE movzbl_(%eax),%eax 0fb600
|
||||||
|
|
Loading…
Reference in a new issue