Plan 9 from Bell Labs’s /usr/web/sources/contrib/quanstro/root/sys/src/9/pc/archtrace.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include	"u.h"
#include	"../port/lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"archtrace.h"

#pragma	profile	0

/*
 * this is the wrong place for this, and a very large hammer,
 * but at least we are controlling access to kernel memory.
 * must match mmuinit()
 */
static void
kmem(int write)
{
	ulong x, *p;

	for(x = KTZERO; x < (ulong)etext; x += BY2PG){
		p = mmuwalk(m->pdb, x, 2, 0);
		if(p == nil)
			panic("kmem");
		if(write)
			*p |= PTEWRITE;
		else
			*p &= ~PTEWRITE;
	}
}

enum {
	CALL	= 0xe8,
	JMP	= 0xeb,
	RET	= 0xc3,
	NOP	= 0x90,
};

char*
archtracectlr(Archtrace *a, char *p, char *e)
{
	int i;

	for(i = 0; i < a->nprobe; i++)
		p = seprint(p, e, "#  tracept %c %#.8p\n",
			a->probe[i]==NOP? 'X': 'E', a->text[i]);
	return p;
}

void
archtraceinstall(Archtrace *a)
{
	int i;

	kmem(1);
	for(i = 0; i < a->nprobe; i++)
		*a->text[i] = a->probe[i];
	kmem(0);
}

void
archtraceuninstall(Archtrace *a)
{
	int i;

	kmem(1);
	for(i = 0; i < a->nprobe; i++)
		*a->text[i] = a->orig[i];
	kmem(0);
}

static int
call4(uchar *call, uchar *targ)
{
	uchar buf[5];
	ulong l;

	buf[0] = CALL;
	l = targ - (call + 5);
	buf[1] = l;
	buf[2] = l>>8;
	buf[3] = l>>16;
	buf[4] = l>>24;
	return memcmp(buf, call, 5);
}

static uchar startsig[] = {JMP, 0x05};

int
mkarchtrace(Archtrace *a, uchar *start, uchar **endp)
{
	uchar *p, *end;

	/*
	 * search by signatures.  we don't really
	 * care we get a whole function or not.
	 */
	end = *endp;
	for(p = start; p + 6 <= end; p++)
		if(memcmp(p, startsig, sizeof startsig) == 0){
			if(call4(p + 2, (uchar*)_tracein) == 0){
				a->text[a->nprobe] = start + 1;
				a->orig[a->nprobe] = *a->text[a->nprobe];
				a->probe[a->nprobe] = 0;		/* jmp 2f */
				a->nprobe++;
			}
		}else  if(p[0] == RET && p[6] == RET){
			if(call4(p + 1, (uchar*)_traceout) == 0){
				if(a->nprobe == Maxprobe)
					error("too many exits");
				a->text[a->nprobe] = p;
				a->orig[a->nprobe] = *a->text[a->nprobe];
				a->probe[a->nprobe] = NOP;
				a->nprobe++;
			}
		}
//	*endp = a->text[a->nprobe - 1];
	return 0;
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.