Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site zinfandel.UUCP Path: utzoo!watmath!clyde!cbosgd!ihnp4!zehntel!zinfandel!berry From: berry@zinfandel.UUCP (Berry Kercheval) Newsgroups: net.bugs Subject: Re: Unusual failure of ranlib Message-ID: <250@zinfandel.UUCP> Date: Wed, 28-Nov-84 12:44:34 EST Article-I.D.: zinfande.250 Posted: Wed Nov 28 12:44:34 1984 Date-Received: Fri, 30-Nov-84 06:42:42 EST References: <152@psivax.UUCP> <596@munnari.OZ> <1336@umcp-cs.UUCP> Reply-To: berry@zinfandel.UUCP (Berry Kercheval) Organization: Zehntel Inc., Walnut Creek, CA Lines: 739 Summary: In article <1336@umcp-cs.UUCP> chris@umcp-cs.UUCP (Chris Torek) writes: >Why not simply special-case the code in ``ld'' and ``ranlib'' for the >name ``__.SYMDEF'', since it is already a special case? (In other words, >ignore its apparent magic number.) That is exactly what I did on our 4.1 (and other random) systems. ``ld'' is already special cased (at least ours was). here is a diff for ``ranlib''. It's long, because I added a bunch of comments while I was tracking down this problem. The #define is called BETH_FIX after Beth Stonebraker, who stumbled upon the problem. -- Berry Kercheval Zehntel Inc. (ihnp4!zehntel!zinfandel!berry) (415)932-6900 ##############################CUT HERE############################## *** ranlib.c.old Wed May 18 15:04:34 1983 --- ranlib.c Wed May 18 14:55:11 1983 *************** *** 7,12 static char sccsid[] = "@(#)ranlib.c 4.3 4/26/81"; /* * ranlib - create table of contents for archive; string table version */ #include#include --- 1,13 ----- static char sccsid[] = "@(#)ranlib.c 4.3 4/26/81"; /* * ranlib - create table of contents for archive; string table version + * + * 18 May 1983 BBK -- Comments added + * + * Special case added: DO NOT try to extract the symbol + * table from a file named "__.SYMDEF" even if it DOES + * start with a valid magic number. Enabled with #define + * BETH_FIX. */ #define BETH_FIX *************** *** 8,13 /* * ranlib - create table of contents for archive; string table version */ #include #include #include --- 9,16 ----- * start with a valid magic number. Enabled with #define * BETH_FIX. */ + #define BETH_FIX + #include #include #include *************** *** 15,22 #include #include ! struct ar_hdr archdr; ! #define OARMAG 0177545 long arsize; struct exec exp; FILE *fi, *fo; --- 18,27 ----- #include #include ! struct ar_hdr archdr; /* storage for header at each element ! * of the archive ! */ ! #define OARMAG 0177545 /* magic number of old-style archive */ long arsize; struct exec exp; /* header on each a.out (or .o?) file */ FILE *fi, *fo; /* input and output stream pointers */ *************** *** 18,26 struct ar_hdr archdr; #define OARMAG 0177545 long arsize; ! struct exec exp; ! FILE *fi, *fo; ! long off, oldoff; long atol(), ftell(); #define TABSZ 5000 struct ranlib tab[TABSZ]; --- 23,31 ----- */ #define OARMAG 0177545 /* magic number of old-style archive */ long arsize; ! struct exec exp; /* header on each a.out (or .o?) file */ ! FILE *fi, *fo; /* input and output stream pointers */ ! long off, oldoff; /* set by nextel() as side effect */ long atol(), ftell(); #define TABSZ 5000 struct ranlib tab[TABSZ]; /* table of symbols */ *************** *** 23,30 long off, oldoff; long atol(), ftell(); #define TABSZ 5000 ! struct ranlib tab[TABSZ]; ! int tnum; #define STRTABSZ 75000 char tstrtab[STRTABSZ]; int tssiz; --- 28,35 ----- long off, oldoff; /* set by nextel() as side effect */ long atol(), ftell(); #define TABSZ 5000 ! struct ranlib tab[TABSZ]; /* table of symbols */ ! int tnum; /* number of elements in table */ #define STRTABSZ 75000 char tstrtab[STRTABSZ]; /* table of strings for symbol names */ int tssiz; /* current size of string table */ *************** *** 26,33 struct ranlib tab[TABSZ]; int tnum; #define STRTABSZ 75000 ! char tstrtab[STRTABSZ]; ! int tssiz; char *strtab; int ssiz; int new; --- 31,38 ----- struct ranlib tab[TABSZ]; /* table of symbols */ int tnum; /* number of elements in table */ #define STRTABSZ 75000 ! char tstrtab[STRTABSZ]; /* table of strings for symbol names */ ! int tssiz; /* current size of string table */ char *strtab; int ssiz; int new; *************** *** 40,48 char cmdbuf[BUFSIZ]; char magbuf[SARMAG+1]; ! --argc; ! while(argc--) { ! fi = fopen(*++argv,"r"); if (fi == NULL) { fprintf(stderr, "ranlib: cannot open %s\n", *argv); continue; --- 45,53 ----- char cmdbuf[BUFSIZ]; char magbuf[SARMAG+1]; ! --argc; /* skip argv[0] */ ! while(argc--) { /* foreach archive... */ ! fi = fopen(*++argv,"r"); /* open next archive file */ if (fi == NULL) { fprintf(stderr, "ranlib: cannot open %s\n", *argv); continue; *************** *** 47,55 fprintf(stderr, "ranlib: cannot open %s\n", *argv); continue; } ! off = SARMAG; ! fread(magbuf, 1, SARMAG, fi); ! if (strncmp(magbuf, ARMAG, SARMAG)) { if (*(int *)magbuf == OARMAG) fprintf(stderr, "old format "); else --- 52,62 ----- fprintf(stderr, "ranlib: cannot open %s\n", *argv); continue; } ! off = SARMAG; /* archive proper starts after ! * "magic" header */ ! fread(magbuf, 1, SARMAG, fi); /* read "magic" header */ ! if (strncmp(magbuf, ARMAG, SARMAG)) { /* is this really an ! * archive? */ if (*(int *)magbuf == OARMAG) fprintf(stderr, "old format "); else *************** *** 57,65 fprintf(stderr, "archive: %s\n", *argv); continue; } ! fseek(fi, 0L, 0); ! new = tnum = 0; ! if (nextel(fi) == 0) { fclose(fi); continue; } --- 64,76 ----- fprintf(stderr, "archive: %s\n", *argv); continue; } ! fseek(fi, 0L, 0); /* back to beginning */ ! new = tnum = 0; /* initially 0 elements in table. ! * new really doesn't need to be ! * initiallized since it is set in ! * fixsize before use anyway */ ! ! if (nextel(fi) == 0) { /* advance to first element */ fclose(fi); continue; } *************** *** 63,69 fclose(fi); continue; } ! do { long o; register n; struct nlist sym; --- 74,80 ----- fclose(fi); continue; } ! do { /* keep going until no more elements */ long o; register n; struct nlist sym; *************** *** 68,73 register n; struct nlist sym; fread((char *)&exp, 1, sizeof(struct exec), fi); if (N_BADMAG(exp)) continue; --- 79,86 ----- register n; struct nlist sym; + /* read a.out header */ + fread((char *)&exp, 1, sizeof(struct exec), fi); if (N_BADMAG(exp)) continue; /* not a.out format */ *************** *** 70,75 fread((char *)&exp, 1, sizeof(struct exec), fi); if (N_BADMAG(exp)) continue; if (exp.a_syms == 0) { fprintf(stderr, "ranlib: warning: %s(%s): no symbol table\n", *argv, archdr.ar_name); --- 83,94 ----- fread((char *)&exp, 1, sizeof(struct exec), fi); if (N_BADMAG(exp)) + continue; /* not a.out format */ + #ifdef BETH_FIX + /* DON'T try to get symbols from the ToC!!! */ + + if(strncmp(archdr.ar_name, tempnm, + sizeof (archdr.ar_name)) == 0) continue; #endif BETH_FIX if (exp.a_syms == 0) { *************** *** 71,76 fread((char *)&exp, 1, sizeof(struct exec), fi); if (N_BADMAG(exp)) continue; if (exp.a_syms == 0) { fprintf(stderr, "ranlib: warning: %s(%s): no symbol table\n", *argv, archdr.ar_name); continue; --- 90,96 ----- if(strncmp(archdr.ar_name, tempnm, sizeof (archdr.ar_name)) == 0) continue; + #endif BETH_FIX if (exp.a_syms == 0) { fprintf(stderr, "ranlib: warning: %s(%s): no symbol table\n", *************** *** 72,78 if (N_BADMAG(exp)) continue; if (exp.a_syms == 0) { ! fprintf(stderr, "ranlib: warning: %s(%s): no symbol table\n", *argv, archdr.ar_name); continue; } o = N_STROFF(exp) - sizeof (struct exec); --- 92,100 ----- continue; #endif BETH_FIX if (exp.a_syms == 0) { ! fprintf(stderr, ! "ranlib: warning: %s(%s): no symbol table\n", ! *argv, archdr.ar_name); continue; } *************** *** 75,80 fprintf(stderr, "ranlib: warning: %s(%s): no symbol table\n", *argv, archdr.ar_name); continue; } o = N_STROFF(exp) - sizeof (struct exec); if (ftell(fi)+o+sizeof(ssiz) >= off) { fprintf(stderr, "ranlib: %s(%s): old format .o file\n", *argv, archdr.ar_name); --- 97,107 ----- *argv, archdr.ar_name); continue; } + + /* calculate offset of symbol table relative to + * beginning of data in a.out-format file + */ + o = N_STROFF(exp) - sizeof (struct exec); /* ssiz is an int... *************** *** 76,81 continue; } o = N_STROFF(exp) - sizeof (struct exec); if (ftell(fi)+o+sizeof(ssiz) >= off) { fprintf(stderr, "ranlib: %s(%s): old format .o file\n", *argv, archdr.ar_name); exit(1); --- 103,114 ----- */ o = N_STROFF(exp) - sizeof (struct exec); + + /* ssiz is an int... + * off is now (after the nextel() call) the offset of + * NEXT element in the file. + */ + if (ftell(fi)+o+sizeof(ssiz) >= off) { fprintf(stderr, "ranlib: %s(%s): old format .o file\n", *************** *** 77,83 } o = N_STROFF(exp) - sizeof (struct exec); if (ftell(fi)+o+sizeof(ssiz) >= off) { ! fprintf(stderr, "ranlib: %s(%s): old format .o file\n", *argv, archdr.ar_name); exit(1); } fseek(fi, o, 1); --- 110,118 ----- */ if (ftell(fi)+o+sizeof(ssiz) >= off) { ! fprintf(stderr, ! "ranlib: %s(%s): old format .o file\n", ! *argv, archdr.ar_name); exit(1); } fseek(fi, o, 1); *************** *** 112,117 } while(nextel(fi)); new = fixsize(); fclose(fi); fo = fopen(tempnm, "w"); if(fo == NULL) { fprintf(stderr, "can't create temporary\n"); --- 147,155 ----- } while(nextel(fi)); new = fixsize(); fclose(fi); + + /* write table of contents into temp file */ + fo = fopen(tempnm, "w"); if(fo == NULL) { fprintf(stderr, "can't create temporary\n"); *************** *** 124,129 fwrite(&tssiz, 1, sizeof (tssiz), fo); fwrite(tstrtab, tssiz, 1, fo); fclose(fo); if(new) sprintf(cmdbuf, "ar rlb %s %s %s\n", firstname, *argv, tempnm); else --- 162,169 ----- fwrite(&tssiz, 1, sizeof (tssiz), fo); fwrite(tstrtab, tssiz, 1, fo); fclose(fo); + + /* archive it into the first place in the archive file. */ if(new) sprintf(cmdbuf, "ar rlb %s %s %s\n", firstname, *argv, tempnm); *************** *** 125,131 fwrite(tstrtab, tssiz, 1, fo); fclose(fo); if(new) ! sprintf(cmdbuf, "ar rlb %s %s %s\n", firstname, *argv, tempnm); else sprintf(cmdbuf, "ar rl %s %s\n", *argv, tempnm); if(system(cmdbuf)) --- 165,172 ----- /* archive it into the first place in the archive file. */ if(new) ! sprintf(cmdbuf, "ar rlb %s %s %s\n", ! firstname, *argv, tempnm); else sprintf(cmdbuf, "ar rl %s %s\n", *argv, tempnm); if(system(cmdbuf)) *************** *** 132,137 fprintf(stderr, "ranlib: ``%s'' failed\n", cmdbuf); else fixdate(*argv); unlink(tempnm); } exit(0); --- 173,179 ----- fprintf(stderr, "ranlib: ``%s'' failed\n", cmdbuf); else fixdate(*argv); + #ifndef DEBUG unlink(tempnm); #endif DEBUG } *************** *** 133,138 else fixdate(*argv); unlink(tempnm); } exit(0); } --- 175,181 ----- fixdate(*argv); #ifndef DEBUG unlink(tempnm); + #endif DEBUG } exit(0); } *************** *** 137,143 exit(0); } ! nextel(af) FILE *af; { register r; --- 180,195 ----- exit(0); } ! /* ! * nextel() -- go to next element of archive ! * arg: stream pointer of archive file ! * returns: 0 for EOF on arch. or error ! * 1 for success ! * side-effect: set off to offset of NEXT element ! * set oldoff to "current" offset ! */ ! ! nextel(af) /* sets oldoff and off as side effect */ FILE *af; { register r; *************** *** 144,149 register char *cp; oldoff = off; fseek(af, off, 0); r = fread((char *)&archdr, 1, sizeof(struct ar_hdr), af); if (r != sizeof(struct ar_hdr)) --- 196,204 ----- register char *cp; oldoff = off; + + /* goto current offset and read arch header */ + fseek(af, off, 0); r = fread((char *)&archdr, 1, sizeof(struct ar_hdr), af); if (r != sizeof(struct ar_hdr)) *************** *** 148,154 r = fread((char *)&archdr, 1, sizeof(struct ar_hdr), af); if (r != sizeof(struct ar_hdr)) return(0); ! for (cp=archdr.ar_name; cp < & archdr.ar_name[sizeof(archdr.ar_name)]; cp++) if (*cp == ' ') *cp = '\0'; arsize = atol(archdr.ar_size); --- 203,215 ----- r = fread((char *)&archdr, 1, sizeof(struct ar_hdr), af); if (r != sizeof(struct ar_hdr)) return(0); ! ! /* zap all blanks in name */ ! ! for (cp=archdr.ar_name; ! cp < & archdr.ar_name[sizeof(archdr.ar_name)]; ! cp++) ! { if (*cp == ' ') *cp = '\0'; } *************** *** 151,157 for (cp=archdr.ar_name; cp < & archdr.ar_name[sizeof(archdr.ar_name)]; cp++) if (*cp == ' ') *cp = '\0'; ! arsize = atol(archdr.ar_size); if (arsize & 1) arsize++; off = ftell(af) + arsize; --- 212,220 ----- { if (*cp == ' ') *cp = '\0'; ! } ! arsize = atol(archdr.ar_size); /* compute size of this arch ! * element */ if (arsize & 1) arsize++; /* make it even */ off = ftell(af) + arsize; /* compute offset of next *************** *** 153,160 *cp = '\0'; arsize = atol(archdr.ar_size); if (arsize & 1) ! arsize++; ! off = ftell(af) + arsize; return(1); } --- 216,224 ----- arsize = atol(archdr.ar_size); /* compute size of this arch * element */ if (arsize & 1) ! arsize++; /* make it even */ ! off = ftell(af) + arsize; /* compute offset of next ! * element */ return(1); } *************** *** 158,163 return(1); } stash(s) struct nlist *s; { --- 222,239 ----- return(1); } + /* + * stash() -- stash this symbol for the ToC + * + * arg: symbol table entry + * returns: 1 on table overflow + * falls out bottom on success + * side-effect: symbol offset and name size saved in tab[] + * name saved in tstrtab + * tnum incremented + * tssiz incremented by size of symbol name + */ + stash(s) struct nlist *s; { *************** *** 178,183 tnum++; } fixsize() { int i; --- 254,270 ----- tnum++; } + /* + * fixdate() -- + * args: none + * returns: new (see side effect) + * side-effect: set new to 1 if there is no ToC in the archive; 0 if there + * is already one + * set firstname[] to name of first element if there was no ToC + * fixes up file offsets in ToC to compensate for the size of the + * ToC at the head of the archive. + */ + fixsize() { int i; *************** *** 183,189 int i; off_t offdelta; ! if (tssiz&1) tssiz++; offdelta = sizeof(archdr) + sizeof (tnum) + tnum * sizeof(struct ranlib) + sizeof (tssiz) + tssiz; --- 270,276 ----- int i; off_t offdelta; ! if (tssiz&1) /* word-align */ tssiz++; offdelta = sizeof(archdr) + sizeof (tnum) + tnum * sizeof(struct ranlib) + *************** *** 185,191 if (tssiz&1) tssiz++; ! offdelta = sizeof(archdr) + sizeof (tnum) + tnum * sizeof(struct ranlib) + sizeof (tssiz) + tssiz; off = SARMAG; nextel(fi); --- 272,279 ----- if (tssiz&1) /* word-align */ tssiz++; ! offdelta = sizeof(archdr) + sizeof (tnum) + ! tnum * sizeof(struct ranlib) + sizeof (tssiz) + tssiz; off = SARMAG; /* go back to the beginning */ nextel(fi); /* get next (i.e. first) element in archive */ *************** *** 187,194 tssiz++; offdelta = sizeof(archdr) + sizeof (tnum) + tnum * sizeof(struct ranlib) + sizeof (tssiz) + tssiz; ! off = SARMAG; ! nextel(fi); if(strncmp(archdr.ar_name, tempnm, sizeof (archdr.ar_name)) == 0) { new = 0; offdelta -= sizeof(archdr) + arsize; --- 275,288 ----- offdelta = sizeof(archdr) + sizeof (tnum) + tnum * sizeof(struct ranlib) + sizeof (tssiz) + tssiz; ! off = SARMAG; /* go back to the beginning */ ! nextel(fi); /* get next (i.e. first) element in archive */ ! ! /* if the name of the first element is tempnm, then clear new and ! * fix offdelta; else set new and save the name in firstname[] for ! * later use by the ar command we will fork ! */ ! if(strncmp(archdr.ar_name, tempnm, sizeof (archdr.ar_name)) == 0) { new = 0; offdelta -= sizeof(archdr) + arsize; *************** *** 196,201 new = 1; strncpy(firstname, archdr.ar_name, sizeof(archdr.ar_name)); } for(i=0; i