char symname[]="__.SYMDEF"; /* table of contents file name */
char *libname; /* current archive */
char firstname[NNAME]; /* first file in archive */
char *errs; /* exit status */
char verbose;
int nextern; /* number of 'T' & 'D' symbols */
int symsize; /* size of __.SYMDEF archive member */
void
main(int argc, char *argv[])
{
int i;
Biobuf *bin;
argv0 = argv[0];
ARGBEGIN {
case 'v':
verbose = 1;
break;
} ARGEND
for(i=0; i<argc; i++){
libname = argv[i];
bin = Bopen(libname, OREAD);
if(bin == 0){
fprint(2, "%s: cannot open %s\n", argv0, libname);
errs = "errors";
continue;
}
if (isar(bin)) {
if (readrl(bin) < 0)
errs = "errors";
else
writerl();
}else{
fprint(2, "%s: not an archive: %s\n", argv0, libname);
errs = "errors";
}
Bclose(bin);
}
exits(errs);
}
/*
* read an archive file,
* processing the symbols for each intermediate file in it.
*/
int
readrl(Biobuf *bp)
{
int i, j, offset, size, obj, lastobj;
Sym *s;
char membername[NNAME];
offset = BOFFSET(bp);
symsize = 0;
lastobj = -1;
objreset();
j = 0;
for (i = 0;;i++) {
size = nextar(bp, offset, membername);
if (size < 0) {
fprint(2, "%s: phase error on ar header %ld\n", argv0, offset);
return -1;
}
if (size == 0)
return 1;
if (i == 0) /* first time through */
strcpy(firstname, membername);
if (strcmp(membername, symname) == 0) {
symsize = size; /* skip symbol table */
offset += size;
continue;
}
obj = objtype(bp);
if (lastobj < 0) /* force match first time & after err */
lastobj = obj;
if (obj < 0 || obj != lastobj) {
fprint(2, "%s: inconsistent file %s in %s\n", argv0,
membername, libname);
return -1;
}
lastobj = obj;
if (!readar(bp, obj, offset+size)) {
fprint(2, "%s: invalid symbol reference in file %s\n", membername);
return -1;
}
while (s = objsym(j)) {
if (s->type == 'T' || s->type == 'D') {
s->value = offset-symsize;
nextern++;
}
j++;
}
offset += size;
}
return 1;
}
void
writerl(void)
{
Biobuf b;
Sym *s;
long new, off;
int fd, i;