DisassemblerLLVMC.cpp revision aa12be49067f5bb14cc3c4ba6d2e97b34e1aec35
132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan//===-- DisassemblerLLVMC.cpp -----------------------------------*- C++ -*-===//
232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan//
332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan//                     The LLVM Compiler Infrastructure
432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan//
532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan// This file is distributed under the University of Illinois Open Source
632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan// License. See LICENSE.TXT for details.
732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan//
832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan//===----------------------------------------------------------------------===//
932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
1032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "DisassemblerLLVMC.h"
1132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
1232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "llvm-c/Disassembler.h"
1332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "llvm/Support/TargetSelect.h"
1432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
1532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Core/Address.h"
1632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Core/DataExtractor.h"
1732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Core/Stream.h"
1832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Symbol/SymbolContext.h"
1932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Target/ExecutionContext.h"
2032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Target/Process.h"
2132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Target/RegisterContext.h"
2232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Target/Target.h"
2332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include "lldb/Target/StackFrame.h"
2432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
2532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan#include <regex.h>
2632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
2732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananusing namespace lldb;
2832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananusing namespace lldb_private;
2932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
3032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananclass InstructionLLVMC : public lldb_private::Instruction
3132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
3232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananpublic:
3332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    InstructionLLVMC (DisassemblerLLVMC &disasm,
3432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                      const lldb_private::Address &address,
3532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                      lldb_private::AddressClass addr_class) :
3632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        Instruction(address, addr_class),
3732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        m_disasm(disasm),
3832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        m_is_valid(false),
3932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        m_no_comments(true),
4032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        m_comment_stream()
4132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
4232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
4332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
4432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    virtual
4532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    ~InstructionLLVMC ()
4632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
4732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
4832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
4932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    static void
5032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    PadToWidth (lldb_private::StreamString &ss,
5132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                int new_width)
5232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
5332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        int old_width = ss.GetSize();
5432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
5532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        if (old_width < new_width)
5632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        {
5732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            ss.Printf("%*s", new_width - old_width, "");
5832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        }
5932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
6032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
6132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    virtual void
6232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    Dump (lldb_private::Stream *s,
6332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan          uint32_t max_opcode_byte_size,
6432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan          bool show_address,
6532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan          bool show_bytes,
6632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan          const lldb_private::ExecutionContext* exe_ctx,
6732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan          bool raw)
6832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
6932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        const size_t opcode_column_width = 7;
7032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        const size_t operand_column_width = 25;
7132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
7232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        StreamString ss;
7332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
7432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        ExecutionContextScope *exe_scope = NULL;
7532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
7632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        if ((!raw) && exe_ctx)
7732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        {
7832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            exe_scope = exe_ctx->GetBestExecutionContextScope();
7932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
8032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            DataExtractor extractor(m_raw_bytes.data(),
8132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                    m_raw_bytes.size(),
8232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                    m_disasm.GetArchitecture().GetByteOrder(),
8332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                    m_disasm.GetArchitecture().GetAddressByteSize());
8432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
8532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            Parse <true> (m_address,
8632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                          m_address_class,
8732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                          extractor,
8832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                          0,
8932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                          exe_scope);
9032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        }
9132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
9232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        if (show_address)
9332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        {
9432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            m_address.Dump(&ss,
9532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                           exe_scope,
9632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                           Address::DumpStyleLoadAddress,
9732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                           Address::DumpStyleModuleWithFileAddress,
9832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                           0);
9932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
10032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            ss.PutCString(":  ");
10132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        }
10232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
10332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        if (show_bytes)
10432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        {
10532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            if (m_opcode.GetType() == Opcode::eTypeBytes)
10632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            {
10732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                // x86_64 and i386 are the only ones that use bytes right now so
10832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                // pad out the byte dump to be able to always show 15 bytes (3 chars each)
10932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                // plus a space
11032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                if (max_opcode_byte_size > 0)
11132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                    m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
11232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                else
11332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                    m_opcode.Dump (&ss, 15 * 3 + 1);
11432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            }
11532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            else
11632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            {
11732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                // Else, we have ARM which can show up to a uint32_t 0x00000000 (10 spaces)
11832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                // plus two for padding...
11932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                if (max_opcode_byte_size > 0)
12032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                    m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
12132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                else
12232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                    m_opcode.Dump (&ss, 12);
12332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            }
12432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        }
12532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
12632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        int size_before_inst = ss.GetSize();
12732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
12832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        ss.PutCString(m_opcode_name.c_str());
12932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
13032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        PadToWidth(ss, size_before_inst + opcode_column_width);
13132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
13232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        ss.PutCString(m_mnemocics.c_str());
13332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
13432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        PadToWidth(ss, size_before_inst + opcode_column_width + operand_column_width);
13532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
13632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        if (!m_comment.empty())
13732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        {
13832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            ss.PutCString(" ; ");
13932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            ss.PutCString(m_comment.c_str());
14032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        }
14132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
14232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        ss.Flush();
14332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
14432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        s->PutCString(ss.GetData());
14532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
14632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
14732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    virtual bool
14832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    DoesBranch () const
14932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
15032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        return false;
15132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
15232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
15332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    virtual size_t
15432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    Decode (const lldb_private::Disassembler &disassembler,
15532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            const lldb_private::DataExtractor &data,
15632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            uint32_t data_offset)
15732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
15832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        Parse <false> (m_address,
15932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                       m_address_class,
16032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                       data,
16132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                       data_offset,
16232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                       NULL);
16332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
16432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        return m_opcode.GetByteSize();
16532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
16632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
16732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    void
16832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    AddReferencedAddress (std::string &description)
16932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
17032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        if (m_no_comments)
17132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            m_comment_stream.PutCString(", ");
17232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        else
17332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            m_no_comments = true;
17432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
17532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        m_comment_stream.PutCString(description.c_str());
17632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
17732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
17832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    virtual void
17932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    CalculateMnemonicOperandsAndComment (lldb_private::ExecutionContextScope *exe_scope)
18032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
18132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        DataExtractor extractor(m_raw_bytes.data(),
18232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                m_raw_bytes.size(),
18332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                m_disasm.GetArchitecture().GetByteOrder(),
18432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                m_disasm.GetArchitecture().GetAddressByteSize());
18532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
18632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        Parse <true> (m_address,
18732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                      m_address_class,
18832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                      extractor,
18932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                      0,
19032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                      exe_scope);
19132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
19232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
19332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    bool
19432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    IsValid ()
19532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
19632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        return m_is_valid;
19732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
19832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
19932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    size_t
20032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    GetByteSize ()
20132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
20232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        return m_opcode.GetByteSize();
20332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
20432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananprotected:
20532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    void PopulateOpcode (const DataExtractor &extractor,
20632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                         uint32_t offset,
20732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                         size_t inst_size)
20832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
20932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        llvm::Triple::ArchType arch = m_disasm.GetArchitecture().GetMachine();
21032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
21132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        switch (arch)
21232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        {
21332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        default:
21432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        case llvm::Triple::x86:
21532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        case llvm::Triple::x86_64:
21632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            m_opcode.SetOpcodeBytes(extractor.PeekData(offset, inst_size), inst_size);
21732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            break;
21832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        case llvm::Triple::arm:
21932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        case llvm::Triple::thumb:
22032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            switch (inst_size)
22132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            {
22232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                case 2:
22332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                    {
22432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                        m_opcode.SetOpcode16 (extractor.GetU16 (&offset));
22532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                        break;
22632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                    }
22732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                    break;
22832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                case 4:
22932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                    {
23032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                        if (arch == llvm::Triple::arm &&
23132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                            m_address_class == eAddressClassCodeAlternateISA)
23232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                        {
23332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                            // If it is a 32-bit THUMB instruction, we need to swap the upper & lower halves.
23432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                            uint32_t orig_bytes = extractor.GetU32 (&offset);
23532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                            uint16_t upper_bits = (orig_bytes >> 16) & ((1u << 16) - 1);
23632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                            uint16_t lower_bits = orig_bytes & ((1u << 16) - 1);
23732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                            uint32_t swapped = (lower_bits << 16) | upper_bits;
23832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                            m_opcode.SetOpcode32 (swapped);
23932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                        }
24032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                        else
24132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                        {
24232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                            m_opcode.SetOpcode32 (extractor.GetU32 (&offset));
24332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                        }
24432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                    }
24532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                    break;
24632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                default:
24732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                    assert (!"Invalid ARM opcode size");
24832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                    break;
24932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            }
25032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            break;
25132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        }
25232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
25332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
25432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    template <bool Reparse> bool Parse (const lldb_private::Address &address,
25532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                        lldb_private::AddressClass addr_class,
25632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                        const DataExtractor &extractor,
25732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                        uint32_t data_offset,
25832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                        lldb_private::ExecutionContextScope *exe_scope)
25932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
26032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        std::vector<char> out_string(256);
26132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
26232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        const uint8_t *data_start = extractor.GetDataStart();
26332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
26432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        m_disasm.Lock(this, exe_scope);
26532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
26632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        ::LLVMDisasmContextRef disasm_context;
26732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
26832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        if (addr_class == eAddressClassCodeAlternateISA)
26932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            disasm_context = m_disasm.m_alternate_disasm_context;
27032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        else
27132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            disasm_context = m_disasm.m_disasm_context;
27232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
27332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        m_comment_stream.Clear();
27432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
27532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        size_t inst_size = ::LLVMDisasmInstruction(disasm_context,
27632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                   const_cast<uint8_t*>(data_start) + data_offset,
27732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                   extractor.GetByteSize() - data_offset,
27832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                   address.GetFileAddress(),
27932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                   out_string.data(),
28032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                   out_string.size());
28132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
28232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        m_comment_stream.Flush();
28332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        m_no_comments = false;
28432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
28532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        m_comment.swap(m_comment_stream.GetString());
28632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
28732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        m_disasm.Unlock();
28832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
28932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        if (Reparse)
29032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        {
29132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            if (inst_size != m_raw_bytes.size())
29232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                return false;
29332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        }
29432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        else
29532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        {
29632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            if (!inst_size)
29732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                return false;
29832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
29932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            PopulateOpcode(extractor, data_offset, inst_size);
30032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
30132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            m_raw_bytes.resize(inst_size);
30232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            memcpy(m_raw_bytes.data(), data_start + data_offset, inst_size);
30332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
30432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            if (!s_regex_compiled)
30532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            {
30632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                ::regcomp(&s_regex, "[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?", REG_EXTENDED);
30732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                s_regex_compiled = true;
30832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            }
30932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
31032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            ::regmatch_t matches[3];
31132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
31232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            const char *out_data = out_string.data();
31332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
31432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            if (!::regexec(&s_regex, out_data, sizeof(matches) / sizeof(::regmatch_t), matches, 0))
31532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            {
31632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                if (matches[1].rm_so != -1)
31732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                    m_opcode_name.assign(out_data + matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so);
31832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                if (matches[2].rm_so != -1)
31932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                    m_mnemocics.assign(out_data + matches[2].rm_so, matches[2].rm_eo - matches[2].rm_so);
32032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            }
32132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
32232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            m_is_valid = true;
32332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        }
32432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
32532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        return true;
32632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
32732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
32832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    bool                    m_is_valid;
32932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    DisassemblerLLVMC      &m_disasm;
33032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    std::vector<uint8_t>    m_raw_bytes;
33132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
33232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    bool                    m_no_comments;
33332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    StreamString            m_comment_stream;
33432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
33532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    static bool             s_regex_compiled;
33632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    static ::regex_t        s_regex;
33732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan};
33832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
33932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananbool InstructionLLVMC::s_regex_compiled = false;
34032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan::regex_t InstructionLLVMC::s_regex;
34132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
34232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassembler *
34332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::CreateInstance (const ArchSpec &arch)
34432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
34532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    std::auto_ptr<DisassemblerLLVMC> disasm_ap (new DisassemblerLLVMC(arch));
34632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
34732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    if (disasm_ap.get() && disasm_ap->IsValid())
34832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        return disasm_ap.release();
34932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
35032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return NULL;
35132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
35232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
35332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch) :
35432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    Disassembler(arch),
35532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    m_disasm_context(NULL),
35632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    m_alternate_disasm_context(NULL)
35732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
35832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    m_disasm_context = ::LLVMCreateDisasm(arch.GetTriple().getTriple().c_str(),
35932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                          (void*)this,
36032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                          /*TagType=*/1,
361aa12be49067f5bb14cc3c4ba6d2e97b34e1aec35Sean Callanan                                          NULL,
36232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                          DisassemblerLLVMC::SymbolLookupCallback);
36332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
36432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    if (arch.GetTriple().getArch() == llvm::Triple::arm)
36532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
36632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        m_alternate_disasm_context = ::LLVMCreateDisasm("thumbv7-apple-darwin",
36732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                        (void*)this,
36832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                        /*TagType=*/1,
369aa12be49067f5bb14cc3c4ba6d2e97b34e1aec35Sean Callanan                                                        NULL,
37032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                        DisassemblerLLVMC::SymbolLookupCallback);
37132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
37232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
37332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
37432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::~DisassemblerLLVMC()
37532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
37632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
37732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
37832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanansize_t
37932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::DecodeInstructions (const Address &base_addr,
38032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                       const DataExtractor& data,
38132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                       uint32_t data_offset,
38232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                       uint32_t num_instructions,
38332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                       bool append)
38432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
38532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    if (!append)
38632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        m_instruction_list.Clear();
38732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
38832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    if (!IsValid())
38932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        return 0;
39032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
39132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    uint32_t data_cursor = data_offset;
39232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    size_t data_byte_size = data.GetByteSize();
39332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    uint32_t instructions_parsed = 0;
39432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
39532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    uint64_t instruction_pointer = base_addr.GetFileAddress();
39632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
39732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    std::vector<char> out_string(256);
39832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
39932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    while (data_offset < data_byte_size && instructions_parsed < num_instructions)
40032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
40132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        Address instr_address = base_addr;
40232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        instr_address.Slide(data_cursor);
40332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
40432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        AddressClass address_class = eAddressClassUnknown;
40532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
40632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        if (m_alternate_disasm_context)
40732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            address_class = instr_address.GetAddressClass ();
40832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
40932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        InstructionSP inst_sp(new InstructionLLVMC(*this,
41032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                   instr_address,
41132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                   address_class));
41232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
41332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        if (!inst_sp)
41432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            return data_cursor - data_offset;
41532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
41632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        uint32_t inst_size = inst_sp->Decode(*this, data, data_cursor);
41732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
41832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        if (!inst_size)
41932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            return data_cursor - data_offset;
42032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
42132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        m_instruction_list.Append(inst_sp);
42232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
42332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        instruction_pointer += inst_size;
42432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        data_cursor += inst_size;
42532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        instructions_parsed++;
42632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
42732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
42832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return data_cursor - data_offset;
42932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
43032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
43132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananvoid
43232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::Initialize()
43332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
43432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    PluginManager::RegisterPlugin (GetPluginNameStatic(),
43532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                   GetPluginDescriptionStatic(),
43632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                   CreateInstance);
43732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
43832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    llvm::InitializeAllTargetInfos();
43932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    llvm::InitializeAllTargetMCs();
44032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    llvm::InitializeAllAsmParsers();
44132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    llvm::InitializeAllDisassemblers();
44232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
44332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
44432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananvoid
44532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::Terminate()
44632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
44732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    PluginManager::UnregisterPlugin (CreateInstance);
44832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
44932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
45032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
45132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananconst char *
45232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::GetPluginNameStatic()
45332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
45432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return "llvm";
45532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
45632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
45732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananconst char *
45832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::GetPluginDescriptionStatic()
45932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
46032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return "Disassembler that uses LLVM opcode tables to disassemble i386, x86_64 and ARM.";
46132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
46232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
46332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananint DisassemblerLLVMC::OpInfoCallback (void *DisInfo,
46432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                       uint64_t PC,
46532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                       uint64_t Offset,
46632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                       uint64_t Size,
46732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                       int TagType,
46832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                       void *TagBug)
46932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
47032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return static_cast<DisassemblerLLVMC*>(DisInfo)->OpInfo(PC,
47132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                            Offset,
47232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                            Size,
47332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                            TagType,
47432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                            TagBug);
47532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
47632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
47732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananconst char *DisassemblerLLVMC::SymbolLookupCallback(void *DisInfo,
47832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                    uint64_t ReferenceValue,
47932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                    uint64_t *ReferenceType,
48032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                    uint64_t ReferencePC,
48132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                    const char **ReferenceName)
48232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
48332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return static_cast<DisassemblerLLVMC*>(DisInfo)->SymbolLookup(ReferenceValue,
48432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                                  ReferenceType,
48532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                                  ReferencePC,
48632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                                                  ReferenceName);
48732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
48832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
48932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananint DisassemblerLLVMC::OpInfo (uint64_t PC,
49032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                               uint64_t Offset,
49132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                               uint64_t Size,
49232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                               int TagType,
49332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                               void *TagBug)
49432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
49532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    switch (TagType)
49632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
49732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    default:
49832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        break;
49932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    case 1:
50032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        bzero (TagBug, sizeof(::LLVMOpInfo1));
50132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        break;
50232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
50332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return 0;
50432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
50532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
50632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananconst char *DisassemblerLLVMC::SymbolLookup (uint64_t ReferenceValue,
50732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                             uint64_t *ReferenceType,
50832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                             uint64_t ReferencePC,
50932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                                             const char **ReferenceName)
51032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
51132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    const char *result_name = NULL;
51232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    uint64_t result_reference_type = LLVMDisassembler_ReferenceType_InOut_None;
51332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    const char *result_referred_name = NULL;
51432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
51532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    if (m_exe_scope && m_inst)
51632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    {
51732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        Address reference_address;
51832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
519dd5e3636821e280b43793384fea14bae51a11292Johnny Chen        TargetSP target_sp (m_exe_scope->CalculateTarget());
520dd5e3636821e280b43793384fea14bae51a11292Johnny Chen        Target *target = target_sp.get();
52132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
52232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        if (target)
52332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        {
52432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            if (!target->GetSectionLoadList().IsEmpty())
52532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                target->GetSectionLoadList().ResolveLoadAddress(ReferenceValue, reference_address);
52632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            else
52732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                target->GetImages().ResolveFileAddress(ReferenceValue, reference_address);
52832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
529aa12be49067f5bb14cc3c4ba6d2e97b34e1aec35Sean Callanan            if (reference_address.IsValid() && reference_address.GetSection())
53032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            {
53132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                StreamString ss;
53232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
533aa12be49067f5bb14cc3c4ba6d2e97b34e1aec35Sean Callanan                reference_address.Dump (&ss,
534aa12be49067f5bb14cc3c4ba6d2e97b34e1aec35Sean Callanan                                        target,
535aa12be49067f5bb14cc3c4ba6d2e97b34e1aec35Sean Callanan                                        Address::DumpStyleResolvedDescriptionNoModule,
536aa12be49067f5bb14cc3c4ba6d2e97b34e1aec35Sean Callanan                                        Address::DumpStyleSectionNameOffset);
53732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
53832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan                m_inst->AddReferencedAddress(ss.GetString());
53932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan            }
54032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan        }
54132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    }
54232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
54332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    *ReferenceType = result_reference_type;
54432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    *ReferenceName = result_referred_name;
54532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
54632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return result_name;
54732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
54832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
54932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan//------------------------------------------------------------------
55032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan// PluginInterface protocol
55132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan//------------------------------------------------------------------
55232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananconst char *
55332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::GetPluginName()
55432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
55532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return "DisassemblerLLVMC";
55632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
55732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
55832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananconst char *
55932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::GetShortPluginName()
56032a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
56132a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return GetPluginNameStatic();
56232a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
56332a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
56432a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callananuint32_t
56532a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean CallananDisassemblerLLVMC::GetPluginVersion()
56632a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan{
56732a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan    return 1;
56832a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan}
56932a56ec72ca8558ff0ef0a129f7ac1ca9b79bde4Sean Callanan
570