Coverage Report

Created: 2024-08-21 06:24

/src/capstonev5/arch/RISCV/RISCVDisassembler.c
Line
Count
Source (jump to first uncovered line)
1
//===-- RISCVDisassembler.cpp - Disassembler for RISCV --------------------===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
10
/* Capstone Disassembly Engine */
11
/* RISC-V Backend By Rodrigo Cortes Porto <porto703@gmail.com> & 
12
   Shawn Chang <citypw@gmail.com>, HardenedLinux@2018 */
13
    
14
#ifdef CAPSTONE_HAS_RISCV
15
16
#include <stdio.h>    // DEBUG
17
#include <stdlib.h>
18
#include <string.h>
19
20
#include "../../cs_priv.h"
21
#include "../../utils.h"
22
23
#include "../../MCInst.h"
24
#include "../../MCInstrDesc.h"
25
#include "../../MCFixedLenDisassembler.h"
26
#include "../../MCRegisterInfo.h"
27
#include "../../MCDisassembler.h"
28
#include "../../MathExtras.h"
29
#include "RISCVBaseInfo.h"
30
#include "RISCVDisassembler.h"
31
32
33
/* Need the feature infos define in 
34
  RISCVGenSubtargetInfo.inc. */
35
#define GET_SUBTARGETINFO_ENUM
36
#include "RISCVGenSubtargetInfo.inc"
37
38
/* When we specify the RISCV64 mode, It means It is RV64IMAFD.
39
  Similar, RISCV32 means RV32IMAFD.
40
*/
41
static uint64_t getFeatureBits(int mode) 
42
99.0k
{
43
99.0k
  uint64_t ret = RISCV_FeatureStdExtM | RISCV_FeatureStdExtA |
44
99.0k
           RISCV_FeatureStdExtF | RISCV_FeatureStdExtD ;
45
46
99.0k
  if (mode & CS_MODE_RISCV64)
47
52.2k
    ret |= RISCV_Feature64Bit;
48
99.0k
  if (mode & CS_MODE_RISCVC)
49
0
    ret |= RISCV_FeatureStdExtC;
50
51
99.0k
  return ret;
52
99.0k
}
53
54
#define GET_REGINFO_ENUM
55
#define GET_REGINFO_MC_DESC
56
#include "RISCVGenRegisterInfo.inc"
57
#define GET_INSTRINFO_ENUM
58
#include "RISCVGenInstrInfo.inc"
59
60
static const unsigned GPRDecoderTable[] = {
61
    RISCV_X0,  RISCV_X1,  RISCV_X2,  RISCV_X3,
62
    RISCV_X4,  RISCV_X5,  RISCV_X6,  RISCV_X7,
63
    RISCV_X8,  RISCV_X9,  RISCV_X10, RISCV_X11,
64
    RISCV_X12, RISCV_X13, RISCV_X14, RISCV_X15,
65
    RISCV_X16, RISCV_X17, RISCV_X18, RISCV_X19,
66
    RISCV_X20, RISCV_X21, RISCV_X22, RISCV_X23,
67
    RISCV_X24, RISCV_X25, RISCV_X26, RISCV_X27,
68
    RISCV_X28, RISCV_X29, RISCV_X30, RISCV_X31
69
};
70
71
static DecodeStatus DecodeGPRRegisterClass(MCInst *Inst, uint64_t RegNo,
72
            uint64_t Address, const void *Decoder) 
