diff options
author | Tamas Berghammer <tberghammer@google.com> | 2015-09-02 13:24:50 +0000 |
---|---|---|
committer | Tamas Berghammer <tberghammer@google.com> | 2015-09-02 13:24:50 +0000 |
commit | ff417efa1deb87523fffd8c05e7bda5b5579f5bd (patch) | |
tree | d5e10d5a36a90793e5bd9d1ea1c48419396fdcc2 /lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp | |
parent | e457c8862d00a4debf069e7f8a354a9cd05a8205 (diff) | |
download | bcm5719-llvm-ff417efa1deb87523fffd8c05e7bda5b5579f5bd.tar.gz bcm5719-llvm-ff417efa1deb87523fffd8c05e7bda5b5579f5bd.zip |
Fix arm disassambler with specifying armv8.1a architecture
If no architecture is defined for the disassambler command then it uses
the architecture of the target. In case of arm it will be "arm" what is
treated as the oldest arm version by the LLVM disassambler causing a lot
of invalid opcode in the output.
This change forces the use of "armv8.1a" (the newest arm architecture) if
no sub architecure was specified (either by the user or by the target) to
disassamble all instruction.
Differential revision: http://reviews.llvm.org/D12553
llvm-svn: 246648
Diffstat (limited to 'lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp')
-rw-r--r-- | lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp index 19e2dbdbead..81603b6a7cd 100644 --- a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp +++ b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp @@ -630,13 +630,12 @@ DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_s m_flavor.assign("default"); } - const char *triple = arch.GetTriple().getTriple().c_str(); unsigned flavor = ~0U; + llvm::Triple triple = arch.GetTriple(); // So far the only supported flavor is "intel" on x86. The base class will set this // correctly coming in. - if (arch.GetTriple().getArch() == llvm::Triple::x86 - || arch.GetTriple().getArch() == llvm::Triple::x86_64) + if (triple.getArch() == llvm::Triple::x86 || triple.getArch() == llvm::Triple::x86_64) { if (m_flavor == "intel") { @@ -649,7 +648,7 @@ DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_s } ArchSpec thumb_arch(arch); - if (arch.GetTriple().getArch() == llvm::Triple::arm || arch.GetTriple().getArch() == llvm::Triple::thumb) + if (triple.getArch() == llvm::Triple::arm || triple.getArch() == llvm::Triple::thumb) { std::string thumb_arch_name (thumb_arch.GetTriple().getArchName().str()); // Replace "arm" with "thumb" so we get all thumb variants correct @@ -665,18 +664,27 @@ DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_s thumb_arch.GetTriple().setArchName(llvm::StringRef(thumb_arch_name.c_str())); } + // If no sub architecture specified then use the most recent arm architecture so the + // disassembler will return all instruction. Without it we will see a lot of unknow opcode + // in case the code uses instructions which are not available in the oldest arm version + // (used when no sub architecture is specified) + if (triple.getArch() == llvm::Triple::arm && triple.getSubArch() == llvm::Triple::NoSubArch) + triple.setArchName("armv8.1a"); + + const char *triple_str = triple.getTriple().c_str(); + // Cortex-M3 devices (e.g. armv7m) can only execute thumb (T2) instructions, // so hardcode the primary disassembler to thumb mode. Same for Cortex-M4 (armv7em). // // Handle the Cortex-M0 (armv6m) the same; the ISA is a subset of the T and T32 // instructions defined in ARMv7-A. - if ((arch.GetTriple().getArch() == llvm::Triple::arm || arch.GetTriple().getArch() == llvm::Triple::thumb) + if ((triple.getArch() == llvm::Triple::arm || triple.getArch() == llvm::Triple::thumb) && (arch.GetCore() == ArchSpec::Core::eCore_arm_armv7m || arch.GetCore() == ArchSpec::Core::eCore_arm_armv7em || arch.GetCore() == ArchSpec::Core::eCore_arm_armv6m)) { - triple = thumb_arch.GetTriple().getTriple().c_str(); + triple_str = thumb_arch.GetTriple().getTriple().c_str(); } const char *cpu = ""; @@ -718,8 +726,8 @@ DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_s } std::string features_str = ""; - if (arch.GetTriple().getArch() == llvm::Triple::mips || arch.GetTriple().getArch() == llvm::Triple::mipsel - || arch.GetTriple().getArch() == llvm::Triple::mips64 || arch.GetTriple().getArch() == llvm::Triple::mips64el) + if (triple.getArch() == llvm::Triple::mips || triple.getArch() == llvm::Triple::mipsel + || triple.getArch() == llvm::Triple::mips64 || triple.getArch() == llvm::Triple::mips64el) { uint32_t arch_flags = arch.GetFlags (); if (arch_flags & ArchSpec::eMIPSAse_msa) @@ -734,7 +742,7 @@ DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_s features_str += "+micromips,"; } - m_disasm_ap.reset (new LLVMCDisassembler(triple, cpu, features_str.c_str(), flavor, *this)); + m_disasm_ap.reset (new LLVMCDisassembler(triple_str, cpu, features_str.c_str(), flavor, *this)); if (!m_disasm_ap->IsValid()) { // We use m_disasm_ap.get() to tell whether we are valid or not, so if this isn't good for some reason, @@ -743,7 +751,7 @@ DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_s } // For arm CPUs that can execute arm or thumb instructions, also create a thumb instruction disassembler. - if (arch.GetTriple().getArch() == llvm::Triple::arm || arch.GetTriple().getArch() == llvm::Triple::thumb) + if (triple.getArch() == llvm::Triple::arm || triple.getArch() == llvm::Triple::thumb) { std::string thumb_triple(thumb_arch.GetTriple().getTriple()); m_alternate_disasm_ap.reset(new LLVMCDisassembler(thumb_triple.c_str(), "", "", flavor, *this)); |