henesyinit from p9fce6d0435 years agoHistory
194 lines · 3.0 KB · Text
RawDownload
// Malloc verification if objtype != "mips" then	error("malloc checker for MIPS\n"); defn go(){	new();			// Make a new process 	xmalloc = malloc + 4;	// Delay slot filler may pull in first	xfree = free + 4;	// instruction 	bpset(xmalloc);	bpset(xfree);	bpset(_exits+4); 	blocklist = {};		// List of allocated blocks	framelist = {};		// Frames they were allocated from	stacks = {};		// The stacks	nstack = 0; 	while 1 do {		cont();		pc = *PC;		if pc == xmalloc then			gotmalloc();		else		if pc == xfree then			gotfree();		else {			pstop(pid);			return {};		}	}} defn stkcmp(s1, s2)		// return true if the stack traces are the same{	local f1, f2; 	while s1 do {		f1 = head s1;		f2 = head s2; 		if f2 == {} || f1[0] != f2[0] || f1[1] != f2[1] then			return 0; 		s1 = tail s1;		s2 = tail s2;	}	if s2 != {} then		return 0; 	return 1;} defn stkindex(s){	local slist, n; 	slist = stacks;	n = 0;	while slist do {		if stkcmp(head slist, s) then			return n; 		slist = tail slist;		n = n+1;	} 	stacks = append stacks, s;	n = nstack;	nstack = nstack+1;	return n;} defn gotmalloc(){	local raddr, stk; 	raddr = *R31;	bpset(raddr);	stk = strace(*PC, *SP, *R31);	// Save a copy of the stack up to the malloc	cont();				// Continue until malloc returns	bpdel(raddr); 	blocklist = append blocklist, *R1;	framelist = append framelist, stkindex(stk);} defn pentry(s){	local sno, blst, gotone, size; 	gotone = 0;	blst = blocklist;	flst = framelist; 	while blst do {		sno = head flst;		if sno == s then {			addr = fmt(head blst, 'X');			size = 1<<*(addr-12);//			print(addr, " of ", fmt(size, 'D'), "bytes\n");			gotone = gotone + size;		}		blst = tail blst;		flst = tail flst;	}	return gotone;} defn leak(){	local n;	local sz; 	n = 0;	while n < nstack do {		sz = pentry(n);		if sz then {			print("Lost a total of ", fmt(sz, 'D'), " bytes from:\n");			mstack(stacks[n]);		}		n = n+1;	}} defn scanmem(start, end){	local n; 	start = fmt(start, 'X');	while start < end do {		n = match(*start, blocklist);		if n >= 0 then {			blocklist = delete blocklist, n;			framelist = delete framelist, n;		}		start++;	}} defn refs()			// Delete blocks with references{	print("data...");	scanmem(bdata, edata); 	print("bss...");	scanmem(edata, *bloc); 	print("stack...");	scanmem(*SP, 0x80000000); 	print("\n");	leak();	} defn mstack(stk){	while stk do {		frame = head stk;		print("\t", fmt(frame[0], 'a'), "() ");		print(pcfile(frame[0]), ":", pcline(frame[0]));		print("called from ", fmt(frame[1], 'a'), " ");		pfl(frame[1]);		stk = tail stk;	}} defn gotfree(){	local n, addr; 	addr = *R1;			// We know the first parameter is register R1	if addr == 0 then		return {}; 	n = match(addr, blocklist);	if n < 0 then {		print("free(", addr, ") called with bad pointer:\n");		stk();		return {};	}	blocklist = delete blocklist, n;	framelist = delete framelist, n;} defn stopped(pid){	return {};} print("/sys/lib/acid/malloc");