#include "pm.h" #include <sys/stat.h> /* * pm - initialization routines */ struct nlist nl[] = /* symbols pulled out of the text image */ { {"_currpid"}, #define CURRPID 0 {"_proctab"}, #define PROC 1 {"_q"}, #define XQ 2 {"_semaph"}, #define SEMS 3 {"_tty"}, #define TTYS 4 {"_vers"}, #define VERS 5 {"_clktime"}, #define CLKTIM 6 0 }; extern struct pentry *proctb; extern struct sentry *semtab; extern struct tty *tptr; extern struct qent *Q; extern char *vers; extern long clktim; setup(argc, argv) int argc; char *argv[]; { char *malloc(); FILE *txtfd, *corefd; struct stat stat; register struct nlist *sp1, *sp2; register i; int s1, s2; int svalcomp(); procargs(argc, argv); if (verbose) printf("Opening core file...\n"); corefd = fopen(corefile, "r"); if(corefd == (FILE *)NULL){ fprintf(stderr, "Can't open %s\n", corefile); exit(-1); } if (verbose) printf("Opening text file...\n"); txtfd = fopen(txtfile, "r"); if(txtfd == (FILE *)NULL){ fprintf(stderr, "Can't open %s\n", txtfile); exit(-2); } if (verbose) printf("Reading core header of %d bytes\n", sizeof(struct core11) ); fread(&c_header, sizeof(struct core11), 1, corefd);/* read the header */ fstat(fileno(corefd), &stat); if ( stat.st_size <= sizeof(struct core11) ) { fprintf(stderr,"Malformed core file header (size=%d)\n", stat.st_size); exit(-2); } stat.st_size -= sizeof(struct core11); if (verbose) printf("Allocating %d bytes for core image\n",stat.st_size); core = (short *)malloc(stat.st_size); if(core == (short *)NULL){ fprintf(stderr, "Can't allocate memory for core image\n"); exit(-3); } if (verbose) printf("Reading core image...\n"); fread(core, sizeof(char), stat.st_size, corefd);/* read the rest */ if (verbose) printf("Reading a.out header...\n"); fread(&a_out, sizeof(struct exec), 1, txtfd); text = (short *)malloc(a_out.a_text + a_out.a_data + a_out.a_bss); if(text == (short *)NULL){ fprintf(stderr, "Can't allocate space for system image\n"); exit(-4); } fread(text, sizeof(char), a_out.a_text + a_out.a_data, txtfd); symtab = (struct nlist *)malloc(a_out.a_syms); esymtab = &symtab[a_out.a_syms / sizeof (struct nlist)]; if(a_out.a_syms == 0) printf("No symbol table\n"); if(symtab == (struct nlist *)NULL){ fprintf(stderr, "Can't allocate space for symbol table\n"); exit(-5); } fread(symtab, a_out.a_syms, sizeof(char), txtfd); /* * produce list of externals sorted by address */ ssymtab = (struct nlist *)malloc(a_out.a_syms); i = 0; for(sp1 = symtab, sp2 = ssymtab; sp1 < esymtab; sp1++){ if((sp1->n_type & N_EXT) == 0) continue; i++; *sp2++ = *sp1; } essymtab = ssymtab + i; qsort(ssymtab, i, sizeof(struct nlist), svalcomp); /* * look up addresses of interesting tables */ nlist11(txtfile, nl); currpid = core[nl[CURRPID].n_value >> 1]; proctb = (struct pentry *)(&core[nl[PROC].n_value >> 1]); semtab = (struct sentry *)(&core[nl[SEMS].n_value >> 1]); Q = (struct qent *)(&core[nl[XQ].n_value >> 1]); tptr = (struct tty *)(&core[nl[TTYS].n_value >> 1]); vers = nl[VERS].n_value == 0 ? "6" : (char *)(&core[nl[VERS].n_value >> 1]); if (nl[CLKTIM].n_value == 0) { clktim = 0L; } else { s1 = 0xffff & (*((short *) &core[ (nl[CLKTIM].n_value>>1)])); s2 = 0xffff & (*((short *) &core[1+(nl[CLKTIM].n_value>>1)])); clktim = (s1<<16) | s2; } } svalcomp(sp1, sp2) register struct nlist *sp1, *sp2; { if(sp1->n_value == sp2->n_value) return(0); if(sp1->n_value < sp2->n_value) return(-1); return(1); } int a_magic[] = {A_MAGIC1, A_MAGIC2, A_MAGIC3, A_MAGIC4, 0}; #define SPACE 100 /* number of symbols read at a time */ nlist11(name, list) char *name; struct nlist *list; { register struct nlist *p, *q; int f, n, m, i; long sa; struct exec buf; struct nlist space[SPACE]; for(p = list; p->n_name[0]; p++) { p->n_type = 0; p->n_value = 0; } f = open(name, 0); if(f < 0) return(-1); read(f, (char *)&buf, sizeof buf); for(i=0; a_magic[i]; i++) if(a_magic[i] == buf.a_magic) break; if(a_magic[i] == 0){ close(f); return(-1); } sa = buf.a_text + (long)buf.a_data; if(buf.a_flag != 1) sa *= 2; sa += sizeof buf; lseek(f, sa, 0); n = buf.a_syms; while(n){ m = sizeof space; if(n < sizeof space) m = n; read(f, (char *)space, m); n -= m; for(q = space; (m -= sizeof(struct nlist)) >= 0; q++) { for(p = list; p->n_name[0]; p++) { for(i=0;i<8;i++) if(p->n_name[i] != q->n_name[i]) goto cont; p->n_value = q->n_value; p->n_type = q->n_type; break; cont: ; } } } close(f); return(0); } /* *=================================================== * procargs - unified argument processing procedure *=================================================== * * This procedure continas the logic for converting the UNIX argument * list into global variables */ procargs(argc, argv) int argc; char *argv[]; { int arg, unswitched, more; char *swptr; corefile = "core11"; txtfile = "a.out"; allopts = 1; popt = sopt = topt = 0; verbose = 0; unswitched = 0; for ( arg=1 ; arg<argc ; arg++ ) { if ( argv[arg][0] == '-' ) { more = 1; swptr = &argv[arg][1]; while ( more && *swptr!='\0' ) { switch ( *swptr++ ) { case 'v': verbose=1; case 'p': allopts = 0; popt = 1; break; case 's': allopts = 0; sopt = 1; break; case 't': allopts = 0; topt = 1; break; default: usagexit(argv[0]); } } } else { /* there's no dash in front */ switch ( unswitched++ ) { case 0: txtfile = argv[arg]; break; case 1: corefile = argv[arg]; break; default: usagexit(argv[0]); } } } } usagexit(pgm) char *pgm; { fprintf(stderr,"usage: %s [program [core]]\n",pgm); exit(1); }