Unusual failure of ranlib

Berry Kercheval berry at zinfandel.UUCP
Thu Nov 29 03:44:34 AEST 1984


In article <1336 at umcp-cs.UUCP> chris at 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 <sys/types.h>
  #include <ar.h>

--- 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 <sys/types.h>
  #include <ar.h>
  #include <ranlib.h>

--- 9,16 -----
   *		      start with a valid magic number. Enabled with #define
   *		      BETH_FIX.
   */
+ #define BETH_FIX
+ 
  #include <sys/types.h>
  #include <ar.h>
  #include <ranlib.h>
***************
*** 15,22
  #include <a.out.h>
  #include <stdio.h>
  
! struct	ar_hdr	archdr;
! #define	OARMAG 0177545
  long	arsize;
  struct	exec	exp;
  FILE	*fi, *fo;

--- 18,27 -----
  #include <a.out.h>
  #include <stdio.h>
  
! 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<tnum; i++)
  		tab[i].ran_off += offdelta;
  	return(new);

--- 290,301 -----
  		new = 1;
  		strncpy(firstname, archdr.ar_name, sizeof(archdr.ar_name));
  	}
+ 
+ 	/*
+ 	 * fix up the offsets in the table (I am not sure why they do this,
+ 	 * but it seems to work
+ 	 */
+ 
  	for(i=0; i<tnum; i++)
  		tab[i].ran_off += offdelta;
  
***************
*** 198,203
  	}
  	for(i=0; i<tnum; i++)
  		tab[i].ran_off += offdelta;
  	return(new);
  }
  

--- 298,304 -----
  
  	for(i=0; i<tnum; i++)
  		tab[i].ran_off += offdelta;
+ 
  	return(new);
  }
  

-- 
Berry Kercheval		Zehntel Inc.	(ihnp4!zehntel!zinfandel!berry)
(415)932-6900



More information about the Net.bugs mailing list