Commit fa04ada8 authored by Hans Wennborg's avatar Hans Wennborg
Browse files

Merging r242381:

------------------------------------------------------------------------
r242381 | jaydeep | 2015-07-15 20:51:55 -0700 (Wed, 15 Jul 2015) | 10 lines

[LLDB][MIPS] Detect MIPS application specific extensions like micromips
    SUMMARY:
    The patch detects MIPS application specific extensions (ASE) like micromips by reading 
    ELF header.e_flags and SHT_MIPS_ABIFLAGS section. MIPS triple does not contain ASE 
    information like micromips, mips16, DSP, MSA etc. These can be read from header.e_flags 
    or SHT_MIPS_ABIFLAGS section.
    
    Reviewers: clayborg
    Subscribers: mohit.bhakkad, sagar, lldb-commits
    Differential Revision: http://reviews.llvm.org/D11133
------------------------------------------------------------------------

llvm-svn: 242411
parent 90a7c4a7
Loading
Loading
Loading
Loading
+37 −1
Original line number Diff line number Diff line
@@ -49,6 +49,25 @@ public:
        eMIPSSubType_mips64r6el,
    };

    // Masks for the ases word of an ABI flags structure.
    enum MIPSASE
    {
        eMIPSAse_dsp        = 0x00000001,   // DSP ASE
        eMIPSAse_dspr2      = 0x00000002,   // DSP R2 ASE
        eMIPSAse_eva        = 0x00000004,   // Enhanced VA Scheme
        eMIPSAse_mcu        = 0x00000008,   // MCU (MicroController) ASE
        eMIPSAse_mdmx       = 0x00000010,   // MDMX ASE
        eMIPSAse_mips3d     = 0x00000020,   // MIPS-3D ASE
        eMIPSAse_mt         = 0x00000040,   // MT ASE
        eMIPSAse_smartmips  = 0x00000080,   // SmartMIPS ASE
        eMIPSAse_virt       = 0x00000100,   // VZ ASE
        eMIPSAse_msa        = 0x00000200,   // MSA ASE
        eMIPSAse_mips16     = 0x00000400,   // MIPS16 ASE
        eMIPSAse_micromips  = 0x00000800,   // MICROMIPS ASE
        eMIPSAse_xpa        = 0x00001000,   // XPA ASE
        eMIPSAse_mask       = 0x00001fff
    };

    enum Core
    {
        eCore_arm_generic,
@@ -546,6 +565,18 @@ public:
    StopInfoOverrideCallbackType
    GetStopInfoOverrideCallback () const;

    uint32_t
    GetFlags () const
    {
        return m_flags;
    }

    void
    SetFlags (uint32_t flags)
    {
        m_flags = flags;
    }

protected:
    bool
    IsEqualTo (const ArchSpec& rhs, bool exact_match) const;
@@ -554,6 +585,11 @@ protected:
    Core m_core;
    lldb::ByteOrder m_byte_order;

    // Additional arch flags which we cannot get from triple and core
    // For MIPS these are application specific extensions like 
    // micromips, mips16 etc.
    uint32_t m_flags;

    ConstString m_distribution_id;

    // Called when m_def or m_entry are changed.  Fills in all remaining
+32 −25
Original line number Diff line number Diff line
@@ -90,28 +90,28 @@ static const CoreDefinition g_core_definitions[] =
    { eByteOrderLittle, 8, 4, 4, llvm::Triple::aarch64, ArchSpec::eCore_arm_aarch64     , "aarch64"   },

    // mips32, mips32r2, mips32r3, mips32r5, mips32r6
    { eByteOrderBig   , 4, 4, 4, llvm::Triple::mips  , ArchSpec::eCore_mips32         , "mips"      },
    { eByteOrderBig   , 4, 4, 4, llvm::Triple::mips  , ArchSpec::eCore_mips32r2       , "mipsr2"    },
    { eByteOrderBig   , 4, 4, 4, llvm::Triple::mips  , ArchSpec::eCore_mips32r3       , "mipsr3"    },
    { eByteOrderBig   , 4, 4, 4, llvm::Triple::mips  , ArchSpec::eCore_mips32r5       , "mipsr5"    },
    { eByteOrderBig   , 4, 4, 4, llvm::Triple::mips  , ArchSpec::eCore_mips32r6       , "mipsr6"    },
    { eByteOrderLittle, 4, 4, 4, llvm::Triple::mipsel, ArchSpec::eCore_mips32el       , "mipsel"    },
    { eByteOrderLittle, 4, 4, 4, llvm::Triple::mipsel, ArchSpec::eCore_mips32r2el     , "mipsr2el"  },
    { eByteOrderLittle, 4, 4, 4, llvm::Triple::mipsel, ArchSpec::eCore_mips32r3el     , "mipsr3el"  },
    { eByteOrderLittle, 4, 4, 4, llvm::Triple::mipsel, ArchSpec::eCore_mips32r5el     , "mipsr5el"  },
    { eByteOrderLittle, 4, 4, 4, llvm::Triple::mipsel, ArchSpec::eCore_mips32r6el     , "mipsr6el"  },
    { eByteOrderBig   , 4, 2, 4, llvm::Triple::mips  , ArchSpec::eCore_mips32         , "mips"      },
    { eByteOrderBig   , 4, 2, 4, llvm::Triple::mips  , ArchSpec::eCore_mips32r2       , "mipsr2"    },
    { eByteOrderBig   , 4, 2, 4, llvm::Triple::mips  , ArchSpec::eCore_mips32r3       , "mipsr3"    },
    { eByteOrderBig   , 4, 2, 4, llvm::Triple::mips  , ArchSpec::eCore_mips32r5       , "mipsr5"    },
    { eByteOrderBig   , 4, 2, 4, llvm::Triple::mips  , ArchSpec::eCore_mips32r6       , "mipsr6"    },
    { eByteOrderLittle, 4, 2, 4, llvm::Triple::mipsel, ArchSpec::eCore_mips32el       , "mipsel"    },
    { eByteOrderLittle, 4, 2, 4, llvm::Triple::mipsel, ArchSpec::eCore_mips32r2el     , "mipsr2el"  },
    { eByteOrderLittle, 4, 2, 4, llvm::Triple::mipsel, ArchSpec::eCore_mips32r3el     , "mipsr3el"  },
    { eByteOrderLittle, 4, 2, 4, llvm::Triple::mipsel, ArchSpec::eCore_mips32r5el     , "mipsr5el"  },
    { eByteOrderLittle, 4, 2, 4, llvm::Triple::mipsel, ArchSpec::eCore_mips32r6el     , "mipsr6el"  },
    
    // mips64, mips64r2, mips64r3, mips64r5, mips64r6
    { eByteOrderBig   , 8, 4, 4, llvm::Triple::mips64  , ArchSpec::eCore_mips64         , "mips64"      },
    { eByteOrderBig   , 8, 4, 4, llvm::Triple::mips64  , ArchSpec::eCore_mips64r2       , "mips64r2"    },
    { eByteOrderBig   , 8, 4, 4, llvm::Triple::mips64  , ArchSpec::eCore_mips64r3       , "mips64r3"    },
    { eByteOrderBig   , 8, 4, 4, llvm::Triple::mips64  , ArchSpec::eCore_mips64r5       , "mips64r5"    },
    { eByteOrderBig   , 8, 4, 4, llvm::Triple::mips64  , ArchSpec::eCore_mips64r6       , "mips64r6"    },
    { eByteOrderLittle, 8, 4, 4, llvm::Triple::mips64el, ArchSpec::eCore_mips64el       , "mips64el"    },
    { eByteOrderLittle, 8, 4, 4, llvm::Triple::mips64el, ArchSpec::eCore_mips64r2el     , "mips64r2el"  },
    { eByteOrderLittle, 8, 4, 4, llvm::Triple::mips64el, ArchSpec::eCore_mips64r3el     , "mips64r3el"  },
    { eByteOrderLittle, 8, 4, 4, llvm::Triple::mips64el, ArchSpec::eCore_mips64r5el     , "mips64r5el"  },
    { eByteOrderLittle, 8, 4, 4, llvm::Triple::mips64el, ArchSpec::eCore_mips64r6el     , "mips64r6el"  },
    { eByteOrderBig   , 8, 2, 4, llvm::Triple::mips64  , ArchSpec::eCore_mips64         , "mips64"      },
    { eByteOrderBig   , 8, 2, 4, llvm::Triple::mips64  , ArchSpec::eCore_mips64r2       , "mips64r2"    },
    { eByteOrderBig   , 8, 2, 4, llvm::Triple::mips64  , ArchSpec::eCore_mips64r3       , "mips64r3"    },
    { eByteOrderBig   , 8, 2, 4, llvm::Triple::mips64  , ArchSpec::eCore_mips64r5       , "mips64r5"    },
    { eByteOrderBig   , 8, 2, 4, llvm::Triple::mips64  , ArchSpec::eCore_mips64r6       , "mips64r6"    },
    { eByteOrderLittle, 8, 2, 4, llvm::Triple::mips64el, ArchSpec::eCore_mips64el       , "mips64el"    },
    { eByteOrderLittle, 8, 2, 4, llvm::Triple::mips64el, ArchSpec::eCore_mips64r2el     , "mips64r2el"  },
    { eByteOrderLittle, 8, 2, 4, llvm::Triple::mips64el, ArchSpec::eCore_mips64r3el     , "mips64r3el"  },
    { eByteOrderLittle, 8, 2, 4, llvm::Triple::mips64el, ArchSpec::eCore_mips64r5el     , "mips64r5el"  },
    { eByteOrderLittle, 8, 2, 4, llvm::Triple::mips64el, ArchSpec::eCore_mips64r6el     , "mips64r6el"  },
    
    { eByteOrderBig   , 4, 4, 4, llvm::Triple::ppc    , ArchSpec::eCore_ppc_generic     , "powerpc"   },
    { eByteOrderBig   , 4, 4, 4, llvm::Triple::ppc    , ArchSpec::eCore_ppc_ppc601      , "ppc601"    },
@@ -419,7 +419,8 @@ ArchSpec::ArchSpec() :
    m_triple (),
    m_core (kCore_invalid),
    m_byte_order (eByteOrderInvalid),
    m_distribution_id ()
    m_distribution_id (),
    m_flags (0)
{
}

@@ -427,7 +428,8 @@ ArchSpec::ArchSpec (const char *triple_cstr, Platform *platform) :
    m_triple (),
    m_core (kCore_invalid),
    m_byte_order (eByteOrderInvalid),
    m_distribution_id ()
    m_distribution_id (),
    m_flags (0)
{
    if (triple_cstr)
        SetTriple(triple_cstr, platform);
@@ -438,7 +440,8 @@ ArchSpec::ArchSpec (const char *triple_cstr) :
    m_triple (),
    m_core (kCore_invalid),
    m_byte_order (eByteOrderInvalid),
    m_distribution_id ()
    m_distribution_id (),
    m_flags (0)
{
    if (triple_cstr)
        SetTriple(triple_cstr);
@@ -448,7 +451,8 @@ ArchSpec::ArchSpec(const llvm::Triple &triple) :
    m_triple (),
    m_core (kCore_invalid),
    m_byte_order (eByteOrderInvalid),
    m_distribution_id ()
    m_distribution_id (),
    m_flags (0)
{
    SetTriple(triple);
}
@@ -457,7 +461,8 @@ ArchSpec::ArchSpec (ArchitectureType arch_type, uint32_t cpu, uint32_t subtype)
    m_triple (),
    m_core (kCore_invalid),
    m_byte_order (eByteOrderInvalid),
    m_distribution_id ()
    m_distribution_id (),
    m_flags (0)
{
    SetArchitecture (arch_type, cpu, subtype);
}
@@ -478,6 +483,7 @@ ArchSpec::operator= (const ArchSpec& rhs)
        m_core = rhs.m_core;
        m_byte_order = rhs.m_byte_order;
        m_distribution_id = rhs.m_distribution_id;
        m_flags = rhs.m_flags;
    }
    return *this;
}
@@ -489,6 +495,7 @@ ArchSpec::Clear()
    m_core = kCore_invalid;
    m_byte_order = eByteOrderInvalid;
    m_distribution_id.Clear ();
    m_flags = 0;
}

