Xinu7/src/cmd/pm/setup.c
#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);
}