11 #include "llvm-c/Disassembler.h"
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/ADT/StringExtras.h"
14 #include "llvm/MC/MCAsmInfo.h"
15 #include "llvm/MC/MCContext.h"
16 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
17 #include "llvm/MC/MCDisassembler/MCExternalSymbolizer.h"
18 #include "llvm/MC/MCDisassembler/MCRelocationInfo.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCInstPrinter.h"
21 #include "llvm/MC/MCInstrInfo.h"
22 #include "llvm/MC/MCRegisterInfo.h"
23 #include "llvm/MC/MCSubtargetInfo.h"
24 #include "llvm/MC/MCTargetOptions.h"
25 #include "llvm/MC/TargetRegistry.h"
26 #include "llvm/Support/AArch64TargetParser.h"
27 #include "llvm/Support/ErrorHandling.h"
28 #include "llvm/Support/ScopedPrinter.h"
29 #include "llvm/Support/TargetSelect.h"
53 static std::unique_ptr<MCDisasmInstance>
54 Create(
const char *triple,
const char *cpu,
const char *features_str,
59 uint64_t GetMCInst(
const uint8_t *opcode_data,
size_t opcode_data_len,
61 void PrintMCInst(llvm::MCInst &mc_inst,
std::string &inst_string,
64 bool CanBranch(llvm::MCInst &mc_inst)
const;
65 bool HasDelaySlot(llvm::MCInst &mc_inst)
const;
66 bool IsCall(llvm::MCInst &mc_inst)
const;
67 bool IsLoad(llvm::MCInst &mc_inst)
const;
68 bool IsAuthenticated(llvm::MCInst &mc_inst)
const;
72 std::unique_ptr<llvm::MCRegisterInfo> &®_info_up,
73 std::unique_ptr<llvm::MCSubtargetInfo> &&subtarget_info_up,
74 std::unique_ptr<llvm::MCAsmInfo> &&asm_info_up,
75 std::unique_ptr<llvm::MCContext> &&context_up,
76 std::unique_ptr<llvm::MCDisassembler> &&disasm_up,
77 std::unique_ptr<llvm::MCInstPrinter> &&instr_printer_up);
126 uint8_t opcode_len = opcode_and_modrm.
opcode_len;
127 uint8_t modrm = opcode_and_modrm.
modrm;
132 if (opcode >= 0x70 && opcode <= 0x7F) {
139 if (opcode >= 0x80 && opcode <= 0x8F) {
152 if (opcode_len == 1) {
153 uint8_t modrm_reg = (modrm >> 3) & 7;
156 else if (modrm_reg == 3)
158 else if (modrm_reg == 4)
160 else if (modrm_reg == 5)
216 if (opcode_len == 2) {
256 llvm::Optional<InstructionOpcodeAndModrm>
258 bool is_exec_mode_64b) {
260 bool prefix_done =
false;
267 while (!prefix_done) {
268 if (op_idx >= bytes_len)
307 if (is_exec_mode_64b)
315 if (!is_exec_mode_64b && (inst_bytes[op_idx + 1] & 0xc0) != 0xc0) {
322 ret.
modrm = inst_bytes[op_idx + 3];
326 if (!is_exec_mode_64b && (inst_bytes[op_idx + 1] & 0xc0) != 0xc0) {
330 ret.
opcode_len = inst_bytes[op_idx + 1] & 0x1f;
332 ret.
modrm = inst_bytes[op_idx + 4];
337 if (!is_exec_mode_64b && (inst_bytes[op_idx + 1] & 0xc0) != 0xc0) {
341 ret.
opcode_len = inst_bytes[op_idx + 1] & 0x03;
343 ret.
modrm = inst_bytes[op_idx + 5];
353 ret.
modrm = inst_bytes[op_idx + 1];
363 ret.
modrm = inst_bytes[op_idx + 1];
367 ret.
modrm = inst_bytes[op_idx + 1];
371 ret.
modrm = inst_bytes[op_idx + 1];
375 ret.
modrm = inst_bytes[op_idx + 1];
378 ret.
modrm = inst_bytes[op_idx + 1];
387 llvm::Optional<InstructionOpcodeAndModrm> ret = llvm::None;
413 disasm.shared_from_this())) {}
419 return m_does_branch;
424 return m_has_delay_slot;
434 return m_is_authenticated;
439 return GetDisasmToUse(is_alternate_isa, disasm);
450 const ArchSpec &arch = disasm->GetArchitecture();
455 if (min_op_byte_size == max_op_byte_size) {
460 switch (min_op_byte_size) {
462 m_opcode.SetOpcode8(data.
GetU8(&data_offset), byte_order);
467 m_opcode.SetOpcode16(data.
GetU16(&data_offset), byte_order);
472 m_opcode.SetOpcode32(data.
GetU32(&data_offset), byte_order);
477 m_opcode.SetOpcode64(data.
GetU64(&data_offset), byte_order);
482 m_opcode.SetOpcodeBytes(data.
PeekData(data_offset, min_op_byte_size),
489 bool is_alternate_isa =
false;
491 GetDisasmToUse(is_alternate_isa, disasm);
493 const llvm::Triple::ArchType machine = arch.
GetMachine();
494 if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb) {
495 if (machine == llvm::Triple::thumb || is_alternate_isa) {
497 if ((thumb_opcode & 0xe000) != 0xe000 ||
498 ((thumb_opcode & 0x1800u) == 0)) {
499 m_opcode.SetOpcode16(thumb_opcode, byte_order);
503 thumb_opcode |= data.
GetU16(&data_offset);
504 m_opcode.SetOpcode16_2(thumb_opcode, byte_order);
508 m_opcode.SetOpcode32(data.
GetU32(&data_offset), byte_order);
514 uint8_t *opcode_data =
515 const_cast<uint8_t *
>(data.
PeekData(data_offset, 1));
516 const size_t opcode_data_len = data.
BytesLeft(data_offset);
517 const addr_t pc = m_address.GetFileAddress();
520 const size_t inst_size =
521 mc_disasm_ptr->
GetMCInst(opcode_data, opcode_data_len,
pc, inst);
525 m_opcode.SetOpcodeBytes(opcode_data, inst_size);
530 return m_opcode.GetByteSize();
536 if (m_comment.empty())
537 m_comment.swap(description);
539 m_comment.append(
", ");
540 m_comment.append(description);
548 if (disasm->GetArchitecture().GetMachine() == llvm::Triple::x86)
550 else if (disasm->GetArchitecture().GetMachine() == llvm::Triple::x86_64)
562 if (m_opcode.GetData(data)) {
570 if (address_class == AddressClass::eCodeAlternateISA)
571 mc_disasm_ptr = disasm->m_alternate_disasm_up.get();
573 mc_disasm_ptr = disasm->m_disasm_up.get();
576 m_using_file_addr =
true;
578 const bool data_from_file = disasm->m_data_from_file;
579 bool use_hex_immediates =
true;
588 if (!data_from_file) {
589 const lldb::addr_t load_addr = m_address.GetLoadAddress(target);
592 m_using_file_addr =
false;
602 mc_disasm_ptr->
GetMCInst(opcode_data, opcode_data_len,
pc, inst);
605 mc_disasm_ptr->
SetStyle(use_hex_immediates, hex_style);
606 mc_disasm_ptr->
PrintMCInst(inst, out_string, comment_string);
608 if (!comment_string.empty()) {
609 AppendComment(comment_string);
613 if (inst_size == 0) {
614 m_comment.assign(
"unknown opcode");
615 inst_size = m_opcode.GetByteSize();
621 const uint8_t uval8 = data.
GetU8(&offset);
622 m_opcode.SetOpcode8(uval8, byte_order);
623 m_opcode_name.assign(
".byte");
624 mnemonic_strm.
Printf(
"0x%2.2x", uval8);
628 m_opcode.SetOpcode16(uval16, byte_order);
629 m_opcode_name.assign(
".short");
630 mnemonic_strm.
Printf(
"0x%4.4x", uval16);
634 m_opcode.SetOpcode32(uval32, byte_order);
635 m_opcode_name.assign(
".long");
636 mnemonic_strm.
Printf(
"0x%8.8x", uval32);
639 const uint64_t uval64 = data.
GetU64(&offset);
640 m_opcode.SetOpcode64(uval64, byte_order);
641 m_opcode_name.assign(
".quad");
642 mnemonic_strm.
Printf(
"0x%16.16" PRIx64, uval64);
648 const uint8_t *bytes = data.
PeekData(offset, inst_size);
649 if (bytes ==
nullptr)
651 m_opcode_name.assign(
".byte");
652 m_opcode.SetOpcodeBytes(bytes, inst_size);
653 mnemonic_strm.
Printf(
"0x%2.2x", bytes[0]);
654 for (
uint32_t i = 1; i < inst_size; ++i)
655 mnemonic_strm.
Printf(
" 0x%2.2x", bytes[i]);
664 llvm::StringRef(
"[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?"));
666 llvm::SmallVector<llvm::StringRef, 4> matches;
667 if (s_regex.
Execute(out_string, &matches)) {
668 m_opcode_name = matches[1].str();
669 m_mnemonics = matches[2].str();
689 : m_disasm(i.m_disasm_wp.lock()) {
690 m_disasm->m_mutex.lock();
691 m_disasm->m_inst = &i;
692 m_disasm->m_exe_ctx = exe_ctx;
697 operator bool()
const {
return static_cast<bool>(m_disasm); }
699 std::shared_ptr<DisassemblerLLVMC>
operator->() {
return m_disasm; }
702 static llvm::StringRef::const_iterator
704 llvm::StringRef::const_iterator ose) {
719 static std::pair<bool, llvm::StringRef::const_iterator>
721 llvm::StringRef::const_iterator ose) {
724 osi = ConsumeWhitespace(osi, ose);
725 if (osi != ose && *osi == c) {
730 return std::make_pair(found, osi);
733 static std::pair<Operand, llvm::StringRef::const_iterator>
735 llvm::StringRef::const_iterator ose) {
737 ret.
m_type = Operand::Type::Register;
740 osi = ConsumeWhitespace(osi, ose);
743 if (*osi >=
'0' && *osi <=
'9') {
745 return std::make_pair(
Operand(), osi);
749 }
else if (*osi >=
'a' && *osi <=
'z') {
755 return std::make_pair(
Operand(), osi);
758 return std::make_pair(ret, osi);
762 return std::make_pair(
Operand(), osi);
771 return std::make_pair(ret, osi);
774 static std::pair<Operand, llvm::StringRef::const_iterator>
776 llvm::StringRef::const_iterator ose) {
778 ret.
m_type = Operand::Type::Immediate;
782 osi = ConsumeWhitespace(osi, ose);
785 if (*osi >=
'0' && *osi <=
'9') {
787 }
else if (*osi >=
'a' && *osi <=
'f') {
791 return std::make_pair(
Operand(), osi);
797 return std::make_pair(
Operand(), osi);
799 ret.
m_immediate = strtoull(str.c_str(),
nullptr, 0);
800 return std::make_pair(ret, osi);
803 if (!str.compare(
"0")) {
807 return std::make_pair(
Operand(), osi);
813 return std::make_pair(
Operand(), osi);
820 return std::make_pair(
Operand(), osi);
827 ret.
m_immediate = strtoull(str.c_str(),
nullptr, 0);
828 return std::make_pair(ret, osi);
832 static std::pair<Operand, llvm::StringRef::const_iterator>
834 llvm::StringRef::const_iterator ose) {
835 std::pair<Operand, llvm::StringRef::const_iterator> offset_and_iterator =
836 ParseImmediate(osi, ose);
837 if (offset_and_iterator.first.IsValid()) {
838 osi = offset_and_iterator.second;
842 std::tie(found, osi) = ConsumeChar(osi,
'(', ose);
844 return std::make_pair(
Operand(), osi);
847 std::pair<Operand, llvm::StringRef::const_iterator> base_and_iterator =
848 ParseRegisterName(osi, ose);
849 if (base_and_iterator.first.IsValid()) {
850 osi = base_and_iterator.second;
852 return std::make_pair(
Operand(), osi);
855 std::tie(found, osi) = ConsumeChar(osi,
',', ose);
857 return std::make_pair(
Operand(), osi);
860 std::pair<Operand, llvm::StringRef::const_iterator> index_and_iterator =
861 ParseRegisterName(osi, ose);
862 if (index_and_iterator.first.IsValid()) {
863 osi = index_and_iterator.second;
865 return std::make_pair(
Operand(), osi);
868 std::tie(found, osi) = ConsumeChar(osi,
',', ose);
870 return std::make_pair(
Operand(), osi);
873 std::pair<Operand, llvm::StringRef::const_iterator>
874 multiplier_and_iterator = ParseImmediate(osi, ose);
875 if (index_and_iterator.first.IsValid()) {
876 osi = index_and_iterator.second;
878 return std::make_pair(
Operand(), osi);
881 std::tie(found, osi) = ConsumeChar(osi,
')', ose);
883 return std::make_pair(
Operand(), osi);
887 product.
m_type = Operand::Type::Product;
888 product.
m_children.push_back(index_and_iterator.first);
889 product.
m_children.push_back(multiplier_and_iterator.first);
892 index.
m_type = Operand::Type::Sum;
893 index.
m_children.push_back(base_and_iterator.first);
896 if (offset_and_iterator.first.IsValid()) {
898 offset.
m_type = Operand::Type::Sum;
899 offset.
m_children.push_back(offset_and_iterator.first);
903 deref.
m_type = Operand::Type::Dereference;
905 return std::make_pair(deref, osi);
908 deref.
m_type = Operand::Type::Dereference;
910 return std::make_pair(deref, osi);
915 static std::pair<Operand, llvm::StringRef::const_iterator>
917 llvm::StringRef::const_iterator ose) {
918 std::pair<Operand, llvm::StringRef::const_iterator> offset_and_iterator =
919 ParseImmediate(osi, ose);
920 if (offset_and_iterator.first.IsValid()) {
921 osi = offset_and_iterator.second;
925 std::tie(found, osi) = ConsumeChar(osi,
'(', ose);
927 return std::make_pair(
Operand(), osi);
930 std::pair<Operand, llvm::StringRef::const_iterator> base_and_iterator =
931 ParseRegisterName(osi, ose);
932 if (base_and_iterator.first.IsValid()) {
933 osi = base_and_iterator.second;
935 return std::make_pair(
Operand(), osi);
938 std::tie(found, osi) = ConsumeChar(osi,
')', ose);
940 return std::make_pair(
Operand(), osi);
943 if (offset_and_iterator.first.IsValid()) {
945 offset.
m_type = Operand::Type::Sum;
946 offset.
m_children.push_back(offset_and_iterator.first);
947 offset.
m_children.push_back(base_and_iterator.first);
950 deref.
m_type = Operand::Type::Dereference;
952 return std::make_pair(deref, osi);
955 deref.
m_type = Operand::Type::Dereference;
956 deref.
m_children.push_back(base_and_iterator.first);
957 return std::make_pair(deref, osi);
962 static std::pair<Operand, llvm::StringRef::const_iterator>
964 llvm::StringRef::const_iterator ose) {
966 std::tie(found, osi) = ConsumeChar(osi,
'[', ose);
968 return std::make_pair(
Operand(), osi);
971 std::pair<Operand, llvm::StringRef::const_iterator> base_and_iterator =
972 ParseRegisterName(osi, ose);
973 if (base_and_iterator.first.IsValid()) {
974 osi = base_and_iterator.second;
976 return std::make_pair(
Operand(), osi);
979 std::tie(found, osi) = ConsumeChar(osi,
',', ose);
981 return std::make_pair(
Operand(), osi);
984 std::pair<Operand, llvm::StringRef::const_iterator> offset_and_iterator =
985 ParseImmediate(osi, ose);
986 if (offset_and_iterator.first.IsValid()) {
987 osi = offset_and_iterator.second;
990 std::tie(found, osi) = ConsumeChar(osi,
']', ose);
992 return std::make_pair(
Operand(), osi);
996 offset.
m_type = Operand::Type::Sum;
997 offset.
m_children.push_back(offset_and_iterator.first);
998 offset.
m_children.push_back(base_and_iterator.first);
1001 deref.
m_type = Operand::Type::Dereference;
1003 return std::make_pair(deref, osi);
1007 static std::pair<Operand, llvm::StringRef::const_iterator>
1009 llvm::StringRef::const_iterator ose) {
1011 std::tie(found, osi) = ConsumeChar(osi,
'[', ose);
1013 return std::make_pair(
Operand(), osi);
1016 std::pair<Operand, llvm::StringRef::const_iterator> base_and_iterator =
1017 ParseRegisterName(osi, ose);
1018 if (base_and_iterator.first.IsValid()) {
1019 osi = base_and_iterator.second;
1021 return std::make_pair(
Operand(), osi);
1024 std::tie(found, osi) = ConsumeChar(osi,
']', ose);
1026 return std::make_pair(
Operand(), osi);
1030 deref.
m_type = Operand::Type::Dereference;
1031 deref.
m_children.push_back(base_and_iterator.first);
1032 return std::make_pair(deref, osi);
1037 case Operand::Type::Dereference:
1041 case Operand::Type::Immediate:
1047 case Operand::Type::Invalid:
1050 case Operand::Type::Product:
1057 case Operand::Type::Register:
1060 case Operand::Type::Sum:
1072 const char *operands_string = GetOperands(
nullptr);
1074 if (!operands_string) {
1078 llvm::StringRef operands_ref(operands_string);
1080 llvm::StringRef::const_iterator osi = operands_ref.begin();
1081 llvm::StringRef::const_iterator ose = operands_ref.end();
1083 while (osi != ose) {
1085 llvm::StringRef::const_iterator iter;
1087 if ((std::tie(operand, iter) = ParseIntelIndexedAccess(osi, ose),
1089 (std::tie(operand, iter) = ParseIntelDerefAccess(osi, ose),
1091 (std::tie(operand, iter) = ParseARMOffsetAccess(osi, ose),
1093 (std::tie(operand, iter) = ParseARMDerefAccess(osi, ose),
1095 (std::tie(operand, iter) = ParseRegisterName(osi, ose),
1097 (std::tie(operand, iter) = ParseImmediate(osi, ose),
1100 operands.push_back(operand);
1105 std::pair<bool, llvm::StringRef::const_iterator> found_and_iter =
1106 ConsumeChar(osi,
',', ose);
1107 if (found_and_iter.first) {
1108 osi = found_and_iter.second;
1111 osi = ConsumeWhitespace(osi, ose);
1114 DisassemblerSP disasm_sp = m_disasm_wp.lock();
1116 if (disasm_sp && operands.size() > 1) {
1118 switch (disasm_sp->GetArchitecture().GetMachine()) {
1121 case llvm::Triple::x86:
1122 case llvm::Triple::x86_64:
1123 operands[operands.size() - 1].m_clobbered =
true;
1125 case llvm::Triple::arm:
1126 operands[0].m_clobbered =
true;
1131 if (
Log *log =
GetLog(LLDBLog::Process)) {
1134 ss.
Printf(
"[%s] expands to %zu operands:\n", operands_string,
1136 for (
const Operand &operand : operands) {
1138 DumpOperand(operand, ss);
1156 bool m_is_valid =
false;
1157 bool m_using_file_addr =
false;
1158 bool m_has_visited_instruction =
false;
1166 bool m_does_branch =
true;
1167 bool m_has_delay_slot =
false;
1168 bool m_is_call =
false;
1169 bool m_is_load =
false;
1170 bool m_is_authenticated =
false;
1173 if (m_has_visited_instruction)
1181 if (!m_opcode.GetData(data))
1184 bool is_alternate_isa;
1187 GetDisasmToUse(is_alternate_isa, disasm);
1189 const size_t opcode_data_len = data.
GetByteSize();
1191 const size_t inst_size =
1192 mc_disasm_ptr->
GetMCInst(opcode_data, opcode_data_len,
pc, inst);
1196 m_has_visited_instruction =
true;
1197 m_does_branch = mc_disasm_ptr->
CanBranch(inst);
1199 m_is_call = mc_disasm_ptr->
IsCall(inst);
1200 m_is_load = mc_disasm_ptr->
IsLoad(inst);
1207 is_alternate_isa =
false;
1209 if (disasm->m_alternate_disasm_up) {
1212 if (address_class == AddressClass::eCodeAlternateISA) {
1213 is_alternate_isa =
true;
1214 return disasm->m_alternate_disasm_up.get();
1217 return disasm->m_disasm_up.get();
1223 std::unique_ptr<DisassemblerLLVMC::MCDisasmInstance>
1225 const char *features_str,
1228 using Instance = std::unique_ptr<DisassemblerLLVMC::MCDisasmInstance>;
1231 const llvm::Target *curr_target =
1232 llvm::TargetRegistry::lookupTarget(triple,
Status);
1236 std::unique_ptr<llvm::MCInstrInfo> instr_info_up(
1237 curr_target->createMCInstrInfo());
1241 std::unique_ptr<llvm::MCRegisterInfo> reg_info_up(
1242 curr_target->createMCRegInfo(triple));
1246 std::unique_ptr<llvm::MCSubtargetInfo> subtarget_info_up(
1247 curr_target->createMCSubtargetInfo(triple, cpu, features_str));
1248 if (!subtarget_info_up)
1251 llvm::MCTargetOptions MCOptions;
1252 std::unique_ptr<llvm::MCAsmInfo> asm_info_up(
1253 curr_target->createMCAsmInfo(*reg_info_up, triple, MCOptions));
1257 std::unique_ptr<llvm::MCContext> context_up(
1258 new llvm::MCContext(llvm::Triple(triple), asm_info_up.get(),
1259 reg_info_up.get(), subtarget_info_up.get()));
1263 std::unique_ptr<llvm::MCDisassembler> disasm_up(
1264 curr_target->createMCDisassembler(*subtarget_info_up, *context_up));
1268 std::unique_ptr<llvm::MCRelocationInfo> rel_info_up(
1269 curr_target->createMCRelocationInfo(triple, *context_up));
1273 std::unique_ptr<llvm::MCSymbolizer> symbolizer_up(
1274 curr_target->createMCSymbolizer(
1276 context_up.get(), std::move(rel_info_up)));
1277 disasm_up->setSymbolizer(std::move(symbolizer_up));
1279 unsigned asm_printer_variant =
1280 flavor == ~0U ? asm_info_up->getAssemblerDialect() : flavor;
1282 std::unique_ptr<llvm::MCInstPrinter> instr_printer_up(
1283 curr_target->createMCInstPrinter(llvm::Triple{triple},
1284 asm_printer_variant, *asm_info_up,
1285 *instr_info_up, *reg_info_up));
1286 if (!instr_printer_up)
1291 std::move(subtarget_info_up), std::move(asm_info_up),
1292 std::move(context_up), std::move(disasm_up),
1293 std::move(instr_printer_up)));
1297 std::unique_ptr<llvm::MCInstrInfo> &&instr_info_up,
1298 std::unique_ptr<llvm::MCRegisterInfo> &®_info_up,
1299 std::unique_ptr<llvm::MCSubtargetInfo> &&subtarget_info_up,
1300 std::unique_ptr<llvm::MCAsmInfo> &&asm_info_up,
1301 std::unique_ptr<llvm::MCContext> &&context_up,
1302 std::unique_ptr<llvm::MCDisassembler> &&disasm_up,
1303 std::unique_ptr<llvm::MCInstPrinter> &&instr_printer_up)
1304 : m_instr_info_up(std::move(instr_info_up)),
1305 m_reg_info_up(std::move(reg_info_up)),
1306 m_subtarget_info_up(std::move(subtarget_info_up)),
1307 m_asm_info_up(std::move(asm_info_up)),
1308 m_context_up(std::move(context_up)), m_disasm_up(std::move(disasm_up)),
1309 m_instr_printer_up(std::move(instr_printer_up)) {
1315 const uint8_t *opcode_data,
size_t opcode_data_len,
lldb::addr_t pc,
1316 llvm::MCInst &mc_inst)
const {
1317 llvm::ArrayRef<uint8_t> data(opcode_data, opcode_data_len);
1318 llvm::MCDisassembler::DecodeStatus status;
1320 uint64_t new_inst_size;
1321 status =
m_disasm_up->getInstruction(mc_inst, new_inst_size, data,
pc,
1323 if (status == llvm::MCDisassembler::Success)
1324 return new_inst_size;
1332 llvm::raw_string_ostream inst_stream(inst_string);
1333 llvm::raw_string_ostream comments_stream(comments_string);
1335 m_instr_printer_up->setCommentStream(comments_stream);
1336 m_instr_printer_up->printInst(&mc_inst, 0, llvm::StringRef(),
1337 *m_subtarget_info_up, inst_stream);
1338 m_instr_printer_up->setCommentStream(llvm::nulls());
1339 comments_stream.flush();
1343 for (
size_t newline_pos = 0;
1344 (newline_pos = comments_string.find_first_of(g_newlines, newline_pos)) !=
1345 comments_string.npos;
1347 comments_string.replace(comments_string.begin() + newline_pos,
1348 comments_string.begin() + newline_pos + 1, 1,
' ');
1354 m_instr_printer_up->setPrintImmHex(use_hex_immed);
1355 switch (hex_style) {
1357 m_instr_printer_up->setPrintHexStyle(llvm::HexStyle::C);
1360 m_instr_printer_up->setPrintHexStyle(llvm::HexStyle::Asm);
1366 llvm::MCInst &mc_inst)
const {
1367 return m_instr_info_up->get(mc_inst.getOpcode())
1368 .mayAffectControlFlow(mc_inst, *m_reg_info_up);
1372 llvm::MCInst &mc_inst)
const {
1373 return m_instr_info_up->get(mc_inst.getOpcode()).hasDelaySlot();
1377 return m_instr_info_up->get(mc_inst.getOpcode()).isCall();
1381 return m_instr_info_up->get(mc_inst.getOpcode()).mayLoad();
1385 llvm::MCInst &mc_inst)
const {
1386 auto InstrDesc = m_instr_info_up->get(mc_inst.getOpcode());
1391 bool IsBrkC47x =
false;
1392 if (InstrDesc.isTrap() && mc_inst.getNumOperands() == 1) {
1393 const llvm::MCOperand &Op0 = mc_inst.getOperand(0);
1394 if (Op0.isImm() && Op0.getImm() >= 0xc470 && Op0.getImm() <= 0xc474)
1398 return InstrDesc.isAuthenticated() || IsBrkC47x;
1402 const char *flavor_string)
1410 unsigned flavor = ~0U;
1415 if (triple.getArch() == llvm::Triple::x86 ||
1416 triple.getArch() == llvm::Triple::x86_64) {
1425 if (triple.getArch() == llvm::Triple::arm) {
1428 if (thumb_arch_name.size() > 3) {
1429 thumb_arch_name.erase(0, 3);
1430 thumb_arch_name.insert(0,
"thumb");
1432 thumb_arch_name =
"thumbv9.3a";
1434 thumb_arch.
GetTriple().setArchName(llvm::StringRef(thumb_arch_name));
1442 if (triple.getArch() == llvm::Triple::arm &&
1443 triple.getSubArch() == llvm::Triple::NoSubArch)
1444 triple.setArchName(
"armv9.3a");
1447 const char *triple_str = triple.getTriple().c_str();
1451 triple_str = thumb_arch.
GetTriple().getTriple().c_str();
1452 features_str +=
"+fp-armv8,";
1455 const char *cpu =
"";
1458 case ArchSpec::eCore_mips32:
1459 case ArchSpec::eCore_mips32el:
1462 case ArchSpec::eCore_mips32r2:
1463 case ArchSpec::eCore_mips32r2el:
1466 case ArchSpec::eCore_mips32r3:
1467 case ArchSpec::eCore_mips32r3el:
1470 case ArchSpec::eCore_mips32r5:
1471 case ArchSpec::eCore_mips32r5el:
1474 case ArchSpec::eCore_mips32r6:
1475 case ArchSpec::eCore_mips32r6el:
1478 case ArchSpec::eCore_mips64:
1479 case ArchSpec::eCore_mips64el:
1482 case ArchSpec::eCore_mips64r2:
1483 case ArchSpec::eCore_mips64r2el:
1486 case ArchSpec::eCore_mips64r3:
1487 case ArchSpec::eCore_mips64r3el:
1490 case ArchSpec::eCore_mips64r5:
1491 case ArchSpec::eCore_mips64r5el:
1494 case ArchSpec::eCore_mips64r6:
1495 case ArchSpec::eCore_mips64r6el:
1505 if (arch_flags & ArchSpec::eMIPSAse_msa)
1506 features_str +=
"+msa,";
1507 if (arch_flags & ArchSpec::eMIPSAse_dsp)
1508 features_str +=
"+dsp,";
1509 if (arch_flags & ArchSpec::eMIPSAse_dspr2)
1510 features_str +=
"+dspr2,";
1514 if (triple.isAArch64()) {
1515 features_str +=
"+all,";
1517 if (triple.getVendor() == llvm::Triple::Apple)
1518 cpu =
"apple-latest";
1521 if (triple.isRISCV()) {
1523 if (arch_flags & ArchSpec::eRISCV_rvc)
1524 features_str +=
"+c,";
1525 if (arch_flags & ArchSpec::eRISCV_rve)
1526 features_str +=
"+e,";
1527 if ((arch_flags & ArchSpec::eRISCV_float_abi_single) ==
1528 ArchSpec::eRISCV_float_abi_single)
1529 features_str +=
"+f,";
1530 if ((arch_flags & ArchSpec::eRISCV_float_abi_double) ==
1531 ArchSpec::eRISCV_float_abi_double)
1532 features_str +=
"+f,+d,";
1533 if ((arch_flags & ArchSpec::eRISCV_float_abi_quad) ==
1534 ArchSpec::eRISCV_float_abi_quad)
1535 features_str +=
"+f,+d,+q,";
1545 llvm::Triple::ArchType llvm_arch = triple.getArch();
1549 if (llvm_arch == llvm::Triple::arm) {
1557 }
else if (arch.
IsMIPS()) {
1560 if (arch_flags & ArchSpec::eMIPSAse_mips16)
1561 features_str +=
"+mips16,";
1562 else if (arch_flags & ArchSpec::eMIPSAse_micromips)
1563 features_str +=
"+micromips,";
1566 triple_str, cpu, features_str.c_str(), flavor, *
this);
1575 const char *flavor) {
1576 if (arch.
GetTriple().getArch() != llvm::Triple::UnknownArch) {
1577 std::unique_ptr<DisassemblerLLVMC> disasm_up(
1580 if (disasm_up.get() && disasm_up->IsValid())
1581 return disasm_up.release();
1589 size_t num_instructions,
1590 bool append,
bool data_from_file) {
1598 uint32_t data_cursor = data_offset;
1603 while (data_cursor < data_byte_size &&
1604 instructions_parsed < num_instructions) {
1611 InstructionSP inst_sp(
1617 uint32_t inst_size = inst_sp->Decode(*
this, data, data_cursor);
1623 data_cursor += inst_size;
1624 inst_addr.
Slide(inst_size);
1625 instructions_parsed++;
1628 return data_cursor - data_offset;
1633 "Disassembler that uses LLVM MC to disassemble "
1634 "i386, x86_64, ARM, and ARM64.",
1637 llvm::InitializeAllTargetInfos();
1638 llvm::InitializeAllTargetMCs();
1639 llvm::InitializeAllAsmParsers();
1640 llvm::InitializeAllDisassemblers();
1648 uint64_t offset, uint64_t size,
1649 int tag_type,
void *tag_bug) {
1651 ->
OpInfo(
pc, offset, size, tag_type, tag_bug);
1656 uint64_t *type, uint64_t
pc,
1657 const char **name) {
1665 if (flavor ==
nullptr || strcmp(flavor,
"default") == 0)
1668 if (triple.getArch() == llvm::Triple::x86 ||
1669 triple.getArch() == llvm::Triple::x86_64) {
1670 return strcmp(flavor,
"intel") == 0 || strcmp(flavor,
"att") == 0;
1678 int tag_type,
void *tag_bug) {
1683 memset(tag_bug, 0,
sizeof(::LLVMOpInfo1));
1690 uint64_t
pc,
const char **name) {
1700 if (*type_ptr == LLVMDisassembler_ReferenceType_In_ARM64_ADRP) {
1704 *type_ptr = LLVMDisassembler_ReferenceType_InOut_None;
1711 if (*type_ptr == LLVMDisassembler_ReferenceType_In_ARM64_ADDXri &&
1713 (
m_adrp_insn.value() & 0x1f) == ((value >> 5) & 0x1f)) {
1715 uint64_t adrp_imm, addxri_imm;
1718 adrp_imm = ((
m_adrp_insn.value() & 0x00ffffe0) >> 3) |
1721 if (adrp_imm & (1ULL << 20))
1722 adrp_imm |= ~((1ULL << 21) - 1);
1724 addxri_inst = value;
1725 addxri_imm = (addxri_inst >> 10) & 0xfff;
1728 if ((addxri_inst >> (12 + 5 + 5)) & 1)
1730 value = (
m_adrp_address & 0xfffffffffffff000LL) + (adrp_imm << 12) +
1740 module_sp->ResolveFileAddress(value, value_so_addr);
1741 module_sp->ResolveFileAddress(
pc, pc_so_addr);
1749 const SymbolContextItem resolve_scope =
1750 eSymbolContextFunction | eSymbolContextSymbol;
1752 pc_so_addr.
GetModule()->ResolveSymbolContextForAddress(
1753 pc_so_addr, resolve_scope, sym_ctx);
1759 bool format_omitting_current_func_name =
false;
1765 format_omitting_current_func_name =
true;
1773 if (format_omitting_current_func_name) {
1774 value_so_addr.
Dump(&ss, target, Address::DumpStyleNoFunctionName,
1775 Address::DumpStyleSectionNameOffset);
1779 Address::DumpStyleResolvedDescriptionNoFunctionArguments,
1780 Address::DumpStyleSectionNameOffset);
1788 size_t first_eol_char = str.find_first_of(
"\r\n");
1789 if (first_eol_char != std::string::npos) {
1790 str.erase(first_eol_char);
1804 *type_ptr = LLVMDisassembler_ReferenceType_InOut_None;