kh (12/11/82)
We have installed Clocksin & Mellish's PDP-11 version of Prolog NU-7 on a VAX-11/780 with the compat package that came with 4BSD. Some changes to the compat package were needed to make it work correctly. I have made the following changes to create a "v7run" that will work better, but it still isn't perfect. (1) The way NU-7 used the stack memory, compat thought that an overflow occurs when there is a BRK system call. We just removed the check (around line 365 of unixtraps.c). This fix was suggested by John Lloyd at the Univ. of Melbourne. (2) Signals, specifically those generated by hitting <BREAK>, can cause an illegal instruction. I have reduced the chance of this happening, but I haven't eliminated it. The rest of this article deals with this problem. The problem (or at least part of the problem), is that when you are in native mode (simulating a system call or a floating point op), and a signal is received, sigcatch is called, and it in turn calls dosig(). Unfortunately, the "pc" that dosig() pushes onto the stack to may not point to the next instruction, but may instead point to a system call argument. There are several possible solutions to this: (1) Update "pc" as soon as possible. Unfortunately, this only reduces the chance that a signal will be caught when pc is bad. To do this, move the code: if (indirflg == 0) pc = argp; from (approx) line 428 of unixtraps.c to (approx) line 135 (right before "switch(code)") (2) Ignore signals entirely in native (VAX) mode. I haven't had much success with this. (3) Delay signals till end of illtrap() when we know pc is okay. This, in combination with (1), has been my best result so far. More on this later. (4) Do signal routine immediately, then return to native mode to finish simulated system call. This is rather complicated, and needs an assembly language routine. I haven't tried it yet. Delaying signal handling until end of illtrap(): To do this, I changed sigcatch() so that it read: { unsigned short *pcptr; extern getregs; extern int sigs, caught[25]; if (incompat) { /* hurry ... */ getregs(); } else { signal(signum,SIG_IGN); /* ignore for rest of "system call" */ caught[sigs++] = signum; return; } /* and the rest of sigcatch ... */ } I just declared the globals sigs and caught[]; caught[] holds all the signals that have been caught; "sigs" is the number of signals that have been caught. Then, I changed illtrap() (in runcompat.c) so that the end of it reads like this: while ( sigs ) { dosig(caught[--sigs],pc); signal(caught[sigs], SIG_DFL); /* restore signal */ /* Restoring to SIG_DFL may not always be the best thing. */ } incompat++; compat(); } Of course, you have to declare caught and sigs at the top of illtrap(). I'm still working on the problem. If you have any questions, or if you think of something better, please let me know. Kenny Hirsch duke!unc!kh kh.unc@UDel-Relay The pdp-11 compatibility mode package "compat" was originally written by Art Wetzel at the University of Pittsburgh. It can be found in /usr/src/games on 4.1BSD. P.S. I am now convinced that the other problem is not the fault of the compat program or Prolog. Hooray for kernel bugs! VAX is a trademark of Digital Equipment Corporation. PDP is a trademark of Digital Equipment Corporation. UNIX is a trademark of Bell Telephone Laboratories. Coke is a trademark of the Coca-Cola Company.