231 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			231 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/* Bra.c -- Converters for RISC code
							 | 
						||
| 
								 | 
							
								2017-04-04 : Igor Pavlov : Public domain */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "Precomp.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "CpuArch.h"
							 | 
						||
| 
								 | 
							
								#include "Bra.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  Byte *p;
							 | 
						||
| 
								 | 
							
								  const Byte *lim;
							 | 
						||
| 
								 | 
							
								  size &= ~(size_t)3;
							 | 
						||
| 
								 | 
							
								  ip += 4;
							 | 
						||
| 
								 | 
							
								  p = data;
							 | 
						||
| 
								 | 
							
								  lim = data + size;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (encoding)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (;;)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    for (;;)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      if (p >= lim)
							 | 
						||
| 
								 | 
							
								        return p - data;
							 | 
						||
| 
								 | 
							
								      p += 4;
							 | 
						||
| 
								 | 
							
								      if (p[-1] == 0xEB)
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      UInt32 v = GetUi32(p - 4);
							 | 
						||
| 
								 | 
							
								      v <<= 2;
							 | 
						||
| 
								 | 
							
								        v += ip + (UInt32)(p - data);
							 | 
						||
| 
								 | 
							
								      v >>= 2;
							 | 
						||
| 
								 | 
							
								      v &= 0x00FFFFFF;
							 | 
						||
| 
								 | 
							
								      v |= 0xEB000000;
							 | 
						||
| 
								 | 
							
								      SetUi32(p - 4, v);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (;;)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    for (;;)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      if (p >= lim)
							 | 
						||
| 
								 | 
							
								        return p - data;
							 | 
						||
| 
								 | 
							
								      p += 4;
							 | 
						||
| 
								 | 
							
								      if (p[-1] == 0xEB)
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      UInt32 v = GetUi32(p - 4);
							 | 
						||
| 
								 | 
							
								      v <<= 2;
							 | 
						||
| 
								 | 
							
								        v -= ip + (UInt32)(p - data);
							 | 
						||
| 
								 | 
							
								      v >>= 2;
							 | 
						||
| 
								 | 
							
								      v &= 0x00FFFFFF;
							 | 
						||
| 
								 | 
							
								      v |= 0xEB000000;
							 | 
						||
| 
								 | 
							
								      SetUi32(p - 4, v);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  Byte *p;
							 | 
						||
| 
								 | 
							
								  const Byte *lim;
							 | 
						||
| 
								 | 
							
								  size &= ~(size_t)1;
							 | 
						||
| 
								 | 
							
								  p = data;
							 | 
						||
| 
								 | 
							
								  lim = data + size - 4;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (encoding)
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								  for (;;)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    UInt32 b1;
							 | 
						||
| 
								 | 
							
								    for (;;)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      UInt32 b3;
							 | 
						||
| 
								 | 
							
								      if (p > lim)
							 | 
						||
| 
								 | 
							
								        return p - data;
							 | 
						||
| 
								 | 
							
								      b1 = p[1];
							 | 
						||
| 
								 | 
							
								      b3 = p[3];
							 | 
						||
| 
								 | 
							
								      p += 2;
							 | 
						||
| 
								 | 
							
								      b1 ^= 8;
							 | 
						||
| 
								 | 
							
								      if ((b3 & b1) >= 0xF8)
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      UInt32 v =
							 | 
						||
| 
								 | 
							
								             ((UInt32)b1 << 19)
							 | 
						||
| 
								 | 
							
								          + (((UInt32)p[1] & 0x7) << 8)
							 | 
						||
| 
								 | 
							
								          + (((UInt32)p[-2] << 11))
							 | 
						||
