Pristine Ack-5.5
[Ack-5.5.git] / doc / v7bugs.doc
1 .\" $Id: v7bugs.doc,v 1.5 1994/06/24 10:02:36 ceriel Exp $
2 .wh 0 hd
3 .wh 60 fo
4 .de hd
5 'sp 5
6 ..
7 .de fo
8 'bp
9 ..
10 .nr e 0 1
11 .de ER
12 .br
13 .ne 20
14 .sp 2
15 .in 5n
16 .ti -5n
17 ERROR \\n+e:
18 ..
19 .de PS
20 .sp
21 .nf
22 .in +5n
23 ..
24 .de PE
25 .sp
26 .fi
27 .in -5n
28 ..
29 .sp 3
30 .ce
31 UNIX version 7 bugs
32 .sp 3
33 This document describes the UNIX version 7 errors fixed at the
34 Vrije Universiteit, Amsterdam.
35 Several of these are discovered at the VU.
36 Others are quoted from a list of bugs distributed by BellLabs.
37 .sp
38 For each error the differences between the original and modified
39 source files are given,
40 as well as a test program.
41 .ER
42 C optimizer bug for unsigned comparison
43 .sp
44 The following C program caused an IOT trap, while it should not
45 (compile with 'cc -O prog.c'):
46 .PS
47 unsigned        i = 0;
48
49 main() {
50         register j;
51
52         j = -1;
53         if (i > 40000)
54                 abort();
55 }
56 .PE
57 BellLabs suggests to make the following patch in c21.c:
58 .PS
59 /* modified /usr/src/cmd/c/c21.c */
60
61 189             if (r==0) {
62 190     /* next 2 lines replaced as indicated by
63 191      * Bell Labs bug distribution ( v7optbug )
64 192                     p->back->back->forw = p->forw;
65 193                     p->forw->back = p->back->back;
66 194       End of lines changed */
67 195                     if (p->forw->op==CBR
68 196                       || p->forw->op==SXT
69 197                       || p->forw->op==CFCC) {
70 198                             p->back->forw = p->forw;
71 199                             p->forw->back = p->back;
72 200                     } else {
73 201                             p->back->back->forw = p->forw;
74 202                             p->forw->back = p->back->back;
75 203                     }
76 204     /* End of new lines */
77 205                     decref(p->ref);
78 206                     p = p->back->back;
79 207                     nchange++;
80 208             } else if (r>0) {
81 .PE
82 Use the previous program to test before and after the modification.
83 .ER
84 The loader fails for large data or text portions
85 .sp
86 The loader 'ld' produces a "local symbol botch" error
87 for the following C program.
88 .PS
89 int     big1[10000] = {
90         1
91 };
92 int     big2[10000] = {
93         2
94 };
95
96 main() {
97         printf("loader is fine\\n");
98 }
99 .PE
100 We have made the following fix:
101 .PS
102 /* original /usr/src/cmd/ld.c */
103
104 113     struct {
105 114             int     fmagic;
106 115             int     tsize;
107 116             int     dsize;
108 117             int     bsize;
109 118             int     ssize;
110 119             int     entry;
111 120             int     pad;
112 121             int     relflg;
113 122     } filhdr;
114
115 /* modified /usr/src/cmd/ld.c */
116
117 113     /*
118 114      * The original Version 7 loader had problems loading large
119 115      * text or data portions.
120 116      * Why not include <a.out.h> ???
121 117      * then they would be declared unsigned
122 118      */
123 119     struct {
124 120             int     fmagic;
125 121             unsigned        tsize;          /* not int !!! */
126 122             unsigned        dsize;          /* not int !!! */
127 123             unsigned        bsize;          /* not int !!! */
128 124             unsigned        ssize;          /* not int !!! */
129 125             unsigned        entry;          /* not int !!! */
130 126             unsigned        pad;            /* not int !!! */
131 127             unsigned        relflg;         /* not int !!! */
132 128     } filhdr;
133 .PE
134 .ER
135 Floating point registers
136 .sp
137 When a program is swapped to disk if it needs more memory,
138 then the floating point registers were not saved, so that
139 it may have different registers when it is restarted.
140 A small assembly program demonstrates this for the status register.
141 If the error is not fixed, then the program generates an IOT error.
142 A "memory fault" is generated if all is fine.
143 .PS
144 start:  ldfps   $7400
145 1:      stfps   r0
146         mov     r0,-(sp)
147         cmp     r0,$7400
148         beq     1b
149         4
150 .PE
151 Some digging into the kernel is required to fix it.
152 The following patch will do:
153 .PS
154 /* original /usr/sys/sys/slp.c */
155
156 563             a2 = malloc(coremap, newsize);
157 564             if(a2 == NULL) {
158 565                     xswap(p, 1, n);
159 566                     p->p_flag |= SSWAP;
160 567                     qswtch();
161 568                     /* no return */
162 569             }
163
164 /* modified /usr/sys/sys/slp.c */
165
166 590             a2 = malloc(coremap, newsize);
167 591             if(a2 == NULL) {
168 592     #ifdef FPBUG
169 593                     /*
170 594                      * copy floating point register and status,
171 595                      * but only if you must switch processes
172 596                      */
173 597                     if(u.u_fpsaved == 0) {
174 598                             savfp(&u.u_fps);
175 599                             u.u_fpsaved = 1;
176 600                     }
177 601     #endif
178 602                     xswap(p, 1, n);
179 603                     p->p_flag |= SSWAP;
180 604                     qswtch();
181 605                     /* no return */
182 606             }
183 .PE
184 .ER
185 Floating point registers.
186 .sp
187 A similar problem arises when a process forks.
188 The child will have random floating point registers as is
189 demonstrated by the following assembly language program.
190 The child process will die by an IOT trap and the father prints
191 the message "child failed".
192 .PS
193 exit    = 1.
194 fork    = 2.
195 write   = 4.
196 wait    = 7.
197
198 start:  ldfps   $7400
199         sys     fork
200         br      child
201         sys     wait
202         tst     r1
203         bne     bad
204         stfps   r2
205         cmp     r2,$7400
206         beq     start
207         4
208 child:  stfps   r2
209         cmp     r2,$7400
210         beq     ex
211         4
212 bad:    clr     r0
213         sys     write;mess;13.
214 ex:     clr     r0
215         sys     exit
216
217         .data
218 mess:   <child failed\\n>
219 .PE
220 The same file slp.c should be patched as follows:
221 .PS
222 /* original /usr/sys/sys/slp.c */
223
224 499             /*
225 500              * When the resume is executed for the new process,
226 501              * here's where it will resume.
227 502              */
228 503             if (save(u.u_ssav)) {
229 504                     sureg();
230 505                     return(1);
231 506             }
232 507             a2 = malloc(coremap, n);
233 508             /*
234 509              * If there is not enough core for the
235 510              * new process, swap out the current process to generate the
236 511              * copy.
237 512              */
238
239 /* modified /usr/sys/sys/slp.c */
240
241 519             /*
242 520              * When the resume is executed for the new process,
243 521              * here's where it will resume.
244 522              */
245 523             if (save(u.u_ssav)) {
246 524                     sureg();
247 525                     return(1);
248 526             }
249 527     #ifdef FPBUG
250 528             /* copy the floating point registers and status to child */
251 529             if(u.u_fpsaved == 0) {
252 530                     savfp(&u.u_fps);
253 531                     u.u_fpsaved = 1;
254 532             }
255 533     #endif
256 534             a2 = malloc(coremap, n);
257 535             /*
258 536              * If there is not enough core for the
259 537              * new process, swap out the current process to generate the
260 538              * copy.
261 539              */
262 .PE
263 .ER
264 /usr/src/libc/v6/stat.c
265 .sp
266 Some system calls are changed from version 6 to version 7.
267 A library of system call entries, that make a version 6 UNIX look like
268 a version 7 system, is provided to run some
269 useful version 7 utilities, like 'tar', on UNIX-6.
270 The entry for 'stat' contained two bugs:
271 the 24-bit file size was incorrectly converted to 32 bits
272 (sign extension of bit 15)
273 and the uid/gid fields suffered from sign extension.
274 .sp
275 Transferring files from version 6 to version 7 using 'tar'
276 will fail for all files for which
277 .sp
278         ( (size & 0100000) != 0 )
279 .sp
280 These two errors are fixed if stat.c is modified as follows:
281 .PS
282 /* original /usr/src/libc/v6/stat.c */
283
284 11              char  os_size0;
285 12              short os_size1;
286 13              short os_addr[8];
287
288 49              buf->st_nlink = osbuf.os_nlinks;
289 50              buf->st_uid = osbuf.os_uid;
290 51              buf->st_gid = osbuf.os_gid;
291 52              buf->st_rdev = 0;
292
293 /* modified /usr/src/libc/v6/stat.c */
294
295 11              char  os_size0;
296 12              unsigned os_size1;
297 13              short os_addr[8];
298
299 49              buf->st_nlink = osbuf.os_nlinks;
300 50              buf->st_uid = osbuf.os_uid & 0377;
301 51              buf->st_gid = osbuf.os_gid & 0377;
302 52              buf->st_rdev = 0;
303 .PE