//===----------------------------------------------------------------------===//
+20 −5
Original line number Diff line number Diff line
@@ -415,7 +415,7 @@ protected:



DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, const char *cpu, unsigned flavor, DisassemblerLLVMC &owner):
DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, const char *cpu, const char *features_str, unsigned flavor, DisassemblerLLVMC &owner):
    m_is_valid(true)
{
    std::string Error;
@@ -429,8 +429,6 @@ DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, con
    m_instr_info_ap.reset(curr_target->createMCInstrInfo());
    m_reg_info_ap.reset (curr_target->createMCRegInfo(triple));

    std::string features_str;

    m_subtarget_info_ap.reset(curr_target->createMCSubtargetInfo(triple, cpu,
                                                                features_str));

@@ -675,7 +673,24 @@ DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_s
            cpu = ""; break;
    }

    m_disasm_ap.reset (new LLVMCDisassembler(triple, cpu, flavor, *this));
    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)
    {
        uint32_t arch_flags = arch.GetFlags ();
        if (arch_flags & ArchSpec::eMIPSAse_msa)
            features_str += "+msa,";
        if (arch_flags & ArchSpec::eMIPSAse_dsp)
            features_str += "+dsp,";
        if (arch_flags & ArchSpec::eMIPSAse_dspr2)
            features_str += "+dspr2,";
        if (arch_flags & ArchSpec::eMIPSAse_mips16)
            features_str += "+mips16,";
        if (arch_flags & ArchSpec::eMIPSAse_micromips)
            features_str += "+micromips,";
    }
    
    m_disasm_ap.reset (new LLVMCDisassembler(triple, 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,
@@ -687,7 +702,7 @@ DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_s
    if (arch.GetTriple().getArch() == llvm::Triple::arm)
    {
        std::string thumb_triple(thumb_arch.GetTriple().getTriple());
        m_alternate_disasm_ap.reset(new LLVMCDisassembler(thumb_triple.c_str(), "", flavor, *this));
        m_alternate_disasm_ap.reset(new LLVMCDisassembler(thumb_triple.c_str(), "", "", flavor, *this));
        if (!m_alternate_disasm_ap->IsValid())
        {
            m_disasm_ap.reset();
+1 −1
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ class DisassemblerLLVMC : public lldb_private::Disassembler
    class LLVMCDisassembler
    {
    public:
        LLVMCDisassembler (const char *triple, const char *cpu, unsigned flavor, DisassemblerLLVMC &owner);
        LLVMCDisassembler (const char *triple, const char *cpu, const char *features_str, unsigned flavor, DisassemblerLLVMC &owner);

        ~LLVMCDisassembler();

+14 −1
Original line number Diff line number Diff line
@@ -124,6 +124,19 @@ EmulateInstructionMIPS::EmulateInstructionMIPS (const lldb_private::ArchSpec &ar
            cpu = "generic"; break;
    }

    std::string features = "";
    uint32_t arch_flags = arch.GetFlags ();
    if (arch_flags & ArchSpec::eMIPSAse_msa)
        features += "+msa,";
    if (arch_flags & ArchSpec::eMIPSAse_dsp)
        features += "+dsp,";
    if (arch_flags & ArchSpec::eMIPSAse_dspr2)
        features += "+dspr2,";
    if (arch_flags & ArchSpec::eMIPSAse_mips16)
        features += "+mips16,";
    if (arch_flags & ArchSpec::eMIPSAse_micromips)
        features += "+micromips,";

    m_reg_info.reset (target->createMCRegInfo (triple.getTriple()));
    assert (m_reg_info.get());

@@ -131,7 +144,7 @@ EmulateInstructionMIPS::EmulateInstructionMIPS (const lldb_private::ArchSpec &ar
    assert (m_insn_info.get());

    m_asm_info.reset (target->createMCAsmInfo (*m_reg_info, triple.getTriple()));
    m_subtype_info.reset (target->createMCSubtargetInfo (triple.getTriple(), cpu, ""));
    m_subtype_info.reset (target->createMCSubtargetInfo (triple.getTriple(), cpu, features));
    assert (m_asm_info.get() && m_subtype_info.get());

    m_context.reset (new llvm::MCContext (m_asm_info.get(), m_reg_info.get(), nullptr));
Loading