[Lldb-commits] [PATCH] D12553: Fix arm disassambler with specifying armv8.1a architecture

Tamas Berghammer via lldb-commits lldb-commits at lists.llvm.org
Wed Sep 2 05:56:55 PDT 2015


tberghammer created this revision.
tberghammer added reviewers: labath, dsrbecky.
tberghammer added a subscriber: lldb-commits.
Herald added subscribers: rengolin, aemerson.

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 architecture was specified (either by the user or by the target) to
disassamble all instruction.

http://reviews.llvm.org/D12553

Files:
  source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp

Index: source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
===================================================================
--- source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
+++ source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
@@ -630,13 +630,12 @@
         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 @@
     }
 
     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 @@
         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 @@
     }
 
     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,16 +742,16 @@
             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,
         // we reset it, and then we won't be valid and FindPlugin will fail and we won't get used.
         m_disasm_ap.reset();
     }
 
     // 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));


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D12553.33800.patch
Type: text/x-patch
Size: 4468 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20150902/b4fccdf3/attachment.bin>


More information about the lldb-commits mailing list