fcml  1.2.2
fcml_disassembler.hpp
Go to the documentation of this file.
1 /*
2  * FCML - Free Code Manipulation Library.
3  * Copyright (C) 2010-2020 Slawomir Wojtasiak
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
27 #ifndef FCML_DISASSEMBLER_HPP_
28 #define FCML_DISASSEMBLER_HPP_
29 
30 #include <string.h>
31 
32 #include "fcml_disassembler.h"
33 
34 #include "fcml_common.hpp"
35 #include "fcml_errors.hpp"
36 #include "fcml_dialect.hpp"
37 
38 namespace fcml {
39 
45 public:
47  const ErrorContainer &errorContainer,
49  ErrorContainerAwareException(msg, errorContainer, error) {
50  }
51 };
52 
59 public:
60 
66  _throwExceptionOnError(true),
67  _incrementIP(true),
68  _enableErrorMessages(true),
69  _carryFlagConditionalSuffix(false),
70  _conditionalGroup(false),
71  _shortForms(false),
72  _extendDispToASA(false),
73  _failIfUnknownInstruction(false) {
74  }
75 
78  return _carryFlagConditionalSuffix;
79  }
80 
82  void setCarryFlagConditionalSuffix(bool carryFlagConditionalSuffix) {
83  _carryFlagConditionalSuffix = carryFlagConditionalSuffix;
84  }
85 
87  fcml_uint8_t getConditionalGroup() const {
88  return _conditionalGroup;
89  }
90 
92  void setConditionalGroup(fcml_uint8_t conditionalGroup) {
93  _conditionalGroup = conditionalGroup;
94  }
95 
97  bool isEnableErrorMessages() const {
98  return _enableErrorMessages;
99  }
100 
102  void setEnableErrorMessages(bool enableErrorMessages) {
103  _enableErrorMessages = enableErrorMessages;
104  }
105 
107  bool isExtendDispToAsa() const {
108  return _extendDispToASA;
109  }
110 
112  void setExtendDispToAsa(bool extendDispToAsa) {
113  _extendDispToASA = extendDispToAsa;
114  }
115 
118  return _failIfUnknownInstruction;
119  }
120 
122  void setFailIfUnknownInstruction(bool failIfUnknownInstruction) {
123  _failIfUnknownInstruction = failIfUnknownInstruction;
124  }
125 
127  bool isIncrementIp() const {
128  return _incrementIP;
129  }
130 
132  void setIncrementIp(bool incrementIp) {
133  _incrementIP = incrementIp;
134  }
135 
137  bool isShortForms() const {
138  return _shortForms;
139  }
140 
142  void setShortForms(bool shortForms) {
143  _shortForms = shortForms;
144  }
145 
153  bool isThrowExceptionOnError() const {
154  return _throwExceptionOnError;
155  }
156 
164  void setThrowExceptionOnError(bool throwExceptionOnError) {
165  _throwExceptionOnError = throwExceptionOnError;
166  }
167 
168 private:
169  bool _throwExceptionOnError;
170  bool _incrementIP;
171  bool _enableErrorMessages;
172  bool _carryFlagConditionalSuffix;
173  fcml_uint8_t _conditionalGroup;
174  bool _shortForms;
175  bool _extendDispToASA;
176  bool _failIfUnknownInstruction;
177 
178 };
179 
184 public:
185 
191  _code(NULL), _codeLength(0) {
192  }
193 
201  DisassemblerContext(fcml_ptr code, fcml_usize codeLength) :
202  _code(code), _codeLength(codeLength) {
203  }
204 
205 public:
206 
213  fcml_ptr getCode() const {
214  return _code;
215  }
216 
223  void setCode(fcml_ptr code) {
224  _code = code;
225  }
226 
233  fcml_usize getCodeLength() const {
234  return _codeLength;
235  }
236 
243  void setCodeLength(fcml_usize codeLength) {
244  _codeLength = codeLength;
245  }
246 
254  return _disassemblerConf;
255  }
256 
264  return _disassemblerConf;
265  }
266 
273  void setDisassemblerConf(DisassemblerConf disassemblerConf) {
274  _disassemblerConf = disassemblerConf;
275  }
276 
284  const EntryPoint& getEntryPoint() const {
285  return _entryPoint;
286  }
287 
295  return _entryPoint;
296  }
305  void setEntryPoint(const EntryPoint &entryPoint) {
306  _entryPoint = entryPoint;
307  }
308 
315  void setIP(fcml_ip ip) {
316  _entryPoint.setIP(ip);
317  }
318 
326  void incrementIP(fcml_ip ip) {
327  _entryPoint.incrementIP(ip);
328  }
329 
337  _entryPoint.setOpMode(operatingMode);
338  }
339 
346  void setAddressSizeAttribute(fcml_usize addressSizeAttribute) {
347  _entryPoint.setAddressSizeAttribute(addressSizeAttribute);
348  }
349 
356  void setOperandSizeAttribute(fcml_usize operandSizeAttribute) {
357  _entryPoint.setOperandSizeAttribute(operandSizeAttribute);
358  }
359 
360 private:
362  DisassemblerConf _disassemblerConf;
364  EntryPoint _entryPoint;
366  fcml_ptr _code;
368  fcml_usize _codeLength;
369 };
370 
375 public:
376 
380  enum PrefixType {
381  PT_GROUP_UNKNOWN = FCML_PT_GROUP_UNKNOWN,
382  PT_GROUP_1 = FCML_PT_GROUP_1,
383  PT_GROUP_2 = FCML_PT_GROUP_2,
384  PT_GROUP_3 = FCML_PT_GROUP_3,
385  PT_GROUP_4 = FCML_PT_GROUP_4,
386  PT_REX = FCML_PT_REX,
387  PT_VEX = FCML_PT_VEX,
388  PT_XOP = FCML_PT_XOP,
389  PT_EVEX = FCML_PT_EVEX
390  };
391 
398  bool isMandatoryPrefix() const {
399  return _mandatoryPrefix;
400  }
401 
409  void setMandatoryPrefix(bool mandatoryPrefix) {
410  _mandatoryPrefix = mandatoryPrefix;
411  }
412 
419  fcml_uint8_t getPrefix() const {
420  return _prefix;
421  }
422 
429  void setPrefix(fcml_uint8_t prefix) {
430  _prefix = prefix;
431  }
432 
440  return _prefixType;
441  }
442 
449  void setPrefixType(PrefixType prefixType) {
450  _prefixType = prefixType;
451  }
452 
459  const fcml_uint8_t* getAvxBytes() const {
460  return _AvxBytes;
461  }
462 
469  fcml_uint8_t* getAvxBytes() {
470  return _AvxBytes;
471  }
472 
473 private:
475  fcml_uint8_t _prefix;
477  PrefixType _prefixType;
479  bool _mandatoryPrefix;
483  fcml_uint8_t _AvxBytes[3];
484 };
485 
490 public:
491 
497  _prefixesCount(0),
498  _prefixesBytesCount(0),
499  _isBranch(false),
500  _isNobranch(false),
501  _isLock(false),
502  _isRep(false),
503  _isRepne(false),
504  _isXrelease(false),
505  _isXacquire(false),
506  _isVex(false),
507  _isEvex(false),
508  _isXop(false),
509  _isAvx(false),
510  _isRex(false),
511  _AvxPrefixFirstByte(false),
512  _R(0),
513  _RPrim(0),
514  _X(0),
515  _B(0),
516  _W(0),
517  _L(0),
518  _LPrim(0),
519  _mmmm(0),
520  _vvvv(0),
521  _VPrim(0),
522  _pp(0),
523  _aaa(0),
524  _b(false),
525  _z(false) {
526  }
527 
535  const InstructionPrefixDetails& operator[](fcml_usize index) const {
536  if (index >= FCML_DASM_PREFIXES_COUNT) {
537  throw IllegalArgumentException(FCML_TEXT("Index out of bound."));
538  }
539  return _prefixes[index];
540  }
541 
550  if (index >= FCML_DASM_PREFIXES_COUNT) {
551  throw IllegalArgumentException(FCML_TEXT("Index out of bound."));
552  }
553  return _prefixes[index];
554  }
555 
562  fcml_uint8_t getB() const {
563  return _B;
564  }
565 
572  void setB(fcml_uint8_t B) {
573  _B = B;
574  }
575 
582  bool isBranch() const {
583  return _isBranch;
584  }
585 
592  void setBranch(bool isBranch) {
593  _isBranch = isBranch;
594  }
595 
602  bool isLock() const {
603  return _isLock;
604  }
605 
612  void setLock(bool isLock) {
613  _isLock = isLock;
614  }
615 
622  bool isNobranch() const {
623  return _isNobranch;
624  }
625 
632  void setNobranch(bool isNobranch) {
633  _isNobranch = isNobranch;
634  }
635 
642  bool isRep() const {
643  return _isRep;
644  }
645 
652  void setRep(bool isRep) {
653  _isRep = isRep;
654  }
655 
662  bool isRepne() const {
663  return _isRepne;
664  }
665 
672  void setRepne(bool isRepne) {
673  _isRepne = isRepne;
674  }
675 
682  bool isRex() const {
683  return _isRex;
684  }
685 
692  void setRex(bool isRex) {
693  _isRex = isRex;
694  }
695 
702  bool isVex() const {
703  return _isVex;
704  }
705 
712  void setVex(bool isVex) {
713  _isVex = isVex;
714  }
715 
722  void setEvex(bool isEvex) {
723  _isEvex = isEvex;
724  }
725 
732  bool isEvex() const {
733  return _isEvex;
734  }
735 
742  bool isXacquire() const {
743  return _isXacquire;
744  }
745 
752  void setXacquire(bool isXacquire) {
753  _isXacquire = isXacquire;
754  }
755 
762  bool isXop() const {
763  return _isXop;
764  }
765 
772  void setXop(bool isXop) {
773  _isXop = isXop;
774  }
775 
782  bool isAvx() const {
783  return _isAvx;
784  }
785 
792  void setAvx(bool isAvx) {
793  _isAvx = isAvx;
794  }
795 
802  bool isXrelease() const {
803  return _isXrelease;
804  }
805 
812  void setXrelease(bool isXrelease) {
813  _isXrelease = isXrelease;
814  }
815 
822  fcml_uint8_t getL() const {
823  return _L;
824  }
825 
832  void setL(fcml_uint8_t L) {
833  _L = L;
834  }
835 
842  fcml_uint8_t getLPrim() const {
843  return _LPrim;
844  }
845 
852  void setLPrim(fcml_uint8_t lPrim) {
853  _LPrim = lPrim;
854  }
855 
862  fcml_uint8_t getMmmm() const {
863  return _mmmm;
864  }
865 
872  void setMmmm(fcml_uint8_t mmmm) {
873  _mmmm = mmmm;
874  }
875 
882  fcml_uint8_t getPp() const {
883  return _pp;
884  }
885 
892  void setPp(fcml_uint8_t pp) {
893  _pp = pp;
894  }
895 
904  const InstructionPrefixDetails& getPrefixes(fcml_usize index) const {
905  if (index > FCML_DASM_PREFIXES_COUNT) {
906  throw BadArgumentException(FCML_TEXT("Array index out of bound."),
908  }
909  return _prefixes[index];
910  }
911 
921  if (index > FCML_DASM_PREFIXES_COUNT) {
922  throw BadArgumentException(FCML_TEXT("Array index out of bound."),
924  }
925  return _prefixes[index];
926  }
927 
934  fcml_int getPrefixesBytesCount() const {
935  return _prefixesBytesCount;
936  }
937 
944  void setPrefixesBytesCount(fcml_int prefixesBytesCount) {
945  _prefixesBytesCount = prefixesBytesCount;
946  }
947 
954  fcml_int getPrefixesCount() const {
955  return _prefixesCount;
956  }
957 
964  void setPrefixesCount(fcml_int prefixesCount) {
965  _prefixesCount = prefixesCount;
966  }
967 
974  fcml_uint8_t getR() const {
975  return _R;
976  }
977 
984  void setR(fcml_uint8_t r) {
985  _R = r;
986  }
987 
994  fcml_uint8_t getRPrim() const {
995  return _RPrim;
996  }
997 
1004  void setRPrim(fcml_uint8_t rPrim) {
1005  _RPrim = rPrim;
1006  }
1007 
1014  fcml_uint8_t getAvxFirstByte() const {
1015  return _AvxPrefixFirstByte;
1016  }
1017 
1024  void setAvxFirstByte(fcml_uint8_t avxFirstByte) {
1025  _AvxPrefixFirstByte = avxFirstByte;
1026  }
1027 
1034  fcml_uint8_t getVvvv() const {
1035  return _vvvv;
1036  }
1037 
1044  void setVvvv(fcml_uint8_t vvvv) {
1045  _vvvv = vvvv;
1046  }
1047 
1054  fcml_uint8_t getAaa() const {
1055  return _aaa;
1056  }
1057 
1064  void setAaa(fcml_uint8_t aaa) {
1065  _aaa = aaa;
1066  }
1067 
1074  fcml_uint8_t getVPrim() const {
1075  return _VPrim;
1076  }
1077 
1084  void setVPrim(fcml_uint8_t vPrim) {
1085  _VPrim = vPrim;
1086  }
1087 
1094  fcml_uint8_t getW() const {
1095  return _W;
1096  }
1097 
1104  void setW(fcml_uint8_t W) {
1105  _W = W;
1106  }
1107 
1114  fcml_uint8_t getX() const {
1115  return _X;
1116  }
1117 
1124  void setX(fcml_uint8_t X) {
1125  _X = X;
1126  }
1127 
1134  bool getBcast() const {
1135  return _b;
1136  }
1137 
1144  void setBcast(bool b) {
1145  _b = b;
1146  }
1147 
1154  bool getZ() const {
1155  return _z;
1156  }
1157 
1164  void setZ(bool z) {
1165  _z = z;
1166  }
1167 
1168 private:
1172  fcml_int _prefixesCount;
1174  fcml_int _prefixesBytesCount;
1176  bool _isBranch;
1178  bool _isNobranch;
1180  bool _isLock;
1182  bool _isRep;
1184  bool _isRepne;
1186  bool _isXrelease;
1188  bool _isXacquire;
1190  bool _isVex;
1194  bool _isEvex;
1196  bool _isXop;
1200  bool _isAvx;
1202  bool _isRex;
1206  fcml_uint8_t _AvxPrefixFirstByte;
1208  fcml_uint8_t _R;
1212  fcml_uint8_t _RPrim;
1214  fcml_uint8_t _X;
1216  fcml_uint8_t _B;
1218  fcml_uint8_t _W;
1220  fcml_uint8_t _L;
1224  fcml_uint8_t _LPrim;
1226  fcml_uint8_t _mmmm;
1228  fcml_uint8_t _vvvv;
1232  fcml_uint8_t _VPrim;
1234  fcml_uint8_t _pp;
1238  fcml_uint8_t _aaa;
1242  bool _b;
1246  bool _z;
1247 };
1248 
1253 public:
1254 
1256  enum AccessMode {
1258  AM_ACCESS_MODE_UNDEFINED = FCML_AM_ACCESS_MODE_UNDEFINED,
1260  AM_READ = FCML_AM_READ,
1262  AM_WRITE = FCML_AM_WRITE,
1264  AM_READ_WRITE = AM_READ | AM_WRITE
1265  };
1266 
1272  _accessMode(AM_ACCESS_MODE_UNDEFINED) {
1273  }
1274 
1282  _accessMode(accessMode) {
1283  }
1284 
1292  return _accessMode;
1293  }
1294 
1301  void setAccessMode(AccessMode accessMode) {
1302  _accessMode = accessMode;
1303  }
1304 
1305 private:
1307  AccessMode _accessMode;
1308 };
1309 
1314 public:
1315 
1321  _isRip(false) {
1322  }
1323 
1330  bool isRip() const {
1331  return _isRip;
1332  }
1333 
1340  void setRip(bool isRip) {
1341  _isRip = isRip;
1342  }
1343 
1351  return _modRM;
1352  }
1353 
1361  return _modRM;
1362  }
1363 
1370  void setModRM(const Nullable<fcml_uint8_t> &modRM) {
1371  _modRM = modRM;
1372  }
1373 
1381  return _sib;
1382  }
1383 
1391  return _sib;
1392  }
1393 
1400  void setSib(const Nullable<fcml_uint8_t> &sib) {
1401  _sib = sib;
1402  }
1403 
1411  return _N;
1412  }
1413 
1421  return _N;
1422  }
1423 
1431  _N = N;
1432  }
1433 
1440  const Integer& getDisplacement() const {
1441  return _displacement;
1442  }
1443 
1451  return _displacement;
1452  }
1453 
1460  void setDisplacement(const Integer &displacement) {
1461  _displacement = displacement;
1462  }
1463 
1464 private:
1466  Nullable<fcml_uint8_t> _modRM;
1471  bool _isRip;
1475  Integer _displacement;
1476  /* N from AVX-512 compressed disp8.
1477  * since 1.2.0
1478  */
1480 };
1481 
1486 public:
1487 
1497  fcml_uint16_t getAddrMode() const {
1498  return _addrMode;
1499  }
1500 
1507  void setAddrMode(fcml_uint16_t addrMode) {
1508  _addrMode = addrMode;
1509  }
1510 
1518  return _instruction;
1519  }
1520 
1528  _instruction = instruction;
1529  }
1530 
1538  const fcml_uint8_t* getInstructionCode() const {
1539  return _instructionCode;
1540  }
1541 
1549  fcml_uint8_t* getInstructionCode() {
1550  return _instructionCode;
1551  }
1552 
1560  fcml_uint64_t getInstructionGroup() const {
1561  return _instructionGroup;
1562  }
1563 
1571  void setInstructionGroup(fcml_uint64_t instructionGroup) {
1572  _instructionGroup = instructionGroup;
1573  }
1574 
1581  fcml_usize getInstructionSize() const {
1582  return _instructionSize;
1583  }
1584 
1591  void setInstructionSize(fcml_usize instructionSize) {
1592  _instructionSize = instructionSize;
1593  }
1594 
1601  bool isShortcut() const {
1602  return _isShortcut;
1603  }
1604 
1611  void setShortcut(bool isShortcut) {
1612  _isShortcut = isShortcut;
1613  }
1614 
1622  return _modRMDetails;
1623  }
1624 
1632  return _modRMDetails;
1633  }
1634 
1641  void setModRmDetails(const DecodedModRMDetails &modRmDetails) {
1642  _modRMDetails = modRmDetails;
1643  }
1644 
1651  bool isOpcodeFieldSBit() const {
1652  return _opcodeFieldSBit;
1653  }
1654 
1661  void setOpcodeFieldSBit(bool opcodeFieldSBit) {
1662  _opcodeFieldSBit = opcodeFieldSBit;
1663  }
1664 
1671  bool isOpcodeFieldWBit() const {
1672  return _opcodeFieldWBit;
1673  }
1674 
1681  void setOpcodeFieldWBit(bool opcodeFieldWBit) {
1682  _opcodeFieldWBit = opcodeFieldWBit;
1683  }
1684 
1693  const OperandDetails& getOperandDetails(fcml_usize index) const {
1694  if (index > FCML_OPERANDS_COUNT) {
1695  throw BadArgumentException(FCML_TEXT("Array index out of bound."),
1697  }
1698  return _operandDetails[index];
1699  }
1700 
1709  OperandDetails& getOperandDetails(fcml_usize index) {
1710  if (index > FCML_OPERANDS_COUNT) {
1711  throw BadArgumentException(FCML_TEXT("Array index out of bound."),
1713  }
1714  return _operandDetails[index];
1715  }
1716 
1724  return _prefixesDetails;
1725  }
1726 
1734  return _prefixesDetails;
1735  }
1736 
1743  void setPrefixesDetails(const PrefixesDetails &prefixesDetails) {
1744  _prefixesDetails = prefixesDetails;
1745  }
1746 
1754  return _pseudoOp;
1755  }
1756 
1764  _pseudoOp = pseudoOp;
1765  }
1766 
1773  bool isPseudoOp() const {
1774  return _isPseudoOp;
1775  }
1776 
1783  void setIsPseudoOp(bool isPseudoOp) {
1784  _isPseudoOp = isPseudoOp;
1785  }
1786 
1791  fcml_uint8_t getTupleType() const {
1792  return _tupleType;
1793  }
1794 
1801  void setTupleType(fcml_uint8_t tupleType) {
1802  _tupleType = tupleType;
1803  }
1804 
1805 private:
1806 
1814  bool _isShortcut;
1819  bool _isPseudoOp;
1823  fcml_uint8_t _instructionCode[FCML_INSTRUCTION_SIZE];
1827  fcml_usize _instructionSize;
1831  PrefixesDetails _prefixesDetails;
1835  OperandDetails _operandDetails[FCML_OPERANDS_COUNT];
1839  DecodedModRMDetails _modRMDetails;
1844  bool _opcodeFieldSBit;
1849  bool _opcodeFieldWBit;
1853  fcml_en_instruction _instruction;
1857  fcml_en_pseudo_operations _pseudoOp;
1861  fcml_uint16_t _addrMode;
1865  fcml_uint64_t _instructionGroup;
1869  fcml_uint8_t _tupleType;
1870 };
1871 
1878 
1879 public:
1880 
1889  return _errorContainer;
1890  }
1891 
1899  const Instruction& getInstruction() const {
1900  return _instruction;
1901  }
1902 
1910  return _instructionDetails;
1911  }
1912 
1917  void clean() {
1918  _errorContainer.clean();
1919  _instructionDetails = InstructionDetails();
1920  _instruction = Instruction();
1921  }
1922 
1923 protected:
1924 
1925  friend class Disassembler;
1926  friend class DisassemblerTypeConverter;
1927 
1934  return _instructionDetails;
1935  }
1936 
1942  void setInstructionDetails(const InstructionDetails &instructionDetails) {
1943  _instructionDetails = instructionDetails;
1944  }
1945 
1952  return _instruction;
1953  }
1954 
1960  void setInstruction(const Instruction &instruction) {
1961  _instruction = instruction;
1962  }
1963 
1969  void setErrorContainer(const ErrorContainer &errorContainer) {
1970  _errorContainer = errorContainer;
1971  }
1972 
1973 private:
1974 
1976  ErrorContainer _errorContainer;
1978  InstructionDetails _instructionDetails;
1980  Instruction _instruction;
1981 
1982 };
1983 
1990 
1991 public:
1992 
1993  static void convert(const DisassemblerContext &src,
1995  dest.code = src.getCode();
1996  dest.code_length = src.getCodeLength();
1997  TypeConverter::convert(src.getEntryPoint(), dest.entry_point);
1998  convert(src.getDisassemblerConf(), dest.configuration);
1999  }
2000 
2001  static void convert(const DisassemblerConf &src,
2002  fcml_st_disassembler_conf &dest) {
2008  dest.increment_ip = src.isIncrementIp();
2009  dest.short_forms = src.isShortForms();
2010  }
2011 
2012  static void convert(const fcml_st_decoded_modrm_details &src,
2013  DecodedModRMDetails &dest) {
2014  dest.setRip(FCML_TO_CPP_BOOL(src.is_rip));
2015  Nullable<fcml_uint8_t> &modRM = dest.getModRM();
2016  modRM.setNotNull(FCML_TO_CPP_BOOL(src.is_modrm));
2017  modRM.setValue(src.modrm);
2018  Nullable<fcml_uint8_t> &sib = dest.getSib();
2019  sib.setNotNull(FCML_TO_CPP_BOOL(src.sib.is_not_null));
2020  sib.setValue(src.sib.value);
2021  TypeConverter::convert(src.displacement.displacement,
2022  dest.getDisplacement());
2024  N.setNotNull(FCML_TO_CPP_BOOL(src.displacement.N.is_not_null));
2025  N.setValue(src.displacement.N.value);
2026  dest.setN(N);
2027  }
2028 
2029  static void convert(const DecodedModRMDetails &src,
2031  dest.is_modrm = src.getModRM().isNotNull();
2032  dest.is_rip = src.isRip();
2033  dest.modrm = src.getModRM().getValue();
2034  fcml_nuint8_t &sib = dest.sib;
2035  sib.is_not_null = src.getSib().isNotNull();
2036  sib.value = src.getSib().getValue();
2037  TypeConverter::convert(src.getDisplacement(),
2038  dest.displacement.displacement);
2039  dest.displacement.N.is_not_null = src.getN().isNotNull();
2040  dest.displacement.N.value = src.getN().getValue();
2041  }
2042 
2043  static void convert(const fcml_st_operand_details &src,
2044  OperandDetails &dest) {
2045  dest.setAccessMode(
2046  static_cast<OperandDetails::AccessMode>(src.access_mode));
2047  }
2048 
2049  static void convert(const OperandDetails &src,
2050  fcml_st_operand_details &dest) {
2051  dest.access_mode =
2052  static_cast<fcml_en_access_mode>(src.getAccessMode());
2053  }
2054 
2055  static void convert(const fcml_st_instruction_prefix &src,
2056  InstructionPrefixDetails &dest) {
2057  dest.setMandatoryPrefix(FCML_TO_CPP_BOOL(src.mandatory_prefix));
2058  dest.setPrefix(src.prefix);
2059  dest.setPrefixType(
2060  static_cast<InstructionPrefixDetails::PrefixType>(src.prefix_type));
2061  ::memcpy(dest.getAvxBytes(), src.avx_bytes, sizeof(src.avx_bytes));
2062  }
2063 
2064  static void convert(const InstructionPrefixDetails &src,
2066  dest.mandatory_prefix = src.isMandatoryPrefix();
2067  dest.prefix = src.getPrefix();
2068  dest.prefix_type =
2069  static_cast<fcml_en_prefix_types>(src.getPrefixType());
2070  ::memcpy(dest.avx_bytes, src.getAvxBytes(), sizeof(dest.avx_bytes));
2071  }
2072 
2073  static void convert(const fcml_st_prefixes_details src,
2074  PrefixesDetails &dest) {
2075  for (int i = 0; i < FCML_DASM_PREFIXES_COUNT; i++) {
2076  convert(src.prefixes[i], dest.getPrefixes(i));
2077  }
2078  dest.setPrefixesCount(src.prefixes_count);
2080  dest.setBranch(FCML_TO_CPP_BOOL(src.is_branch));
2081  dest.setNobranch(FCML_TO_CPP_BOOL(src.is_nobranch));
2082  dest.setLock(FCML_TO_CPP_BOOL(src.is_lock));
2083  dest.setRep(FCML_TO_CPP_BOOL(src.is_rep));
2084  dest.setRepne(FCML_TO_CPP_BOOL(src.is_repne));
2085  dest.setXrelease(FCML_TO_CPP_BOOL(src.is_xrelease));
2086  dest.setXacquire(FCML_TO_CPP_BOOL(src.is_xacquire));
2087  dest.setVex(FCML_TO_CPP_BOOL(src.is_vex));
2088  dest.setEvex(FCML_TO_CPP_BOOL(src.is_evex));
2089  dest.setXop(FCML_TO_CPP_BOOL(src.is_xop));
2090  dest.setAvx(FCML_TO_CPP_BOOL(src.is_avx));
2091  dest.setRex(FCML_TO_CPP_BOOL(src.is_rex));
2092  dest.setAvxFirstByte(src.avx_first_byte);
2093  dest.setR(src.R);
2094  dest.setRPrim(src.R_prim);
2095  dest.setX(src.X);
2096  dest.setB(src.B);
2097  dest.setW(src.W);
2098  dest.setL(src.L);
2099  dest.setLPrim(src.L_prim);
2100  dest.setMmmm(src.mmmm);
2101  dest.setVvvv(src.vvvv);
2102  dest.setVPrim(src.V_prim);
2103  dest.setPp(src.pp);
2104  dest.setAaa(src.aaa);
2105  dest.setBcast(src.b);
2106  dest.setZ(src.z);
2107  }
2108 
2109  static void convert(const PrefixesDetails src,
2110  fcml_st_prefixes_details &dest) {
2111  for (int i = 0; i < FCML_DASM_PREFIXES_COUNT; i++) {
2112  convert(src.getPrefixes(i), dest.prefixes[i]);
2113  }
2114  dest.prefixes_count = src.getPrefixesCount();
2116  dest.is_branch = src.isBranch();
2117  dest.is_nobranch = src.isNobranch();
2118  dest.is_lock = src.isLock();
2119  dest.is_rep = src.isRep();
2120  dest.is_repne = src.isRepne();
2121  dest.is_xrelease = src.isXrelease();
2122  dest.is_xacquire = src.isXacquire();
2123  dest.is_vex = src.isVex();
2124  dest.is_xop = src.isXop();
2125  dest.is_avx = src.isAvx();
2126  dest.is_evex = src.isEvex();
2127  dest.is_rex = src.isRex();
2128  dest.avx_first_byte = src.getAvxFirstByte();
2129  dest.R = src.getR();
2130  dest.R_prim = src.getRPrim();
2131  dest.X = src.getX();
2132  dest.B = src.getB();
2133  dest.W = src.getW();
2134  dest.L = src.getL();
2135  dest.L_prim = src.getLPrim();
2136  dest.mmmm = src.getMmmm();
2137  dest.vvvv = src.getVvvv();
2138  dest.V_prim = src.getVPrim();
2139  dest.pp = src.getPp();
2140  dest.aaa = src.getAaa();
2141  dest.b = src.getBcast();
2142  dest.z = src.getZ() ? 1 : 0;
2143  }
2144 
2145  static void convert(const fcml_st_instruction_details &src,
2146  InstructionDetails &dest) {
2147  dest.setTupleType(src.tuple_type);
2148  dest.setAddrMode(src.addr_mode);
2149  dest.setInstruction(src.instruction);
2152  dest.setOpcodeFieldSBit(FCML_TO_CPP_BOOL(src.opcode_field_s_bit));
2153  dest.setOpcodeFieldWBit(FCML_TO_CPP_BOOL(src.opcode_field_w_bit));
2154  dest.setIsPseudoOp(FCML_TO_CPP_BOOL(src.is_pseudo_op));
2155  dest.setPseudoOp(src.pseudo_op);
2156  dest.setShortcut(FCML_TO_CPP_BOOL(src.is_shortcut));
2157  convert(src.modrm_details, dest.getModRmDetails());
2158  for (int i = 0; i < FCML_OPERANDS_COUNT; i++) {
2159  convert(src.operand_details[i], dest.getOperandDetails(i));
2160  }
2161  fcml_uint8_t *code = dest.getInstructionCode();
2162  for (int i = 0; i < FCML_INSTRUCTION_SIZE; i++) {
2163  code[i] = src.instruction_code[i];
2164  }
2165  convert(src.prefixes_details, dest.getPrefixesDetails());
2166  }
2167 
2168  static void convert(const InstructionDetails &src,
2170  dest.tuple_type = src.getTupleType();
2171  dest.addr_mode = src.getAddrMode();
2172  dest.instruction = src.getInstruction();
2174  dest.instruction_size = src.getInstructionSize();
2177  dest.is_pseudo_op = src.isPseudoOp();
2178  dest.pseudo_op = src.getPseudoOp();
2179  dest.is_shortcut = src.isShortcut();
2180  convert(src.getModRmDetails(), dest.modrm_details);
2181  for (int i = 0; i < FCML_OPERANDS_COUNT; i++) {
2182  convert(src.getOperandDetails(i), dest.operand_details[i]);
2183  }
2184  for (int i = 0; i < FCML_INSTRUCTION_SIZE; i++) {
2185  dest.instruction_code[i] = src.getInstructionCode()[i];
2186  }
2187  convert(src.getPrefixesDetails(), dest.prefixes_details);
2188  }
2189 
2190  static void convert(const fcml_st_disassembler_result &src,
2191  DisassemblerResult &dest) {
2192  TypeConverter::convert(src.instruction, dest.getInstructionInternal());
2194  }
2195 
2196  static void convert(const DisassemblerResult &src,
2198  TypeConverter::convert(src.getInstruction(), dest.instruction);
2199  convert(src.getInstructionDetails(), dest.instruction_details);
2200  }
2201 
2202  static void free(fcml_st_disassembler_result &src) {
2203  TypeConverter::free(src.instruction);
2204  }
2205 
2206 };
2207 
2211 class Disassembler: public NonCopyable, protected DialectAware {
2212 public:
2213 
2221  Disassembler(Dialect &dialect) :
2222  _dialect(dialect) {
2224  extractDialect(dialect), &_disassembler);
2225  if (error) {
2226  throw InitException(
2227  FCML_TEXT("Cannot initialize the disassembler."), error);
2228  }
2229  }
2230 
2235  virtual ~Disassembler() {
2236  if (_disassembler) {
2237  ::fcml_fn_disassembler_free(_disassembler);
2238  _disassembler = NULL;
2239  }
2240  }
2241 
2242 public:
2243 
2254  DisassemblerResult &disassemblerResult) {
2255 
2257 
2259  DisassemblerTypeConverter::convert(ctx, context);
2260 
2261  context.disassembler = _disassembler;
2262 
2263  /* Prepare assembler result. */
2264  fcml_st_disassembler_result disassembler_result;
2265  ::fcml_fn_disassembler_result_prepare(&disassembler_result);
2266 
2267  try {
2268 
2269  disassemblerResult.clean();
2270 
2271  error = ::fcml_fn_disassemble(&context, &disassembler_result);
2272 
2273  ErrorContainer errorContainer;
2274  ErrorTypeConverter::convert(disassembler_result.errors,
2275  errorContainer);
2276 
2277  disassemblerResult.setErrorContainer(errorContainer);
2278 
2279  if (error && ctx.getDisassemblerConf().isThrowExceptionOnError()) {
2280  ::fcml_fn_disassembler_result_free(&disassembler_result);
2282  FCML_TEXT("Assembling failed."), errorContainer, error);
2283  }
2284 
2285  if (!error) {
2286 
2287  // Convert result.
2288  DisassemblerTypeConverter::convert(disassembler_result,
2289  disassemblerResult);
2290 
2291  ctx.getEntryPoint().setIP(context.entry_point.ip);
2292  ctx.setCode(context.code);
2293  ctx.setCodeLength(context.code_length);
2294 
2295  }
2296 
2297  ::fcml_fn_disassembler_result_free(&disassembler_result);
2298 
2299  } catch (std::exception &exc) {
2300  // If anything failed, free assembler results.
2301  ::fcml_fn_disassembler_result_free(&disassembler_result);
2302  throw exc;
2303  }
2304 
2305  return error;
2306  }
2307 
2313  Dialect& getDialect() const {
2314  return _dialect;
2315  }
2316 
2317 private:
2318 
2320  Dialect &_dialect;
2322  fcml_st_disassembler *_disassembler;
2323 
2324 };
2325 
2326 }
2327 
2328 #endif //FCML_DISASSEMBLER_HPP_
2329 
DecodedModRMDetails & getModRmDetails()
Gets ModR/M instruction details.
Definition: fcml_disassembler.hpp:1631
void setIsPseudoOp(bool isPseudoOp)
Sets pseudo operation flag.
Definition: fcml_disassembler.hpp:1783
void setLPrim(fcml_uint8_t lPrim)
Sets L&#39; flag.
Definition: fcml_disassembler.hpp:852
DisassemblerContext()
Creates empty disassembler context.
Definition: fcml_disassembler.hpp:190
fcml_uint8_t mmmm
m-mmmm field of XOP or VEX prefix.
Definition: fcml_disassembler.h:177
void setAccessMode(AccessMode accessMode)
Sets an access mode for the operand.
Definition: fcml_disassembler.hpp:1301
fcml_ip ip
Instruction pointer EIP/RIP.
Definition: fcml_common.h:833
void clean()
Cleans the disassembling result.
Definition: fcml_disassembler.hpp:1917
fcml_bool is_xacquire
FCML_TRUE if xacquire explicit prefix exists.
Definition: fcml_disassembler.h:147
bool isBranch() const
Gets true if branch prefix is available.
Definition: fcml_disassembler.hpp:582
fcml_en_access_mode access_mode
Instruction operand access mode READ, WRITE or both.
Definition: fcml_disassembler.h:193
fcml_en_pseudo_operations getPseudoOp() const
Gets pseudo operation code.
Definition: fcml_disassembler.hpp:1753
void setOperatingMode(EntryPoint::OperatingMode operatingMode)
Sets processor operating mode directly into the entry point.
Definition: fcml_disassembler.hpp:336
fcml_bool is_rep
FCML_TRUE if rep explicit prefix exists.
Definition: fcml_disassembler.h:141
Operand is set by instruction.
Definition: fcml_common.h:548
fcml_int getPrefixesBytesCount() const
Gets number of bytes interpreted to be prefixes.
Definition: fcml_disassembler.hpp:934
void setCodeLength(fcml_usize codeLength)
Sets length of the code buffer in bytes.
Definition: fcml_disassembler.hpp:243
fcml_bool opcode_field_s_bit
Opcode field &#39;s&#39;.
Definition: fcml_disassembler.h:247
fcml_st_instruction instruction
Decoded instruction in its generic form.
Definition: fcml_disassembler.h:274
fcml_uint8_t * getAvxBytes()
Gets the second and third bytes of the XOP/VEX prefix.
Definition: fcml_disassembler.hpp:469
void setAaa(fcml_uint8_t aaa)
Sets &#39;aaa&#39; field of the EVEX prefix.
Definition: fcml_disassembler.hpp:1064
void setAvxFirstByte(fcml_uint8_t avxFirstByte)
Sets a first byte of the XOP/VEX prefix.
Definition: fcml_disassembler.hpp:1024
void setPseudoOp(fcml_en_pseudo_operations pseudoOp)
Sets pseudo operation for the instruction.
Definition: fcml_disassembler.hpp:1763
void setPrefix(fcml_uint8_t prefix)
Sets the prefix byte.
Definition: fcml_disassembler.hpp:429
Nullable< fcml_uint32_t > & getN()
Gets N (see compressed AVX-512 disp8).
Definition: fcml_disassembler.hpp:1420
bool isNobranch() const
Gets true if no-branch prefix is available.
Definition: fcml_disassembler.hpp:622
void setInstructionGroup(fcml_uint64_t instructionGroup)
Sets an instruction group.
Definition: fcml_disassembler.hpp:1571
C++ wrappers common classes.
Disassembler wrapper.
Definition: fcml_disassembler.hpp:2211
fcml_uint8_t vvvv
vvvv field of XOP or VEX prefix.
Definition: fcml_disassembler.h:179
bool isAvx() const
Gets true if any AVX prefix is available.
Definition: fcml_disassembler.hpp:782
bool isRepne() const
Gets true if Repne prefix is available.
Definition: fcml_disassembler.hpp:662
bool isRip() const
Gets true if RIP byte is available.
Definition: fcml_disassembler.hpp:1330
void setIP(fcml_ip ip)
Sets a new instruction pointer for the entry point.
Definition: fcml_common.hpp:651
void setCode(fcml_ptr code)
Sets a new buffer with machine code for the context.
Definition: fcml_disassembler.hpp:223
void incrementIP(fcml_ip ip)
Increments entry point by given number of bytes.
Definition: fcml_disassembler.hpp:326
fcml_uint8_t V_prim
V’ field of EVEX prefix.
Definition: fcml_disassembler.h:185
fcml_bool is_vex
FCML_TRUE if VEX prefix exists.
Definition: fcml_disassembler.h:149
void setCarryFlagConditionalSuffix(bool carryFlagConditionalSuffix)
Definition: fcml_disassembler.hpp:82
void setVPrim(fcml_uint8_t vPrim)
Sets V&#39; flag.
Definition: fcml_disassembler.hpp:1084
fcml_bool is_rip
True if RIP encoding is used by decoded instruction.
Definition: fcml_disassembler.h:214
void setInstructionSize(fcml_usize instructionSize)
Sets the instruction size in bytes.
Definition: fcml_disassembler.hpp:1591
void setEntryPoint(const EntryPoint &entryPoint)
Copies given entry point to the instance associated with the context.
Definition: fcml_disassembler.hpp:305
fcml_en_instruction
Instruction codes.
Definition: fcml_instructions.h:184
fcml_bool is_repne
FCML_TRUE if repne explicit prefix exists.
Definition: fcml_disassembler.h:143
fcml_uint8_t getTupleType() const
Gets avx-512 tuple type.
Definition: fcml_disassembler.hpp:1791
void setRepne(bool isRepne)
Sets Repne prefix availability.
Definition: fcml_disassembler.hpp:672
void setL(fcml_uint8_t L)
Sets L flag.
Definition: fcml_disassembler.hpp:832
void setTupleType(fcml_uint8_t tupleType)
Sets avx-512 tuple type.
Definition: fcml_disassembler.hpp:1801
fcml_st_disassembler_conf configuration
Disassembler configuration.
Definition: fcml_disassembler.h:84
Nullable< fcml_uint8_t > & getModRM()
Gets ModR/M nullable byte.
Definition: fcml_disassembler.hpp:1360
fcml_uint8_t R_prim
EVEX R’ High-16 register specifier modifier.
Definition: fcml_disassembler.h:163
fcml_en_pseudo_operations
Pseudo operations.
Definition: fcml_instructions.h:1539
void setRip(bool isRip)
Sets RIP byte availability.
Definition: fcml_disassembler.hpp:1340
std::basic_string< fcml_char > fcml_cstring
By using this type definition here, it will be definitely much easier to support UNICODE in future re...
Definition: fcml_common.hpp:53
Contains some additional information about all decoded instruction prefixes.
Definition: fcml_disassembler.h:127
bool isXrelease() const
Gets true if xrelease prefix is available.
Definition: fcml_disassembler.hpp:802
fcml_en_pseudo_operations pseudo_op
Pseudo operation code.
Definition: fcml_disassembler.h:256
fcml_uint8_t getAaa() const
Gets &#39;aaa&#39; field of the EVEX prefix.
Definition: fcml_disassembler.hpp:1054
fcml_st_instruction_details instruction_details
Additional disassembler specific information about decoded instruction.
Definition: fcml_disassembler.h:272
fcml_int prefixes_bytes_count
Number of bytes used by all decoded prefixes.
Definition: fcml_disassembler.h:133
bool isShortForms() const
Definition: fcml_disassembler.hpp:137
const Nullable< fcml_uint8_t > & getModRM() const
Gets ModR/M nullable byte.
Definition: fcml_disassembler.hpp:1350
Disassembler context.
Definition: fcml_disassembler.h:80
Converts objects to their structures counterparts.
Definition: fcml_disassembler.hpp:1989
fcml_ptr getCode() const
Gets pointer to the machine code buffer.
Definition: fcml_disassembler.hpp:213
Definition: fcml_types.h:217
void setFailIfUnknownInstruction(bool failIfUnknownInstruction)
Definition: fcml_disassembler.hpp:122
DecodedModRMDetails()
Creates an empty ModR/M details.
Definition: fcml_disassembler.hpp:1320
Disassembler configuration.
Definition: fcml_disassembler.hpp:58
void setShortForms(bool shortForms)
Definition: fcml_disassembler.hpp:142
bool isXacquire() const
Gets true if xacquire prefix is available.
Definition: fcml_disassembler.hpp:742
fcml_en_prefix_types
Available types of instruction prefixes.
Definition: fcml_disassembler.h:97
bool isVex() const
Gets true if Vex prefix is available.
Definition: fcml_disassembler.hpp:702
Additional details about an instruction.
Definition: fcml_disassembler.hpp:1485
fcml_uint64_t instruction_group
Instruction group.
Definition: fcml_disassembler.h:261
fcml_en_access_mode
Operand access mode.
Definition: fcml_common.h:542
fcml_uint8_t avx_bytes[3]
Place for additional bytes of VEX/EVEX/XOP prefix.
Definition: fcml_disassembler.h:120
fcml_uint8_t getR() const
Gets R flag.
Definition: fcml_disassembler.hpp:974
PrefixesDetails & getPrefixesDetails()
Gets instruction prefixes details.
Definition: fcml_disassembler.hpp:1733
#define FCML_TEXT(x)
Used to code literal strings.
Definition: fcml_types.h:61
Dialect & getDialect() const
Gets dialect associated with the disassembler.
Definition: fcml_disassembler.hpp:2313
void setPrefixType(PrefixType prefixType)
Sets a new prefix type.
Definition: fcml_disassembler.hpp:449
fcml_bool is_nobranch
FCML_TRUE if nobranch prefix exists.
Definition: fcml_disassembler.h:137
bool getZ() const
Gets EVEX.z bit.
Definition: fcml_disassembler.hpp:1154
void setB(fcml_uint8_t B)
Sets B flag.
Definition: fcml_disassembler.hpp:572
LIB_EXPORT void LIB_CALL fcml_fn_disassembler_free(fcml_st_disassembler *disassembler)
Frees disassembler instance.
void setR(fcml_uint8_t r)
Sets R flag.
Definition: fcml_disassembler.hpp:984
void setXacquire(bool isXacquire)
Sets xacquire prefix availability.
Definition: fcml_disassembler.hpp:752
void setPrefixesBytesCount(fcml_int prefixesBytesCount)
Sets number of prefixes bytes available for the instruction.
Definition: fcml_disassembler.hpp:944
fcml_bool is_avx
True if it is an AVX instruction (VEX/XOP/EVEX).
Definition: fcml_disassembler.h:155
fcml_usize getInstructionSize() const
Instruction size in bytes.
Definition: fcml_disassembler.hpp:1581
void setModRM(const Nullable< fcml_uint8_t > &modRM)
Sets ModR/M nullable byte.
Definition: fcml_disassembler.hpp:1370
fcml_en_instruction instruction
Instruction code/number.
Definition: fcml_disassembler.h:254
fcml_bool is_modrm
True if ModR/M exists.
Definition: fcml_disassembler.h:216
bool isLock() const
Gets true if lock prefix is available.
Definition: fcml_disassembler.hpp:602
Holds instruction pointer, processor operating mode and memory segment flags.
Definition: fcml_common.hpp:524
fcml_int prefixes_count
Number of decoded prefixes.
Definition: fcml_disassembler.h:131
PrefixType getPrefixType() const
Gets the prefix type.
Definition: fcml_disassembler.hpp:439
fcml_bool is_pseudo_op
True if given instruction is a short form of pseudo-ops instructions.
Definition: fcml_disassembler.h:232
Base class for all exceptions that are aware of ErrorContainer.
Definition: fcml_errors.hpp:347
fcml_bool is_xop
FCML_TRUE if XOP prefix exists.
Definition: fcml_disassembler.h:153
void setMmmm(fcml_uint8_t mmmm)
Sets MMMM field.
Definition: fcml_disassembler.hpp:872
Disassembler configuration.
Definition: fcml_disassembler.h:53
bool isEvex() const
Gets true if EVEX prefix is available.
Definition: fcml_disassembler.hpp:732
void setOpcodeFieldSBit(bool opcodeFieldSBit)
Sets &#39;S&#39; field of the opcode byte.
Definition: fcml_disassembler.hpp:1661
fcml_bool is_evex
FCML TRUE if EVEX prefix exists.
Definition: fcml_disassembler.h:151
const OperandDetails & getOperandDetails(fcml_usize index) const
Gets the operand details for given index.
Definition: fcml_disassembler.hpp:1693
void setInstructionDetails(const InstructionDetails &instructionDetails)
Sets new instruction details for the disassembler.
Definition: fcml_disassembler.hpp:1942
Instruction prefix.
Definition: fcml_disassembler.hpp:374
fcml_ptr code
Pointer to the encoded instruction.
Definition: fcml_disassembler.h:88
fcml_bool increment_ip
Set to true in order to make disassembler to increment IP address by length of the disassembled instr...
Definition: fcml_disassembler.h:56
void setOperandSizeAttribute(fcml_usize operandSizeAttribute)
Sets a new operand size attribute for the entry point.
Definition: fcml_disassembler.hpp:356
Integer & getDisplacement()
Gets raw displacement.
Definition: fcml_disassembler.hpp:1450
bool isCarryFlagConditionalSuffix() const
Definition: fcml_disassembler.hpp:77
AccessMode getAccessMode() const
Gets access mode for the operand.
Definition: fcml_disassembler.hpp:1291
Some basic information about decoded ModR/M and SIB bytes.
Definition: fcml_disassembler.h:207
Definition: fcml_assembler.hpp:39
void setModRmDetails(const DecodedModRMDetails &modRmDetails)
Sets a new instruction details for the instruction.
Definition: fcml_disassembler.hpp:1641
void setIncrementIp(bool incrementIp)
Definition: fcml_disassembler.hpp:132
bool getBcast() const
Gets EVEX.b bit.
Definition: fcml_disassembler.hpp:1134
virtual ~Disassembler()
Destructor.
Definition: fcml_disassembler.hpp:2235
void setVvvv(fcml_uint8_t vvvv)
Sets VVVV field of the XOP/VEX prefix.
Definition: fcml_disassembler.hpp:1044
fcml_uint8_t getPp() const
Gets PP field.
Definition: fcml_disassembler.hpp:882
#define FCML_OPERANDS_COUNT
Maximal number of the instruction operands.
Definition: fcml_common.h:35
fcml_bool enable_error_messages
True if optional error and warning messages should be collected during processing.
Definition: fcml_disassembler.h:59
fcml_uint8_t instruction_code[FCML_INSTRUCTION_SIZE]
Code of the disassembled instruction.
Definition: fcml_disassembler.h:234
void setN(const Nullable< fcml_uint32_t > &N)
Sets N (see compressed AVX-512 disp8).
Definition: fcml_disassembler.hpp:1430
const Nullable< fcml_uint32_t > & getN() const
Gets constant N (see AVX-512 compressed disp8).
Definition: fcml_disassembler.hpp:1410
DisassemblerContext(fcml_ptr code, fcml_usize codeLength)
Creates disassembler context for given piece of machine code.
Definition: fcml_disassembler.hpp:201
fcml_uint8_t getConditionalGroup() const
Definition: fcml_disassembler.hpp:87
void setBranch(bool isBranch)
Sets branch prefix availability.
Definition: fcml_disassembler.hpp:592
Some additional disassembler specific information about decoded operands.
Definition: fcml_disassembler.h:191
Component can not be initialized correctly.
Definition: fcml_disassembler.hpp:44
Inherit from this class in order to get access to the native FCML dialect structure.
Definition: fcml_dialect.hpp:98
bool isRep() const
Gets true if Rep prefix is available.
Definition: fcml_disassembler.hpp:642
EntryPoint & getEntryPoint()
Gets reference to the entry point instance associated with the context.
Definition: fcml_disassembler.hpp:294
fcml_uint64_t getInstructionGroup() const
Gets instruction group.
Definition: fcml_disassembler.hpp:1560
Used mainly in case of integers and offsets.
Definition: fcml_errors.h:55
const InstructionPrefixDetails & getPrefixes(fcml_usize index) const
Gets a reference to the prefix of the given index.
Definition: fcml_disassembler.hpp:904
fcml_uint8_t getVPrim() const
Gets V&#39; flag.
Definition: fcml_disassembler.hpp:1074
const DecodedModRMDetails & getModRmDetails() const
Gets ModR/M instruction details.
Definition: fcml_disassembler.hpp:1621
DisassemblerConf & getDisassemblerConf()
Gets a reference to the configuration object associated with the context.
Definition: fcml_disassembler.hpp:263
fcml_uint8_t L
L field of XOP or VEX prefix.
Definition: fcml_disassembler.h:173
Represents integer value.
Definition: fcml_common.hpp:700
void setEvex(bool isEvex)
Sets EVEX prefix availability.
Definition: fcml_disassembler.hpp:722
fcml_uint8_t tuple_type
avx-512 tuple type
Definition: fcml_disassembler.h:263
bool isShortcut() const
Gets true if it&#39;s a shortcut instruction.
Definition: fcml_disassembler.hpp:1601
Structures and functions declarations related to FCML disassembler.
void setXrelease(bool isXrelease)
Sets xrelease prefix availability.
Definition: fcml_disassembler.hpp:812
fcml_bool extend_disp_to_asa
True if displacement should be sign extended to effective address size; otherwise false...
Definition: fcml_disassembler.h:72
void setEnableErrorMessages(bool enableErrorMessages)
Definition: fcml_disassembler.hpp:102
fcml_uint8_t getLPrim() const
Gets L&#39; flag.
Definition: fcml_disassembler.hpp:842
fcml_uint8_t B
B field of REX,XOP or VEX prefix.
Definition: fcml_disassembler.h:167
fcml_st_decoded_modrm_details modrm_details
Details about decoded ModR/M and SIB bytes.
Definition: fcml_disassembler.h:242
bool isMandatoryPrefix() const
Returns true if it&#39;s a mandatory prefix.
Definition: fcml_disassembler.hpp:398
const EntryPoint & getEntryPoint() const
Gets reference to the constant entry point instance associated with the context.
Definition: fcml_disassembler.hpp:284
void setLock(bool isLock)
Sets lock prefix availability.
Definition: fcml_disassembler.hpp:612
ModRM details.
Definition: fcml_disassembler.hpp:1313
Disassembler(Dialect &dialect)
Creates a disassembler instance for the given dialect.
Definition: fcml_disassembler.hpp:2221
Instruction & getInstructionInternal()
Gets mutable instruction.
Definition: fcml_disassembler.hpp:1951
fcml_uint8_t prefix
Prefix itself as raw byte.
Definition: fcml_disassembler.h:112
OperandDetails()
Creates default operand details with an undefined access mode.
Definition: fcml_disassembler.hpp:1271
const fcml_uint8_t * getAvxBytes() const
Gets the second and third bytes of the XOP/VEX prefix.
Definition: fcml_disassembler.hpp:459
fcml_bool fail_if_unknown_instruction
If set to true assembler will return FCML_CEH_GEC_UNKNOWN_INSTRUCTION error code if instruction is no...
Definition: fcml_disassembler.h:76
fcml_bool short_forms
Set to true in order to use short forms.
Definition: fcml_disassembler.h:69
fcml_int64_t fcml_ip
General instruction pointer holder.
Definition: fcml_common.h:96
void setAddrMode(fcml_uint16_t addrMode)
Sets instruction form.
Definition: fcml_disassembler.hpp:1507
bool isThrowExceptionOnError() const
Returns true if exception should be thrown when disassembling fails.
Definition: fcml_disassembler.hpp:153
fcml_uint8_t getVvvv() const
Gets VVVV field of the XOP/VEX prefix.
Definition: fcml_disassembler.hpp:1034
OperandDetails & getOperandDetails(fcml_usize index)
Gets the operand details for given index.
Definition: fcml_disassembler.hpp:1709
void setDisplacement(const Integer &displacement)
Sets displacement.
Definition: fcml_disassembler.hpp:1460
fcml_uint8_t W
W field of REX,XOP or VEX/EVEX prefix.
Definition: fcml_disassembler.h:171
fcml_en_prefix_types prefix_type
Type of the prefix.
Definition: fcml_disassembler.h:114
bool isEnableErrorMessages() const
Definition: fcml_disassembler.hpp:97
PrefixType
Type of the instruction prefix.
Definition: fcml_disassembler.hpp:380
Reusable disassembler result holder.
Definition: fcml_disassembler.h:267
C++ wrapper for the base dialect.
fcml_uint8_t X
X field of REX,XOP or VEX prefix.
Definition: fcml_disassembler.h:165
DisassemblerConf()
Default constructor.
Definition: fcml_disassembler.hpp:65
Operand is read by instruction.
Definition: fcml_common.h:546
void setDisassemblerConf(DisassemblerConf disassemblerConf)
Sets a new disassembler configuration for the context.
Definition: fcml_disassembler.hpp:273
fcml_st_entry_point entry_point
Instruction entry point configuration.
Definition: fcml_disassembler.h:86
void setAddressSizeAttribute(fcml_usize addressSizeAttribute)
Sets a new address size attribute for the entry point.
Definition: fcml_disassembler.hpp:346
fcml_st_integer displacement
Displacement as encoded in disp8/disp16/disp32/disp8*N.
Definition: fcml_disassembler.h:201
LIB_EXPORT void LIB_CALL fcml_fn_disassembler_result_free(fcml_st_disassembler_result *result)
Cleans result holder.
Describes one decoded prefix.
Definition: fcml_disassembler.h:110
const fcml_uint8_t * getInstructionCode() const
Gets a pointer to the instruction code.
Definition: fcml_disassembler.hpp:1538
fcml_ceh_error disassemble(DisassemblerContext &ctx, DisassemblerResult &disassemblerResult)
Disassembled the next instruction from the context.
Definition: fcml_disassembler.hpp:2253
OperatingMode
Supported operating modes.
Definition: fcml_common.hpp:531
void setNobranch(bool isNobranch)
Sets no-branch prefix availability.
Definition: fcml_disassembler.hpp:632
void setRPrim(fcml_uint8_t rPrim)
Sets R&#39; flag.
Definition: fcml_disassembler.hpp:1004
bool isXop() const
Gets true if XOP prefix is available.
Definition: fcml_disassembler.hpp:762
bool isPseudoOp() const
Gets true is it&#39;s a pseudo operation.
Definition: fcml_disassembler.hpp:1773
fcml_bool mandatory_prefix
FCML_TRUE if prefix is treated as mandatory one.
Definition: fcml_disassembler.h:116
LIB_EXPORT void LIB_CALL fcml_fn_disassembler_result_prepare(fcml_st_disassembler_result *result)
Prepares reusable result holder for disassembler.
void setPrefixesDetails(const PrefixesDetails &prefixesDetails)
Sets a new instruction prefixes details.
Definition: fcml_disassembler.hpp:1743
fcml_uint8_t R
R field of REX,XOP or VEX prefix.
Definition: fcml_disassembler.h:161
fcml_bool is_branch
FCML_TRUE if branch prefix exists.
Definition: fcml_disassembler.h:135
const Instruction & getInstruction() const
Gets errors container with errors related to the failed disassembling process.
Definition: fcml_disassembler.hpp:1899
fcml_bool is_rex
FCML_TRUE if REX prefix exists.
Definition: fcml_disassembler.h:157
fcml_uint8_t L_prim
L’ field of EVEX prefix.
Definition: fcml_disassembler.h:175
Prefixes details.
Definition: fcml_disassembler.hpp:489
fcml_st_raw_displacement displacement
Raw displacement.
Definition: fcml_disassembler.h:218
Disassembler result.
Definition: fcml_disassembler.hpp:1877
fcml_uint8_t getB() const
Gets b flag.
Definition: fcml_disassembler.hpp:562
const PrefixesDetails & getPrefixesDetails() const
Gets instruction prefixes details.
Definition: fcml_disassembler.hpp:1723
fcml_uint16_t getAddrMode() const
Gets address mode/instruction form.
Definition: fcml_disassembler.hpp:1497
fcml_uint16_t addr_mode
Code of the instruction form/addressing mode of the instruction above.
Definition: fcml_disassembler.h:259
bool isOpcodeFieldSBit() const
Gets opcode field &#39;S&#39;.
Definition: fcml_disassembler.hpp:1651
Undefined mode.
Definition: fcml_common.h:544
fcml_uint8_t getW() const
Gets W flag.
Definition: fcml_disassembler.hpp:1094
fcml_uint8_t conditional_group
There are two groups of suffixes for conditional instructions, you can choose which one should be use...
Definition: fcml_disassembler.h:64
fcml_st_prefixes_details prefixes_details
Some additional information about decoded instruction prefixes.
Definition: fcml_disassembler.h:238
Wraps multiple errors into one component.
Definition: fcml_errors.hpp:148
const InstructionDetails & getInstructionDetails() const
Gets instruction details associated with the instruction.
Definition: fcml_disassembler.hpp:1909
fcml_bool is_shortcut
True if this is a shortcut.
Definition: fcml_disassembler.h:229
fcml_st_disassembler * disassembler
Disassembler used to decode instructions.
Definition: fcml_disassembler.h:82
InstructionPrefixDetails & getPrefixes(fcml_usize index)
Gets a reference to the prefix of the given index.
Definition: fcml_disassembler.hpp:920
void setShortcut(bool isShortcut)
Marks the instruction as a shortcut.
Definition: fcml_disassembler.hpp:1611
void setRex(bool isRex)
Sets REX prefix availability.
Definition: fcml_disassembler.hpp:692
AccessMode
Definition: fcml_disassembler.hpp:1256
Describes an instruction.
Definition: fcml_common.hpp:7185
void setInstruction(const Instruction &instruction)
Sets a new instruction for the result.
Definition: fcml_disassembler.hpp:1960
InstructionDetails & getInstructionDetailsInternal()
Gets mutable instruction details.
Definition: fcml_disassembler.hpp:1933
#define FCML_INSTRUCTION_SIZE
Maximal number of bytes instruction can use.
Definition: fcml_common.h:37
fcml_usize code_length
Size of the code in the buffer above.
Definition: fcml_disassembler.h:90
void setExtendDispToAsa(bool extendDispToAsa)
Definition: fcml_disassembler.hpp:112
#define FCML_DASM_PREFIXES_COUNT
Maximal number of instruction prefixes.
Definition: fcml_disassembler.h:42
bool isRex() const
Gets true if Rex prefix is available.
Definition: fcml_disassembler.hpp:682
void setXop(bool isXop)
Sets XOP prefix availability.
Definition: fcml_disassembler.hpp:772
fcml_bool opcode_field_w_bit
Opcode field &#39;w&#39;.
Definition: fcml_disassembler.h:252
Operation succeed.
Definition: fcml_errors.h:42
fcml_usize getCodeLength() const
Gets length of the buffer in bytes.
Definition: fcml_disassembler.hpp:233
void setErrorContainer(const ErrorContainer &errorContainer)
Sets error container.
Definition: fcml_disassembler.hpp:1969
bool isExtendDispToAsa() const
Definition: fcml_disassembler.hpp:107
const Nullable< fcml_uint8_t > & getSib() const
Gets SIB nullable byte.
Definition: fcml_disassembler.hpp:1380
void setPp(fcml_uint8_t pp)
Sets PP field.
Definition: fcml_disassembler.hpp:892
fcml_uint8_t modrm
ModR/M byte if exists.
Definition: fcml_disassembler.h:209
void setSib(const Nullable< fcml_uint8_t > &sib)
Sets SIB nullable byte.
Definition: fcml_disassembler.hpp:1400
fcml_st_ceh_error_container errors
All errors and warnings messages going here.
Definition: fcml_disassembler.h:269
Bad arguments.
Definition: fcml_common.hpp:242
Disassembler context.
Definition: fcml_disassembler.hpp:183
void setThrowExceptionOnError(bool throwExceptionOnError)
Sets the way how the error handling is done.
Definition: fcml_disassembler.hpp:164
fcml_nuint8_t sib
SIB byte if exists.
Definition: fcml_disassembler.h:211
void setBcast(bool b)
Sets EVEX.b bit.
Definition: fcml_disassembler.hpp:1144
OperandDetails(AccessMode accessMode)
Creates operand details for given access mode.
Definition: fcml_disassembler.hpp:1281
fcml_uint8_t getPrefix() const
Gets the prefix byte.
Definition: fcml_disassembler.hpp:419
fcml_bool carry_flag_conditional_suffix
True if suffixes for carry flag has to be used by disassembler.
Definition: fcml_disassembler.h:61
An abstract dialect.
Definition: fcml_dialect.hpp:41
void setOpcodeFieldWBit(bool opcodeFieldWBit)
Sets &#39;W&#39; field of the opcode byte.
Definition: fcml_disassembler.hpp:1681
fcml_uint8_t * getInstructionCode()
Gets a pointer to the instruction code.
Definition: fcml_disassembler.hpp:1549
void setConditionalGroup(fcml_uint8_t conditionalGroup)
Definition: fcml_disassembler.hpp:92
fcml_en_instruction getInstruction() const
Gets instruction code.
Definition: fcml_disassembler.hpp:1517
fcml_uint8_t getX() const
Gets X flag.
Definition: fcml_disassembler.hpp:1114
Operand details.
Definition: fcml_disassembler.hpp:1252
void setVex(bool isVex)
Sets VEX prefix availability.
Definition: fcml_disassembler.hpp:712
fcml_bool is_xrelease
FCML_TRUE if xrelease explicit prefix exists.
Definition: fcml_disassembler.h:145
void setIP(fcml_ip ip)
Sets instruction pointer directly into the entry point.
Definition: fcml_disassembler.hpp:315
bool isIncrementIp() const
Definition: fcml_disassembler.hpp:127
fcml_usize instruction_size
Instruction size in bytes.
Definition: fcml_disassembler.h:236
fcml_uint8_t getAvxFirstByte() const
Gets the first byte of the AVX prefix.
Definition: fcml_disassembler.hpp:1014
fcml_uint8_t aaa
Embedded opmask register specifier.
Definition: fcml_disassembler.h:187
const DisassemblerConf & getDisassemblerConf() const
Gets a reference to the configuration object associated with the context.
Definition: fcml_disassembler.hpp:253
bool isFailIfUnknownInstruction() const
Definition: fcml_disassembler.hpp:117
fcml_int getPrefixesCount() const
Gets number of prefixes available for the instruction.
Definition: fcml_disassembler.hpp:954
fcml_uint8_t avx_first_byte
First byte of AVX prefix.
Definition: fcml_disassembler.h:159
fcml_bool is_lock
FCML_TRUE if lock explicit prefix exists.
Definition: fcml_disassembler.h:139
void setInstruction(fcml_en_instruction instruction)
Gets a new instruction code for the instruction.
Definition: fcml_disassembler.hpp:1527
bool isOpcodeFieldWBit() const
Gets opcode field &#39;W&#39;.
Definition: fcml_disassembler.hpp:1671
InstructionPrefixDetails & operator[](fcml_usize index)
Gets reference to the instruction prefix at given index.
Definition: fcml_disassembler.hpp:549
void setRep(bool isRep)
Sets Rep prefix availability.
Definition: fcml_disassembler.hpp:652
ErrorContainerAwareException(const fcml_cstring &msg, const ErrorContainer &errorContainer, fcml_ceh_error error=FCML_CEH_GEC_NO_ERROR)
Creates an error container aware exception instance and sets basic information for it...
Definition: fcml_errors.hpp:357
fcml_uint8_t b
b field of EVEX prefix.
Definition: fcml_disassembler.h:169
Component can not be initialized correctly.
Definition: fcml_common.hpp:231
struct fcml_st_disassembler fcml_st_disassembler
This structure and type declaration represents an abstract disassembler.
Definition: fcml_disassembler.h:50
LIB_EXPORT fcml_ceh_error LIB_CALL fcml_fn_disassembler_init(const fcml_st_dialect *dialect, fcml_st_disassembler **disassembler)
Initializes disassembler instance.
void setW(fcml_uint8_t W)
Sets W flag.
Definition: fcml_disassembler.hpp:1104
Additional instruction details provided by disassembler.
Definition: fcml_disassembler.h:222
Nullable< fcml_uint8_t > & getSib()
Gets SIB nullable byte.
Definition: fcml_disassembler.hpp:1390
fcml_uint16_t fcml_ceh_error
All error codes should be held in variables of this type.
Definition: fcml_errors.h:156
fcml_uint8_t getL() const
Gets L flag.
Definition: fcml_disassembler.hpp:822
void setMandatoryPrefix(bool mandatoryPrefix)
Sets mandatory prefix flag for the prefix.
Definition: fcml_disassembler.hpp:409
Object which shouldn&#39;t be copied can inherit from this class.
Definition: fcml_common.hpp:288
const Integer & getDisplacement() const
Gets constant raw displacement.
Definition: fcml_disassembler.hpp:1440
void setX(fcml_uint8_t X)
Sets X flag.
Definition: fcml_disassembler.hpp:1124
fcml_uint8_t getMmmm() const
Gets MMMM field.
Definition: fcml_disassembler.hpp:862
C++ wrapper for the FCML errors handling.
fcml_uint8_t z
z field of EVEX prefix
Definition: fcml_disassembler.h:183
Illegal argument exception.
Definition: fcml_common.hpp:264
void setPrefixesCount(fcml_int prefixesCount)
Sets number of prefixes available for the instruction.
Definition: fcml_disassembler.hpp:964
LIB_EXPORT fcml_ceh_error LIB_CALL fcml_fn_disassemble(fcml_st_disassembler_context *context, fcml_st_disassembler_result *result)
Disassembles one instruction from provided code buffer.
void setAvx(bool isAvx)
Sets XOP prefix availability.
Definition: fcml_disassembler.hpp:792
PrefixesDetails()
Default constructor.
Definition: fcml_disassembler.hpp:496
void setZ(bool z)
Sets EVEX.z bit.
Definition: fcml_disassembler.hpp:1164
fcml_nuint32_t N
Scaling factor N in EVEX specific compressed disp8*N.
Definition: fcml_disassembler.h:203
fcml_uint8_t getRPrim() const
Gets R&#39; flag.
Definition: fcml_disassembler.hpp:994
fcml_st_operand_details operand_details[FCML_OPERANDS_COUNT]
All disassembler specific information about operands going there.
Definition: fcml_disassembler.h:240
const ErrorContainer & getErrorContainer() const
Gets errors container with errors related to the failed disassembling process.
Definition: fcml_disassembler.hpp:1888
fcml_uint8_t pp
pp field of XOP or VEX/EVEX prefix.
Definition: fcml_disassembler.h:181
fcml_st_instruction_prefix prefixes[FCML_DASM_PREFIXES_COUNT]
Array with decoded prefixes.
Definition: fcml_disassembler.h:129
const InstructionPrefixDetails & operator[](fcml_usize index) const
Gets reference to the instruction prefix at given index.
Definition: fcml_disassembler.hpp:535