188 lines · 3.0 KB · C
RawDownload
#include "java.h"#include "reloc.h" /* * Manage module data relocation and instruction patch information. */ static	Ipatch	*dreloc;static	int	Ipatchtid; voidsetIpatchtid(void){	Ipatchtid = descid(1, 0, (uchar*)"");} /* * Add an instruction patch directive to ip. * (flag == SAVEINST) <=> runtime relocation: Inst* needed later * (flag == !SAVEINST) <=> other: pinfo expected in sequential order */ voidaddIpatch(Ipatch *ip, Inst *i, int operand, int patchkind, int flag){ 	if(ip->n >= ip->max) {		ip->max += ALLOCINCR;		ip->pinfo = Realloc(ip->pinfo, ip->max * sizeof(int));		if(flag == SAVEINST)			ip->i = Realloc(ip->i, ip->max * sizeof(Inst*));	}	ip->pinfo[ip->n] = (i->pc << 8) | operand | patchkind;	if(flag == SAVEINST)		ip->i[ip->n] = i;	ip->n += 1;} static char *operand[] = {	"?",	"src",		/* PSRC >> 2 */	"dst",		/* PDST >> 2 */	"mid"		/* PMID >> 2 */}; static char *mode[] = {	"$x",		/* PIMM */	"x(reg)",	/* PSIND */	"n(x(reg))",	/* PDIND1 */	"x(n(reg))"	/* PDIND2 */}; static	schar	*ba;static	int	nba;static	int	szba; static voidsizeba(int sz){	if(sz > szba) {		szba = sz;		ba = Realloc(ba, szba * sizeof(schar));	}} static voidfillba(Ipatch *ip){	int i;	int pclast, pcnext, delta, skip; 	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) {			skip = (delta > 1024) ? 1024 : delta & 0xfffffff8;			ba[nba++] = -(skip >> 3);			delta -= skip;		}		ba[nba++] = (delta << 4) | (ip->pinfo[i] & 0xf);		pclast = pcnext;	}} /* * Write Ipatch information to .s file. */ voidasmIpatch(int off, Ipatch *ip){	int i;	int reloff;		/* relative offset for array elements */	int pc; 	if(ip == nil || ip->n == 0)		return; 	fillba(ip); 	reloff = 0;	asmarray(off, Ipatchtid, nba, reloff);	pc = 0;	for(i = 0; i < nba; i++) {		Bprint(bout, "\tbyte\t@mp+%d,%d", reloff, (uchar)ba[i]);		if(ba[i] < 0)			pc += -ba[i] << 3;		else			pc += ba[i] >> 4;		Bprint(bout, "\t# %d", pc);		if(ba[i] > 0) {			Bprint(bout, ", %s, %s", operand[(ba[i] >> 2) & 0x3],				mode[ba[i] & 0x3]);		}		Bputc(bout, '\n');		reloff += 1;	}	Bprint(bout, "\tapop\n"); 	free(ba);	ba = nil;	nba = 0;	szba = 0;} /* * Write Ipatch information to .dis file. */ voiddisIpatch(int off, Ipatch *ip){	int i;	int reloff;		/* 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, (uchar)ba[i]);		reloff += 1;	}	disapop(); 	free(ba);	ba = nil;	nba = 0;	szba = 0;} /* * Add instruction patch information to dreloc. */ voidaddDreloc(Inst *i, int operand, int patchkind){	if(dreloc == nil)		dreloc = Mallocz(sizeof(Ipatch));	addIpatch(dreloc, i, operand, patchkind, !SAVEINST);} /* * Write Dreloc information to .s file. */ voidasmDreloc(int off){	asmIpatch(off, dreloc);} /* * Write Dreloc information to .dis file. */ voiddisDreloc(int off){	disIpatch(off, dreloc);}