Home | History | Annotate | Download | only in C
      1 /* Bra.c -- Converters for RISC code
      2 2010-04-16 : Igor Pavlov : Public domain */
      3 
      4 #include "Precomp.h"
      5 
      6 #include "Bra.h"
      7 
      8 SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
      9 {
     10   SizeT i;
     11   if (size < 4)
     12     return 0;
     13   size -= 4;
     14   ip += 8;
     15   for (i = 0; i <= size; i += 4)
     16   {
     17     if (data[i + 3] == 0xEB)
     18     {
     19       UInt32 dest;
     20       UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]);
     21       src <<= 2;
     22       if (encoding)
     23         dest = ip + (UInt32)i + src;
     24       else
     25         dest = src - (ip + (UInt32)i);
     26       dest >>= 2;
     27       data[i + 2] = (Byte)(dest >> 16);
     28       data[i + 1] = (Byte)(dest >> 8);
     29       data[i + 0] = (Byte)dest;
     30     }
     31   }
     32   return i;
     33 }
     34 
     35 SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
     36 {
     37   SizeT i;
     38   if (size < 4)
     39     return 0;
     40   size -= 4;
     41   ip += 4;
     42   for (i = 0; i <= size; i += 2)
     43   {
     44     if ((data[i + 1] & 0xF8) == 0xF0 &&
     45         (data[i + 3] & 0xF8) == 0xF8)
     46     {
     47       UInt32 dest;
     48       UInt32 src =
     49         (((UInt32)data[i + 1] & 0x7) << 19) |
     50         ((UInt32)data[i + 0] << 11) |
     51         (((UInt32)data[i + 3] & 0x7) << 8) |
     52         (data[i + 2]);
     53 
     54       src <<= 1;
     55       if (encoding)
     56         dest = ip + (UInt32)i + src;
     57       else
     58         dest = src - (ip + (UInt32)i);
     59       dest >>= 1;
     60 
     61       data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7));
     62       data[i + 0] = (Byte)(dest >> 11);
     63       data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));
     64       data[i + 2] = (Byte)dest;
     65       i += 2;
     66     }
     67   }
     68   return i;
     69 }
     70 
     71 SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
     72 {
     73   SizeT i;
     74   if (size < 4)
     75     return 0;
     76   size -= 4;
     77   for (i = 0; i <= size; i += 4)
     78   {
     79     if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1)
     80     {
     81       UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) |
     82         ((UInt32)data[i + 1] << 16) |
     83         ((UInt32)data[i + 2] << 8) |
     84         ((UInt32)data[i + 3] & (~3));
     85 
     86       UInt32 dest;
     87       if (encoding)
     88         dest = ip + (UInt32)i + src;
     89       else
     90         dest = src - (ip + (UInt32)i);
     91       data[i + 0] = (Byte)(0x48 | ((dest >> 24) &  0x3));
     92       data[i + 1] = (Byte)(dest >> 16);
     93       data[i + 2] = (Byte)(dest >> 8);
     94       data[i + 3] &= 0x3;
     95       data[i + 3] |= dest;
     96     }
     97   }
     98   return i;
     99 }
    100 
    101 SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
    102 {
    103   UInt32 i;
    104   if (size < 4)
    105     return 0;
    106   size -= 4;
    107   for (i = 0; i <= size; i += 4)
    108   {
    109     if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) ||
    110         (data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0))
    111     {
    112       UInt32 src =
    113         ((UInt32)data[i + 0] << 24) |
    114         ((UInt32)data[i + 1] << 16) |
    115         ((UInt32)data[i + 2] << 8) |
    116         ((UInt32)data[i + 3]);
    117       UInt32 dest;
    118 
    119       src <<= 2;
    120       if (encoding)
    121         dest = ip + i + src;
    122       else
    123         dest = src - (ip + i);
    124       dest >>= 2;
    125 
    126       dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
    127 
    128       data[i + 0] = (Byte)(dest >> 24);
    129       data[i + 1] = (Byte)(dest >> 16);
    130       data[i + 2] = (Byte)(dest >> 8);
    131       data[i + 3] = (Byte)dest;
    132     }
    133   }
    134   return i;
    135 }
    136