19a1941b32dbd6de385a26fec7cac238a8fb9af25Greg Clayton//===-- UnwindAssembly-x86.cpp ----------------------------------*- C++ -*-===//
23a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//
33a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//                     The LLVM Compiler Infrastructure
43a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//
53a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// This file is distributed under the University of Illinois Open Source
63a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// License. See LICENSE.TXT for details.
73a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//
83a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//===----------------------------------------------------------------------===//
93a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
109a1941b32dbd6de385a26fec7cac238a8fb9af25Greg Clayton#include "UnwindAssembly-x86.h"
113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
12dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda#include "llvm-c/Disassembler.h"
13c23d842872157feb400f055e3b0e4ac87f586549Johnny Chen#include "llvm/Support/TargetSelect.h"
1497eecb1834431b39d4d58257f8ccfdea1db7f1deGreg Clayton
153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Core/Address.h"
163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Core/Error.h"
173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Core/ArchSpec.h"
183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Core/PluginManager.h"
1997eecb1834431b39d4d58257f8ccfdea1db7f1deGreg Clayton#include "lldb/Symbol/UnwindPlan.h"
203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Target/ExecutionContext.h"
213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Target/Process.h"
223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Target/RegisterContext.h"
233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Target/Thread.h"
243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#include "lldb/Target/Target.h"
258badcb2503ed2e2884a48f66099c1d48494817f4Greg Clayton#include "lldb/Target/UnwindAssembly.h"
263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendausing namespace lldb;
283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendausing namespace lldb_private;
293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaenum CPU {
313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_i386,
323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_x86_64
333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda};
343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaenum i386_register_numbers {
363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_eax = 0,
373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_ecx = 1,
383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_edx = 2,
393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_ebx = 3,
403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_esp = 4,
413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_ebp = 5,
423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_esi = 6,
433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_edi = 7,
443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_eip = 8
453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda};
463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaenum x86_64_register_numbers {
483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_rax = 0,
493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_rcx = 1,
503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_rdx = 2,
513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_rbx = 3,
523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_rsp = 4,
533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_rbp = 5,
543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_rsi = 6,
553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_rdi = 7,
563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_r8 = 8,
573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_r9 = 9,
583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_r10 = 10,
593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_r11 = 11,
603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_r12 = 12,
613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_r13 = 13,
623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_r14 = 14,
633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_r15 = 15,
643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    k_machine_rip = 16
653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda};
663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendastruct regmap_ent {
683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    const char *name;
693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int machine_regno;
703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int lldb_regno;
713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda};
723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendastatic struct regmap_ent i386_register_map[] = {
743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"eax", k_machine_eax, -1},
753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"ecx", k_machine_ecx, -1},
763a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"edx", k_machine_edx, -1},
773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"ebx", k_machine_ebx, -1},
783a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"esp", k_machine_esp, -1},
793a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"ebp", k_machine_ebp, -1},
803a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"esi", k_machine_esi, -1},
813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"edi", k_machine_edi, -1},
823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"eip", k_machine_eip, -1}
833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda};
843a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
853a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaconst int size_of_i386_register_map = sizeof (i386_register_map) / sizeof (struct regmap_ent);
863a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendastatic int i386_register_map_initialized = 0;
883a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
893a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendastatic struct regmap_ent x86_64_register_map[] = {
903a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"rax", k_machine_rax, -1},
913a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"rcx", k_machine_rcx, -1},
923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"rdx", k_machine_rdx, -1},
933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"rbx", k_machine_rbx, -1},
943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"rsp", k_machine_rsp, -1},
953a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"rbp", k_machine_rbp, -1},
963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"rsi", k_machine_rsi, -1},
973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"rdi", k_machine_rdi, -1},
983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"r8", k_machine_r8, -1},
993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"r9", k_machine_r9, -1},
1003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"r10", k_machine_r10, -1},
1013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"r11", k_machine_r11, -1},
1023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"r12", k_machine_r12, -1},
1033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"r13", k_machine_r13, -1},
1043a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"r14", k_machine_r14, -1},
1053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"r15", k_machine_r15, -1},
1063a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {"rip", k_machine_rip, -1}
1073a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda};
1083a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1093a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaconst int size_of_x86_64_register_map = sizeof (x86_64_register_map) / sizeof (struct regmap_ent);
1103a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendastatic int x86_64_register_map_initialized = 0;
1123a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1133a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//-----------------------------------------------------------------------------------------------
1143a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//  AssemblyParse_x86 local-file class definition & implementation functions
1153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//-----------------------------------------------------------------------------------------------
1163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaclass AssemblyParse_x86 {
1183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendapublic:
1193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
120dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    AssemblyParse_x86 (const ExecutionContext &exe_ctx, int cpu, ArchSpec &arch, AddressRange func);
121dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda
122dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    ~AssemblyParse_x86 ();
1233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool get_non_call_site_unwind_plan (UnwindPlan &unwind_plan);
1253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1268280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    bool get_fast_unwind_plan (AddressRange& func, UnwindPlan &unwind_plan);
1273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool find_first_non_prologue_insn (Address &address);
1293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaprivate:
1313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    enum { kMaxInstructionByteSize = 32 };
1323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool nonvolatile_reg_p (int machine_regno);
1343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool push_rbp_pattern_p ();
1353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool push_0_pattern_p ();
1363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool mov_rsp_rbp_pattern_p ();
1373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool sub_rsp_pattern_p (int& amount);
1383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool push_reg_p (int& regno);
1393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool mov_reg_to_local_stack_frame_p (int& regno, int& fp_offset);
1403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool ret_pattern_p ();
1413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint32_t extract_4 (uint8_t *b);
1423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool machine_regno_to_lldb_regno (int machine_regno, uint32_t& lldb_regno);
1433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool instruction_length (Address addr, int &length);
1443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
145f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    const ExecutionContext m_exe_ctx;
1463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    AddressRange m_func_bounds;
1483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    Address m_cur_insn;
1503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint8_t m_cur_insn_bytes[kMaxInstructionByteSize];
1513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int m_machine_ip_regnum;
1533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int m_machine_sp_regnum;
1543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int m_machine_fp_regnum;
1553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int m_lldb_ip_regnum;
1573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int m_lldb_sp_regnum;
1583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int m_lldb_fp_regnum;
1593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int m_wordsize;
1613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int m_cpu;
162dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    ArchSpec m_arch;
163dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    ::LLVMDisasmContextRef m_disasm_context;
164a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda
165a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda    DISALLOW_COPY_AND_ASSIGN (AssemblyParse_x86);
1663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda};
1673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
168dac50c2cc644f4114ea809103d6efb1e440b5063Jason MolendaAssemblyParse_x86::AssemblyParse_x86 (const ExecutionContext &exe_ctx, int cpu, ArchSpec &arch, AddressRange func) :
169f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    m_exe_ctx (exe_ctx),
170f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    m_func_bounds(func),
171f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    m_cur_insn (),
172f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    m_machine_ip_regnum (LLDB_INVALID_REGNUM),
173f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    m_machine_sp_regnum (LLDB_INVALID_REGNUM),
174f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    m_machine_fp_regnum (LLDB_INVALID_REGNUM),
175f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    m_lldb_ip_regnum (LLDB_INVALID_REGNUM),
176f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    m_lldb_sp_regnum (LLDB_INVALID_REGNUM),
177f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    m_lldb_fp_regnum (LLDB_INVALID_REGNUM),
178f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    m_wordsize (-1),
179dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    m_cpu(cpu),
180e33ebf02e64d120a692a37115fe58c2ad648a60eJason Molenda    m_arch(arch)
1818280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda{
1823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int *initialized_flag = NULL;
1833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (cpu == k_i386)
1843a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
1853a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        m_machine_ip_regnum = k_machine_eip;
1863a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        m_machine_sp_regnum = k_machine_esp;
1873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        m_machine_fp_regnum = k_machine_ebp;
1883a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        m_wordsize = 4;
1893a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        initialized_flag = &i386_register_map_initialized;
1903a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
1913a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    else
1923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
1933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        m_machine_ip_regnum = k_machine_rip;
1943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        m_machine_sp_regnum = k_machine_rsp;
1953a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        m_machine_fp_regnum = k_machine_rbp;
1963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        m_wordsize = 8;
1973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        initialized_flag = &x86_64_register_map_initialized;
1983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
1993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
2003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    // we only look at prologue - it will be complete earlier than 512 bytes into func
2013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (m_func_bounds.GetByteSize() == 0)
2023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        m_func_bounds.SetByteSize(512);
2033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
204f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    Thread *thread = m_exe_ctx.GetThreadPtr();
205f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    if (thread && *initialized_flag == 0)
2063a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
207f4124deeb9532044a38c0774ced872f2709347daGreg Clayton        RegisterContext *reg_ctx = thread->GetRegisterContext().get();
20808d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton        if (reg_ctx)
2093a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
2103a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            struct regmap_ent *ent;
2113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            int count, i;
2123a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            if (cpu == k_i386)
2133a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            {
2143a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                ent = i386_register_map;
2153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                count = size_of_i386_register_map;
2163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            }
2173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            else
2183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            {
2193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                ent = x86_64_register_map;
2203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                count = size_of_x86_64_register_map;
2213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            }
2223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            for (i = 0; i < count; i++, ent++)
2233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            {
22408d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton                const RegisterInfo *ri = reg_ctx->GetRegisterInfoByName (ent->name);
2253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                if (ri)
2263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                    ent->lldb_regno = ri->kinds[eRegisterKindLLDB];
2273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            }
2283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            *initialized_flag = 1;
2293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
2303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
2313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
2323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda   // on initial construction we may not have a Thread so these have to remain
2333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda   // uninitialized until we can get a RegisterContext to set up the register map table
2343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda   if (*initialized_flag == 1)
2353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda   {
2363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda       uint32_t lldb_regno;
2373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda       if (machine_regno_to_lldb_regno (m_machine_sp_regnum, lldb_regno))
2383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda           m_lldb_sp_regnum = lldb_regno;
2393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda       if (machine_regno_to_lldb_regno (m_machine_fp_regnum, lldb_regno))
2403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda           m_lldb_fp_regnum = lldb_regno;
2413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda       if (machine_regno_to_lldb_regno (m_machine_ip_regnum, lldb_regno))
2423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda           m_lldb_ip_regnum = lldb_regno;
2433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda   }
244dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda
245dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda   m_disasm_context = ::LLVMCreateDisasm(m_arch.GetTriple().getTriple().c_str(),
246dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda                                          (void*)this,
247dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda                                          /*TagType=*/1,
248dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda                                          NULL,
249dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda                                          NULL);
2503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
2513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
252dac50c2cc644f4114ea809103d6efb1e440b5063Jason MolendaAssemblyParse_x86::~AssemblyParse_x86 ()
253dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda{
254dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    ::LLVMDisasmDispose(m_disasm_context);
255dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda}
2563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
2573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// This function expects an x86 native register number (i.e. the bits stripped out of the
2583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// actual instruction), not an lldb register number.
2593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
2603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool
2613a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::nonvolatile_reg_p (int machine_regno)
2623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
2633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (m_cpu == k_i386)
2643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
2653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda          switch (machine_regno) {
2663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_ebx:
2673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_ebp:  // not actually a nonvolatile but often treated as such by convention
2683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_esi:
2693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_edi:
2703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_esp:
2713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                  return true;
2723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              default:
2733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                  return false;
2743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda          }
2753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
2763a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (m_cpu == k_x86_64)
2773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
2783a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda          switch (machine_regno) {
2793a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_rbx:
2803a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_rsp:
2813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_rbp:  // not actually a nonvolatile but often treated as such by convention
2823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_r12:
2833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_r13:
2843a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_r14:
2853a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_r15:
2863a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                  return true;
2873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              default:
2883a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                  return false;
2893a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda          }
2903a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
2913a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return false;
2923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
2933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
2943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
2953a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// Macro to detect if this is a REX mode prefix byte.
2963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#define REX_W_PREFIX_P(opcode) (((opcode) & (~0x5)) == 0x48)
2973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
2983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// The high bit which should be added to the source register number (the "R" bit)
2993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#define REX_W_SRCREG(opcode) (((opcode) & 0x4) >> 2)
3003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
3013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// The high bit which should be added to the destination register number (the "B" bit)
3023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#define REX_W_DSTREG(opcode) ((opcode) & 0x1)
3033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
3043a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// pushq %rbp [0x55]
3053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::push_rbp_pattern_p () {
3063a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint8_t *p = m_cur_insn_bytes;
3073a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (*p == 0x55)
3083a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda      return true;
3093a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return false;
3103a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
3113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
3123a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// pushq $0 ; the first instruction in start() [0x6a 0x00]
3133a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::push_0_pattern_p ()
3143a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
3153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint8_t *p = m_cur_insn_bytes;
3163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (*p == 0x6a && *(p + 1) == 0x0)
3173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        return true;
3183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return false;
3193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
3203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
3213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// movq %rsp, %rbp [0x48 0x8b 0xec] or [0x48 0x89 0xe5]
3223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// movl %esp, %ebp [0x8b 0xec] or [0x89 0xe5]
3233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::mov_rsp_rbp_pattern_p () {
3243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint8_t *p = m_cur_insn_bytes;
3253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (m_wordsize == 8 && *p == 0x48)
3263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda      p++;
3273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (*(p) == 0x8b && *(p + 1) == 0xec)
3283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        return true;
3293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (*(p) == 0x89 && *(p + 1) == 0xe5)
3303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        return true;
3313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return false;
3323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
3333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
3343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// subq $0x20, %rsp
3353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::sub_rsp_pattern_p (int& amount) {
3363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint8_t *p = m_cur_insn_bytes;
3373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (m_wordsize == 8 && *p == 0x48)
3383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda      p++;
3393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    // 8-bit immediate operand
3403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (*p == 0x83 && *(p + 1) == 0xec) {
3413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        amount = (int8_t) *(p + 2);
3423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        return true;
3433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
3443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    // 32-bit immediate operand
3453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (*p == 0x81 && *(p + 1) == 0xec) {
3463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        amount = (int32_t) extract_4 (p + 2);
3473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        return true;
3483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
3493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    // Not handled:  [0x83 0xc4] for imm8 with neg values
3503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    // [0x81 0xc4] for imm32 with neg values
3513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return false;
3523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
3533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
3543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// pushq %rbx
3553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// pushl $ebx
3563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::push_reg_p (int& regno) {
3573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint8_t *p = m_cur_insn_bytes;
3583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int regno_prefix_bit = 0;
3593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    // If we have a rex prefix byte, check to see if a B bit is set
3603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (m_wordsize == 8 && *p == 0x41) {
3613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        regno_prefix_bit = 1 << 3;
3623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        p++;
3633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
3643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (*p >= 0x50 && *p <= 0x57) {
3653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        regno = (*p - 0x50) | regno_prefix_bit;
3663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        return true;
3673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
3683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return false;
3693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
3703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
3713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// Look for an instruction sequence storing a nonvolatile register
3723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// on to the stack frame.
3733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
3743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//  movq %rax, -0x10(%rbp) [0x48 0x89 0x45 0xf0]
3753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//  movl %eax, -0xc(%ebp)  [0x89 0x45 0xf4]
3763a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::mov_reg_to_local_stack_frame_p (int& regno, int& rbp_offset) {
3773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint8_t *p = m_cur_insn_bytes;
3783a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int src_reg_prefix_bit = 0;
3793a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int target_reg_prefix_bit = 0;
3803a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
3813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (m_wordsize == 8 && REX_W_PREFIX_P (*p)) {
3823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        src_reg_prefix_bit = REX_W_SRCREG (*p) << 3;
3833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        target_reg_prefix_bit = REX_W_DSTREG (*p) << 3;
3843a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (target_reg_prefix_bit == 1) {
3853a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // rbp/ebp don't need a prefix bit - we know this isn't the
3863a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // reg we care about.
3873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            return false;
3883a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
3893a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        p++;
3903a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
3913a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
3923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (*p == 0x89) {
3933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        /* Mask off the 3-5 bits which indicate the destination register
3943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda           if this is a ModR/M byte.  */
3953a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        int opcode_destreg_masked_out = *(p + 1) & (~0x38);
3963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
3973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        /* Is this a ModR/M byte with Mod bits 01 and R/M bits 101
3983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda           and three bits between them, e.g. 01nnn101
3993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda           We're looking for a destination of ebp-disp8 or ebp-disp32.   */
4003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        int immsize;
4013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (opcode_destreg_masked_out == 0x45)
4023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda          immsize = 2;
4033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        else if (opcode_destreg_masked_out == 0x85)
4043a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda          immsize = 4;
4053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        else
4063a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda          return false;
4073a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
4083a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        int offset = 0;
4093a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (immsize == 2)
4103a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda          offset = (int8_t) *(p + 2);
4113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (immsize == 4)
4123a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda             offset = (uint32_t) extract_4 (p + 2);
4133a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (offset > 0)
4143a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda          return false;
4153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
4163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        regno = ((*(p + 1) >> 3) & 0x7) | src_reg_prefix_bit;
4173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        rbp_offset = offset > 0 ? offset : -offset;
4183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        return true;
4193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
4203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return false;
4213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
4223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
4233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// ret [0xc9] or [0xc2 imm8] or [0xca imm8]
4243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool
4253a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::ret_pattern_p ()
4263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
4273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint8_t *p = m_cur_insn_bytes;
4283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (*p == 0xc9 || *p == 0xc2 || *p == 0xca || *p == 0xc3)
4293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        return true;
4303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return false;
4313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
4323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
4333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendauint32_t
4343a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::extract_4 (uint8_t *b)
4353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
4363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint32_t v = 0;
4373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    for (int i = 3; i >= 0; i--)
4383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        v = (v << 8) | b[i];
4393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return v;
4403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
4413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
4423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool
4433a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::machine_regno_to_lldb_regno (int machine_regno, uint32_t &lldb_regno)
4443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
4453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    struct regmap_ent *ent;
4463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int count, i;
4473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (m_cpu == k_i386)
4483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
4493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        ent = i386_register_map;
4503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        count = size_of_i386_register_map;
4513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
4523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    else
4533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
4543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        ent = x86_64_register_map;
4553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        count = size_of_x86_64_register_map;
4563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
4573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    for (i = 0; i < count; i++, ent++)
4583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
4593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (ent->machine_regno == machine_regno)
4603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            if (ent->lldb_regno != -1)
4613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            {
4623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                lldb_regno = ent->lldb_regno;
4633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                return true;
4643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            }
4653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
4663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return false;
4673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
4683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
4693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool
4703a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::instruction_length (Address addr, int &length)
4713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
472dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    const uint32_t max_op_byte_size = m_arch.GetMaximumOpcodeByteSize();
473e33ebf02e64d120a692a37115fe58c2ad648a60eJason Molenda    llvm::SmallVector <uint8_t, 32> opcode_data;
474e33ebf02e64d120a692a37115fe58c2ad648a60eJason Molenda    opcode_data.resize (max_op_byte_size);
475800d11d87769e1a7083f7a5545613625396deb3eJason Molenda
476800d11d87769e1a7083f7a5545613625396deb3eJason Molenda    if (!addr.IsValid())
477800d11d87769e1a7083f7a5545613625396deb3eJason Molenda        return false;
478800d11d87769e1a7083f7a5545613625396deb3eJason Molenda
479dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    const bool prefer_file_cache = true;
480dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    Error error;
481dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    Target *target = m_exe_ctx.GetTargetPtr();
482e33ebf02e64d120a692a37115fe58c2ad648a60eJason Molenda    if (target->ReadMemory (addr, prefer_file_cache, opcode_data.data(), max_op_byte_size, error) == -1)
4833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
4848280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        return false;
4853a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
486dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda
487dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    char out_string[512];
488dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    const addr_t pc = addr.GetFileAddress();
489dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    const size_t inst_size = ::LLVMDisasmInstruction (m_disasm_context,
490e33ebf02e64d120a692a37115fe58c2ad648a60eJason Molenda                                                      opcode_data.data(),
491dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda                                                      max_op_byte_size,
492dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda                                                      pc, // PC value
493dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda                                                      out_string,
494dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda                                                      sizeof(out_string));
495dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda
496dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    length = inst_size;
4973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return true;
4983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
4993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool
5023a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan)
5033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
50468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    UnwindPlan::RowSP row(new UnwindPlan::Row);
5053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int non_prologue_insn_count = 0;
506800d11d87769e1a7083f7a5545613625396deb3eJason Molenda    m_cur_insn = m_func_bounds.GetBaseAddress ();
5073a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int current_func_text_offset = 0;
5083a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int current_sp_bytes_offset_from_cfa = 0;
509a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda    UnwindPlan::Row::RegisterLocation initial_regloc;
51019e54354ca524df5f39352569cf3ec615e69e89dJason Molenda    Error error;
5113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
512800d11d87769e1a7083f7a5545613625396deb3eJason Molenda    if (!m_cur_insn.IsValid())
513800d11d87769e1a7083f7a5545613625396deb3eJason Molenda    {
514800d11d87769e1a7083f7a5545613625396deb3eJason Molenda        return false;
515800d11d87769e1a7083f7a5545613625396deb3eJason Molenda    }
516800d11d87769e1a7083f7a5545613625396deb3eJason Molenda
5173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    unwind_plan.SetPlanValidAddressRange (m_func_bounds);
5183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    unwind_plan.SetRegisterKind (eRegisterKindLLDB);
5193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    // At the start of the function, find the CFA by adding wordsize to the SP register
52168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetOffset (current_func_text_offset);
52268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetCFARegister (m_lldb_sp_regnum);
52368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetCFAOffset (m_wordsize);
5243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    // caller's stack pointer value before the call insn is the CFA address
526a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda    initial_regloc.SetIsCFAPlusOffset (0);
52768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetRegisterInfo (m_lldb_sp_regnum, initial_regloc);
5283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    // saved instruction pointer can be found at CFA - wordsize.
5303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    current_sp_bytes_offset_from_cfa = m_wordsize;
531a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda    initial_regloc.SetAtCFAPlusOffset (-current_sp_bytes_offset_from_cfa);
53268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetRegisterInfo (m_lldb_ip_regnum, initial_regloc);
5333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    unwind_plan.AppendRow (row);
53568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda
53668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    // Allocate a new Row, populate it with the existing Row contents.
53768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    UnwindPlan::Row *newrow = new UnwindPlan::Row;
53868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    *newrow = *row.get();
53968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row.reset(newrow);
54068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda
54126100dcbc49648eac03fa8e8c3d7c793808fc8d6Greg Clayton    const bool prefer_file_cache = true;
5423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
543f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    Target *target = m_exe_ctx.GetTargetPtr();
5443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    while (m_func_bounds.ContainsFileAddress (m_cur_insn) && non_prologue_insn_count < 10)
5453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
5463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        int stack_offset, insn_len;
5473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        int machine_regno;          // register numbers masked directly out of instructions
5483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        uint32_t lldb_regno;        // register numbers in lldb's eRegisterKindLLDB numbering scheme
5493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (!instruction_length (m_cur_insn, insn_len) || insn_len == 0 || insn_len > kMaxInstructionByteSize)
5513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
5523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // An unrecognized/junk instruction
5533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            break;
5543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
555f4124deeb9532044a38c0774ced872f2709347daGreg Clayton        if (target->ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes, insn_len, error) == -1)
5563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
5573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda           // Error reading the instruction out of the file, stop scanning
5583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda           break;
5593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
5603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (push_rbp_pattern_p ())
5623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
56368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            row->SetOffset (current_func_text_offset + insn_len);
5643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            current_sp_bytes_offset_from_cfa += m_wordsize;
56568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            row->SetCFAOffset (current_sp_bytes_offset_from_cfa);
5663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            UnwindPlan::Row::RegisterLocation regloc;
56768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            regloc.SetAtCFAPlusOffset (-row->GetCFAOffset());
56868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            row->SetRegisterInfo (m_lldb_fp_regnum, regloc);
5693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            unwind_plan.AppendRow (row);
57068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            // Allocate a new Row, populate it with the existing Row contents.
57168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            newrow = new UnwindPlan::Row;
57268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            *newrow = *row.get();
57368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            row.reset(newrow);
5743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            goto loopnext;
5753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
576a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda
577a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda        if (mov_rsp_rbp_pattern_p ())
578a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda        {
57968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            row->SetOffset (current_func_text_offset + insn_len);
58068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            row->SetCFARegister (m_lldb_fp_regnum);
581a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda            unwind_plan.AppendRow (row);
58268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            // Allocate a new Row, populate it with the existing Row contents.
58368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            newrow = new UnwindPlan::Row;
58468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            *newrow = *row.get();
58568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            row.reset(newrow);
586a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda            goto loopnext;
587a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda        }
588a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda
5898280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        // This is the start() function (or a pthread equivalent), it starts with a pushl $0x0 which puts the
5908280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        // saved pc value of 0 on the stack.  In this case we want to pretend we didn't see a stack movement at all --
5918280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        // normally the saved pc value is already on the stack by the time the function starts executing.
5923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (push_0_pattern_p ())
5933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
5943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            goto loopnext;
5953a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
5963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (push_reg_p (machine_regno))
5983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
5993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            current_sp_bytes_offset_from_cfa += m_wordsize;
6003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            if (nonvolatile_reg_p (machine_regno) && machine_regno_to_lldb_regno (machine_regno, lldb_regno))
6013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            {
60268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row->SetOffset (current_func_text_offset + insn_len);
60368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                if (row->GetCFARegister() == m_lldb_sp_regnum)
6043a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                {
60568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                    row->SetCFAOffset (current_sp_bytes_offset_from_cfa);
6063a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                }
6073a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                UnwindPlan::Row::RegisterLocation regloc;
6083a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                regloc.SetAtCFAPlusOffset (-current_sp_bytes_offset_from_cfa);
60968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row->SetRegisterInfo (lldb_regno, regloc);
6103a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                unwind_plan.AppendRow (row);
61168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                // Allocate a new Row, populate it with the existing Row contents.
61268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                newrow = new UnwindPlan::Row;
61368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                *newrow = *row.get();
61468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row.reset(newrow);
6153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            }
6163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            goto loopnext;
6173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
6183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
6193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (mov_reg_to_local_stack_frame_p (machine_regno, stack_offset) && nonvolatile_reg_p (machine_regno))
6203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
6213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            if (machine_regno_to_lldb_regno (machine_regno, lldb_regno))
6223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            {
62368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row->SetOffset (current_func_text_offset + insn_len);
6243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                UnwindPlan::Row::RegisterLocation regloc;
62568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                regloc.SetAtCFAPlusOffset (-row->GetCFAOffset());
62668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row->SetRegisterInfo (lldb_regno, regloc);
6273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                unwind_plan.AppendRow (row);
62868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                // Allocate a new Row, populate it with the existing Row contents.
62968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                newrow = new UnwindPlan::Row;
63068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                *newrow = *row.get();
63168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row.reset(newrow);
6323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                goto loopnext;
6333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            }
6343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
6353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
6363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (sub_rsp_pattern_p (stack_offset))
6373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
6383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            current_sp_bytes_offset_from_cfa += stack_offset;
63968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            if (row->GetCFARegister() == m_lldb_sp_regnum)
6403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            {
64168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row->SetOffset (current_func_text_offset + insn_len);
64268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row->SetCFAOffset (current_sp_bytes_offset_from_cfa);
6433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                unwind_plan.AppendRow (row);
64468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                // Allocate a new Row, populate it with the existing Row contents.
64568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                newrow = new UnwindPlan::Row;
64668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                *newrow = *row.get();
64768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row.reset(newrow);
6483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            }
6493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            goto loopnext;
6503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
6513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
6523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (ret_pattern_p ())
6533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
6543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // we know where the end of the function is; set the limit on the PlanValidAddressRange
6553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // in case our initial "high pc" value was overly large
6563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // int original_size = m_func_bounds.GetByteSize();
6573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // int calculated_size = m_cur_insn.GetOffset() - m_func_bounds.GetBaseAddress().GetOffset() + insn_len + 1;
6583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // m_func_bounds.SetByteSize (calculated_size);
6593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // unwind_plan.SetPlanValidAddressRange (m_func_bounds);
6603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            break;
6613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
6623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
6633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        // FIXME recognize the i386 picbase setup instruction sequence,
6643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        // 0x1f16:  call   0x1f1b                   ; main + 11 at /private/tmp/a.c:3
6653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        // 0x1f1b:  popl   %eax
6663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        // and record the temporary stack movements if the CFA is not expressed in terms of ebp.
6673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
6683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        non_prologue_insn_count++;
6693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaloopnext:
6703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        m_cur_insn.SetOffset (m_cur_insn.GetOffset() + insn_len);
6713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        current_func_text_offset += insn_len;
6723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
6733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
67419e54354ca524df5f39352569cf3ec615e69e89dJason Molenda    // Now look at the byte at the end of the AddressRange for a limited attempt at describing the
675528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    // epilogue.  We're looking for the sequence
67619e54354ca524df5f39352569cf3ec615e69e89dJason Molenda
677528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    //  [ 0x5d ] mov %rbp, %rsp
678528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    //  [ 0xc3 ] ret
679528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    //  [ 0xe8 xx xx xx xx ] call __stack_chk_fail  (this is sometimes the final insn in the function)
680528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
681528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    // We want to add a Row describing how to unwind when we're stopped on the 'ret' instruction where the
682528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    // CFA is no longer defined in terms of rbp, but is now defined in terms of rsp like on function entry.
683528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
684528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    uint64_t ret_insn_offset = LLDB_INVALID_ADDRESS;
685528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    Address end_of_fun(m_func_bounds.GetBaseAddress());
686528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    end_of_fun.SetOffset (end_of_fun.GetOffset() + m_func_bounds.GetByteSize());
687528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
688528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    if (m_func_bounds.GetByteSize() > 7)
68919e54354ca524df5f39352569cf3ec615e69e89dJason Molenda    {
690528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        uint8_t bytebuf[7];
691528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        Address last_seven_bytes(end_of_fun);
692528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        last_seven_bytes.SetOffset (last_seven_bytes.GetOffset() - 7);
693528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        if (target->ReadMemory (last_seven_bytes, prefer_file_cache, bytebuf, 7, error) != -1)
69419e54354ca524df5f39352569cf3ec615e69e89dJason Molenda        {
695528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda            if (bytebuf[5] == 0x5d && bytebuf[6] == 0xc3)  // mov, ret
69619e54354ca524df5f39352569cf3ec615e69e89dJason Molenda            {
697528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda                ret_insn_offset = m_func_bounds.GetByteSize() - 1;
698528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda            }
699528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda            else if (bytebuf[0] == 0x5d && bytebuf[1] == 0xc3 && bytebuf[2] == 0xe8) // mov, ret, call
700528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda            {
701528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda                ret_insn_offset = m_func_bounds.GetByteSize() - 6;
70219e54354ca524df5f39352569cf3ec615e69e89dJason Molenda            }
70319e54354ca524df5f39352569cf3ec615e69e89dJason Molenda        }
704528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    } else if (m_func_bounds.GetByteSize() > 2)
705528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    {
706528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        uint8_t bytebuf[2];
707528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        Address last_two_bytes(end_of_fun);
708528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        last_two_bytes.SetOffset (last_two_bytes.GetOffset() - 2);
709528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        if (target->ReadMemory (last_two_bytes, prefer_file_cache, bytebuf, 2, error) != -1)
710528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        {
711528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda            if (bytebuf[0] == 0x5d && bytebuf[1] == 0xc3) // mov, ret
712528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda            {
713528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda                ret_insn_offset = m_func_bounds.GetByteSize() - 1;
714528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda            }
715528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        }
716528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    }
717528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
718528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    if (ret_insn_offset != LLDB_INVALID_ADDRESS)
719528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    {
720528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        // Create a fresh, empty Row and RegisterLocation - don't mention any other registers
72168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda        UnwindPlan::RowSP epi_row(new UnwindPlan::Row);
722528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        UnwindPlan::Row::RegisterLocation epi_regloc;
723528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
724528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        // When the ret instruction is about to be executed, here's our state
72568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda        epi_row->SetOffset (ret_insn_offset);
72668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda        epi_row->SetCFARegister (m_lldb_sp_regnum);
72768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda        epi_row->SetCFAOffset (m_wordsize);
728528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
729528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        // caller's stack pointer value before the call insn is the CFA address
730528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        epi_regloc.SetIsCFAPlusOffset (0);
73168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda        epi_row->SetRegisterInfo (m_lldb_sp_regnum, epi_regloc);
732528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
733528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        // saved instruction pointer can be found at CFA - wordsize
734528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        epi_regloc.SetAtCFAPlusOffset (-m_wordsize);
73568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda        epi_row->SetRegisterInfo (m_lldb_ip_regnum, epi_regloc);
736528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
737528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        unwind_plan.AppendRow (epi_row);
73819e54354ca524df5f39352569cf3ec615e69e89dJason Molenda    }
73919e54354ca524df5f39352569cf3ec615e69e89dJason Molenda
7408280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    unwind_plan.SetSourceName ("assembly insn profiling");
74137816a3429a075e19b74f64fd642d5a5d7ec6f2fJason Molenda    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
74237816a3429a075e19b74f64fd642d5a5d7ec6f2fJason Molenda    unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
7438280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
7443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return true;
7453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
7463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
7478280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda/* The "fast unwind plan" is valid for functions that follow the usual convention of
7488280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda   using the frame pointer register (ebp, rbp), i.e. the function prologue looks like
7498280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda     push   %rbp      [0x55]
7508280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda     mov    %rsp,%rbp [0x48 0x89 0xe5]   (this is a 2-byte insn seq on i386)
7518280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda*/
7528280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
7533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool
7548280cbe80c79bc206335831dd732e0f9fb69c519Jason MolendaAssemblyParse_x86::get_fast_unwind_plan (AddressRange& func, UnwindPlan &unwind_plan)
7553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
75668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    UnwindPlan::RowSP row(new UnwindPlan::Row);
7578280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    UnwindPlan::Row::RegisterLocation pc_reginfo;
7588280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    UnwindPlan::Row::RegisterLocation sp_reginfo;
7598280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    UnwindPlan::Row::RegisterLocation fp_reginfo;
7608280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    unwind_plan.SetRegisterKind (eRegisterKindLLDB);
7618280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
7628280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    if (!func.GetBaseAddress().IsValid())
7638280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        return false;
7648280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
765f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    Target *target = m_exe_ctx.GetTargetPtr();
766f4124deeb9532044a38c0774ced872f2709347daGreg Clayton
7678280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    uint8_t bytebuf[4];
7688280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    Error error;
76926100dcbc49648eac03fa8e8c3d7c793808fc8d6Greg Clayton    const bool prefer_file_cache = true;
770f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    if (target->ReadMemory (func.GetBaseAddress(), prefer_file_cache, bytebuf, sizeof (bytebuf), error) == -1)
7718280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        return false;
7728280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
7738280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    uint8_t i386_prologue[] = {0x55, 0x89, 0xe5};
7748280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    uint8_t x86_64_prologue[] = {0x55, 0x48, 0x89, 0xe5};
7758280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    int prologue_size;
7768280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
7778280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    if (memcmp (bytebuf, i386_prologue, sizeof (i386_prologue)) == 0)
7788280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    {
7798280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        prologue_size = sizeof (i386_prologue);
7808280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    }
7818280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    else if (memcmp (bytebuf, x86_64_prologue, sizeof (x86_64_prologue)) == 0)
7828280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    {
7838280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        prologue_size = sizeof (x86_64_prologue);
7848280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    }
7858280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    else
7868280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    {
7878280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        return false;
7888280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    }
7898280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
7908280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    pc_reginfo.SetAtCFAPlusOffset (-m_wordsize);
79168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetRegisterInfo (m_lldb_ip_regnum, pc_reginfo);
7928280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
7938280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    sp_reginfo.SetIsCFAPlusOffset (0);
79468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetRegisterInfo (m_lldb_sp_regnum, sp_reginfo);
7958280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
7968280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    // Zero instructions into the function
79768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetCFARegister (m_lldb_sp_regnum);
79868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetCFAOffset (m_wordsize);
79968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetOffset (0);
8008280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    unwind_plan.AppendRow (row);
80168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    UnwindPlan::Row *newrow = new UnwindPlan::Row;
80268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    *newrow = *row.get();
80368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row.reset(newrow);
8048280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
8058280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    // push %rbp has executed - stack moved, rbp now saved
80668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetCFAOffset (2 * m_wordsize);
8078280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    fp_reginfo.SetAtCFAPlusOffset (2 * -m_wordsize);
80868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetRegisterInfo (m_lldb_fp_regnum, fp_reginfo);
80968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetOffset (1);
8108280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    unwind_plan.AppendRow (row);
8118280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
81268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    newrow = new UnwindPlan::Row;
81368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    *newrow = *row.get();
81468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row.reset(newrow);
81568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda
8168280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    // mov %rsp, %rbp has executed
81768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetCFARegister (m_lldb_fp_regnum);
81868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetCFAOffset (2 * m_wordsize);
81968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetOffset (prologue_size);     /// 3 or 4 bytes depending on arch
8208280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    unwind_plan.AppendRow (row);
8218280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
82268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    newrow = new UnwindPlan::Row;
82368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    *newrow = *row.get();
82468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row.reset(newrow);
82568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda
8268280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    unwind_plan.SetPlanValidAddressRange (func);
82737816a3429a075e19b74f64fd642d5a5d7ec6f2fJason Molenda    unwind_plan.SetSourceName ("fast unwind assembly profiling");
82837816a3429a075e19b74f64fd642d5a5d7ec6f2fJason Molenda    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
82937816a3429a075e19b74f64fd642d5a5d7ec6f2fJason Molenda    unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
8308280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    return true;
8313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
8323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
8333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool
8343a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::find_first_non_prologue_insn (Address &address)
8353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
8363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    m_cur_insn = m_func_bounds.GetBaseAddress ();
837800d11d87769e1a7083f7a5545613625396deb3eJason Molenda    if (!m_cur_insn.IsValid())
838800d11d87769e1a7083f7a5545613625396deb3eJason Molenda    {
839800d11d87769e1a7083f7a5545613625396deb3eJason Molenda        return false;
840800d11d87769e1a7083f7a5545613625396deb3eJason Molenda    }
841800d11d87769e1a7083f7a5545613625396deb3eJason Molenda
84226100dcbc49648eac03fa8e8c3d7c793808fc8d6Greg Clayton    const bool prefer_file_cache = true;
843f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    Target *target = m_exe_ctx.GetTargetPtr();
8443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    while (m_func_bounds.ContainsFileAddress (m_cur_insn))
8453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
8463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        Error error;
8473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        int insn_len, offset, regno;
8483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (!instruction_length (m_cur_insn, insn_len) || insn_len > kMaxInstructionByteSize || insn_len == 0)
8493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
8503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // An error parsing the instruction, i.e. probably data/garbage - stop scanning
8513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            break;
8523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
853f4124deeb9532044a38c0774ced872f2709347daGreg Clayton        if (target->ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes, insn_len, error) == -1)
8543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
8553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda           // Error reading the instruction out of the file, stop scanning
8563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda           break;
8573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
8583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
8593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (push_rbp_pattern_p () || mov_rsp_rbp_pattern_p () || sub_rsp_pattern_p (offset)
8603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            || push_reg_p (regno) || mov_reg_to_local_stack_frame_p (regno, offset))
8613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
8623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            m_cur_insn.SetOffset (m_cur_insn.GetOffset() + insn_len);
8633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            continue;
8643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
8653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
8663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        // Unknown non-prologue instruction - stop scanning
8673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        break;
8683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
8693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
8703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    address = m_cur_insn;
8713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return true;
8723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
8733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
8743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
8753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
8763a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
8773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
8783a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
8793a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//-----------------------------------------------------------------------------------------------
8803a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//  UnwindAssemblyParser_x86 method definitions
8813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//-----------------------------------------------------------------------------------------------
8823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
883888a7334344778d1a4edbd58b5852ae4d53ffed9Greg ClaytonUnwindAssembly_x86::UnwindAssembly_x86 (const ArchSpec &arch, int cpu) :
884888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton    lldb_private::UnwindAssembly(arch),
885dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    m_cpu(cpu),
886dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    m_arch(arch)
887888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton{
888888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton}
889888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton
890888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton
891888a7334344778d1a4edbd58b5852ae4d53ffed9Greg ClaytonUnwindAssembly_x86::~UnwindAssembly_x86 ()
892888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton{
893888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton}
894888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton
8953a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool
896f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& func, Thread& thread, UnwindPlan& unwind_plan)
8973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
898f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    ExecutionContext exe_ctx (thread.shared_from_this());
899dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func);
9003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return asm_parse.get_non_call_site_unwind_plan (unwind_plan);
9013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool
904f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetFastUnwindPlan (AddressRange& func, Thread& thread, UnwindPlan &unwind_plan)
9053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
906f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    ExecutionContext exe_ctx (thread.shared_from_this());
907dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func);
9088280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    return asm_parse.get_fast_unwind_plan (func, unwind_plan);
9093a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9103a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool
912f4124deeb9532044a38c0774ced872f2709347daGreg ClaytonUnwindAssembly_x86::FirstNonPrologueInsn (AddressRange& func, const ExecutionContext &exe_ctx, Address& first_non_prologue_insn)
9133a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
914dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func);
9153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return asm_parse.find_first_non_prologue_insn (first_non_prologue_insn);
9163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9188badcb2503ed2e2884a48f66099c1d48494817f4Greg ClaytonUnwindAssembly *
919f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::CreateInstance (const ArchSpec &arch)
9203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
921940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton    const llvm::Triple::ArchType cpu = arch.GetMachine ();
922940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton    if (cpu == llvm::Triple::x86)
923888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        return new UnwindAssembly_x86 (arch, k_i386);
924940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton    else if (cpu == llvm::Triple::x86_64)
925888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        return new UnwindAssembly_x86 (arch, k_x86_64);
926940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton    return NULL;
9273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//------------------------------------------------------------------
9313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// PluginInterface protocol in UnwindAssemblyParser_x86
9323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//------------------------------------------------------------------
9333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9340e191607adcb0ea8ebd06c278be648a7f5c0097fGreg ClaytonConstString
935f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetPluginName()
9363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
9370e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton    return GetPluginNameStatic();
9383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendauint32_t
942f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetPluginVersion()
9433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
9443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return 1;
9453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendavoid
948f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::Initialize()
9493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
9503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    PluginManager::RegisterPlugin (GetPluginNameStatic(),
9513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                                   GetPluginDescriptionStatic(),
9523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                                   CreateInstance);
9533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendavoid
956f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::Terminate()
9573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
9583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    PluginManager::UnregisterPlugin (CreateInstance);
9593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9620e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Claytonlldb_private::ConstString
963f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetPluginNameStatic()
9643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
9650e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton    static ConstString g_name("x86");
9660e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton    return g_name;
9673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaconst char *
970f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetPluginDescriptionStatic()
9713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
9723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return "i386 and x86_64 assembly language profiler plugin.";
9733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
974