static char sccsid
[] = " runcompat.c 4.1 82/05/12 ";
* Compatability mode support under UNIX-32V
* written by Art Wetzel during August 1979
* at the Interdisciplinary Dept of Information Science
* University of Pittsburgh
* No claims are made on the completeness of the support of any
* of the systems simulated under this package
main(argc
, argv
, envp
) int argc
; char **argv
, **envp
; {
fprintf(stderr
,"Usage: %s [-rootdir] file args...\n",argv
[0]);
/* remember where the program name etc should go for using ps */
/* set up alternate root directory if flagged for */
fprintf(stderr
,"Can't change root to %s\n",argv
[0]+1);
/* check out file stats of file to run */
if(stat(argv
[0], &stat32v
)) {
fprintf(stderr
,"%s does not exist\n",argv
[0]);
/* a version of SETUID and SETGID file executions */
/* the binary of this program should be SETUID root for this to work */
/* requires nonstandard seteuid and setegid sys calls */
if(!(stat32v
.st_mode
& S_ISGID
) || setegid(stat32v
.st_gid
))
/* if not SETGID file or error, drop back to real group */
if(!(stat32v
.st_mode
& S_ISUID
) || seteuid(stat32v
.st_uid
))
/* if not SETUID file or error, drop back to real uid */
/* no umasks in version 6 */
/* go try to execute , passing along args and environment */
execute(argv
[0], argv
, envp
);
/* only get here if execute fails */
fprintf(stderr
,"Execution failure on %s\n",argv
[0]);
execute(file
, argv
, envp
) char *file
, **argv
, **envp
; {
int fd
, n
, tloadpt
, dloadpt
, tloadsize
, dloadsize
, stacksize
;
/* file to run should be readable */
if((fd
= open(file
, 0)) == -1) {
fprintf(stderr
,"Can't open %s for read access\n",file
);
if((n
= read(fd
, &header
, sizeof header
)) != sizeof header
)
/* check to see if really unix file */
if(header
.magic
!= MAGIC1
&& header
.magic
!= MAGIC2
&&
header
.magic
!= MAGIC3
&& header
.magic
!= MAGIC4
) {
/* if a UNIX-32V file run it */
if(header
.textsize
== 0) {
/* if no explicit env, pass along environ */
return(execve(file
, argv
, environ
));
return(execve(file
, argv
, envp
));
/* checks out OK as PDP-11 UNIX file */
if(header
.magic
== MAGIC3
) {
fprintf(stderr
,"%s compiled for separate I/D space\n",argv
[0]);
/* unix text loads at 0 */
/* set starting pc value */
pc
= (unsigned short *)header
.entry
;
/* figure out where to load initialized data */
dloadpt
= tloadsize
= header
.textsize
;
/* check if alignment of data segment to 8k byte boundary */
if(header
.magic
== MAGIC2
)
dloadpt
= (dloadpt
+8191) & (~8191);
dloadsize
= header
.datasize
;
stacksize
= header
.bsssize
;
if((n
= read(fd
, shortspace
, RTHDRSIZ
)) != RTHDRSIZ
) {
fprintf(stderr
,"Error reading 1st block\n");
/* rt11 files are 0 aligned including the header */
/* set starting pc value */
pc
= (unsigned short *)shortspace
[RTPC
];
/* initialize stack location */
regs
[6] = shortspace
[RTSP
];
/* figure how much to load */
dloadpt
= tloadsize
= shortspace
[RTHGH
]-RTHDRSIZ
;
/* no separate data as in unix */
/* see if it all fits into available memory space */
if((dloadpt
+dloadsize
+stacksize
) > (int)memsiz
) {
fprintf(stderr
,"File too big to run\n");
if((n
= read(fd
, tloadpt
, tloadsize
)) < tloadsize
) {
fprintf(stderr
,"Text read failure\n");
if((n
= read(fd
, dloadpt
, dloadsize
)) < dloadsize
) {
fprintf(stderr
,"Data read failure\n");
/* clear out the rest of memory */
p
= (short *)(dloadpt
+ dloadsize
);
while(p
< (short *)memsiz
) *p
++ = 0;
/* close file before starting it */
/* set up illegal instruction trapping */
illtrap(signum
,faultcode
,myaddr
,stpc
,stps
) int signum
; {
/* record the fact that we are not in compatability mode now */
/* get the register values before they get clobbered */
/* figure out what the pc was */
pcptr
= (unsigned short *) &stpc
;
pcptr
= (unsigned short *)((char *)&pcptr
+ 20);
pc
= (unsigned short *) *pcptr
;
/* get the instruction */
/* incriment the pc over this instruction */
/* set register 7 as pc synonym */
regs
[7] = (unsigned short)(int)pc
;
/* set up psl with condition codes */
/* a UNIX-32V monitor patch is required to not clear condition codes */
psl
= 0x83c00000 | (stps
& 017);
psl
= 0x83c00000 | (*(pcptr
- 6) & 017);
/* pick out the appropriate action for this illegal instruction */
if(sigvals
[SIGEMT
] && ((sigvals
[SIGEMT
]%2) != 1)) {
if(instr
>= 075000 && instr
< 075040) {
/* floating point unit instructions */
/* genuine illegal instruction */
/* if signal trap set go to user's trap location */
if(sigvals
[SIGILL
] && ((sigvals
[SIGILL
]%2) != 1)) {
/* ignore uncaught setd instructions */
/* otherwise put out a message and quit */
printf("illegal instruction, psl 0x%08x, pc 0%04o\n",psl
,pc
-1);
for(i
=0; i
<7; i
++) printf("0x%04x ",regs
[i
]);
printf("0x%04x -> 0%o\n",pc
-1,instr
);
/* set up to dump on illegal instruction */
/* set pc back to bad instruction */
/* go do it again for dump */
/* go back to compatability mode */