| 
								 | 
							
								          + (p[0]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      p += 2;
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
							 | 
						||
| 
								 | 
							
								          v += cur;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      p[-4] = (Byte)(v >> 11);
							 | 
						||
| 
								 | 
							
								      p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
							 | 
						||
| 
								 | 
							
								      p[-2] = (Byte)v;
							 | 
						||
| 
								 | 
							
								      p[-1] = (Byte)(0xF8 | (v >> 8));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								  for (;;)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    UInt32 b1;
							 | 
						||
| 
								 | 
							
								    for (;;)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      UInt32 b3;
							 | 
						||
| 
								 | 
							
								      if (p > lim)
							 | 
						||
| 
								 | 
							
								        return p - data;
							 | 
						||
| 
								 | 
							
								      b1 = p[1];
							 | 
						||
| 
								 | 
							
								      b3 = p[3];
							 | 
						||
| 
								 | 
							
								      p += 2;
							 | 
						||
| 
								 | 
							
								      b1 ^= 8;
							 | 
						||
| 
								 | 
							
								      if ((b3 & b1) >= 0xF8)
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      UInt32 v =
							 | 
						||
| 
								 | 
							
								             ((UInt32)b1 << 19)
							 | 
						||
| 
								 | 
							
								          + (((UInt32)p[1] & 0x7) << 8)
							 | 
						||
| 
								 | 
							
								          + (((UInt32)p[-2] << 11))
							 | 
						||
| 
								 | 
							
								          + (p[0]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      p += 2;
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
							 | 
						||
| 
								 | 
							
								          v -= cur;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      /*
							 | 
						||
| 
								 | 
							
								      SetUi16(p - 4, (UInt16)(((v >> 11) & 0x7FF) | 0xF000));
							 | 
						||
| 
								 | 
							
								      SetUi16(p - 2, (UInt16)(v | 0xF800));
							 | 
						||
| 
								 | 
							
								      */
							 | 
						||
| 
								 | 
							
								      
							 | 
						||
| 
								 | 
							
								      p[-4] = (Byte)(v >> 11);
							 | 
						||
| 
								 | 
							
								      p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
							 | 
						||
| 
								 | 
							
								      p[-2] = (Byte)v;
							 | 
						||
| 
								 | 
							
								      p[-1] = (Byte)(0xF8 | (v >> 8));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  Byte *p;
							 | 
						||
| 
								 | 
							
								  const Byte *lim;
							 | 
						||
| 
								 | 
							
								  size &= ~(size_t)3;
							 | 
						||
| 
								 | 
							
								  ip -= 4;
							 | 
						||
| 
								 | 
							
								  p = data;
							 | 
						||
| 
								 | 
							
								  lim = data + size;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (;;)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    for (;;)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      if (p >= lim)
							 | 
						||
| 
								 | 
							
								        return p - data;
							 | 
						||
| 
								 | 
							
								      p += 4;
							 | 
						||
| 
								 | 
							
								      /* if ((v & 0xFC000003) == 0x48000001) */
							 | 
						||
| 
								 | 
							
								      if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1)
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      UInt32 v = GetBe32(p - 4);
							 | 
						||
| 
								 | 
							
								      if (encoding)
							 | 
						||
| 
								 | 
							
								        v += ip + (UInt32)(p - data);
							 | 
						||
| 
								 | 
							
								      else
							 | 
						||
| 
								 | 
							
								        v -= ip + (UInt32)(p - data);
							 | 
						||
| 
								 | 
							
								      v &= 0x03FFFFFF;
							 | 
						||
| 
								 | 
							
								      v |= 0x48000000;
							 | 
						||
| 
								 | 
							
								      SetBe32(p - 4, v);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  Byte *p;
							 | 
						||
| 
								 | 
							
								  const Byte *lim;
							 | 
						||
| 
								 | 
							
								  size &= ~(size_t)3;
							 | 
						||
| 
								 | 
							
								  ip -= 4;
							 | 
						||
| 
								 | 
							
								  p = data;
							 | 
						||
| 
								 | 
							
								  lim = data + size;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (;;)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    for (;;)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      if (p >= lim)
							 | 
						||
| 
								 | 
							
								        return p - data;
							 | 
						||
| 
								 | 
							
								      /*
							 | 
						||
| 
								 | 
							
								      v = GetBe32(p);
							 | 
						||
| 
								 | 
							
								      p += 4;
							 | 
						||
| 
								 | 
							
								      m = v + ((UInt32)5 << 29);
							 | 
						||
| 
								 | 
							
								      m ^= (UInt32)7 << 29;
							 | 
						||
| 
								 | 
							
								      m += (UInt32)1 << 22;
							 | 
						||
| 
								 | 
							
								      if ((m & ((UInt32)0x1FF << 23)) == 0)
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      */
							 | 
						||
| 
								 | 
							
								      p += 4;
							 | 
						||
| 
								 | 
							
								      if ((p[-4] == 0x40 && (p[-3] & 0xC0) == 0) ||
							 | 
						||
| 
								 | 
							
								          (p[-4] == 0x7F && (p[-3] >= 0xC0)))
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      UInt32 v = GetBe32(p - 4);
							 | 
						||
| 
								 | 
							
								      v <<= 2;
							 | 
						||
| 
								 | 
							
								      if (encoding)
							 | 
						||
| 
								 | 
							
								        v += ip + (UInt32)(p - data);
							 | 
						||
| 
								 | 
							
								      else
							 | 
						||
| 
								 | 
							
								        v -= ip + (UInt32)(p - data);
							 | 
						||
| 
								 | 
							
								      
							 | 
						||
| 
								 | 
							
								      v &= 0x01FFFFFF;
							 | 
						||
| 
								 | 
							
								      v -= (UInt32)1 << 24;
							 | 
						||
| 
								 | 
							
								      v ^= 0xFF000000;
							 | 
						||
| 
								 | 
							
								      v >>= 2;
							 | 
						||
| 
								 | 
							
								      v |= 0x40000000;
							 | 
						||
| 
								 | 
							
								      SetBe32(p - 4, v);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 |