tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Bcj2.c (6351B)


      1 /* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
      2 2018-04-28 : Igor Pavlov : Public domain */
      3 
      4 #include "Precomp.h"
      5 
      6 #include "Bcj2.h"
      7 #include "CpuArch.h"
      8 
      9 #define CProb UInt16
     10 
     11 #define kTopValue ((UInt32)1 << 24)
     12 #define kNumModelBits 11
     13 #define kBitModelTotal (1 << kNumModelBits)
     14 #define kNumMoveBits 5
     15 
     16 #define _IF_BIT_0 ttt = *prob; bound = (p->range >> kNumModelBits) * ttt; if (p->code < bound)
     17 #define _UPDATE_0 p->range = bound; *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
     18 #define _UPDATE_1 p->range -= bound; p->code -= bound; *prob = (CProb)(ttt - (ttt >> kNumMoveBits));
     19 
     20 void Bcj2Dec_Init(CBcj2Dec *p)
     21 {
     22  unsigned i;
     23 
     24  p->state = BCJ2_DEC_STATE_OK;
     25  p->ip = 0;
     26  p->temp[3] = 0;
     27  p->range = 0;
     28  p->code = 0;
     29  for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++)
     30    p->probs[i] = kBitModelTotal >> 1;
     31 }
     32 
     33 SRes Bcj2Dec_Decode(CBcj2Dec *p)
     34 {
     35  if (p->range <= 5)
     36  {
     37    p->state = BCJ2_DEC_STATE_OK;
     38    for (; p->range != 5; p->range++)
     39    {
     40      if (p->range == 1 && p->code != 0)
     41        return SZ_ERROR_DATA;
     42      
     43      if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
     44      {
     45        p->state = BCJ2_STREAM_RC;
     46        return SZ_OK;
     47      }
     48 
     49      p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
     50    }
     51    
     52    if (p->code == 0xFFFFFFFF)
     53      return SZ_ERROR_DATA;
     54    
     55    p->range = 0xFFFFFFFF;
     56  }
     57  else if (p->state >= BCJ2_DEC_STATE_ORIG_0)
     58  {
     59    while (p->state <= BCJ2_DEC_STATE_ORIG_3)
     60    {
     61      Byte *dest = p->dest;
     62      if (dest == p->destLim)
     63        return SZ_OK;
     64      *dest = p->temp[(size_t)p->state - BCJ2_DEC_STATE_ORIG_0];
     65      p->state++;
     66      p->dest = dest + 1;
     67    }
     68  }
     69 
     70  /*
     71  if (BCJ2_IS_32BIT_STREAM(p->state))
     72  {
     73    const Byte *cur = p->bufs[p->state];
     74    if (cur == p->lims[p->state])
     75      return SZ_OK;
     76    p->bufs[p->state] = cur + 4;
     77    
     78    {
     79      UInt32 val;
     80      Byte *dest;
     81      SizeT rem;
     82      
     83      p->ip += 4;
     84      val = GetBe32(cur) - p->ip;
     85      dest = p->dest;
     86      rem = p->destLim - dest;
     87      if (rem < 4)
     88      {
     89        SizeT i;
     90        SetUi32(p->temp, val);
     91        for (i = 0; i < rem; i++)
     92          dest[i] = p->temp[i];
     93        p->dest = dest + rem;
     94        p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
     95        return SZ_OK;
     96      }
     97      SetUi32(dest, val);
     98      p->temp[3] = (Byte)(val >> 24);
     99      p->dest = dest + 4;
    100      p->state = BCJ2_DEC_STATE_OK;
    101    }
    102  }
    103  */
    104 
    105  for (;;)
    106  {
    107    if (BCJ2_IS_32BIT_STREAM(p->state))
    108      p->state = BCJ2_DEC_STATE_OK;
    109    else
    110    {
    111      if (p->range < kTopValue)
    112      {
    113        if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
    114        {
    115          p->state = BCJ2_STREAM_RC;
    116          return SZ_OK;
    117        }
    118        p->range <<= 8;
    119        p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
    120      }
    121 
    122      {
    123        const Byte *src = p->bufs[BCJ2_STREAM_MAIN];
    124        const Byte *srcLim;
    125        Byte *dest;
    126        SizeT num = p->lims[BCJ2_STREAM_MAIN] - src;
    127        
    128        if (num == 0)
    129        {
    130          p->state = BCJ2_STREAM_MAIN;
    131          return SZ_OK;
    132        }
    133        
    134        dest = p->dest;
    135        if (num > (SizeT)(p->destLim - dest))
    136        {
    137          num = p->destLim - dest;
    138          if (num == 0)
    139          {
    140            p->state = BCJ2_DEC_STATE_ORIG;
    141            return SZ_OK;
    142          }
    143        }
    144       
    145        srcLim = src + num;
    146 
    147        if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80)
    148          *dest = src[0];
    149        else for (;;)
    150        {
    151          Byte b = *src;
    152          *dest = b;
    153          if (b != 0x0F)
    154          {
    155            if ((b & 0xFE) == 0xE8)
    156              break;
    157            dest++;
    158            if (++src != srcLim)
    159              continue;
    160            break;
    161          }
    162          dest++;
    163          if (++src == srcLim)
    164            break;
    165          if ((*src & 0xF0) != 0x80)
    166            continue;
    167          *dest = *src;
    168          break;
    169        }
    170        
    171        num = src - p->bufs[BCJ2_STREAM_MAIN];
    172        
    173        if (src == srcLim)
    174        {
    175          p->temp[3] = src[-1];
    176          p->bufs[BCJ2_STREAM_MAIN] = src;
    177          p->ip += (UInt32)num;
    178          p->dest += num;
    179          p->state =
    180            p->bufs[BCJ2_STREAM_MAIN] ==
    181            p->lims[BCJ2_STREAM_MAIN] ?
    182              (unsigned)BCJ2_STREAM_MAIN :
    183              (unsigned)BCJ2_DEC_STATE_ORIG;
    184          return SZ_OK;
    185        }
    186        
    187        {
    188          UInt32 bound, ttt;
    189          CProb *prob;
    190          Byte b = src[0];
    191          Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]);
    192          
    193          p->temp[3] = b;
    194          p->bufs[BCJ2_STREAM_MAIN] = src + 1;
    195          num++;
    196          p->ip += (UInt32)num;
    197          p->dest += num;
    198          
    199          prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0));
    200          
    201          _IF_BIT_0
    202          {
    203            _UPDATE_0
    204            continue;
    205          }
    206          _UPDATE_1
    207            
    208        }
    209      }
    210    }
    211 
    212    {
    213      UInt32 val;
    214      unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP;
    215      const Byte *cur = p->bufs[cj];
    216      Byte *dest;
    217      SizeT rem;
    218      
    219      if (cur == p->lims[cj])
    220      {
    221        p->state = cj;
    222        break;
    223      }
    224      
    225      val = GetBe32(cur);
    226      p->bufs[cj] = cur + 4;
    227 
    228      p->ip += 4;
    229      val -= p->ip;
    230      dest = p->dest;
    231      rem = p->destLim - dest;
    232      
    233      if (rem < 4)
    234      {
    235        p->temp[0] = (Byte)val; if (rem > 0) dest[0] = (Byte)val; val >>= 8;
    236        p->temp[1] = (Byte)val; if (rem > 1) dest[1] = (Byte)val; val >>= 8;
    237        p->temp[2] = (Byte)val; if (rem > 2) dest[2] = (Byte)val; val >>= 8;
    238        p->temp[3] = (Byte)val;
    239        p->dest = dest + rem;
    240        p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
    241        break;
    242      }
    243      
    244      SetUi32(dest, val);
    245      p->temp[3] = (Byte)(val >> 24);
    246      p->dest = dest + 4;
    247    }
    248  }
    249 
    250  if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC])
    251  {
    252    p->range <<= 8;
    253    p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
    254  }
    255 
    256  return SZ_OK;
    257 }