/* * init routines */#include "defs.h"#include "fns.h" char *symfil;char *corfil; Map *symmap;Map *cormap;Map *dotmap; int fsym, fcor;static Fhdr fhdr; extern Mach mmips;extern Machdata mipsmach; static int getfile(char*, int, int); voidsetsym(void){ Symbol s; if((fsym = getfile(symfil, 1, wtflag)) < 0) { symmap = dumbmap(-1); machdata = &mipsmach; mach = &mmips; return; } if (crackhdr(fsym, &fhdr)) { machbytype(fhdr.type); symmap = loadmap(symmap, fsym, &fhdr); if (symmap == 0) symmap = dumbmap(fsym); if (syminit(fsym, &fhdr) < 0) dprint("%r\n"); if (mach->sbreg && lookup(0, mach->sbreg, &s)) mach->sb = s.value; } else symmap = dumbmap(fsym);} voidsetcor(void){ char buf[64]; int fd; ulong ksp; long proc; /* address of proc table */ if(pid > 0){ /* set kbase; should probably do other things, too */ sprint(buf, "/proc/%d/proc", pid); fd = open(buf, 0); if(fd >= 0){ seek(fd, mach->kspoff, 0); if(read(fd, (char *)&ksp, 4) == 4) mach->kbase = machdata->swal(ksp) & ~(mach->pgsize-1); close(fd); } } if (cormap) close(fcor); fcor = getfile(corfil, 2, ORDWR); if (fcor <= 0) { if (cormap) free(cormap); cormap = dumbmap(-1); return; } cormap = newmap(cormap, fcor, 3); if (!cormap) return; setmap(cormap, fhdr.txtaddr, fhdr.txtaddr+fhdr.txtsz, fhdr.txtaddr, "text"); setmap(cormap, fhdr.dataddr, mach->kbase, fhdr.dataddr, "data"); setmap(cormap, mach->kbase, mach->kbase+mach->pgsize, mach->kbase, "ublock"); fixregs(cormap); if (kflag) { if (get4(cormap, mach->kbase, &proc) < 0) error("can't find proc table: %r"); adjustreg(mach->pc, proc+mach->kpcoff, mach->kpcdelta); adjustreg(mach->sp, proc+mach->kspoff, mach->kspdelta); } kmsys(); return;} Map *dumbmap(int fd){ Map *dumb; extern Mach mmips; extern Machdata mipsmach; dumb = newmap(0, fd, 1); setmap(dumb, 0, 0xffffffff, 0, "data"); if (!mach) /* default machine = mips */ mach = &mmips; if (!machdata) machdata = &mipsmach; return dumb;} /* * set up maps for a direct process image (/proc) */ voidcmdmap(Map *map){ int i; char name[MAXSYM]; extern char lastc; rdc(); readsym(name); i = findseg(map, name); if (i < 0) /* not found */ error("Invalid map name"); if (expr(0)) { if (strcmp(name, "text") == 0) textseg(expv, &fhdr); map->seg[i].b = expv; } else error("Invalid base address"); if (expr(0)) map->seg[i].e = expv; else error("Invalid end address"); if (expr(0)) map->seg[i].f = expv; else error("Invalid file offset"); if (rdc()=='?' && map == cormap) { if (fcor) close(fcor); fcor=fsym; corfil=symfil; cormap = symmap; } else if (lastc == '/' && map == symmap) { if (fsym) close(fsym); fsym=fcor; symfil=corfil; symmap=cormap; } else reread();} static intgetfile(char *filnam, int cnt, int omode){ int f; if (filnam == 0) return -1; if (strcmp(filnam, "-") == 0) return 0; f = open(filnam, omode|OCEXEC); if(f < 0 && omode == ORDWR){ f = open(filnam, OREAD|OCEXEC); if(f >= 0) dprint("%s open read-only\n", filnam); } if (f < 0 && xargc > cnt) if (wtflag) f = create(filnam, 1, 0666); if (f < 0) { dprint("cannot open `%s': %r\n", filnam); return -1; } return f;} voidkmsys(void){ int i; i = findseg(symmap, "text"); if (i >= 0) { symmap->seg[i].b = symmap->seg[i].b&~mach->ktmask; symmap->seg[i].e = ~0; } i = findseg(symmap, "data"); if (i >= 0) { symmap->seg[i].b |= mach->kbase; symmap->seg[i].e |= mach->kbase; } i = findseg(symmap, "ublock"); if (i >= 0) unusemap(symmap, i); cormap = newmap(cormap, fcor, 1); if (cormap) setmap(cormap, 0, ~0, 0, "data");} voidattachproc(void){ char buf[100]; int statstat; Dir sym, mem; int fd; if (!adrflg) { dprint("used pid$a\n"); return; } statstat = dirfstat(fsym, &sym); sprint(buf, "/proc/%d/mem", adrval); corfil = buf; setcor(); sprint(buf, "/proc/%d/text", adrval); fd = open(buf, OREAD); if (statstat < 0 || fd < 0 || dirfstat(fd, &mem) < 0 || sym.qid.path != mem.qid.path) dprint("warning: text images may be inconsistent\n"); if (fd >= 0) close(fd);}
/*
* init routines
*/
#include "defs.h"
#include "fns.h"
char *symfil;
char *corfil;
Map *symmap;
Map *cormap;
Map *dotmap;
int fsym, fcor;
static Fhdr fhdr;
extern Mach mmips;
extern Machdata mipsmach;
static int getfile(char*, int, int);
void
setsym(void)
{
Symbol s;
if((fsym = getfile(symfil, 1, wtflag)) < 0) {
symmap = dumbmap(-1);
machdata = &mipsmach;
mach = &mmips;
return;
}
if (crackhdr(fsym, &fhdr)) {
machbytype(fhdr.type);
symmap = loadmap(symmap, fsym, &fhdr);
if (symmap == 0)
symmap = dumbmap(fsym);
if (syminit(fsym, &fhdr) < 0)
dprint("%r\n");
if (mach->sbreg && lookup(0, mach->sbreg, &s))
mach->sb = s.value;
}
else
symmap = dumbmap(fsym);
}
void
setcor(void)
{
char buf[64];
int fd;
ulong ksp;
long proc; /* address of proc table */
if(pid > 0){ /* set kbase; should probably do other things, too */
sprint(buf, "/proc/%d/proc", pid);
fd = open(buf, 0);
if(fd >= 0){
seek(fd, mach->kspoff, 0);
if(read(fd, (char *)&ksp, 4) == 4)
mach->kbase = machdata->swal(ksp) & ~(mach->pgsize-1);
close(fd);
}
}
if (cormap)
close(fcor);
fcor = getfile(corfil, 2, ORDWR);
if (fcor <= 0) {
if (cormap)
free(cormap);
cormap = dumbmap(-1);
return;
}
cormap = newmap(cormap, fcor, 3);
if (!cormap)
return;
setmap(cormap, fhdr.txtaddr, fhdr.txtaddr+fhdr.txtsz, fhdr.txtaddr, "text");
setmap(cormap, fhdr.dataddr, mach->kbase, fhdr.dataddr, "data");
setmap(cormap, mach->kbase, mach->kbase+mach->pgsize, mach->kbase, "ublock");
fixregs(cormap);
if (kflag) {
if (get4(cormap, mach->kbase, &proc) < 0)
error("can't find proc table: %r");
adjustreg(mach->pc, proc+mach->kpcoff, mach->kpcdelta);
adjustreg(mach->sp, proc+mach->kspoff, mach->kspdelta);
}
kmsys();
return;
}
Map *
dumbmap(int fd)
{
Map *dumb;
extern Mach mmips;
extern Machdata mipsmach;
dumb = newmap(0, fd, 1);
setmap(dumb, 0, 0xffffffff, 0, "data");
if (!mach) /* default machine = mips */
mach = &mmips;
if (!machdata)
machdata = &mipsmach;
return dumb;
}
/*
* set up maps for a direct process image (/proc)
*/
void
cmdmap(Map *map)
{
int i;
char name[MAXSYM];
extern char lastc;
rdc();
readsym(name);
i = findseg(map, name);
if (i < 0) /* not found */
error("Invalid map name");
if (expr(0)) {
if (strcmp(name, "text") == 0)
textseg(expv, &fhdr);
map->seg[i].b = expv;
} else
error("Invalid base address");
if (expr(0))
map->seg[i].e = expv;
else
error("Invalid end address");
if (expr(0))
map->seg[i].f = expv;
else
error("Invalid file offset");
if (rdc()=='?' && map == cormap) {
if (fcor)
close(fcor);
fcor=fsym;
corfil=symfil;
cormap = symmap;
} else if (lastc == '/' && map == symmap) {
if (fsym)
close(fsym);
fsym=fcor;
symfil=corfil;
symmap=cormap;
} else
reread();
}
static int
getfile(char *filnam, int cnt, int omode)
{
int f;
if (filnam == 0)
return -1;
if (strcmp(filnam, "-") == 0)
return 0;
f = open(filnam, omode|OCEXEC);
if(f < 0 && omode == ORDWR){
f = open(filnam, OREAD|OCEXEC);
if(f >= 0)
dprint("%s open read-only\n", filnam);
}
if (f < 0 && xargc > cnt)
if (wtflag)
f = create(filnam, 1, 0666);
if (f < 0) {
dprint("cannot open `%s': %r\n", filnam);
return -1;
}
return f;
}
void
kmsys(void)
{
int i;
i = findseg(symmap, "text");
if (i >= 0) {
symmap->seg[i].b = symmap->seg[i].b&~mach->ktmask;
symmap->seg[i].e = ~0;
}
i = findseg(symmap, "data");
if (i >= 0) {
symmap->seg[i].b |= mach->kbase;
symmap->seg[i].e |= mach->kbase;
}
i = findseg(symmap, "ublock");
if (i >= 0)
unusemap(symmap, i);
cormap = newmap(cormap, fcor, 1);
if (cormap)
setmap(cormap, 0, ~0, 0, "data");
}
void
attachproc(void)
{
char buf[100];
int statstat;
Dir sym, mem;
int fd;
if (!adrflg) {
dprint("used pid$a\n");
return;
}
statstat = dirfstat(fsym, &sym);
sprint(buf, "/proc/%d/mem", adrval);
corfil = buf;
setcor();
sprint(buf, "/proc/%d/text", adrval);
fd = open(buf, OREAD);
if (statstat < 0 || fd < 0 || dirfstat(fd, &mem) < 0
|| sym.qid.path != mem.qid.path)
dprint("warning: text images may be inconsistent\n");
if (fd >= 0)
close(fd);
}