UnwindAssembly-x86.cpp revision dac50c2cc644f4114ea809103d6efb1e440b5063
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),
180dac50c2cc644f4114ea809103d6efb1e440b5063Jason 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();
473800d11d87769e1a7083f7a5545613625396deb3eJason Molenda
474800d11d87769e1a7083f7a5545613625396deb3eJason Molenda    if (!addr.IsValid())
475800d11d87769e1a7083f7a5545613625396deb3eJason Molenda        return false;
476800d11d87769e1a7083f7a5545613625396deb3eJason Molenda
477dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    uint8_t *opcode_data = (uint8_t *) malloc (max_op_byte_size);
478dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    if (opcode_data == NULL)
4793a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
4808280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        return false;
4813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
4823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
483dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    const bool prefer_file_cache = true;
484dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    Error error;
485dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    Target *target = m_exe_ctx.GetTargetPtr();
486dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    if (target->ReadMemory (addr, prefer_file_cache, opcode_data, max_op_byte_size, error) == -1)
4873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
4888280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        return false;
4893a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
490dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda
491dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    char out_string[512];
492dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    const addr_t pc = addr.GetFileAddress();
493dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    const size_t inst_size = ::LLVMDisasmInstruction (m_disasm_context,
494dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda                                                      opcode_data,
495dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda                                                      max_op_byte_size,
496dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda                                                      pc, // PC value
497dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda                                                      out_string,
498dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda                                                      sizeof(out_string));
499dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda
500dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda    length = inst_size;
501dac50c2cc644f4114ea809103d6efb1e440b5063Jason Molenda
5023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return true;
5033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
5043a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5063a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool
5073a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan)
5083a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
50968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    UnwindPlan::RowSP row(new UnwindPlan::Row);
5103a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int non_prologue_insn_count = 0;
511800d11d87769e1a7083f7a5545613625396deb3eJason Molenda    m_cur_insn = m_func_bounds.GetBaseAddress ();
5123a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int current_func_text_offset = 0;
5133a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int current_sp_bytes_offset_from_cfa = 0;
514a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda    UnwindPlan::Row::RegisterLocation initial_regloc;
51519e54354ca524df5f39352569cf3ec615e69e89dJason Molenda    Error error;
5163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
517800d11d87769e1a7083f7a5545613625396deb3eJason Molenda    if (!m_cur_insn.IsValid())
518800d11d87769e1a7083f7a5545613625396deb3eJason Molenda    {
519800d11d87769e1a7083f7a5545613625396deb3eJason Molenda        return false;
520800d11d87769e1a7083f7a5545613625396deb3eJason Molenda    }
521800d11d87769e1a7083f7a5545613625396deb3eJason Molenda
5223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    unwind_plan.SetPlanValidAddressRange (m_func_bounds);
5233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    unwind_plan.SetRegisterKind (eRegisterKindLLDB);
5243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    // At the start of the function, find the CFA by adding wordsize to the SP register
52668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetOffset (current_func_text_offset);
52768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetCFARegister (m_lldb_sp_regnum);
52868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetCFAOffset (m_wordsize);
5293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    // caller's stack pointer value before the call insn is the CFA address
531a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda    initial_regloc.SetIsCFAPlusOffset (0);
53268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetRegisterInfo (m_lldb_sp_regnum, initial_regloc);
5333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    // saved instruction pointer can be found at CFA - wordsize.
5353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    current_sp_bytes_offset_from_cfa = m_wordsize;
536a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda    initial_regloc.SetAtCFAPlusOffset (-current_sp_bytes_offset_from_cfa);
53768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetRegisterInfo (m_lldb_ip_regnum, initial_regloc);
5383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    unwind_plan.AppendRow (row);
54068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda
54168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    // Allocate a new Row, populate it with the existing Row contents.
54268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    UnwindPlan::Row *newrow = new UnwindPlan::Row;
54368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    *newrow = *row.get();
54468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row.reset(newrow);
54568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda
54626100dcbc49648eac03fa8e8c3d7c793808fc8d6Greg Clayton    const bool prefer_file_cache = true;
5473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
548f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    Target *target = m_exe_ctx.GetTargetPtr();
5493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    while (m_func_bounds.ContainsFileAddress (m_cur_insn) && non_prologue_insn_count < 10)
5503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
5513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        int stack_offset, insn_len;
5523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        int machine_regno;          // register numbers masked directly out of instructions
5533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        uint32_t lldb_regno;        // register numbers in lldb's eRegisterKindLLDB numbering scheme
5543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (!instruction_length (m_cur_insn, insn_len) || insn_len == 0 || insn_len > kMaxInstructionByteSize)
5563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
5573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // An unrecognized/junk instruction
5583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            break;
5593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
560f4124deeb9532044a38c0774ced872f2709347daGreg Clayton        if (target->ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes, insn_len, error) == -1)
5613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
5623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda           // Error reading the instruction out of the file, stop scanning
5633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda           break;
5643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
5653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (push_rbp_pattern_p ())
5673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
56868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            row->SetOffset (current_func_text_offset + insn_len);
5693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            current_sp_bytes_offset_from_cfa += m_wordsize;
57068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            row->SetCFAOffset (current_sp_bytes_offset_from_cfa);
5713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            UnwindPlan::Row::RegisterLocation regloc;
57268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            regloc.SetAtCFAPlusOffset (-row->GetCFAOffset());
57368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            row->SetRegisterInfo (m_lldb_fp_regnum, regloc);
5743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            unwind_plan.AppendRow (row);
57568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            // Allocate a new Row, populate it with the existing Row contents.
57668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            newrow = new UnwindPlan::Row;
57768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            *newrow = *row.get();
57868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            row.reset(newrow);
5793a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            goto loopnext;
5803a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
581a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda
582a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda        if (mov_rsp_rbp_pattern_p ())
583a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda        {
58468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            row->SetOffset (current_func_text_offset + insn_len);
58568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            row->SetCFARegister (m_lldb_fp_regnum);
586a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda            unwind_plan.AppendRow (row);
58768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            // Allocate a new Row, populate it with the existing Row contents.
58868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            newrow = new UnwindPlan::Row;
58968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            *newrow = *row.get();
59068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            row.reset(newrow);
591a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda            goto loopnext;
592a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda        }
593a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda
5948280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        // This is the start() function (or a pthread equivalent), it starts with a pushl $0x0 which puts the
5958280cbe80c79bc206335831dd732e0f9fb69c519Jason 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 --
5968280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        // normally the saved pc value is already on the stack by the time the function starts executing.
5973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (push_0_pattern_p ())
5983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
5993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            goto loopnext;
6003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
6013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
6023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (push_reg_p (machine_regno))
6033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
6043a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            current_sp_bytes_offset_from_cfa += m_wordsize;
6053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            if (nonvolatile_reg_p (machine_regno) && machine_regno_to_lldb_regno (machine_regno, lldb_regno))
6063a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            {
60768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row->SetOffset (current_func_text_offset + insn_len);
60868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                if (row->GetCFARegister() == m_lldb_sp_regnum)
6093a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                {
61068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                    row->SetCFAOffset (current_sp_bytes_offset_from_cfa);
6113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                }
6123a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                UnwindPlan::Row::RegisterLocation regloc;
6133a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                regloc.SetAtCFAPlusOffset (-current_sp_bytes_offset_from_cfa);
61468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row->SetRegisterInfo (lldb_regno, regloc);
6153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                unwind_plan.AppendRow (row);
61668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                // Allocate a new Row, populate it with the existing Row contents.
61768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                newrow = new UnwindPlan::Row;
61868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                *newrow = *row.get();
61968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row.reset(newrow);
6203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            }
6213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            goto loopnext;
6223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
6233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
6243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (mov_reg_to_local_stack_frame_p (machine_regno, stack_offset) && nonvolatile_reg_p (machine_regno))
6253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
6263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            if (machine_regno_to_lldb_regno (machine_regno, lldb_regno))
6273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            {
62868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row->SetOffset (current_func_text_offset + insn_len);
6293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                UnwindPlan::Row::RegisterLocation regloc;
63068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                regloc.SetAtCFAPlusOffset (-row->GetCFAOffset());
63168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row->SetRegisterInfo (lldb_regno, regloc);
6323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                unwind_plan.AppendRow (row);
63368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                // Allocate a new Row, populate it with the existing Row contents.
63468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                newrow = new UnwindPlan::Row;
63568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                *newrow = *row.get();
63668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row.reset(newrow);
6373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                goto loopnext;
6383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            }
6393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
6403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
6413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (sub_rsp_pattern_p (stack_offset))
6423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
6433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            current_sp_bytes_offset_from_cfa += stack_offset;
64468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            if (row->GetCFARegister() == m_lldb_sp_regnum)
6453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            {
64668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row->SetOffset (current_func_text_offset + insn_len);
64768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row->SetCFAOffset (current_sp_bytes_offset_from_cfa);
6483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                unwind_plan.AppendRow (row);
64968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                // Allocate a new Row, populate it with the existing Row contents.
65068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                newrow = new UnwindPlan::Row;
65168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                *newrow = *row.get();
65268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row.reset(newrow);
6533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            }
6543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            goto loopnext;
6553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
6563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
6573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (ret_pattern_p ())
6583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
6593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // we know where the end of the function is; set the limit on the PlanValidAddressRange
6603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // in case our initial "high pc" value was overly large
6613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // int original_size = m_func_bounds.GetByteSize();
6623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // int calculated_size = m_cur_insn.GetOffset() - m_func_bounds.GetBaseAddress().GetOffset() + insn_len + 1;
6633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // m_func_bounds.SetByteSize (calculated_size);
6643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // unwind_plan.SetPlanValidAddressRange (m_func_bounds);
6653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            break;
6663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
6673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
6683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        // FIXME recognize the i386 picbase setup instruction sequence,
6693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        // 0x1f16:  call   0x1f1b                   ; main + 11 at /private/tmp/a.c:3
6703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        // 0x1f1b:  popl   %eax
6713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        // and record the temporary stack movements if the CFA is not expressed in terms of ebp.
6723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
6733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        non_prologue_insn_count++;
6743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaloopnext:
6753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        m_cur_insn.SetOffset (m_cur_insn.GetOffset() + insn_len);
6763a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        current_func_text_offset += insn_len;
6773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
6783a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
67919e54354ca524df5f39352569cf3ec615e69e89dJason Molenda    // Now look at the byte at the end of the AddressRange for a limited attempt at describing the
680528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    // epilogue.  We're looking for the sequence
68119e54354ca524df5f39352569cf3ec615e69e89dJason Molenda
682528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    //  [ 0x5d ] mov %rbp, %rsp
683528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    //  [ 0xc3 ] ret
684528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    //  [ 0xe8 xx xx xx xx ] call __stack_chk_fail  (this is sometimes the final insn in the function)
685528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
686528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    // We want to add a Row describing how to unwind when we're stopped on the 'ret' instruction where the
687528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    // CFA is no longer defined in terms of rbp, but is now defined in terms of rsp like on function entry.
688528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
689528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    uint64_t ret_insn_offset = LLDB_INVALID_ADDRESS;
690528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    Address end_of_fun(m_func_bounds.GetBaseAddress());
691528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    end_of_fun.SetOffset (end_of_fun.GetOffset() + m_func_bounds.GetByteSize());
692528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
693528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    if (m_func_bounds.GetByteSize() > 7)
69419e54354ca524df5f39352569cf3ec615e69e89dJason Molenda    {
695528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        uint8_t bytebuf[7];
696528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        Address last_seven_bytes(end_of_fun);
697528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        last_seven_bytes.SetOffset (last_seven_bytes.GetOffset() - 7);
698528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        if (target->ReadMemory (last_seven_bytes, prefer_file_cache, bytebuf, 7, error) != -1)
69919e54354ca524df5f39352569cf3ec615e69e89dJason Molenda        {
700528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda            if (bytebuf[5] == 0x5d && bytebuf[6] == 0xc3)  // mov, ret
70119e54354ca524df5f39352569cf3ec615e69e89dJason Molenda            {
702528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda                ret_insn_offset = m_func_bounds.GetByteSize() - 1;
703528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda            }
704528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda            else if (bytebuf[0] == 0x5d && bytebuf[1] == 0xc3 && bytebuf[2] == 0xe8) // mov, ret, call
705528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda            {
706528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda                ret_insn_offset = m_func_bounds.GetByteSize() - 6;
70719e54354ca524df5f39352569cf3ec615e69e89dJason Molenda            }
70819e54354ca524df5f39352569cf3ec615e69e89dJason Molenda        }
709528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    } else if (m_func_bounds.GetByteSize() > 2)
710528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    {
711528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        uint8_t bytebuf[2];
712528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        Address last_two_bytes(end_of_fun);
713528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        last_two_bytes.SetOffset (last_two_bytes.GetOffset() - 2);
714528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        if (target->ReadMemory (last_two_bytes, prefer_file_cache, bytebuf, 2, error) != -1)
715528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        {
716528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda            if (bytebuf[0] == 0x5d && bytebuf[1] == 0xc3) // mov, ret
717528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda            {
718528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda                ret_insn_offset = m_func_bounds.GetByteSize() - 1;
719528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda            }
720528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        }
721528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    }
722528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
723528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    if (ret_insn_offset != LLDB_INVALID_ADDRESS)
724528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    {
725528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        // Create a fresh, empty Row and RegisterLocation - don't mention any other registers
72668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda        UnwindPlan::RowSP epi_row(new UnwindPlan::Row);
727528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        UnwindPlan::Row::RegisterLocation epi_regloc;
728528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
729528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        // When the ret instruction is about to be executed, here's our state
73068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda        epi_row->SetOffset (ret_insn_offset);
73168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda        epi_row->SetCFARegister (m_lldb_sp_regnum);
73268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda        epi_row->SetCFAOffset (m_wordsize);
733528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
734528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        // caller's stack pointer value before the call insn is the CFA address
735528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        epi_regloc.SetIsCFAPlusOffset (0);
73668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda        epi_row->SetRegisterInfo (m_lldb_sp_regnum, epi_regloc);
737528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
738528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        // saved instruction pointer can be found at CFA - wordsize
739528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        epi_regloc.SetAtCFAPlusOffset (-m_wordsize);
74068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda        epi_row->SetRegisterInfo (m_lldb_ip_regnum, epi_regloc);
741528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
742528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        unwind_plan.AppendRow (epi_row);
74319e54354ca524df5f39352569cf3ec615e69e89dJason Molenda    }
74419e54354ca524df5f39352569cf3ec615e69e89dJason Molenda
7458280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    unwind_plan.SetSourceName ("assembly insn profiling");
7468280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
7473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return true;
7483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
7493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
7508280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda/* The "fast unwind plan" is valid for functions that follow the usual convention of
7518280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda   using the frame pointer register (ebp, rbp), i.e. the function prologue looks like
7528280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda     push   %rbp      [0x55]
7538280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda     mov    %rsp,%rbp [0x48 0x89 0xe5]   (this is a 2-byte insn seq on i386)
7548280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda*/
7558280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
7563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool
7578280cbe80c79bc206335831dd732e0f9fb69c519Jason MolendaAssemblyParse_x86::get_fast_unwind_plan (AddressRange& func, UnwindPlan &unwind_plan)
7583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
75968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    UnwindPlan::RowSP row(new UnwindPlan::Row);
7608280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    UnwindPlan::Row::RegisterLocation pc_reginfo;
7618280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    UnwindPlan::Row::RegisterLocation sp_reginfo;
7628280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    UnwindPlan::Row::RegisterLocation fp_reginfo;
7638280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    unwind_plan.SetRegisterKind (eRegisterKindLLDB);
7648280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
7658280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    if (!func.GetBaseAddress().IsValid())
7668280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        return false;
7678280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
768f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    Target *target = m_exe_ctx.GetTargetPtr();
769f4124deeb9532044a38c0774ced872f2709347daGreg Clayton
7708280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    uint8_t bytebuf[4];
7718280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    Error error;
77226100dcbc49648eac03fa8e8c3d7c793808fc8d6Greg Clayton    const bool prefer_file_cache = true;
773f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    if (target->ReadMemory (func.GetBaseAddress(), prefer_file_cache, bytebuf, sizeof (bytebuf), error) == -1)
7748280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        return false;
7758280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
7768280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    uint8_t i386_prologue[] = {0x55, 0x89, 0xe5};
7778280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    uint8_t x86_64_prologue[] = {0x55, 0x48, 0x89, 0xe5};
7788280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    int prologue_size;
7798280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
7808280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    if (memcmp (bytebuf, i386_prologue, sizeof (i386_prologue)) == 0)
7818280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    {
7828280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        prologue_size = sizeof (i386_prologue);
7838280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    }
7848280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    else if (memcmp (bytebuf, x86_64_prologue, sizeof (x86_64_prologue)) == 0)
7858280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    {
7868280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        prologue_size = sizeof (x86_64_prologue);
7878280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    }
7888280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    else
7898280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    {
7908280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        return false;
7918280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    }
7928280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
7938280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    pc_reginfo.SetAtCFAPlusOffset (-m_wordsize);
79468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetRegisterInfo (m_lldb_ip_regnum, pc_reginfo);
7958280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
7968280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    sp_reginfo.SetIsCFAPlusOffset (0);
79768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetRegisterInfo (m_lldb_sp_regnum, sp_reginfo);
7988280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
7998280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    // Zero instructions into the function
80068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetCFARegister (m_lldb_sp_regnum);
80168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetCFAOffset (m_wordsize);
80268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetOffset (0);
8038280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    unwind_plan.AppendRow (row);
80468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    UnwindPlan::Row *newrow = new UnwindPlan::Row;
80568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    *newrow = *row.get();
80668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row.reset(newrow);
8078280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
8088280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    // push %rbp has executed - stack moved, rbp now saved
80968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetCFAOffset (2 * m_wordsize);
8108280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    fp_reginfo.SetAtCFAPlusOffset (2 * -m_wordsize);
81168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetRegisterInfo (m_lldb_fp_regnum, fp_reginfo);
81268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetOffset (1);
8138280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    unwind_plan.AppendRow (row);
8148280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
81568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    newrow = new UnwindPlan::Row;
81668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    *newrow = *row.get();
81768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row.reset(newrow);
81868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda
8198280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    // mov %rsp, %rbp has executed
82068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetCFARegister (m_lldb_fp_regnum);
82168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetCFAOffset (2 * m_wordsize);
82268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetOffset (prologue_size);     /// 3 or 4 bytes depending on arch
8238280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    unwind_plan.AppendRow (row);
8248280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
82568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    newrow = new UnwindPlan::Row;
82668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    *newrow = *row.get();
82768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row.reset(newrow);
82868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda
8298280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    unwind_plan.SetPlanValidAddressRange (func);
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
9343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaconst char *
935f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetPluginName()
9363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
937f6e287a873007543f3b419a71546ab8f007be90bGreg Clayton    return "UnwindAssembly_x86";
9383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaconst char *
941f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetShortPluginName()
9423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
943f6e287a873007543f3b419a71546ab8f007be90bGreg Clayton    return "unwindassembly.x86";
9443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendauint32_t
948f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetPluginVersion()
9493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
9503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return 1;
9513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendavoid
954f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::Initialize()
9553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
9563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    PluginManager::RegisterPlugin (GetPluginNameStatic(),
9573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                                   GetPluginDescriptionStatic(),
9583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                                   CreateInstance);
9593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendavoid
962f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::Terminate()
9633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
9643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    PluginManager::UnregisterPlugin (CreateInstance);
9653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaconst char *
969f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetPluginNameStatic()
9703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
971f6e287a873007543f3b419a71546ab8f007be90bGreg Clayton    return "UnwindAssembly_x86";
9723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaconst char *
975f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetPluginDescriptionStatic()
9763a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
9773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return "i386 and x86_64 assembly language profiler plugin.";
9783a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
979