0001
0002 #ifndef _ASM_X86_INSN_H
0003 #define _ASM_X86_INSN_H
0004
0005
0006
0007
0008
0009
0010 #include <asm/byteorder.h>
0011
0012 #include <asm/inat.h> /* __ignore_sync_check__ */
0013
0014 #if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN)
0015
0016 struct insn_field {
0017 union {
0018 insn_value_t value;
0019 insn_byte_t bytes[4];
0020 };
0021
0022 unsigned char got;
0023 unsigned char nbytes;
0024 };
0025
0026 static inline void insn_field_set(struct insn_field *p, insn_value_t v,
0027 unsigned char n)
0028 {
0029 p->value = v;
0030 p->nbytes = n;
0031 }
0032
0033 static inline void insn_set_byte(struct insn_field *p, unsigned char n,
0034 insn_byte_t v)
0035 {
0036 p->bytes[n] = v;
0037 }
0038
0039 #else
0040
0041 struct insn_field {
0042 insn_value_t value;
0043 union {
0044 insn_value_t little;
0045 insn_byte_t bytes[4];
0046 };
0047
0048 unsigned char got;
0049 unsigned char nbytes;
0050 };
0051
0052 static inline void insn_field_set(struct insn_field *p, insn_value_t v,
0053 unsigned char n)
0054 {
0055 p->value = v;
0056 p->little = __cpu_to_le32(v);
0057 p->nbytes = n;
0058 }
0059
0060 static inline void insn_set_byte(struct insn_field *p, unsigned char n,
0061 insn_byte_t v)
0062 {
0063 p->bytes[n] = v;
0064 p->value = __le32_to_cpu(p->little);
0065 }
0066 #endif
0067
0068 struct insn {
0069 struct insn_field prefixes;
0070
0071
0072
0073 struct insn_field rex_prefix;
0074 struct insn_field vex_prefix;
0075 struct insn_field opcode;
0076
0077
0078
0079
0080 struct insn_field modrm;
0081 struct insn_field sib;
0082 struct insn_field displacement;
0083 union {
0084 struct insn_field immediate;
0085 struct insn_field moffset1;
0086 struct insn_field immediate1;
0087 };
0088 union {
0089 struct insn_field moffset2;
0090 struct insn_field immediate2;
0091 };
0092
0093 int emulate_prefix_size;
0094 insn_attr_t attr;
0095 unsigned char opnd_bytes;
0096 unsigned char addr_bytes;
0097 unsigned char length;
0098 unsigned char x86_64;
0099
0100 const insn_byte_t *kaddr;
0101 const insn_byte_t *end_kaddr;
0102 const insn_byte_t *next_byte;
0103 };
0104
0105 #define MAX_INSN_SIZE 15
0106
0107 #define X86_MODRM_MOD(modrm) (((modrm) & 0xc0) >> 6)
0108 #define X86_MODRM_REG(modrm) (((modrm) & 0x38) >> 3)
0109 #define X86_MODRM_RM(modrm) ((modrm) & 0x07)
0110
0111 #define X86_SIB_SCALE(sib) (((sib) & 0xc0) >> 6)
0112 #define X86_SIB_INDEX(sib) (((sib) & 0x38) >> 3)
0113 #define X86_SIB_BASE(sib) ((sib) & 0x07)
0114
0115 #define X86_REX_W(rex) ((rex) & 8)
0116 #define X86_REX_R(rex) ((rex) & 4)
0117 #define X86_REX_X(rex) ((rex) & 2)
0118 #define X86_REX_B(rex) ((rex) & 1)
0119
0120
0121 #define X86_VEX_W(vex) ((vex) & 0x80)
0122 #define X86_VEX_R(vex) ((vex) & 0x80)
0123 #define X86_VEX_X(vex) ((vex) & 0x40)
0124 #define X86_VEX_B(vex) ((vex) & 0x20)
0125 #define X86_VEX_L(vex) ((vex) & 0x04)
0126
0127 #define X86_EVEX_M(vex) ((vex) & 0x07)
0128 #define X86_VEX3_M(vex) ((vex) & 0x1f)
0129 #define X86_VEX2_M 1
0130 #define X86_VEX_V(vex) (((vex) & 0x78) >> 3)
0131 #define X86_VEX_P(vex) ((vex) & 0x03)
0132 #define X86_VEX_M_MAX 0x1f
0133
0134 extern void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64);
0135 extern int insn_get_prefixes(struct insn *insn);
0136 extern int insn_get_opcode(struct insn *insn);
0137 extern int insn_get_modrm(struct insn *insn);
0138 extern int insn_get_sib(struct insn *insn);
0139 extern int insn_get_displacement(struct insn *insn);
0140 extern int insn_get_immediate(struct insn *insn);
0141 extern int insn_get_length(struct insn *insn);
0142
0143 enum insn_mode {
0144 INSN_MODE_32,
0145 INSN_MODE_64,
0146
0147 INSN_MODE_KERN,
0148 INSN_NUM_MODES,
0149 };
0150
0151 extern int insn_decode(struct insn *insn, const void *kaddr, int buf_len, enum insn_mode m);
0152
0153 #define insn_decode_kernel(_insn, _ptr) insn_decode((_insn), (_ptr), MAX_INSN_SIZE, INSN_MODE_KERN)
0154
0155
0156 static inline void insn_get_attribute(struct insn *insn)
0157 {
0158 insn_get_modrm(insn);
0159 }
0160
0161
0162 extern int insn_rip_relative(struct insn *insn);
0163
0164 static inline int insn_is_avx(struct insn *insn)
0165 {
0166 if (!insn->prefixes.got)
0167 insn_get_prefixes(insn);
0168 return (insn->vex_prefix.value != 0);
0169 }
0170
0171 static inline int insn_is_evex(struct insn *insn)
0172 {
0173 if (!insn->prefixes.got)
0174 insn_get_prefixes(insn);
0175 return (insn->vex_prefix.nbytes == 4);
0176 }
0177
0178 static inline int insn_has_emulate_prefix(struct insn *insn)
0179 {
0180 return !!insn->emulate_prefix_size;
0181 }
0182
0183 static inline insn_byte_t insn_vex_m_bits(struct insn *insn)
0184 {
0185 if (insn->vex_prefix.nbytes == 2)
0186 return X86_VEX2_M;
0187 else if (insn->vex_prefix.nbytes == 3)
0188 return X86_VEX3_M(insn->vex_prefix.bytes[1]);
0189 else
0190 return X86_EVEX_M(insn->vex_prefix.bytes[1]);
0191 }
0192
0193 static inline insn_byte_t insn_vex_p_bits(struct insn *insn)
0194 {
0195 if (insn->vex_prefix.nbytes == 2)
0196 return X86_VEX_P(insn->vex_prefix.bytes[1]);
0197 else
0198 return X86_VEX_P(insn->vex_prefix.bytes[2]);
0199 }
0200
0201
0202 static inline int insn_last_prefix_id(struct insn *insn)
0203 {
0204 if (insn_is_avx(insn))
0205 return insn_vex_p_bits(insn);
0206
0207 if (insn->prefixes.bytes[3])
0208 return inat_get_last_prefix_id(insn->prefixes.bytes[3]);
0209
0210 return 0;
0211 }
0212
0213
0214 static inline int insn_offset_rex_prefix(struct insn *insn)
0215 {
0216 return insn->prefixes.nbytes;
0217 }
0218 static inline int insn_offset_vex_prefix(struct insn *insn)
0219 {
0220 return insn_offset_rex_prefix(insn) + insn->rex_prefix.nbytes;
0221 }
0222 static inline int insn_offset_opcode(struct insn *insn)
0223 {
0224 return insn_offset_vex_prefix(insn) + insn->vex_prefix.nbytes;
0225 }
0226 static inline int insn_offset_modrm(struct insn *insn)
0227 {
0228 return insn_offset_opcode(insn) + insn->opcode.nbytes;
0229 }
0230 static inline int insn_offset_sib(struct insn *insn)
0231 {
0232 return insn_offset_modrm(insn) + insn->modrm.nbytes;
0233 }
0234 static inline int insn_offset_displacement(struct insn *insn)
0235 {
0236 return insn_offset_sib(insn) + insn->sib.nbytes;
0237 }
0238 static inline int insn_offset_immediate(struct insn *insn)
0239 {
0240 return insn_offset_displacement(insn) + insn->displacement.nbytes;
0241 }
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255 #define for_each_insn_prefix(insn, idx, prefix) \
0256 for (idx = 0; idx < ARRAY_SIZE(insn->prefixes.bytes) && (prefix = insn->prefixes.bytes[idx]) != 0; idx++)
0257
0258 #define POP_SS_OPCODE 0x1f
0259 #define MOV_SREG_OPCODE 0x8e
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269 static inline int insn_masking_exception(struct insn *insn)
0270 {
0271 return insn->opcode.bytes[0] == POP_SS_OPCODE ||
0272 (insn->opcode.bytes[0] == MOV_SREG_OPCODE &&
0273 X86_MODRM_REG(insn->modrm.bytes[0]) == 2);
0274 }
0275
0276 #endif