#include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "probe.h" extern void template(void); void dcbst(void *); void icbi(void *); void meminvalidate(void *vp, int n) { int i; u32int *fp; fp = vp; for(i = 0; i < n / sizeof fp[0]; i++){ dcbst(fp+i); icbi(fp+i); } } Probe * mkprobe(void *func, void (*pentry)(Probe *), void (*pexit)(Probe *)) { Probe *p; u32int *fp; u32int rjmp; int i; fp = (u32int*)func; p = malloc(sizeof p[0]); print("entrycode = %p\n", p->entrycode); //print("exitcode = %p\n", p->exitcode); p->entry = pentry; p->exit = pexit; p->func = fp; memmove(p->orig, fp, sizeof p->orig); /* 5 is size of rcall */ rjmp = (ulong)p->entrycode; /* 00001028: 3c80dead 6084beef(804) MOVW $-559038737,R4 00001030: 7c8803a6 4e800021(804) BL ,0(R4) */ i = 0; p->probe[i++] = 0x7cc802a6; p->probe[i++] = 0x3c800000 | (rjmp >> 16); p->probe[i++] = 0x60840000 | (rjmp & 0xffff); p->probe[i++] = 0x7c8803a6; p->probe[i] = 0x4e800020; memmove(p->entrycode, template, sizeof p->entrycode); meminvalidate(p, sizeof p[0]); //memmove(p->exitcode, pexittmpl, sizeof p->exitcode); return p; } void probeinstall(Probe *p) { u32int *fp; int x; x = splhi(); fp = (u32int*)p->func; memmove(fp, p->probe, sizeof p->probe); meminvalidate(fp, sizeof p->orig); p->enabled = 1; splx(x); } void probeuninstall(Probe *p) { u32int *fp; int x; x = splhi(); fp = (u32int*)p->func; memmove(fp, p->orig, sizeof p->orig); meminvalidate(fp, sizeof p->orig); p->enabled = 0; splx(x); } void freeprobe(Probe *p) { free(p); }