⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dis.c

📁 转载一份有关M68K反汇编C语言源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
			perror("fseek");			jumpfree();		}		flags = 0;		if (insts[offset].size) {			if (stored) {				flush(stored, consts, 0, 1);				stored = 0;			}			pc = ppc = initialpc + offset;			leninstbuf = 0;			validinst();		} else {			size_t	i;			if (stored == 0)				pc = ppc = initialpc + offset;			for (i = 0; i < WORDSIZE; i++)				if (fread(consts + stored, 1, 1, infp) == 1)					if (++stored >= sizeof consts) {						stored = flush(stored, consts,						  0, 0);						memmove(consts, consts						  + sizeof consts - stored,						  stored);					}		}	}	if (stored)		flush(stored, consts, 0, 1);	fflush(NULL);}/* * Make the first pass over the input. * Gather references to other addresses. */voidpass1(void){	m68kaddr	offset;	pass = FIRSTPASS;	for (curoffset = offset = 0; offset <= maxoffset;	  offset += (odd ? 1 : WORDSIZE)) {		if (curoffset != offset		  && fseek(infp, curoffset = offset, SEEK_SET) == -1) {			perror("fseek");			jumpfree();		}		flags = 0;		pc = ppc = offset + initialpc;		leninstbuf = 0;		if (validinst()) {			/*			 * It's a potential instruction.			 */			insts[offset].size = curoffset - offset;			insts[offset].flags = flags;			if (flags & 3) {				m68kaddr	*reqd;				if ((reqd = malloc((flags & 3) * sizeof(*reqd)))				  == NULL) {					perror("malloc");					jumpfree();				}				switch (flags & 3) {				case 3:	reqd[2] = required[2];				case 2:	reqd[1] = required[1];				case 1:	reqd[0] = required[0];				}				insts[offset].required = reqd;			} else				insts[offset].required = NULL;#ifdef DEBUG			if (debug & INITIAL) {				int	i;				fprintf(outfp,				  "Writing offset = %lx, size = %d, flags = %d",				  (long)offset, insts[offset].size,				  insts[offset].flags);				for (i = 0; i < (insts[offset].flags & 3); i++)					fprintf(outfp, ", reqd = %lx",					  (long)insts[offset].required[i]);				fprintf(outfp, "\n");			}#endif		}		else {#ifndef NOBAD			bad[offset] = offset + initialpc;#endif#ifdef DEBUG			if (debug & DELETIONS)				fprintf(outfp, "0. Deleting offset %lx\n",				  (long)offset);#endif		}	}#if !defined(NOBAD) || defined(DEBUG)	for (offset = maxoffset + (odd ? 1 : WORDSIZE);	  offset <= maxoffset + longestinstsize;	  offset += (odd ? 1 : WORDSIZE)) {#ifndef NOBAD		if (offset <= maxoffset)			bad[offset] = offset + initialpc;#endif#ifdef DEBUG		if (debug & DELETIONS)			fprintf(outfp, "0. Deleting offset %lx\n",			  (long)offset);#endif	}#endif}/* * Make a pass over the instruction database, checking for consistency. */voidfindbadrefs(void){	long	offset;		/* must be signed */	long	offset2;	/* must be signed */	int	i;	size_t	size;	int	changes;	int	try = 0;#if 0	int totalchanges = 0;#endif#ifdef DEBUG	if (debug & TRY) {		printall();		fprintf(outfp, "\n\n\n");	}#endif	/*	 * Instructions that don't set PC	 * must be followed by a valid instruction.	 */	do {		changes = 0;		try++;		for (offset = maxoffset + longestinstsize; offset >= 0;		  offset -= (odd ? 1 : WORDSIZE)) {			/*			 * Back up to a possible instruction.			 * We do this to jump over a large data section.			 */			for (offset2 = offset; offset2 >= 0			  && insts[offset2].size == 0;			  offset2 -= (odd ? 1 : WORDSIZE))				;			if (offset2 < 0)				break;			if (offset2 + longestinstsize < offset)				offset = offset2 + longestinstsize;			if (!linkfallthrough && (insts[offset].flags & ISLINK)			  || !FETCH(offset, -1)) {				/*				 * We've found an invalid instruction.				 * See if any instructions advance PC here				 * based on the size of the instruction				 * and its operands.				 */				for (size = odd ? 1 : WORDSIZE;				  size <= longestinstsize && size <= offset;				  size += (odd ? 1 : WORDSIZE))					if (FETCH(offset - size, size)					  && !JUMP(offset - size)) {#ifndef NOBAD						if (!linkfallthrough						  && (insts[offset].flags						  & ISLINK))							bad[offset - size]							  = offset + initialpc;						else							bad[offset - size]							  = bad[offset];#endif#ifdef DEBUG						if (debug & DELETIONS)fprintf(outfp,  "1. Deleting offset %lx, size %d, flags = %d\n", (long)(offset - size),  size, insts[offset - size].flags);#endif						DELETE(offset - size);						changes++;					}			}		}		/*		 * See if any instructions require		 * an invalid instruction to be valid.		 */		for (offset2 = 0; offset2 <= maxoffset;		  offset2 += (odd ? 1 : WORDSIZE)) {			if (insts[offset2].size == 0)				continue;			for (i = 0; i < NREQD(offset2); i++)				if (insts[offset2].required[i] >= initialpc				  && insts[offset2].required[i] <= initialpc				  + maxoffset				  && !FETCH(insts[offset2].required[i]				  - initialpc, -1)) {#ifndef NOBAD					bad[offset2]					  = bad[insts[offset2].required[i]					  - initialpc];#endif#ifdef DEBUG					if (debug & DELETIONS)fprintf(outfp, "2. Deleting offset %lx, size %d because %lx is not valid\n",(long)offset2, insts[offset2].size, (long)insts[offset2].required[i]);#endif					DELETE(offset2);					changes++;					break;				}		}#ifdef DEBUG		if (debug & TRY) {			fprintf(outfp,			  "TRY %d ###############################\n", try);			printall();			fprintf(outfp, "\n\n\n");		}#endif#if 0		totalchanges += changes;#endif	} while (changes);#if 0	printf("Tries = %d\n", (int)try);	printf("Changes = %d\n", (int)totalchanges);#endif#ifdef DEBUG	if (debug & LASTTRY) {		fprintf(outfp, "TRY %d ###############################\n",		  try - 1);		printall();		fprintf(outfp, "\n\n\n");	}#endif}struct queue {	m68kaddr	address;	struct queue	*next;};/* * The ``writeq'' and ``readq'' functions * maintain a queue of addresses for ``makegood''. */static struct queue	head = { 0, NULL };/* * Add to the queue. */static voidwriteq(m68kaddr address){	struct queue	*tail;	struct queue	*newq;	if ((newq = malloc(sizeof(*newq))) == NULL) {		perror("malloc");		jumpfree();	}	newq->address = address;#ifdef DEBUG	if (debug & MAKEGOOD)		fprintf(outfp, "Wrote offset = %lx\n", (long)address);#endif	newq->next = NULL;	for (tail = &head; tail->next; tail = tail->next)		;	tail->next = newq;}/* * Read (and delete) from the queue. */static struct queue *readq(void){	struct queue	*result;	if (head.next) {		result = head.next;		head.next = head.next->next;#ifdef DEBUG		if (debug & MAKEGOOD)			fprintf(outfp, "Read offset = %lx\n",			  (long)result->address);#endif	} else		result = NULL;	return result;}/* * Mark ``offset'' as an instruction to be included in the final output. * Recursively mark as good all instructions that reference it. * Delete instructions that contradict those marked good. * Return the number off offsets deleted. */static unsignedmakegood(m68kaddr offset){	size_t		size;	struct queue	*qptr = NULL;	m68kaddr	origoffset = offset;	unsigned	deletions = 0;	if (insts[offset].flags & ISGOOD)		return deletions;#ifdef DEBUG	if (debug & MAKEGOOD)		fprintf(outfp, "makegood(%lx)\n", (long)offset);#endif	do {		if (qptr) {			offset = qptr->address;			free(qptr);		}#ifdef DEBUG		if (debug & MAKEGOOD)			fprintf(outfp, "Going with offset = %lx\n",			  (long)offset);#endif		while (1) {#ifdef DEBUG			if (debug & MAKEGOOD)				fprintf(outfp, "Offset = %lx\n", (long)offset);#endif			if (insts[offset].size == 0 ||			  insts[offset].flags & ISGOOD)				break;			/*			 * We have a ``good'' instruction.			 * Instructions that overlap it should be deleted.			 */			for (size = odd ? 1 : WORDSIZE; size < longestinstsize			  && size + maxoffset >= offset && size <= offset;			  size += (odd ? 1 : WORDSIZE))				if (insts[offset - size].size > size) {#ifndef NOBAD					bad[offset - size] = origoffset					  + initialpc;#endif#ifdef DEBUG					if (debug & DELETIONS)fprintf(outfp, "3. Deleting offset %lx, size %d, flags = %d because of %lx\n",  (long)(offset - size), insts[offset - size].size, insts[offset - size].flags,  (long)offset);#endif					DELETE(offset - size);					deletions++;				}			for (size = odd ? 1 : WORDSIZE;			  size < insts[offset].size			  && maxoffset >= offset + size;			  size += (odd ? 1 : WORDSIZE))				if (insts[offset + size].size) {#ifndef NOBAD					bad[offset + size] = origoffset					  + initialpc;#endif#ifdef DEBUG					if (debug & DELETIONS)fprintf(outfp, "4. Deleting offset %lx, size %d, flags = %d because of %lx\n",  (long)(offset + size), insts[offset + size].size, insts[offset + size].flags,  (long)offset);#endif					DELETE(offset + size);					deletions++;				}			insts[offset].flags |= ISGOOD;#ifndef NOBAD			good[offset] = origoffset + initialpc;#endif			if ((insts[offset].flags & ISBRA)			  || ((insts[offset].flags & ISJMP) &&			  insts[offset].flags & 3)) {				if (insts[offset].required[0] >= initialpc				  && insts[offset].required[0] <= initialpc				  + maxoffset)					offset = insts[offset].required[0]					  - initialpc;				else					break;			} else if ((insts[offset].flags			  & (ISBSR | ISJSR | ISBRA | ISBRcc | ISDBcc | ISJMP))			  && (insts[offset].flags & 3)			  && insts[offset].required[0] >= initialpc			  && insts[offset].required[0] <= initialpc			  + maxoffset) {				writeq(insts[offset].required[0] - initialpc);				offset += insts[offset].size;			} else if (insts[offset].flags & (ISRTS | ISJMP))				break;			else				offset += insts[offset].size;		}	} while (qptr = readq());	return deletions;}/* * Determine the number of remaining instances * of still-valid instructions overlapping each other. */static longoverlaps(int list){	long	num = 0;	long	offset;	size_t	size;	for (offset = 0; offset <= maxoffset; offset += (odd ? 1 : WORDSIZE)) {		if (insts[offset].size == 0)			continue;		for (size = odd ? 1 : WORDSIZE; size < longestinstsize		  && size <= offset; size += (odd ? 1 : WORDSIZE))			if (insts[offset - size].size > size) {				num++;				if (list)					fprintf(stderr, "%s: Overlap at %lx\n",					  sfile, offset);			}	}	return num;}/* * Starting from ``offset'', return the next highest offset * containing an instruction marked good (or -1). */static longnextgood(m68kaddr offset){	long	next;	for (next = offset + (odd ? 1 : WORDSIZE); next <= maxoffset	  && (insts[next].size == 0 || (insts[next].flags & ISGOOD) == 0);	  next += (odd ? 1 : WORDSIZE))		;	return (next > maxoffset) ? -1 : next;}/* * Return whether program flow reaches address ``target'' * starting from address ``prevonly''. */static intreach(m68kaddr prevonly, m68kaddr target){	m68kaddr	offset;	for (offset = prevonly; insts[offset].size && offset < target;	  offset += insts[offset].size)		;	return offset == target;}/* * Fix the overlap situation. * Do this by minimizing the amount of data (constants) in the input. */static unsignedfixoverlaps(void){	m68kaddr	offset;	m68kaddr	goodone = nextgood(0);	unsigned	deletions = 0;	for (offset = 0; offset <= maxoffset; ) {		if (insts[offset].size == 0) {			if (odd)				offset++;			else				offset += WORDSIZE;			continue;		}		if (insts[offset].flags & ISGOOD) {			offset += insts[offset].size;			continue;		}		if (/*goodone >= 0 &&*/ goodone <= offset)			goodone = nextgood(offset);		if (reach(offset, goodone))			deletions += makegood(offset);		else if (odd)			offset++;		else			offset += WORDSIZE;	}	return deletions;}static intaddrcmp(const void *p1, const void *p2){	m68kaddr	a1 = *(m68kaddr *)p1;	m68kaddr	a2 = *(m68kaddr *)p2;	if (a1 < a2)		return -1;	else if (a1 > a2)		return 1;	else		return 0;}/* * Return whether a ``math'' FPU instruction * has the word at ``offset'' as an extension word. */static intfpuoverlap(m68kaddr offset){	size_t	size;	if (!FPU(chip) || (insts[offset].flags & (ISBSR | ISBRA | ISBRcc)) == 0)		return 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -