📄 codecpy.c
字号:
/************************************************************* * File: lib/codecpy.c * Purpose: Part of C runtime library * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970304 Start of revision history * 970325 Replaced Ulong typedef with include of utypes.h * 970329 Added code to handle 'j' instructions */#define assert(x)#define LUI_T0 0x3c080000#define ORI_T0 0x35080000#define JR_T0 0x01000008#define MAXIJMPS 20 /* max number of inter-segment jumps */#include <utypes.h>#ifdef TEST/************************************************************** main()*/main(){int f1(),fx_end();int len,tot,n;Ulong *f;len = ((Ulong)fx_end) - ((Ulong)f1);tot = len + jalBytes(f1,len/4);f = (Ulong *)malloc(tot);n = codecpy(f,f1,len/4);printf("f=%08x len=%d tot=%d n=%d\n",f,len,tot,n);}f1(){printf("hello world\n");f2();}f2(){printf("hello world again\n");}fx_end() {}#endif/************************************************************** codecpy(dst,src,n)* copy n instructions into mem* It fixes up the jal's during the copying process.* It handles jal's in three different ways.* 1. jumps within the block are fixed up to have the correct* address.* 2. jumps out of the block that are targeted to a the same* segment are fixed up to have the correct address.* 3. jumps out of the block that are targeted to a different* segment are fixed to point to a special* interseg jump routine. These routines are generated* automatically and placed at the end of the copied * code.*/codecpy(dst,src,n)Ulong *dst,*src;int n;{Ulong w,sseg,send,dseg,sbase,dbase,t,o,list[MAXIJMPS];int i,x,j;sbase = (Ulong)src;dbase = (Ulong)dst;sseg = sbase&0xf0000000;send = sbase+(n*4);dseg = dbase&0xf0000000;dbase &= ~0xf0000000;for (i=0,x=0;i<n;i++) { w = *src; /* get instruction */ if ((w&0xfc000000)==0x0c000000 || /* jal detected */ (w&0xfc000000)==0x08000000) { /* j detected 970329 */ t = sseg|((w&0x03ffffff)<<2); /* get target address */ w &= ~0x03ffffff; /* mask out address part */ if (t >= sbase && t < send) { /* jumps within the block */ o = t-sbase; w |= ((dbase+o)>>2); } else if (dseg == sseg) { /* same seg case */ w |= ((t&~0xf0000000)>>2); } else { /* different seg case */ assert(x <= MAXIJMPS); for (j=0;j<x;j++) { /* do we already have this adr? */ if (list[j] == t) break; /* yes */ } if (j == x) { /* new address */ list[x] = t; /* save target address */ j = x; x++; } t = (n*4)+(16*j); /* compute new target address */ w |= ((dbase+t)>>2); /* merge into instruction */ } } *dst++ = w; /* write the instruction to memory */ src++; }for (i=0;i<x;i++) { /* generate the interseg jump routines */ *dst++ = LUI_T0|(list[i]>>16); *dst++ = ORI_T0|(list[i]&0xffff); *dst++ = JR_T0; *dst++ = 0; /* nop */ }return(n+x); /* return number of words generated */}/************************************************************** jalBytes(src,n)* Return the max number of bytes that may be required* for inter-seg jumps. 16 bytes are required for* each inter-seg jump.*/jalBytes(src,n)Ulong *src;int n;{int i,m;Ulong w;for (i=m=0;i<n;i++,src++) { w = *src; /* get instruction */ if ((w&0xfc000000)==0x0c000000) m += 16; }return(m);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -