Home | History | Annotate | Download | only in C
      1 /* Bra.c -- Converters for RISC code
      2 2017-04-04 : Igor Pavlov : Public domain */
      3 
      4 #include "Precomp.h"
      5 
      6 #include "CpuArch.h"
      7 #include "Bra.h"
      8 
      9 SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
     10 {
     11   Byte *p;
     12   const Byte *lim;
     13   size &= ~(size_t)3;
     14   ip += 4;
     15   p = data;
     16   lim = data + size;
     17 
     18   if (encoding)
     19 
     20   for (;;)
     21   {
     22     for (;;)
     23     {
     24       if (p >= lim)
     25         return p - data;
     26       p += 4;
     27       if (p[-1] == 0xEB)
     28         break;
     29     }
     30     {
     31       UInt32 v = GetUi32(p - 4);
     32       v <<= 2;
     33         v += ip + (UInt32)(p - data);
     34       v >>= 2;
     35       v &= 0x00FFFFFF;
     36       v |= 0xEB000000;
     37       SetUi32(p - 4, v);
     38     }
     39   }
     40 
     41   for (;;)
     42   {
     43     for (;;)
     44     {
     45       if (p >= lim)
     46         return p - data;
     47       p += 4;
     48       if (p[-1] == 0xEB)
     49         break;
     50     }
     51     {
     52       UInt32 v = GetUi32(p - 4);
     53       v <<= 2;
     54         v -= ip + (UInt32)(p - data);
     55       v >>= 2;
     56       v &= 0x00FFFFFF;
     57       v |= 0xEB000000;
     58       SetUi32(p - 4, v);
     59     }
     60   }
     61 }
     62 
     63 
     64 SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
     65 {
     66   Byte *p;
     67   const Byte *lim;
     68   size &= ~(size_t)1;
     69   p = data;
     70   lim = data + size - 4;
     71 
     72   if (encoding)
     73 
     74   for (;;)
     75   {
     76     UInt32 b1;
     77     for (;;)
     78     {
     79       UInt32 b3;
     80       if (p > lim)
     81         return p - data;
     82       b1 = p[1];
     83       b3 = p[3];
     84       p += 2;
     85       b1 ^= 8;
     86       if ((b3 & b1) >= 0xF8)
     87         break;
     88     }
     89     {
     90       UInt32 v =
     91              ((UInt32)b1 << 19)
     92           + (((UInt32)p[1] & 0x7) << 8)
     93           + (((UInt32)p[-2] << 11))
     94           + (p[0]);
     95 
     96       p += 2;
     97       {
     98         UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
     99           v += cur;
    100       }
    101 
    102       p[-4] = (Byte)(v >> 11);
    103       p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
    104       p[-2] = (Byte)v;
    105       p[-1] = (Byte)(0xF8 | (v >> 8));
    106     }
    107   }
    108 
    109   for (;;)
    110   {
    111     UInt32 b1;
    112     for (;;)
    113     {
    114       UInt32 b3;
    115       if (p > lim)
    116         return p - data;
    117       b1 = p[1];
    118       b3 = p[3];
    119       p += 2;
    120       b1 ^= 8;
    121       if ((b3 & b1) >= 0xF8)
    122         break;
    123     }
    124     {
    125       UInt32 v =
    126              ((UInt32)b1 << 19)
    127           + (((UInt32)p[1] & 0x7) << 8)
    128           + (((UInt32)p[-2] << 11))
    129           + (p[0]);
    130 
    131       p += 2;
    132       {
    133         UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
    134           v -= cur;
    135       }
    136 
    137       /*
    138       SetUi16(p - 4, (UInt16)(((v >> 11) & 0x7FF) | 0xF000));
    139       SetUi16(p - 2, (UInt16)(v | 0xF800));
    140       */
    141 
    142       p[-4] = (Byte)(v >> 11);
    143       p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
    144       p[-2] = (Byte)v;
    145       p[-1] = (Byte)(0xF8 | (v >> 8));
    146     }
    147   }
    148 }
    149 
    150 
    151 SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
    152 {
    153   Byte *p;
    154   const Byte *lim;
    155   size &= ~(size_t)3;
    156   ip -= 4;
    157   p = data;
    158   lim = data + size;
    159 
    160   for (;;)
    161   {
    162     for (;;)
    163     {
    164       if (p >= lim)
    165         return p - data;
    166       p += 4;
    167       /* if ((v & 0xFC000003) == 0x48000001) */
    168       if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1)
    169         break;
    170     }
    171     {
    172       UInt32 v = GetBe32(p - 4);
    173       if (encoding)
    174         v += ip + (UInt32)(p - data);
    175       else
    176         v -= ip + (UInt32)(p - data);
    177       v &= 0x03FFFFFF;
    178       v |= 0x48000000;
    179       SetBe32(p - 4, v);
    180     }
    181   }
    182 }
    183 
    184 
    185 SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
    186 {
    187   Byte *p;
    188   const Byte *lim;
    189   size &= ~(size_t)3;
    190   ip -= 4;
    191   p = data;
    192   lim = data + size;
    193 
    194   for (;;)
    195   {
    196     for (;;)
    197     {
    198       if (p >= lim)
    199         return p - data;
    200       /*
    201       v = GetBe32(p);
    202       p += 4;
    203       m = v + ((UInt32)5 << 29);
    204       m ^= (UInt32)7 << 29;
    205       m += (UInt32)1 << 22;
    206       if ((m & ((UInt32)0x1FF << 23)) == 0)
    207         break;
    208       */
    209       p += 4;
    210       if ((p[-4] == 0x40 && (p[-3] & 0xC0) == 0) ||
    211           (p[-4] == 0x7F && (p[-3] >= 0xC0)))
    212         break;
    213     }
    214     {
    215       UInt32 v = GetBe32(p - 4);
    216       v <<= 2;
    217       if (encoding)
    218         v += ip + (UInt32)(p - data);
    219       else
    220         v -= ip + (UInt32)(p - data);
    221 
    222       v &= 0x01FFFFFF;
    223       v -= (UInt32)1 << 24;
    224       v ^= 0xFF000000;
    225       v >>= 2;
    226       v |= 0x40000000;
    227       SetBe32(p - 4, v);
    228     }
    229   }
    230 }
    231