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