Index: include/lldb/Core/ArchSpec.h =================================================================== --- include/lldb/Core/ArchSpec.h +++ include/lldb/Core/ArchSpec.h @@ -581,6 +581,22 @@ m_flags = flags; } + //------------------------------------------------------------------ + /// Detect whether this architecture uses thumb code exclusively + /// + /// Some embedded ARM chips (e.g. the ARM Cortex M0-7 line) can + /// only execute the Thumb instructions, never Arm. We should normally + /// pick up arm/thumbness from their the processor status bits (cpsr/xpsr) + /// or hints on each function - but when doing bare-boards low level + /// debugging (especially common with these embedded processors), we may + /// not have those things easily accessible. + /// + /// @return true if this is an arm ArchSpec which can only execute Thumb + /// instructions + //------------------------------------------------------------------ + bool + IsAlwaysThumbInstructions () const; + protected: bool IsEqualTo (const ArchSpec& rhs, bool exact_match) const; Index: source/Core/ArchSpec.cpp =================================================================== --- source/Core/ArchSpec.cpp +++ source/Core/ArchSpec.cpp @@ -850,6 +850,19 @@ GetTriple().setOS(other.GetTriple().getOS()); if (GetTriple().getArch() == llvm::Triple::UnknownArch) GetTriple().setArch(other.GetTriple().getArch()); + + // If this and other are both arm ArchSpecs and this ArchSpec is a generic "some kind of arm" + // spec but the other ArchSpec is a specific arm core, adopt the specific arm core. + if (GetTriple().getArch() == llvm::Triple::arm + && other.GetTriple().getArch() == llvm::Triple::arm + && IsCompatibleMatch (other) + && GetCore() == ArchSpec::eCore_arm_generic + && other.GetCore() != ArchSpec::eCore_arm_generic) + { + m_core = other.GetCore(); + CoreUpdated (true); + } + if (GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment) GetTriple().setEnvironment(other.GetTriple().getEnvironment()); } @@ -1444,3 +1457,22 @@ return StopInfoOverrideCallbackTypeARM; return NULL; } + +bool +ArchSpec::IsAlwaysThumbInstructions () const +{ + // v. https://en.wikipedia.org/wiki/ARM_Cortex-M#Silicon_customization + // Cortex-M0 - ARMv6-M - armv6m + // Cortex-M3 - ARMv7-M - armv7m + // Cortex-M4 - ARMv7E-M - armv7em + if (GetTriple().getArch() == llvm::Triple::arm || GetTriple().getArch() == llvm::Triple::thumb) + { + if (GetCore() == ArchSpec::Core::eCore_arm_armv6m + || GetCore() == ArchSpec::Core::eCore_arm_armv7m + || GetCore() == ArchSpec::Core::eCore_arm_armv7em) + { + return true; + } + } + return false; +} Index: source/Core/Disassembler.cpp =================================================================== --- source/Core/Disassembler.cpp +++ source/Core/Disassembler.cpp @@ -1270,10 +1270,7 @@ // If this is an arm variant that can only include thumb (T16, T32) // instructions, force the arch triple to be "thumbv.." instead of // "armv..." - if ((arch.GetTriple().getArch() == llvm::Triple::arm || arch.GetTriple().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)) + if (arch.IsAlwaysThumbInstructions()) { std::string thumb_arch_name (arch.GetTriple().getArchName().str()); // Replace "arm" with "thumb" so we get all thumb variants correct Index: source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp =================================================================== --- source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp +++ source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp @@ -673,18 +673,8 @@ const char *triple_str = triple.getTriple().c_str(); - // v. https://en.wikipedia.org/wiki/ARM_Cortex-M#Silicon_customization - // - // 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 ((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)) + // ARM Cortex M0-M7 devices only execute thumb instructions + if (arch.IsAlwaysThumbInstructions ()) { triple_str = thumb_arch.GetTriple().getTriple().c_str(); } Index: source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp =================================================================== --- source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -12992,8 +12992,10 @@ { if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target)) { - if (m_arch.GetTriple().getArch() == llvm::Triple::thumb) + if (m_arch.GetTriple().getArch() == llvm::Triple::thumb || m_arch.IsAlwaysThumbInstructions ()) + { m_opcode_mode = eModeThumb; + } else { AddressClass addr_class = inst_addr.GetAddressClass(); @@ -13028,7 +13030,7 @@ read_inst_context.type = eContextReadOpcode; read_inst_context.SetNoArgs (); - if (m_opcode_cpsr & MASK_CPSR_T) + if (m_opcode_cpsr & MASK_CPSR_T || m_arch.IsAlwaysThumbInstructions()) { m_opcode_mode = eModeThumb; uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); @@ -13657,19 +13659,17 @@ } test_opcode = value_sp->GetUInt64Value (); - if (arch.GetTriple().getArch() == llvm::Triple::arm) - { - m_opcode_mode = eModeARM; - m_opcode.SetOpcode32 (test_opcode, GetByteOrder()); - } - else if (arch.GetTriple().getArch() == llvm::Triple::thumb) + if (arch.GetTriple().getArch() == llvm::Triple::thumb || arch.IsAlwaysThumbInstructions ()) { m_opcode_mode = eModeThumb; if (test_opcode < 0x10000) m_opcode.SetOpcode16 (test_opcode, GetByteOrder()); else m_opcode.SetOpcode32 (test_opcode, GetByteOrder()); - + } else if (arch.GetTriple().getArch() == llvm::Triple::arm) + { + m_opcode_mode = eModeARM; + m_opcode.SetOpcode32 (test_opcode, GetByteOrder()); } else {