#include <u.h>
#include <libc.h>
#include "../probe.h"
extern void pentrytmpl(void);
extern void pexittmpl(void);
void
trapme(void)
{
}
void
pentry(Probe *p)
{
ulong *sp;
int i;
print("pentry %p\n", p);
print("saveret %p\n", p->saveret);
print("callerpc %p\n", getcallerpc(&p));
print("arg0 %ud\n", *p->argp);
sp = (ulong *)&p;
for(i = -2; i < 16; i++)
print("%d 0x%lux\n", i, sp[i]);
trapme();
}
void
pexit(Probe *p)
{
ulong *sp;
int i;
print("pexit %p\n", p);
print("saveret %p\n", p->saveret);
print("callerpc %p\n", getcallerpc(&p));
print("rval %ud\n", p->rval);
sp = (ulong *)&p;
for(i = 0; i < 16; i++)
print("%d 0x%lux\n", i, sp[i]);
}
int (*nopclone)(int);
int
nop(int)
{
char tab[6];
char *p;
int r;
r = 0;
for(p = tab; p < &tab[6]; p++)
r += *p = 7;
return r;
}
Probe *
mkprobe(void *func, void (*pentry)(Probe *), void (*pexit)(Probe *))
{
Probe *p;
u32int *fp;
u32int rjmp;
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 = func;
p->orig[0] = fp[0];
p->orig[1] = fp[1];
/* 5 is size of rcall */
rjmp = (ulong)p->entrycode - (ulong)func - 5;
p->probe[0] = 0xe8 | (rjmp << 8);
p->probe[1] = (rjmp >> 24);
memmove(p->entrycode, pentrytmpl, sizeof p->entrycode);
memmove(p->exitcode, pexittmpl, sizeof p->exitcode);
return p;
}
void
probeinstall(Probe *p)
{
u32int *fp;
fp = (u32int*)p->func;
fp[0] = p->probe[0];
fp[1] = p->probe[1];
}
void
probeuninstall(Probe *p)
{
u32int *fp;
fp = (u32int*)p->func;
fp[0] = p->orig[0];
fp[1] = p->orig[1];
}
void
main(void)
{
Probe *p;
print("#define argp %lud\n", offsetof(Probe, argp));
print("#define entry %lud\n", offsetof(Probe, entry));
print("#define entrycode %lud\n", offsetof(Probe, entrycode[0]));
print("#define exit %lud\n", offsetof(Probe, exit));
print("#define exitcode %lud\n", offsetof(Probe, exitcode[0]));
print("#define func %lud\n", offsetof(Probe, func));
print("#define orig1 %lud\n", offsetof(Probe, orig[0]));
print("#define orig2 %lud\n", offsetof(Probe, orig[1]));
print("#define probe1 %lud\n", offsetof(Probe, probe[0]));
print("#define probe2 %lud\n", offsetof(Probe, probe[1]));
print("#define rval %lud\n", offsetof(Probe, rval));
print("#define saveret %lud\n", offsetof(Probe, saveret));
nopclone = malloc(256);
memmove(nopclone, nop, 256);
print("nopclone %p\n", nopclone);
p = mkprobe(nopclone, pentry, pexit);
probeinstall(p);
print("&p = %p\n", &p);
nopclone(10);
print("&p = %p\n", &p);
probeuninstall(p);
print("hey\n");
exits(nil);
}
|