123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- .\" $Header$
- .wh 0 hd
- .wh 60 fo
- .de hd
- 'sp 5
- ..
- .de fo
- 'bp
- ..
- .nr e 0 1
- .de ER
- .br
- .ne 20
- .sp 2
- .in 5n
- .ti -5n
- ERROR \\n+e:
- ..
- .de PS
- .sp
- .nf
- .in +5n
- ..
- .de PE
- .sp
- .fi
- .in -5n
- ..
- .sp 3
- .ce
- UNIX version 7 bugs
- .sp 3
- This document describes the UNIX version 7 errors fixed at the
- Vrije Universiteit, Amsterdam.
- Several of these are discovered at the VU.
- Others are quoted from a list of bugs distributed by BellLabs.
- .sp
- For each error the differences between the original and modified
- source files are given,
- as well as a test program.
- .ER
- C optimizer bug for unsigned comparison
- .sp
- The following C program caused an IOT trap, while it should not
- (compile with 'cc -O prog.c'):
- .PS
- unsigned i = 0;
- main() {
- register j;
- j = -1;
- if (i > 40000)
- abort();
- }
- .PE
- BellLabs suggests to make the following patch in c21.c:
- .PS
- /* modified /usr/src/cmd/c/c21.c */
- 189 if (r==0) {
- 190 /* next 2 lines replaced as indicated by
- 191 * Bell Labs bug distribution ( v7optbug )
- 192 p->back->back->forw = p->forw;
- 193 p->forw->back = p->back->back;
- 194 End of lines changed */
- 195 if (p->forw->op==CBR
- 196 || p->forw->op==SXT
- 197 || p->forw->op==CFCC) {
- 198 p->back->forw = p->forw;
- 199 p->forw->back = p->back;
- 200 } else {
- 201 p->back->back->forw = p->forw;
- 202 p->forw->back = p->back->back;
- 203 }
- 204 /* End of new lines */
- 205 decref(p->ref);
- 206 p = p->back->back;
- 207 nchange++;
- 208 } else if (r>0) {
- .PE
- Use the previous program to test before and after the modification.
- .ER
- The loader fails for large data or text portions
- .sp
- The loader 'ld' produces a "local symbol botch" error
- for the following C program.
- .PS
- int big1[10000] = {
- 1
- };
- int big2[10000] = {
- 2
- };
- main() {
- printf("loader is fine\\n");
- }
- .PE
- We have made the following fix:
- .PS
- /* original /usr/src/cmd/ld.c */
- 113 struct {
- 114 int fmagic;
- 115 int tsize;
- 116 int dsize;
- 117 int bsize;
- 118 int ssize;
- 119 int entry;
- 120 int pad;
- 121 int relflg;
- 122 } filhdr;
- /* modified /usr/src/cmd/ld.c */
- 113 /*
- 114 * The original Version 7 loader had problems loading large
- 115 * text or data portions.
- 116 * Why not include <a.out.h> ???
- 117 * then they would be declared unsigned
- 118 */
- 119 struct {
- 120 int fmagic;
- 121 unsigned tsize; /* not int !!! */
- 122 unsigned dsize; /* not int !!! */
- 123 unsigned bsize; /* not int !!! */
- 124 unsigned ssize; /* not int !!! */
- 125 unsigned entry; /* not int !!! */
- 126 unsigned pad; /* not int !!! */
- 127 unsigned relflg; /* not int !!! */
- 128 } filhdr;
- .PE
- .ER
- Floating point registers
- .sp
- When a program is swapped to disk if it needs more memory,
- then the floating point registers were not saved, so that
- it may have different registers when it is restarted.
- A small assembly program demonstrates this for the status register.
- If the error is not fixed, then the program generates an IOT error.
- A "memory fault" is generated if all is fine.
- .PS
- start: ldfps $7400
- 1: stfps r0
- mov r0,-(sp)
- cmp r0,$7400
- beq 1b
- 4
- .PE
- You have to dig into the kernel to fix it.
- The following patch will do:
- .PS
- /* original /usr/sys/sys/slp.c */
- 563 a2 = malloc(coremap, newsize);
- 564 if(a2 == NULL) {
- 565 xswap(p, 1, n);
- 566 p->p_flag |= SSWAP;
- 567 qswtch();
- 568 /* no return */
- 569 }
- /* modified /usr/sys/sys/slp.c */
- 590 a2 = malloc(coremap, newsize);
- 591 if(a2 == NULL) {
- 592 #ifdef FPBUG
- 593 /*
- 594 * copy floating point register and status,
- 595 * but only if you must switch processes
- 596 */
- 597 if(u.u_fpsaved == 0) {
- 598 savfp(&u.u_fps);
- 599 u.u_fpsaved = 1;
- 600 }
- 601 #endif
- 602 xswap(p, 1, n);
- 603 p->p_flag |= SSWAP;
- 604 qswtch();
- 605 /* no return */
- 606 }
- .PE
- .ER
- Floating point registers.
- .sp
- A similar problem arises when a process forks.
- The child will have random floating point registers as is
- demonstrated by the following assembly language program.
- The child process will die by an IOT trap and the father prints
- the message "child failed".
- .PS
- exit = 1.
- fork = 2.
- write = 4.
- wait = 7.
- start: ldfps $7400
- sys fork
- br child
- sys wait
- tst r1
- bne bad
- stfps r2
- cmp r2,$7400
- beq start
- 4
- child: stfps r2
- cmp r2,$7400
- beq ex
- 4
- bad: clr r0
- sys write;mess;13.
- ex: clr r0
- sys exit
- .data
- mess: <child failed\\n>
- .PE
- The same file slp.c should be patched as follows:
- .PS
- /* original /usr/sys/sys/slp.c */
- 499 /*
- 500 * When the resume is executed for the new process,
- 501 * here's where it will resume.
- 502 */
- 503 if (save(u.u_ssav)) {
- 504 sureg();
- 505 return(1);
- 506 }
- 507 a2 = malloc(coremap, n);
- 508 /*
- 509 * If there is not enough core for the
- 510 * new process, swap out the current process to generate the
- 511 * copy.
- 512 */
- /* modified /usr/sys/sys/slp.c */
- 519 /*
- 520 * When the resume is executed for the new process,
- 521 * here's where it will resume.
- 522 */
- 523 if (save(u.u_ssav)) {
- 524 sureg();
- 525 return(1);
- 526 }
- 527 #ifdef FPBUG
- 528 /* copy the floating point registers and status to child */
- 529 if(u.u_fpsaved == 0) {
- 530 savfp(&u.u_fps);
- 531 u.u_fpsaved = 1;
- 532 }
- 533 #endif
- 534 a2 = malloc(coremap, n);
- 535 /*
- 536 * If there is not enough core for the
- 537 * new process, swap out the current process to generate the
- 538 * copy.
- 539 */
- .PE
- .ER
- /usr/src/libc/v6/stat.c
- .sp
- Some system calls are changed from version 6 to version 7.
- A library of system call entries, that make a version 6 UNIX look like
- a version 7 system, is provided to enable you to run some
- useful version 7 utilities, like 'tar', on UNIX-6.
- The entry for 'stat' contained two bugs:
- the 24-bit file size was incorrectly converted to 32 bits
- (sign extension of bit 15)
- and the uid/gid fields suffered from sign extension.
- .sp
- Transferring your files from version 6 to version 7 using 'tar'
- will fail for all files for which
- .sp
- ( (size & 0100000) != 0 )
- .sp
- These two errors are fixed if stat.c is modified as follows:
- .PS
- /* original /usr/src/libc/v6/stat.c */
- 11 char os_size0;
- 12 short os_size1;
- 13 short os_addr[8];
- 49 buf->st_nlink = osbuf.os_nlinks;
- 50 buf->st_uid = osbuf.os_uid;
- 51 buf->st_gid = osbuf.os_gid;
- 52 buf->st_rdev = 0;
- /* modified /usr/src/libc/v6/stat.c */
- 11 char os_size0;
- 12 unsigned os_size1;
- 13 short os_addr[8];
- 49 buf->st_nlink = osbuf.os_nlinks;
- 50 buf->st_uid = osbuf.os_uid & 0377;
- 51 buf->st_gid = osbuf.os_gid & 0377;
- 52 buf->st_rdev = 0;
- .PE
|