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