186 lines · 3.1 KB · Brainfuck
RawDownload
## Manage module data relocation and instruction patch information.# dreloc:		ref Ipatch;Ipatchtid:	int; setIpatchtid(){	Ipatchtid = descid(1, 0, array [1] of { byte 0 });} ## Add an instruction patch directive to ip.# (flag == SAVEINST) <=> runtime relocation: Inst* needed later# (flag == !SAVEINST) <=> other: pinfo expected in sequential order# addIpatch(ip: ref Ipatch, i: ref Inst, operand: int, patchkind: int, flag: int){	j: int; 	if(ip.n >= ip.max) {		oldmax := ip.max;		ip.max += ALLOCINCR;		newippinfo := array [ip.max] of int;		for(j = 0; j < oldmax; j++)			newippinfo[j] = ip.pinfo[j];		ip.pinfo = newippinfo;		if(flag == SAVEINST) {			newipi := array [ip.max] of ref Inst;			for(j = 0; j < oldmax; j++)				newipi[j] = ip.i[j];			ip.i = newipi;		}	}	ip.pinfo[ip.n] = (i.pc << 8) | operand | patchkind;	if(flag == SAVEINST)		ip.i[ip.n] = i;	ip.n += 1;} operand := array [] of {	"?",	"src",		# PSRC >> 2	"dst",		# PDST >> 2	"mid"		# PMID >> 2}; mode := array [] of {	"$x",		# PIMM	"x(reg)",	# PSIND	"n(x(reg))",	# PDIND1	"x(n(reg))"	# PDIND2}; ba:		array of byte;nba:		int;HIGHBIT:	con byte 16r80; sizeba(sz: int){	if(sz > len ba) {		newba := array [sz] of byte;		for(i := 0; i < nba; i++)			newba[i] = ba[i];		ba = newba;	}} fillba(ip: ref Ipatch){	i: int;	pclast, pcnext, delta, skip: int; 	sizeba(2*ip.n);	pclast = 0;	for(i = 0; i < ip.n; i++) {		pcnext = ip.pinfo[i] >> 8;		delta = pcnext-pclast;		sizeba(nba + delta/1024 + 2);		while(delta > 7) {			if(delta > 1024)				skip = 1024;			else				skip = delta & int 16rfffffff8;			ba[nba++] = byte(256 - (skip >> 3));			delta -= skip;		}		ba[nba++] = byte((delta << 4) | (ip.pinfo[i] & 16rf));		pclast = pcnext;	}} ## Write Ipatch information to .s file.# asmIpatch(off: int, ip: ref Ipatch){	i: int;	reloff: int;		# relative offset for array elements	pc: int; 	if(ip == nil || ip.n == 0)		return; 	fillba(ip); 	reloff = 0;	asmarray(off, Ipatchtid, nba, reloff);	pc = 0;	for(i = 0; i < nba; i++) {		bout.puts("\tbyte\t@mp+" + string reloff + "," + string ba[i]);		if(int(ba[i] & HIGHBIT))			pc += (256 - int ba[i]) << 3;		else			pc += int ba[i] >> 4;		bout.puts("\t# " + string pc);		if(!int(ba[i] & HIGHBIT)) {			bout.puts(", " + operand[(int ba[i] >> 2) & 16r3]				+ ", " + mode[int ba[i] & 16r3]);		}		bout.putc('\n');		reloff += 1;	}	bout.puts("\tapop\n"); 	ba = nil;	nba = 0;} ## Write Ipatch information to .dis file.# disIpatch(off: int, ip: ref Ipatch){	i: int;	reloff: int;		# relative offset for array elements 	if(ip == nil || ip.n == 0)		return; 	fillba(ip); 	disarray(off, Ipatchtid, nba);	reloff = 0;	for(i = 0; i < nba; i++) {		disbyte(reloff, ba[i]);		reloff += 1;	}	disapop(); 	ba = nil;	nba = 0;} ## Add instruction patch information to dreloc.# addDreloc(i: ref Inst, operand: int, patchkind: int){	if(dreloc == nil)		dreloc = ref Ipatch(0, 0, nil, nil);	addIpatch(dreloc, i, operand, patchkind, !SAVEINST);} ## Write Dreloc information to .s file.# asmDreloc(off: int){	asmIpatch(off, dreloc);} ## Write Dreloc information to .dis file.# disDreloc(off: int){	disIpatch(off, dreloc);}