|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 4214 (0x1076) Types: TextFile Notes: UNIX file Names: »ranlib.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦f4b8d8c84⟧ UNIX Filesystem └─ ⟦this⟧ »cmd/ranlib.c«
/* * Make libraries more accessible to the loader * by copying all the globally defined symbols * into a special module at the front of the archive. */ #include <stdio.h> #include "n.out.h" #include <ar.h> #include <canon.h> static struct ldheader ldh; main(argc, argv) int argc; char *argv[]; { register int i, errors = 0; if (argc==1) { fprintf(stderr, "Usage: %s [ archive]+\n", argv[0]); exit(1); } for (i=1; i<argc; i++) { errors += ranlib(argv[i]); } unlink(HDRNAME); exit(errors); } static void complain(plaint) char *plaint; { fprintf(stderr, "Ranlib: %r", &plaint); putc('\n', stderr); } static void xwrite(sym, fp) ar_sym *sym; FILE *fp; { if (fwrite(sym, sizeof(ar_sym), 1, fp)!=1) { complain("write error on header file"); exit(1); } } static void addhdr(base, arhp, hdrfp, arfp, archive) size_t base; struct ar_hdr *arhp; FILE *hdrfp, *arfp; char *archive; { size_t off; cansize(arhp->ar_size); arhp->ar_size += off = ftell(arfp); off -= base; ldh.l_magic = 0; /* in case fread fails */ if (fread(&ldh, sizeof ldh, 1, arfp)!=1) { complain("%.*s in %s is not a load module\n", DIRSIZ, arhp->ar_name, archive); } else { canshort(ldh.l_magic); canshort(ldh.l_flag); if (ldh.l_magic!=L_MAGIC) { complain("%.*s in %s is not a load module\n", DIRSIZ, arhp->ar_name, archive); } else { int seg, nsym; size_t offset; if ((ldh.l_flag & LF_32) == 0) ldh.l_tbase = sizeof(ldh) - 2*sizeof(short); else canshort(ldh.l_tbase); offset = ldh.l_tbase - sizeof(ldh); for (seg=0; seg<L_SYM; seg++) { if (seg==L_BSSI || seg==L_BSSD) continue; cansize(ldh.l_ssize[seg]); offset += ldh.l_ssize[seg]; } fseek(arfp, offset, 1); cansize(ldh.l_ssize[L_SYM]); if ((ldh.l_flag & LF_32) == 0) nsym = ldh.l_ssize[L_SYM] / (sizeof(struct ldsym) - sizeof(short)); else nsym = ldh.l_ssize[L_SYM]/sizeof(struct ldsym); while (nsym--) { union {struct ldsym; ar_sym;} sym; if (readsym((struct ldsym *)&sym, arfp) == 0) { complain("truncated module %.*s in %s", DIRSIZ, arhp->ar_name, archive); exit(1); } if ((sym.ls_type&L_GLOBAL) == 0) continue; if ((sym.ls_type&LR_SEG) != L_REF #if 0 || sym.ls_addr != 0) { #else ) { #endif sym.ar_off = off; cansize(sym.ar_off); xwrite(&sym, hdrfp); } } } } fseek(arfp, arhp->ar_size, 0); /* to end of module */ return; } static readsym(sp, fp) register struct ldsym *sp; FILE *fp; { register int r; union { long l; unsigned u[2]; } u; if ((ldh.l_flag & LF_32) == 0) { r = fread(sp, sizeof(struct ldsym)-sizeof(short), 1, fp); u.l = sp->ls_addr; canshort(u.u[0]); sp->ls_addr = u.u[0]; } else { r = fread(sp, sizeof(struct ldsym), 1, fp); canlong(sp->ls_addr); } canshort(sp->ls_type); return (r); } static int ranlib(archive) char *archive; { FILE *arfile, *hdrfile; char arcmd[256]; struct ar_hdr arhdr; int armagic = 0; size_t arbase = sizeof armagic+sizeof arhdr; if ((arfile=fopen(archive, "r"))==NULL) { complain("can't open archive %s", archive); return (1); } fread(&armagic, sizeof armagic, 1, arfile); canint(armagic); if (armagic!=ARMAG) { complain("%s is not an archive", archive); fclose(arfile); return (1); } if (fread(&arhdr, sizeof arhdr, 1, arfile)!=1) { fclose(arfile); /* void archive */ return (0); } if ((hdrfile=fopen(HDRNAME, "w"))==NULL) { complain("can't create header file"); fclose(arfile); exit(1); } if (strncmp(arhdr.ar_name, HDRNAME, DIRSIZ)==0) { sprintf(arcmd, "ar ru %s %s", archive, HDRNAME); cansize(arhdr.ar_size); fseek(arfile, arhdr.ar_size, 1); arbase += arhdr.ar_size+sizeof arhdr; } else { sprintf(arcmd, "ar rub %.*s %s %s", DIRSIZ, arhdr.ar_name, archive, HDRNAME); addhdr(arbase, &arhdr, hdrfile, arfile, archive); } while(fread(&arhdr, sizeof arhdr, 1, arfile)==1) addhdr(arbase, &arhdr, hdrfile, arfile, archive); if (fclose(hdrfile)==EOF) { complain("close error on header file"); exit(1); } if (ferror(arfile)) { complain("read error on archive %s", archive); fclose(arfile); return (1); } fclose(arfile); system(arcmd); return (0); }