73
138k
{
74
138k
    unsigned Reg = 0;
75
76
138k
    if (RegNo >= ARR_SIZE(GPRDecoderTable))
77
0
        return MCDisassembler_Fail;
78
79
    // We must define our own mapping from RegNo to register identifier.
80
    // Accessing index RegNo in the register class will work in the case that
81
    // registers were added in ascending order, but not in general.
82
138k
    Reg = GPRDecoderTable[RegNo];
83
    //Inst.addOperand(MCOperand::createReg(Reg));
84
138k
    MCOperand_CreateReg0(Inst, Reg);
85
138k
    return MCDisassembler_Success;
86
138k
}
87
88
static const unsigned FPR32DecoderTable[] = {
89
    RISCV_F0_32,  RISCV_F1_32,  RISCV_F2_32,  RISCV_F3_32,
90
    RISCV_F4_32,  RISCV_F5_32,  RISCV_F6_32,  RISCV_F7_32,
91
    RISCV_F8_32,  RISCV_F9_32,  RISCV_F10_32, RISCV_F11_32,
92
    RISCV_F12_32, RISCV_F13_32, RISCV_F14_32, RISCV_F15_32,
93
    RISCV_F16_32, RISCV_F17_32, RISCV_F18_32, RISCV_F19_32,
94
    RISCV_F20_32, RISCV_F21_32, RISCV_F22_32, RISCV_F23_32,
95
    RISCV_F24_32, RISCV_F25_32, RISCV_F26_32, RISCV_F27_32,
96
    RISCV_F28_32, RISCV_F29_32, RISCV_F30_32, RISCV_F31_32
97
};
98
99
static DecodeStatus DecodeFPR32RegisterClass(MCInst *Inst, uint64_t RegNo,
100
       uint64_t Address, const void *Decoder) 
101
31.3k
{
102
31.3k
    unsigned Reg = 0;
103
104
31.3k
    if (RegNo >= ARR_SIZE(FPR32DecoderTable))
105
0
        return MCDisassembler_Fail;
106
107
    // We must define our own mapping from RegNo to register identifier.
108
    // Accessing index RegNo in the register class will work in the case that
109
    // registers were added in ascending order, but not in general.
110
31.3k
    Reg = FPR32DecoderTable[RegNo];
111
31.3k
    MCOperand_CreateReg0(Inst, Reg);
112
31.3k
    return MCDisassembler_Success;
113
31.3k
}
114
115
static DecodeStatus DecodeFPR32CRegisterClass(MCInst *Inst, uint64_t RegNo,
116
                                              uint64_t Address,
117
                                              const void *Decoder) 
118
0
{
119
0
    unsigned Reg = 0;
120
121
0
    if (RegNo > 8) 
122
0
        return MCDisassembler_Fail;
123
0
    Reg = FPR32DecoderTable[RegNo + 8];
124
0
    MCOperand_CreateReg0(Inst, Reg);
125
0
    return MCDisassembler_Success;
126
0
}
127
128
static const unsigned FPR64DecoderTable[] = {
129
    RISCV_F0_64,  RISCV_F1_64,  RISCV_F2_64,  RISCV_F3_64,
130
    RISCV_F4_64,  RISCV_F5_64,  RISCV_F6_64,  RISCV_F7_64,
131
    RISCV_F8_64,  RISCV_F9_64,  RISCV_F10_64, RISCV_F11_64,
132
    RISCV_F12_64, RISCV_F13_64, RISCV_F14_64, RISCV_F15_64,
133
    RISCV_F16_64, RISCV_F17_64, RISCV_F18_64, RISCV_F19_64,
134
    RISCV_F20_64, RISCV_F21_64, RISCV_F22_64, RISCV_F23_64,
135
    RISCV_F24_64, RISCV_F25_64, RISCV_F26_64, RISCV_F27_64,
136
    RISCV_F28_64, RISCV_F29_64, RISCV_F30_64, RISCV_F31_64
137
};
138
139
static DecodeStatus DecodeFPR64RegisterClass(MCInst *Inst, uint64_t RegNo,
140
       uint64_t Address, const void *Decoder) 
141
13.8k
{
142
13.8k
    unsigned Reg = 0;
143
144
13.8k
    if (RegNo >= ARR_SIZE(FPR64DecoderTable))
145
0
        return MCDisassembler_Fail;
146
147
  // We must define our own mapping from RegNo to register identifier.
148
    // Accessing index RegNo in the register class will work in the case that
149
    // registers were added in ascending order, but not in general.
150
13.8k
    Reg = FPR64DecoderTable[RegNo];
151
13.8k
    MCOperand_CreateReg0(Inst, Reg);
152
13.8k
    return MCDisassembler_Success;
153
13.8k
}
154
155
static DecodeStatus DecodeFPR64CRegisterClass(MCInst *Inst, uint64_t RegNo,
156
                                              uint64_t Address,
157
                                              const void *Decoder) 
