xref: /aosp_15_r20/external/lzma/CPP/7zip/Compress/Rar3Vm.h (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1 // Rar3Vm.h
2 // According to unRAR license, this code may not be used to develop
3 // a program that creates RAR archives
4 
5 #ifndef ZIP7_INC_COMPRESS_RAR3_VM_H
6 #define ZIP7_INC_COMPRESS_RAR3_VM_H
7 
8 #include "../../../C/CpuArch.h"
9 
10 #include "../../Common/MyVector.h"
11 
12 #define Z7_RARVM_STANDARD_FILTERS
13 // #define Z7_RARVM_VM_ENABLE
14 
15 namespace NCompress {
16 namespace NRar3 {
17 
18 class CMemBitDecoder
19 {
20   const Byte *_data;
21   UInt32 _bitSize;
22   UInt32 _bitPos;
23 public:
Init(const Byte * data,UInt32 byteSize)24   void Init(const Byte *data, UInt32 byteSize)
25   {
26     _data = data;
27     _bitSize = (byteSize << 3);
28     _bitPos = 0;
29   }
30   UInt32 ReadBits(unsigned numBits);
31   UInt32 ReadBit();
Avail()32   bool Avail() const { return (_bitPos < _bitSize); }
33 
34   UInt32 ReadEncodedUInt32();
35 };
36 
37 namespace NVm {
38 
GetValue32(const void * addr)39 inline UInt32 GetValue32(const void *addr) { return GetUi32(addr); }
SetValue32(void * addr,UInt32 value)40 inline void SetValue32(void *addr, UInt32 value) { SetUi32(addr, value) }
41 
42 const unsigned kNumRegBits = 3;
43 const UInt32 kNumRegs = 1 << kNumRegBits;
44 const UInt32 kNumGpRegs = kNumRegs - 1;
45 
46 const UInt32 kSpaceSize = 0x40000;
47 const UInt32 kSpaceMask = kSpaceSize - 1;
48 const UInt32 kGlobalOffset = 0x3C000;
49 const UInt32 kGlobalSize = 0x2000;
50 const UInt32 kFixedGlobalSize = 64;
51 
52 namespace NGlobalOffset
53 {
54   const UInt32 kBlockSize = 0x1C;
55   const UInt32 kBlockPos  = 0x20;
56   const UInt32 kExecCount = 0x2C;
57   const UInt32 kGlobalMemOutSize = 0x30;
58 }
59 
60 
61 #ifdef Z7_RARVM_VM_ENABLE
62 
63 enum ECommand
64 {
65   CMD_MOV,  CMD_CMP,  CMD_ADD,  CMD_SUB,  CMD_JZ,   CMD_JNZ,  CMD_INC,  CMD_DEC,
66   CMD_JMP,  CMD_XOR,  CMD_AND,  CMD_OR,   CMD_TEST, CMD_JS,   CMD_JNS,  CMD_JB,
67   CMD_JBE,  CMD_JA,   CMD_JAE,  CMD_PUSH, CMD_POP,  CMD_CALL, CMD_RET,  CMD_NOT,
68   CMD_SHL,  CMD_SHR,  CMD_SAR,  CMD_NEG,  CMD_PUSHA,CMD_POPA, CMD_PUSHF,CMD_POPF,
69   CMD_MOVZX,CMD_MOVSX,CMD_XCHG, CMD_MUL,  CMD_DIV,  CMD_ADC,  CMD_SBB,  CMD_PRINT,
70 
71   CMD_MOVB, CMD_CMPB, CMD_ADDB, CMD_SUBB, CMD_INCB, CMD_DECB,
72   CMD_XORB, CMD_ANDB, CMD_ORB,  CMD_TESTB,CMD_NEGB,
73   CMD_SHLB, CMD_SHRB, CMD_SARB, CMD_MULB
74 };
75 
76 enum EOpType {OP_TYPE_REG, OP_TYPE_INT, OP_TYPE_REGMEM, OP_TYPE_NONE};
77 
78 // Addr in COperand object can link (point) to CVm object!!!
79 
80 struct COperand
81 {
82   EOpType Type;
83   UInt32 Data;
84   UInt32 Base;
COperandCOperand85   COperand(): Type(OP_TYPE_NONE), Data(0), Base(0) {}
86 };
87 
88 struct CCommand
89 {
90   ECommand OpCode;
91   bool ByteMode;
92   COperand Op1, Op2;
93 };
94 
95 #endif
96 
97 
98 struct CBlockRef
99 {
100   UInt32 Offset;
101   UInt32 Size;
102 };
103 
104 
105 class CProgram
106 {
107   #ifdef Z7_RARVM_VM_ENABLE
108   void ReadProgram(const Byte *code, UInt32 codeSize);
109 public:
110   CRecordVector<CCommand> Commands;
111   #endif
112 
113 public:
114   #ifdef Z7_RARVM_STANDARD_FILTERS
115   int StandardFilterIndex;
116   #endif
117 
118   bool IsSupported;
119   CRecordVector<Byte> StaticData;
120 
121   bool PrepareProgram(const Byte *code, UInt32 codeSize);
122 };
123 
124 
125 struct CProgramInitState
126 {
127   UInt32 InitR[kNumGpRegs];
128   CRecordVector<Byte> GlobalData;
129 
AllocateEmptyFixedGlobalCProgramInitState130   void AllocateEmptyFixedGlobal()
131   {
132     GlobalData.ClearAndSetSize(NVm::kFixedGlobalSize);
133     memset(&GlobalData[0], 0, NVm::kFixedGlobalSize);
134   }
135 };
136 
137 
138 class CVm
139 {
GetValue(bool byteMode,const void * addr)140   static UInt32 GetValue(bool byteMode, const void *addr)
141   {
142     if (byteMode)
143       return(*(const Byte *)addr);
144     else
145       return GetUi32(addr);
146   }
147 
SetValue(bool byteMode,void * addr,UInt32 value)148   static void SetValue(bool byteMode, void *addr, UInt32 value)
149   {
150     if (byteMode)
151       *(Byte *)addr = (Byte)value;
152     else
153       SetUi32(addr, value)
154   }
155 
GetFixedGlobalValue32(UInt32 globalOffset)156   UInt32 GetFixedGlobalValue32(UInt32 globalOffset) { return GetValue(false, &Mem[kGlobalOffset + globalOffset]); }
157 
SetBlockSize(UInt32 v)158   void SetBlockSize(UInt32 v) { SetValue(&Mem[kGlobalOffset + NGlobalOffset::kBlockSize], v); }
SetBlockPos(UInt32 v)159   void SetBlockPos(UInt32 v) { SetValue(&Mem[kGlobalOffset + NGlobalOffset::kBlockPos], v); }
160 public:
SetValue(void * addr,UInt32 value)161   static void SetValue(void *addr, UInt32 value) { SetValue(false, addr, value); }
162 
163 private:
164 
165   #ifdef Z7_RARVM_VM_ENABLE
166   UInt32 GetOperand32(const COperand *op) const;
167   void SetOperand32(const COperand *op, UInt32 val);
168   Byte GetOperand8(const COperand *op) const;
169   void SetOperand8(const COperand *op, Byte val);
170   UInt32 GetOperand(bool byteMode, const COperand *op) const;
171   void SetOperand(bool byteMode, const COperand *op, UInt32 val);
172   bool ExecuteCode(const CProgram *prg);
173   #endif
174 
175   #ifdef Z7_RARVM_STANDARD_FILTERS
176   bool ExecuteStandardFilter(unsigned filterIndex);
177   #endif
178 
179   Byte *Mem;
180   UInt32 R[kNumRegs + 1]; // R[kNumRegs] = 0 always (speed optimization)
181   UInt32 Flags;
182 
183 public:
184   CVm();
185   ~CVm();
186   bool Create();
187   void SetMemory(UInt32 pos, const Byte *data, UInt32 dataSize);
188   bool Execute(CProgram *prg, const CProgramInitState *initState,
189       CBlockRef &outBlockRef, CRecordVector<Byte> &outGlobalData);
GetDataPointer(UInt32 offset)190   const Byte *GetDataPointer(UInt32 offset) const { return Mem + offset; }
191 };
192 
193 #endif
194 
195 }}}
196