|
@@ -3,7 +3,7 @@ MODULE Kernel;
|
|
|
(* THIS IS TEXT COPY OF Kernel.odc *)
|
|
|
(* DO NOT EDIT *)
|
|
|
|
|
|
- (* A. V. Shiryaev, 2012.09
|
|
|
+ (* A. V. Shiryaev, 2012.10
|
|
|
OpenBSD Kernel
|
|
|
Based on 1.6-rc6 Windows Kernel
|
|
|
+ 20120822 Marc changes
|
|
@@ -15,8 +15,10 @@ MODULE Kernel;
|
|
|
OpenBSD(/Linux)-specific code marked green
|
|
|
|
|
|
TODO:
|
|
|
- IsReadable
|
|
|
+ handle stack overflow exceptions
|
|
|
+ IsReadable0
|
|
|
correct cmdLine
|
|
|
+ Quit from TrapHandler
|
|
|
*)
|
|
|
|
|
|
IMPORT S := SYSTEM, Libc := LinLibc, Dl := LinDl;
|
|
@@ -65,7 +67,9 @@ MODULE Kernel;
|
|
|
debug = FALSE;
|
|
|
|
|
|
|
|
|
+(*
|
|
|
sigStackSize = MAX(Libc.SIGSTKSZ, 65536);
|
|
|
+*)
|
|
|
|
|
|
trapReturn = 1; (* Return value for sigsetjmp given from siglongjmp *)
|
|
|
|
|
@@ -264,10 +268,14 @@ MODULE Kernel;
|
|
|
watcher*: PROCEDURE (event: INTEGER); (* for debugging *)
|
|
|
|
|
|
|
|
|
+(*
|
|
|
sigStack: Libc.PtrVoid;
|
|
|
+*)
|
|
|
|
|
|
loopContext: Libc.sigjmp_buf; (* trap return context, if no Kernel.Try has been used. *)
|
|
|
currentTryContext: POINTER TO Libc.sigjmp_buf; (* trap return context, if Kernel.Try has been used. *)
|
|
|
+ isReadableContext: Libc.sigjmp_buf; (* for IsReadable *)
|
|
|
+ isReadableCheck: BOOLEAN;
|
|
|
|
|
|
guiHook: GuiHook;
|
|
|
|
|
@@ -487,7 +495,7 @@ MODULE Kernel;
|
|
|
|
|
|
(* -------------------- system memory management --------------------- *)
|
|
|
|
|
|
- (* A. V. Shiryaev, 2012.09: NOTE: it seems that GC works correctly with positive addesses only *)
|
|
|
+ (* A. V. Shiryaev, 2012.10: NOTE: it seems that GC works correctly with positive addesses only *)
|
|
|
|
|
|
(*
|
|
|
PROCEDURE HeapAlloc (adr: INTEGER; size: INTEGER; prot: SET): Libc.PtrVoid;
|
|
@@ -608,39 +616,35 @@ MODULE Kernel;
|
|
|
END IsReadable;
|
|
|
*)
|
|
|
|
|
|
- (* NOTE:
|
|
|
- TRUE result DOES NOT GUARANTEE what mem region is REALLY accessible! (implementation limit) *)
|
|
|
+ (* Alexander Shiryaev, 2012.10: I do not know other way that works in OpenBSD *)
|
|
|
PROCEDURE IsReadable* (from, to: INTEGER): BOOLEAN;
|
|
|
(* check wether memory between from (incl.) and to (excl.) may be read *)
|
|
|
- VAR nullfd: INTEGER;
|
|
|
- res1, errno: INTEGER;
|
|
|
- res: BOOLEAN;
|
|
|
+ VAR res: BOOLEAN; res1: INTEGER;
|
|
|
+ x: SHORTCHAR;
|
|
|
BEGIN
|
|
|
- ASSERT(from < to, 20);
|
|
|
-
|
|
|
res := FALSE;
|
|
|
-
|
|
|
- nullfd := Libc.open("/dev/null", Libc.O_WRONLY, {});
|
|
|
- IF nullfd >= 0 THEN
|
|
|
- res1 := Libc.write(nullfd, from, to - from);
|
|
|
- IF res1 = -1 THEN
|
|
|
- S.GET(Libc.__errno_location(), errno);
|
|
|
- IF errno = Libc.EFAULT THEN
|
|
|
- res := FALSE
|
|
|
- ELSE
|
|
|
- HALT(101)
|
|
|
- END
|
|
|
- ELSE ASSERT(res1 = to - from);
|
|
|
- res := TRUE
|
|
|
- END;
|
|
|
- res1 := Libc.close(nullfd)
|
|
|
- ELSE ASSERT(nullfd = -1);
|
|
|
- HALT(100)
|
|
|
+ res1 := Libc.sigsetjmp(isReadableContext, Libc.TRUE);
|
|
|
+ IF res1 = 0 THEN
|
|
|
+ isReadableCheck := TRUE;
|
|
|
+ (* read memory *)
|
|
|
+ REPEAT
|
|
|
+ S.GET(from, x);
|
|
|
+ INC(from)
|
|
|
+ UNTIL from = to;
|
|
|
+ res := TRUE
|
|
|
+ ELSE
|
|
|
+ ASSERT(res1 = 1, 100)
|
|
|
END;
|
|
|
-
|
|
|
+ isReadableCheck := FALSE;
|
|
|
RETURN res
|
|
|
END IsReadable;
|
|
|
|
|
|
+ (* to call from TrapHandler *)
|
|
|
+ PROCEDURE IsReadable0 (from, to: INTEGER): BOOLEAN;
|
|
|
+ BEGIN
|
|
|
+ RETURN TRUE (* TODO *)
|
|
|
+ END IsReadable0;
|
|
|
+
|
|
|
(* --------------------- NEW implementation (portable) -------------------- *)
|
|
|
|
|
|
PROCEDURE^ NewBlock (size: INTEGER): Block;
|
|
@@ -1168,6 +1172,30 @@ MODULE Kernel;
|
|
|
|
|
|
(* -------------------- dynamic link libraries --------------------- *)
|
|
|
|
|
|
+(*
|
|
|
+ PROCEDURE DlOpen (name: ARRAY OF SHORTCHAR): Dl.HANDLE;
|
|
|
+ CONST flags = Dl.RTLD_LAZY + Dl.RTLD_GLOBAL;
|
|
|
+ VAR h: Dl.HANDLE;
|
|
|
+ i: INTEGER;
|
|
|
+ BEGIN
|
|
|
+ h := Dl.NULL;
|
|
|
+ i := 0; WHILE (i < LEN(name)) & (name[i] # 0X) DO INC(i) END;
|
|
|
+ IF i < LEN(name) THEN
|
|
|
+ h := Dl.dlopen(name, flags);
|
|
|
+ WHILE (h = Dl.NULL) & (i > 0) DO
|
|
|
+ DEC(i);
|
|
|
+ WHILE (i > 0) & (name[i] # '.') DO DEC(i) END;
|
|
|
+ IF i > 0 THEN
|
|
|
+ name[i] := 0X;
|
|
|
+ h := Dl.dlopen(name, flags);
|
|
|
+ (* IF h # Dl.NULL THEN Msg(name$) END *)
|
|
|
+ END
|
|
|
+ END
|
|
|
+ END;
|
|
|
+ RETURN h
|
|
|
+ END DlOpen;
|
|
|
+*)
|
|
|
+
|
|
|
PROCEDURE LoadDll* (IN name: ARRAY OF SHORTCHAR; VAR ok: BOOLEAN);
|
|
|
VAR h: Dl.HANDLE;
|
|
|
BEGIN
|
|
@@ -1869,8 +1897,14 @@ MODULE Kernel;
|
|
|
WriteString("================================"); WriteLn
|
|
|
END ShowTrap;
|
|
|
|
|
|
- PROCEDURE TrapHandler (sig: INTEGER; siginfo: Libc.Ptrsiginfo_t; context: Libc.Ptrucontext_t);
|
|
|
+ PROCEDURE (* [ccall] *) TrapHandler (sig: INTEGER; siginfo: Libc.Ptrsiginfo_t; context: Libc.Ptrucontext_t);
|
|
|
BEGIN
|
|
|
+ IF isReadableCheck THEN
|
|
|
+ isReadableCheck := FALSE;
|
|
|
+ Msg("~IsReadable");
|
|
|
+ Libc.siglongjmp(isReadableContext, 1)
|
|
|
+ END;
|
|
|
+
|
|
|
(*
|
|
|
S.GETREG(SP, sp);
|
|
|
S.GETREG(FP, fp);
|
|
@@ -1900,7 +1934,7 @@ MODULE Kernel;
|
|
|
err := 200 (* Interrupt (ANSI). *)
|
|
|
| Libc.SIGILL: (* Illegal instruction (ANSI). *)
|
|
|
err := 202; val := 0;
|
|
|
- IF IsReadable(pc, pc + 4) THEN
|
|
|
+ IF IsReadable0(pc, pc + 4) THEN
|
|
|
S.GET(pc, val);
|
|
|
IF val MOD 100H = 8DH THEN (* lea reg,reg *)
|
|
|
IF val DIV 100H MOD 100H = 0F0H THEN
|
|
@@ -1954,16 +1988,19 @@ MODULE Kernel;
|
|
|
IF restart # NIL THEN (* Start failed *)
|
|
|
Libc.siglongjmp(loopContext, trapReturn)
|
|
|
END;
|
|
|
- Quit(1);
|
|
|
+ Quit(1); (* FIXME *)
|
|
|
END;
|
|
|
trapped := FALSE
|
|
|
END TrapHandler;
|
|
|
|
|
|
PROCEDURE InstallSignals*;
|
|
|
VAR sa, old: Libc.sigaction_t; res, i: INTEGER;
|
|
|
+(*
|
|
|
sigstk: Libc.sigaltstack_t;
|
|
|
errno: INTEGER;
|
|
|
+*)
|
|
|
BEGIN
|
|
|
+(*
|
|
|
(* A. V. Shiryaev: Set alternative stack on which signals are to be processed *)
|
|
|
sigstk.ss_sp := sigStack;
|
|
|
sigstk.ss_size := sigStackSize;
|
|
@@ -1974,13 +2011,14 @@ MODULE Kernel;
|
|
|
Int(errno);
|
|
|
Libc.exit(1)
|
|
|
END;
|
|
|
+*)
|
|
|
|
|
|
sa.sa_sigaction := TrapHandler;
|
|
|
(*
|
|
|
res := LinLibc.sigemptyset(S.ADR(sa.sa_mask));
|
|
|
*)
|
|
|
res := Libc.sigfillset(S.ADR(sa.sa_mask));
|
|
|
- sa.sa_flags := Libc.SA_ONSTACK + Libc.SA_SIGINFO; (* TrapHandler takes three arguments *)
|
|
|
+ sa.sa_flags := (* Libc.SA_ONSTACK + *) Libc.SA_SIGINFO; (* TrapHandler takes three arguments *)
|
|
|
(*
|
|
|
IF LinLibc.sigaction(LinLibc.SIGINT, sa, old) # 0 THEN Msg("failed to install SIGINT") END;
|
|
|
IF LinLibc.sigaction(LinLibc.SIGILL, sa, old) # 0 THEN Msg("failed to install SIGILL") END;
|
|
@@ -2004,12 +2042,16 @@ MODULE Kernel;
|
|
|
PROCEDURE Init;
|
|
|
VAR i: INTEGER;
|
|
|
BEGIN
|
|
|
+(*
|
|
|
(* for sigaltstack *)
|
|
|
sigStack := Libc.calloc(1, sigStackSize);
|
|
|
IF sigStack = Libc.NULL THEN
|
|
|
Msg("ERROR: Kernel.Init: calloc(1, sigStackSize) failed!");
|
|
|
Libc.exit(1)
|
|
|
END;
|
|
|
+*)
|
|
|
+
|
|
|
+ isReadableCheck := FALSE;
|
|
|
|
|
|
InstallSignals; (* init exception handling *)
|
|
|
currentTryContext := NIL;
|
|
@@ -2057,13 +2099,12 @@ MODULE Kernel;
|
|
|
|
|
|
BEGIN
|
|
|
IF modList = NIL THEN (* only once *)
|
|
|
+ S.GETREG(SP, baseStack); (* TODO: Check that this is ok. *)
|
|
|
IF bootInfo # NIL THEN
|
|
|
modList := bootInfo.modList; (* boot loader initializes the bootInfo struct *)
|
|
|
- S.GETREG(SP, baseStack); (* TODO: Check that this is ok. *)
|
|
|
SetCmdLine
|
|
|
ELSE
|
|
|
S.GETREG(ML, modList); (* linker loads module list to BX *)
|
|
|
- S.GETREG(SP, baseStack);
|
|
|
SetCmdLine2
|
|
|
END;
|
|
|
static := init IN modList.opts;
|