158
0
{
159
0
    unsigned Reg = 0;
160
161
0
    if (RegNo > 8)
162
0
        return MCDisassembler_Fail;
163
0
    Reg = FPR64DecoderTable[RegNo + 8];
164
0
    MCOperand_CreateReg0(Inst, Reg);
165
0
    return MCDisassembler_Success;
166
0
}
167
168
static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst *Inst, uint64_t RegNo,
169
                                               uint64_t Address,
170
                                               const void *Decoder) 
171
0
{
172
0
    if (RegNo == 0)
173
0
        return MCDisassembler_Fail;
174
0
    return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
175
0
}
176
177
static DecodeStatus DecodeGPRNoX0X2RegisterClass(MCInst *Inst, uint64_t RegNo,
178
                                                 uint64_t Address,
179
                                                 const void *Decoder) 
180
0
{
181
0
    if (RegNo == 2)
182
0
        return MCDisassembler_Fail;
183
0
    return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder);
184
0
}
185
186
static DecodeStatus DecodeGPRCRegisterClass(MCInst *Inst, uint64_t RegNo,
187
                                            uint64_t Address,
188
                                            const void *Decoder) 
189
0
{
190
0
    unsigned Reg = 0;
191
192
0
    if (RegNo > 8)
193
0
        return MCDisassembler_Fail;
194
195
0
    Reg = GPRDecoderTable[RegNo + 8];
196
0
    MCOperand_CreateReg0(Inst, Reg);
197
0
    return MCDisassembler_Success;
198
0
}
199
200
// Add implied SP operand for instructions *SP compressed instructions. The SP
201
// operand isn't explicitly encoded in the instruction.
202
static void addImplySP(MCInst *Inst, int64_t Address, const void *Decoder) 
203
88.5k
{
204
88.5k
    if (MCInst_getOpcode(Inst) == RISCV_C_LWSP || 
205
88.5k
            MCInst_getOpcode(Inst) == RISCV_C_SWSP ||
206
88.5k
            MCInst_getOpcode(Inst) == RISCV_C_LDSP || 
207
88.5k
            MCInst_getOpcode(Inst) == RISCV_C_SDSP ||
208
88.5k
            MCInst_getOpcode(Inst) == RISCV_C_FLWSP ||
209
88.5k
            MCInst_getOpcode(Inst) == RISCV_C_FSWSP ||
210
88.5k
            MCInst_getOpcode(Inst) == RISCV_C_FLDSP ||
211
88.5k
            MCInst_getOpcode(Inst) == RISCV_C_FSDSP ||
212
88.5k
            MCInst_getOpcode(Inst) == RISCV_C_ADDI4SPN) {
213
0
    DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
214
0
    }
215
216
88.5k
    if (MCInst_getOpcode(Inst) == RISCV_C_ADDI16SP) {
217
0
        DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
218
0
        DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
219
0
    }
220
88.5k
}
221
222
static DecodeStatus decodeUImmOperand(MCInst *Inst, uint64_t Imm,
223
                                      int64_t Address, const void *Decoder,
224
              unsigned N) 
225
80.8k
{
226
    //CS_ASSERT(isUInt<N>(Imm) && "Invalid immediate");
227
80.8k
    addImplySP(Inst, Address, Decoder);
228
    //Inst.addOperand(MCOperand::createImm(Imm));
229
80.8k
    MCOperand_CreateImm0(Inst, Imm);
230
80.8k
    return MCDisassembler_Success;
231
80.8k
}
232
233
static DecodeStatus decodeUImmNonZeroOperand(MCInst *Inst, uint64_t Imm,
234
                                             int64_t Address,
235
                                             const void *Decoder, 
236
               unsigned N) 
237
0
{
238
0
    if (Imm == 0)
239
0
        return MCDisassembler_Fail;
240
0
    return decodeUImmOperand(Inst, Imm, Address, Decoder, N);
241
0
}
242
243
static DecodeStatus decodeSImmOperand(MCInst *Inst, uint64_t Imm,
244
                                      int64_t Address, const void *Decoder,
245
              unsigned N) 
246
7.71k
{
247
    //CS_ASSERT(isUInt<N>(Imm) && "Invalid immediate");
248
7.71k
    addImplySP(Inst, Address, Decoder);
249
    // Sign-extend the number in the bottom N bits of Imm
250
    //Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
251
7.71k
    MCOperand_CreateImm0(Inst, SignExtend64(Imm, N));
252
7.71k
    return MCDisassembler_Success;
253
7.71k
}
254
255
static DecodeStatus decodeSImmNonZeroOperand(MCInst *Inst, uint64_t Imm,
256
                                             int64_t Address,
257
                                             const void *Decoder,
258
               unsigned N) 
259
0
{
260
0
    if (Imm == 0)
261
0
        return MCDisassembler_Fail;
262
0
    return decodeSImmOperand(Inst, Imm, Address, Decoder, N);
263
0
}
264
265
static DecodeStatus decodeSImmOperandAndLsl1(MCInst *Inst, uint64_t Imm,
266
                                             int64_t Address,
267
                                             const void *Decoder,
268
               unsigned N) 
269
4.25k
{
270
    //CS_ASSERT(isUInt<N>(Imm) && "Invalid immediate");
271
    // Sign-extend the number in the bottom N bits of Imm after accounting for
272
    // the fact that the N bit immediate is stored in N-1 bits (the LSB is
273
    // always zero)
274
    //Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1)));
275
4.25k
    MCOperand_CreateImm0(Inst, SignExtend64(Imm << 1, N));
276
4.25k
    return MCDisassembler_Success;
277
4.25k
}
278
279
static DecodeStatus decodeCLUIImmOperand(MCInst *Inst, uint64_t Imm,
280
                                         int64_t Address,
281
                                         const void *Decoder) 
282
0
{
283
    //CS_ASSERT(isUInt<6>(Imm) && "Invalid immediate");
284
0
    if (Imm > 31) {
285
0
        Imm = (SignExtend64(Imm, 6) & 0xfffff);
286
0
    }
287
    //Inst.addOperand(MCOperand::createImm(Imm));
288
0
    MCOperand_CreateImm0(Inst, Imm);
289
0
    return MCDisassembler_Success;
290
0
}
291
292
static DecodeStatus decodeFRMArg(MCInst *Inst, uint64_t Imm,
293
                                 int64_t Address,
294
                                 const void *Decoder) 
295
17.5k
{
296
    //CS_ASSERT(isUInt<3>(Imm) && "Invalid immediate");
297
17.5k
    if (!RISCVFPRndMode_isValidRoundingMode(Imm))
298
29
        return MCDisassembler_Fail;
299
300
    //Inst.addOperand(MCOperand::createImm(Imm));
301
17.4k
    MCOperand_CreateImm0(Inst, Imm);
302
17.4k
    return MCDisassembler_Success;
303
17.5k
}
304
305
306
#include "RISCVGenDisassemblerTables.inc"
307
308
static void init_MI_insn_detail(MCInst *MI) 
309
97.7k
{
310
97.7k
    if (MI->flat_insn->detail) {
311
97.7k
        memset(MI->flat_insn->detail, 0, sizeof(cs_detail));
312
97.7k
    }
313
314
97.7k
    return;
315
97.7k
}
316
317
// mark the load/store instructions through the opcode.
318
static void markLSInsn(MCInst *MI, uint32_t in)
319
24.4k
{
320
  /* 
321
     I   ld 0000011 = 0x03
322
         st 0100011 = 0x23
323
     F/D ld 0000111 = 0x07
324
         st 0100111 = 0x27
325
  */
326
24.4k
#define MASK_LS_INSN 0x0000007f
327
24.4k
  uint32_t opcode = in & MASK_LS_INSN;
328
24.4k
  if (0 == (opcode ^ 0x03) || 0 == (opcode ^ 0x07) ||
329
24.4k
      0 == (opcode ^ 0x23) || 0 == (opcode ^ 0x27))
330
424
    MI->flat_insn->detail->riscv.need_effective_addr = true;
331
24.4k
#undef MASK_LS_INSN
332
24.4k
  return;
333
24.4k
}
334
335
static DecodeStatus RISCVDisassembler_getInstruction(int mode, MCInst *MI,
336
         const uint8_t *code, size_t code_len,
337
         uint16_t *Size, uint64_t Address,
338
         MCRegisterInfo *MRI) 
339
25.1k
{
340
    // TODO: This will need modification when supporting instruction set
341
    // extensions with instructions > 32-bits (up to 176 bits wide).
342
25.1k
    uint32_t Inst = 0;
343
25.1k
    DecodeStatus Result;
344
345
    // It's a 32 bit instruction if bit 0 and 1 are 1.
346
25.1k
    if ((code[0] & 0x3) == 0x3) {
347
24.6k
          if (code_len < 4) {
348
138
            *Size = 0;
349
138
            return MCDisassembler_Fail;
350
138
          }
351
352
24.4k
          *Size = 4;
353
          // Get the four bytes of the instruction.
354
          //Encoded as little endian 32 bits.
355
24.4k
          Inst = code[0] | (code[1] << 8) | (code[2] << 16) | ((uint32_t)code[3] << 24);
356
24.4k
    init_MI_insn_detail(MI);
357
    // Now we need mark what instruction need fix effective address output.
358
24.4k
        if (MI->csh->detail) 
359
24.4k
      markLSInsn(MI, Inst);
360
24.4k
          Result = decodeInstruction(DecoderTable32, MI, Inst, Address, MRI, mode);
361
24.4k
    } else {
362
533
        if (code_len < 2) {
363
53
            *Size = 0;
364
53
            return MCDisassembler_Fail;
365
53
        }
366
367
    // If not b4bit.
368
480
        if (! (getFeatureBits(mode) & ((uint64_t)RISCV_Feature64Bit))) {
369
            // Trying RISCV32Only_16 table (16-bit Instruction)
370
225
            Inst = code[0] | (code[1] << 8);
371
225
            init_MI_insn_detail(MI);
372
225
            Result = decodeInstruction(DecoderTableRISCV32Only_16, MI, Inst, Address,
373
225
                                         MRI, mode);
374
225
            if (Result != MCDisassembler_Fail) {
375
0
              *Size = 2;
376
0
              return Result;
377
0
            }
378
225
        }
379
    
380
        // Trying RISCV_C table (16-bit Instruction)
381
480
        Inst = code[0] | (code[1] << 8);
382
480
        init_MI_insn_detail(MI);
383
        // Calling the auto-generated decoder function.
384
480
        Result = decodeInstruction(DecoderTable16, MI, Inst, Address, MRI, mode);
385
480
        *Size = 2;
386
480
    }
387
388
24.9k
    return Result;
389
25.1k
}
390
391
bool RISCV_getInstruction(csh ud, const uint8_t *code, size_t code_len,
392
              MCInst *instr, uint16_t *size, uint64_t address,
393
              void *info) 
394
97.8k
{
395
97.8k
    cs_struct *handle = (cs_struct *)(uintptr_t)ud;
396
397
97.8k
    return MCDisassembler_Success == 
398
97.8k
      RISCVDisassembler_getInstruction(handle->mode, instr,
399
97.8k
                       code, code_len,
400
97.8k
                             size, address,
401
97.8k
                             (MCRegisterInfo *)info);
402
403
97.8k
}
404
405
void RISCV_init(MCRegisterInfo * MRI) 
406
3.60k
{
407
    /*
408
    InitMCRegisterInfo(RISCVRegDesc, 97, RA, PC,
409
                     RISCVMCRegisterClasses, 11,
410
                     RISCVRegUnitRoots,
411
                     64,
412
                     RISCVRegDiffLists,
413
                     RISCVLaneMaskLists,
414
                     RISCVRegStrings,
415
                     RISCVRegClassStrings,
416
                     RISCVSubRegIdxLists,
417
                     2,
418
                     RISCVSubRegIdxRanges,
419
                     RISCVRegEncodingTable);
420
    */
421
422
3.60k
    MCRegisterInfo_InitMCRegisterInfo(MRI, RISCVRegDesc, 97, 0, 0,
423
3.60k
                RISCVMCRegisterClasses, 11,
424
3.60k
                  0, 
425
3.60k
                  0,
426
3.60k
                  RISCVRegDiffLists,
427
3.60k
                  0, 
428
3.60k
                  RISCVSubRegIdxLists, 
429
3.60k
                  2, 
430
3.60k
                  0);
431
3.60k
}
432
433
#endif