UnwindAssembly-x86.cpp revision 68fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7
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
1297eecb1834431b39d4d58257f8ccfdea1db7f1deGreg Clayton#include "llvm-c/EnhancedDisassembly.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
120f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    AssemblyParse_x86 (const ExecutionContext &exe_ctx, int cpu, AddressRange func);
1213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool get_non_call_site_unwind_plan (UnwindPlan &unwind_plan);
1233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1248280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    bool get_fast_unwind_plan (AddressRange& func, UnwindPlan &unwind_plan);
1253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool find_first_non_prologue_insn (Address &address);
1273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaprivate:
1293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    enum { kMaxInstructionByteSize = 32 };
1303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool nonvolatile_reg_p (int machine_regno);
1323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool push_rbp_pattern_p ();
1333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool push_0_pattern_p ();
1343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool mov_rsp_rbp_pattern_p ();
1353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool sub_rsp_pattern_p (int& amount);
1363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool push_reg_p (int& regno);
1373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool mov_reg_to_local_stack_frame_p (int& regno, int& fp_offset);
1383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool ret_pattern_p ();
1393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint32_t extract_4 (uint8_t *b);
1403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool machine_regno_to_lldb_regno (int machine_regno, uint32_t& lldb_regno);
1413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    bool instruction_length (Address addr, int &length);
1423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
143f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    const ExecutionContext m_exe_ctx;
1443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    AddressRange m_func_bounds;
1463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    Address m_cur_insn;
1483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint8_t m_cur_insn_bytes[kMaxInstructionByteSize];
1493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int m_machine_ip_regnum;
1513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int m_machine_sp_regnum;
1523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int m_machine_fp_regnum;
1533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int m_lldb_ip_regnum;
1553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int m_lldb_sp_regnum;
1563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int m_lldb_fp_regnum;
1573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int m_wordsize;
1593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int m_cpu;
160a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda
161a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda    DISALLOW_COPY_AND_ASSIGN (AssemblyParse_x86);
1623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda};
1633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
164f4124deeb9532044a38c0774ced872f2709347daGreg ClaytonAssemblyParse_x86::AssemblyParse_x86 (const ExecutionContext &exe_ctx, int cpu, AddressRange func) :
165f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    m_exe_ctx (exe_ctx),
166f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    m_func_bounds(func),
167f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    m_cur_insn (),
168f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    m_machine_ip_regnum (LLDB_INVALID_REGNUM),
169f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    m_machine_sp_regnum (LLDB_INVALID_REGNUM),
170f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    m_machine_fp_regnum (LLDB_INVALID_REGNUM),
171f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    m_lldb_ip_regnum (LLDB_INVALID_REGNUM),
172f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    m_lldb_sp_regnum (LLDB_INVALID_REGNUM),
173f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    m_lldb_fp_regnum (LLDB_INVALID_REGNUM),
174f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    m_wordsize (-1),
175f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    m_cpu(cpu)
1768280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda{
1773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int *initialized_flag = NULL;
1783a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (cpu == k_i386)
1793a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
1803a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        m_machine_ip_regnum = k_machine_eip;
1813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        m_machine_sp_regnum = k_machine_esp;
1823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        m_machine_fp_regnum = k_machine_ebp;
1833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        m_wordsize = 4;
1843a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        initialized_flag = &i386_register_map_initialized;
1853a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
1863a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    else
1873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
1883a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        m_machine_ip_regnum = k_machine_rip;
1893a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        m_machine_sp_regnum = k_machine_rsp;
1903a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        m_machine_fp_regnum = k_machine_rbp;
1913a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        m_wordsize = 8;
1923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        initialized_flag = &x86_64_register_map_initialized;
1933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
1943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
1953a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    // we only look at prologue - it will be complete earlier than 512 bytes into func
1963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (m_func_bounds.GetByteSize() == 0)
1973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        m_func_bounds.SetByteSize(512);
1983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
199f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    Thread *thread = m_exe_ctx.GetThreadPtr();
200f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    if (thread && *initialized_flag == 0)
2013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
202f4124deeb9532044a38c0774ced872f2709347daGreg Clayton        RegisterContext *reg_ctx = thread->GetRegisterContext().get();
20308d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton        if (reg_ctx)
2043a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
2053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            struct regmap_ent *ent;
2063a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            int count, i;
2073a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            if (cpu == k_i386)
2083a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            {
2093a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                ent = i386_register_map;
2103a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                count = size_of_i386_register_map;
2113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            }
2123a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            else
2133a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            {
2143a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                ent = x86_64_register_map;
2153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                count = size_of_x86_64_register_map;
2163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            }
2173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            for (i = 0; i < count; i++, ent++)
2183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            {
21908d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton                const RegisterInfo *ri = reg_ctx->GetRegisterInfoByName (ent->name);
2203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                if (ri)
2213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                    ent->lldb_regno = ri->kinds[eRegisterKindLLDB];
2223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            }
2233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            *initialized_flag = 1;
2243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
2253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
2263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
2273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda   // on initial construction we may not have a Thread so these have to remain
2283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda   // uninitialized until we can get a RegisterContext to set up the register map table
2293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda   if (*initialized_flag == 1)
2303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda   {
2313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda       uint32_t lldb_regno;
2323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda       if (machine_regno_to_lldb_regno (m_machine_sp_regnum, lldb_regno))
2333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda           m_lldb_sp_regnum = lldb_regno;
2343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda       if (machine_regno_to_lldb_regno (m_machine_fp_regnum, lldb_regno))
2353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda           m_lldb_fp_regnum = lldb_regno;
2363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda       if (machine_regno_to_lldb_regno (m_machine_ip_regnum, lldb_regno))
2373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda           m_lldb_ip_regnum = lldb_regno;
2383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda   }
2393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
2403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
2413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
2423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// This function expects an x86 native register number (i.e. the bits stripped out of the
2433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// actual instruction), not an lldb register number.
2443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
2453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool
2463a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::nonvolatile_reg_p (int machine_regno)
2473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
2483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (m_cpu == k_i386)
2493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
2503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda          switch (machine_regno) {
2513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_ebx:
2523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_ebp:  // not actually a nonvolatile but often treated as such by convention
2533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_esi:
2543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_edi:
2553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_esp:
2563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                  return true;
2573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              default:
2583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                  return false;
2593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda          }
2603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
2613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (m_cpu == k_x86_64)
2623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
2633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda          switch (machine_regno) {
2643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_rbx:
2653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_rsp:
2663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_rbp:  // not actually a nonvolatile but often treated as such by convention
2673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_r12:
2683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_r13:
2693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_r14:
2703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              case k_machine_r15:
2713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                  return true;
2723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda              default:
2733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                  return false;
2743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda          }
2753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
2763a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return false;
2773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
2783a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
2793a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
2803a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// Macro to detect if this is a REX mode prefix byte.
2813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#define REX_W_PREFIX_P(opcode) (((opcode) & (~0x5)) == 0x48)
2823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
2833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// The high bit which should be added to the source register number (the "R" bit)
2843a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#define REX_W_SRCREG(opcode) (((opcode) & 0x4) >> 2)
2853a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
2863a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// The high bit which should be added to the destination register number (the "B" bit)
2873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda#define REX_W_DSTREG(opcode) ((opcode) & 0x1)
2883a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
2893a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// pushq %rbp [0x55]
2903a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::push_rbp_pattern_p () {
2913a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint8_t *p = m_cur_insn_bytes;
2923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (*p == 0x55)
2933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda      return true;
2943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return false;
2953a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
2963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
2973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// pushq $0 ; the first instruction in start() [0x6a 0x00]
2983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::push_0_pattern_p ()
2993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
3003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint8_t *p = m_cur_insn_bytes;
3013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (*p == 0x6a && *(p + 1) == 0x0)
3023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        return true;
3033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return false;
3043a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
3053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
3063a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// movq %rsp, %rbp [0x48 0x8b 0xec] or [0x48 0x89 0xe5]
3073a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// movl %esp, %ebp [0x8b 0xec] or [0x89 0xe5]
3083a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::mov_rsp_rbp_pattern_p () {
3093a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint8_t *p = m_cur_insn_bytes;
3103a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (m_wordsize == 8 && *p == 0x48)
3113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda      p++;
3123a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (*(p) == 0x8b && *(p + 1) == 0xec)
3133a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        return true;
3143a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (*(p) == 0x89 && *(p + 1) == 0xe5)
3153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        return true;
3163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return false;
3173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
3183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
3193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// subq $0x20, %rsp
3203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::sub_rsp_pattern_p (int& amount) {
3213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint8_t *p = m_cur_insn_bytes;
3223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (m_wordsize == 8 && *p == 0x48)
3233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda      p++;
3243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    // 8-bit immediate operand
3253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (*p == 0x83 && *(p + 1) == 0xec) {
3263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        amount = (int8_t) *(p + 2);
3273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        return true;
3283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
3293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    // 32-bit immediate operand
3303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (*p == 0x81 && *(p + 1) == 0xec) {
3313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        amount = (int32_t) extract_4 (p + 2);
3323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        return true;
3333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
3343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    // Not handled:  [0x83 0xc4] for imm8 with neg values
3353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    // [0x81 0xc4] for imm32 with neg values
3363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return false;
3373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
3383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
3393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// pushq %rbx
3403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// pushl $ebx
3413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::push_reg_p (int& regno) {
3423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint8_t *p = m_cur_insn_bytes;
3433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int regno_prefix_bit = 0;
3443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    // If we have a rex prefix byte, check to see if a B bit is set
3453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (m_wordsize == 8 && *p == 0x41) {
3463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        regno_prefix_bit = 1 << 3;
3473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        p++;
3483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
3493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (*p >= 0x50 && *p <= 0x57) {
3503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        regno = (*p - 0x50) | regno_prefix_bit;
3513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        return true;
3523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
3533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return false;
3543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
3553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
3563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// Look for an instruction sequence storing a nonvolatile register
3573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// on to the stack frame.
3583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
3593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//  movq %rax, -0x10(%rbp) [0x48 0x89 0x45 0xf0]
3603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//  movl %eax, -0xc(%ebp)  [0x89 0x45 0xf4]
3613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool AssemblyParse_x86::mov_reg_to_local_stack_frame_p (int& regno, int& rbp_offset) {
3623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint8_t *p = m_cur_insn_bytes;
3633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int src_reg_prefix_bit = 0;
3643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int target_reg_prefix_bit = 0;
3653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
3663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (m_wordsize == 8 && REX_W_PREFIX_P (*p)) {
3673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        src_reg_prefix_bit = REX_W_SRCREG (*p) << 3;
3683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        target_reg_prefix_bit = REX_W_DSTREG (*p) << 3;
3693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (target_reg_prefix_bit == 1) {
3703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // rbp/ebp don't need a prefix bit - we know this isn't the
3713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // reg we care about.
3723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            return false;
3733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
3743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        p++;
3753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
3763a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
3773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (*p == 0x89) {
3783a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        /* Mask off the 3-5 bits which indicate the destination register
3793a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda           if this is a ModR/M byte.  */
3803a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        int opcode_destreg_masked_out = *(p + 1) & (~0x38);
3813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
3823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        /* Is this a ModR/M byte with Mod bits 01 and R/M bits 101
3833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda           and three bits between them, e.g. 01nnn101
3843a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda           We're looking for a destination of ebp-disp8 or ebp-disp32.   */
3853a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        int immsize;
3863a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (opcode_destreg_masked_out == 0x45)
3873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda          immsize = 2;
3883a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        else if (opcode_destreg_masked_out == 0x85)
3893a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda          immsize = 4;
3903a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        else
3913a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda          return false;
3923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
3933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        int offset = 0;
3943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (immsize == 2)
3953a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda          offset = (int8_t) *(p + 2);
3963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (immsize == 4)
3973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda             offset = (uint32_t) extract_4 (p + 2);
3983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (offset > 0)
3993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda          return false;
4003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
4013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        regno = ((*(p + 1) >> 3) & 0x7) | src_reg_prefix_bit;
4023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        rbp_offset = offset > 0 ? offset : -offset;
4033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        return true;
4043a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
4053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return false;
4063a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
4073a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
4083a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// ret [0xc9] or [0xc2 imm8] or [0xca imm8]
4093a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool
4103a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::ret_pattern_p ()
4113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
4123a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint8_t *p = m_cur_insn_bytes;
4133a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (*p == 0xc9 || *p == 0xc2 || *p == 0xca || *p == 0xc3)
4143a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        return true;
4153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return false;
4163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
4173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
4183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendauint32_t
4193a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::extract_4 (uint8_t *b)
4203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
4213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint32_t v = 0;
4223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    for (int i = 3; i >= 0; i--)
4233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        v = (v << 8) | b[i];
4243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return v;
4253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
4263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
4273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool
4283a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::machine_regno_to_lldb_regno (int machine_regno, uint32_t &lldb_regno)
4293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
4303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    struct regmap_ent *ent;
4313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int count, i;
4323a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (m_cpu == k_i386)
4333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
4343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        ent = i386_register_map;
4353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        count = size_of_i386_register_map;
4363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
4373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    else
4383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
4393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        ent = x86_64_register_map;
4403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        count = size_of_x86_64_register_map;
4413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
4423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    for (i = 0; i < count; i++, ent++)
4433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
4443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (ent->machine_regno == machine_regno)
4453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            if (ent->lldb_regno != -1)
4463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            {
4473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                lldb_regno = ent->lldb_regno;
4483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                return true;
4493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            }
4503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
4513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return false;
4523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
4533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
4543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendastruct edis_byte_read_token
4553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
4563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    Address *address;
4573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    Target *target;
4583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda};
4593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
4603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
4613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendastatic int
4623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaread_byte_for_edis (uint8_t *buf, uint64_t offset_address, void *arg)
4633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
4643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (arg == 0)
4653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        return -1;
4663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    struct edis_byte_read_token *tok = (edis_byte_read_token *) arg;
4673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    Address *base_address = tok->address;
4683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    Target *target = tok->target;
4693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
4703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    Address read_addr = *base_address;
4713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    read_addr.SetOffset (offset_address);
4723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
4733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint8_t onebyte_buf[1];
4743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    Error error;
47526100dcbc49648eac03fa8e8c3d7c793808fc8d6Greg Clayton    const bool prefer_file_cache = true;
47626100dcbc49648eac03fa8e8c3d7c793808fc8d6Greg Clayton    if (target->ReadMemory (read_addr, prefer_file_cache, onebyte_buf, 1, error) != -1)
4773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
4783a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        *buf = onebyte_buf[0];
4793a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        return 0;
4803a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
4813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return -1;
4823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
4833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
4843a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
4853a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool
4863a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::instruction_length (Address addr, int &length)
4873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
4883a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    const char *triple;
489800d11d87769e1a7083f7a5545613625396deb3eJason Molenda
490800d11d87769e1a7083f7a5545613625396deb3eJason Molenda    if (!addr.IsValid())
491800d11d87769e1a7083f7a5545613625396deb3eJason Molenda        return false;
492800d11d87769e1a7083f7a5545613625396deb3eJason Molenda
4933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    // FIXME should probably pass down the ArchSpec and work from that to make a portable triple
4943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (m_cpu == k_i386)
495a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda        triple = "i386-unknown-unknown";
4963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    else
497a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda        triple = "x86_64-unknown-unknown";
4983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
499c23d842872157feb400f055e3b0e4ac87f586549Johnny Chen    // Initialize the LLVM objects needed to use the disassembler.
500c23d842872157feb400f055e3b0e4ac87f586549Johnny Chen    static struct InitializeLLVM {
501c23d842872157feb400f055e3b0e4ac87f586549Johnny Chen        InitializeLLVM() {
502c23d842872157feb400f055e3b0e4ac87f586549Johnny Chen            llvm::InitializeAllTargetInfos();
503c23d842872157feb400f055e3b0e4ac87f586549Johnny Chen            llvm::InitializeAllTargetMCs();
504c23d842872157feb400f055e3b0e4ac87f586549Johnny Chen            llvm::InitializeAllAsmParsers();
505c23d842872157feb400f055e3b0e4ac87f586549Johnny Chen            llvm::InitializeAllDisassemblers();
506c23d842872157feb400f055e3b0e4ac87f586549Johnny Chen        }
507c23d842872157feb400f055e3b0e4ac87f586549Johnny Chen    } InitializeLLVM;
508c23d842872157feb400f055e3b0e4ac87f586549Johnny Chen
5093a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    EDDisassemblerRef disasm;
510f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    EDInstRef cur_insn;
5113a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
512a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda    if (EDGetDisassembler (&disasm, triple, kEDAssemblySyntaxX86ATT) != 0)
5133a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
5148280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        return false;
5153a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
5163a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5173a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint64_t addr_offset = addr.GetOffset();
5183a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    struct edis_byte_read_token arg;
5193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    arg.address = &addr;
520f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    arg.target = m_exe_ctx.GetTargetPtr();
5213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    if (EDCreateInsts (&cur_insn, 1, disasm, read_byte_for_edis, addr_offset, &arg) != 1)
5223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
5238280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        return false;
5243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
5253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    length = EDInstByteSize (cur_insn);
5263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    EDReleaseInst (cur_insn);
5273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return true;
5283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
5293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool
5323a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan)
5333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
53468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    UnwindPlan::RowSP row(new UnwindPlan::Row);
5353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int non_prologue_insn_count = 0;
536800d11d87769e1a7083f7a5545613625396deb3eJason Molenda    m_cur_insn = m_func_bounds.GetBaseAddress ();
5373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int current_func_text_offset = 0;
5383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    int current_sp_bytes_offset_from_cfa = 0;
539a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda    UnwindPlan::Row::RegisterLocation initial_regloc;
54019e54354ca524df5f39352569cf3ec615e69e89dJason Molenda    Error error;
5413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
542800d11d87769e1a7083f7a5545613625396deb3eJason Molenda    if (!m_cur_insn.IsValid())
543800d11d87769e1a7083f7a5545613625396deb3eJason Molenda    {
544800d11d87769e1a7083f7a5545613625396deb3eJason Molenda        return false;
545800d11d87769e1a7083f7a5545613625396deb3eJason Molenda    }
546800d11d87769e1a7083f7a5545613625396deb3eJason Molenda
5473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    unwind_plan.SetPlanValidAddressRange (m_func_bounds);
5483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    unwind_plan.SetRegisterKind (eRegisterKindLLDB);
5493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    // At the start of the function, find the CFA by adding wordsize to the SP register
55168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetOffset (current_func_text_offset);
55268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetCFARegister (m_lldb_sp_regnum);
55368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetCFAOffset (m_wordsize);
5543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    // caller's stack pointer value before the call insn is the CFA address
556a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda    initial_regloc.SetIsCFAPlusOffset (0);
55768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetRegisterInfo (m_lldb_sp_regnum, initial_regloc);
5583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5593a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    // saved instruction pointer can be found at CFA - wordsize.
5603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    current_sp_bytes_offset_from_cfa = m_wordsize;
561a6b71de68536fd9c9917f59e42f1d8e39b06f8fcJason Molenda    initial_regloc.SetAtCFAPlusOffset (-current_sp_bytes_offset_from_cfa);
56268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetRegisterInfo (m_lldb_ip_regnum, initial_regloc);
5633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    unwind_plan.AppendRow (row);
56568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda
56668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    // Allocate a new Row, populate it with the existing Row contents.
56768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    UnwindPlan::Row *newrow = new UnwindPlan::Row;
56868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    *newrow = *row.get();
56968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row.reset(newrow);
57068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda
57126100dcbc49648eac03fa8e8c3d7c793808fc8d6Greg Clayton    const bool prefer_file_cache = true;
5723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
573f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    Target *target = m_exe_ctx.GetTargetPtr();
5743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    while (m_func_bounds.ContainsFileAddress (m_cur_insn) && non_prologue_insn_count < 10)
5753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
5763a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        int stack_offset, insn_len;
5773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        int machine_regno;          // register numbers masked directly out of instructions
5783a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        uint32_t lldb_regno;        // register numbers in lldb's eRegisterKindLLDB numbering scheme
5793a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5803a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (!instruction_length (m_cur_insn, insn_len) || insn_len == 0 || insn_len > kMaxInstructionByteSize)
5813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
5823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // An unrecognized/junk instruction
5833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            break;
5843a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
585f4124deeb9532044a38c0774ced872f2709347daGreg Clayton        if (target->ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes, insn_len, error) == -1)
5863a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
5873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda           // Error reading the instruction out of the file, stop scanning
5883a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda           break;
5893a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
5903a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
5913a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (push_rbp_pattern_p ())
5923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
59368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            row->SetOffset (current_func_text_offset + insn_len);
5943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            current_sp_bytes_offset_from_cfa += m_wordsize;
59568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            row->SetCFAOffset (current_sp_bytes_offset_from_cfa);
5963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            UnwindPlan::Row::RegisterLocation regloc;
59768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            regloc.SetAtCFAPlusOffset (-row->GetCFAOffset());
59868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            row->SetRegisterInfo (m_lldb_fp_regnum, regloc);
5993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            unwind_plan.AppendRow (row);
60068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            // Allocate a new Row, populate it with the existing Row contents.
60168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            newrow = new UnwindPlan::Row;
60268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            *newrow = *row.get();
60368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            row.reset(newrow);
6043a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            goto loopnext;
6053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
606a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda
607a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda        if (mov_rsp_rbp_pattern_p ())
608a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda        {
60968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            row->SetOffset (current_func_text_offset + insn_len);
61068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            row->SetCFARegister (m_lldb_fp_regnum);
611a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda            unwind_plan.AppendRow (row);
61268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            // Allocate a new Row, populate it with the existing Row contents.
61368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            newrow = new UnwindPlan::Row;
61468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            *newrow = *row.get();
61568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            row.reset(newrow);
616a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda            goto loopnext;
617a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda        }
618a2c269c017d37b3e35f461af52e11cdd6300d5e4Jason Molenda
6198280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        // This is the start() function (or a pthread equivalent), it starts with a pushl $0x0 which puts the
6208280cbe80c79bc206335831dd732e0f9fb69c519Jason 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 --
6218280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        // normally the saved pc value is already on the stack by the time the function starts executing.
6223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (push_0_pattern_p ())
6233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
6243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            goto loopnext;
6253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
6263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
6273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (push_reg_p (machine_regno))
6283a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
6293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            current_sp_bytes_offset_from_cfa += m_wordsize;
6303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            if (nonvolatile_reg_p (machine_regno) && machine_regno_to_lldb_regno (machine_regno, lldb_regno))
6313a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            {
63268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row->SetOffset (current_func_text_offset + insn_len);
63368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                if (row->GetCFARegister() == m_lldb_sp_regnum)
6343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                {
63568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                    row->SetCFAOffset (current_sp_bytes_offset_from_cfa);
6363a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                }
6373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                UnwindPlan::Row::RegisterLocation regloc;
6383a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                regloc.SetAtCFAPlusOffset (-current_sp_bytes_offset_from_cfa);
63968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row->SetRegisterInfo (lldb_regno, regloc);
6403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                unwind_plan.AppendRow (row);
64168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                // Allocate a new Row, populate it with the existing Row contents.
64268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                newrow = new UnwindPlan::Row;
64368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                *newrow = *row.get();
64468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row.reset(newrow);
6453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            }
6463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            goto loopnext;
6473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
6483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
6493a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (mov_reg_to_local_stack_frame_p (machine_regno, stack_offset) && nonvolatile_reg_p (machine_regno))
6503a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
6513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            if (machine_regno_to_lldb_regno (machine_regno, lldb_regno))
6523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            {
65368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row->SetOffset (current_func_text_offset + insn_len);
6543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                UnwindPlan::Row::RegisterLocation regloc;
65568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                regloc.SetAtCFAPlusOffset (-row->GetCFAOffset());
65668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row->SetRegisterInfo (lldb_regno, regloc);
6573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                unwind_plan.AppendRow (row);
65868fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                // Allocate a new Row, populate it with the existing Row contents.
65968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                newrow = new UnwindPlan::Row;
66068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                *newrow = *row.get();
66168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row.reset(newrow);
6623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                goto loopnext;
6633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            }
6643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
6653a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
6663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (sub_rsp_pattern_p (stack_offset))
6673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
6683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            current_sp_bytes_offset_from_cfa += stack_offset;
66968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda            if (row->GetCFARegister() == m_lldb_sp_regnum)
6703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            {
67168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row->SetOffset (current_func_text_offset + insn_len);
67268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row->SetCFAOffset (current_sp_bytes_offset_from_cfa);
6733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                unwind_plan.AppendRow (row);
67468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                // Allocate a new Row, populate it with the existing Row contents.
67568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                newrow = new UnwindPlan::Row;
67668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                *newrow = *row.get();
67768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda                row.reset(newrow);
6783a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            }
6793a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            goto loopnext;
6803a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
6813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
6823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (ret_pattern_p ())
6833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
6843a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // we know where the end of the function is; set the limit on the PlanValidAddressRange
6853a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // in case our initial "high pc" value was overly large
6863a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // int original_size = m_func_bounds.GetByteSize();
6873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // int calculated_size = m_cur_insn.GetOffset() - m_func_bounds.GetBaseAddress().GetOffset() + insn_len + 1;
6883a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // m_func_bounds.SetByteSize (calculated_size);
6893a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // unwind_plan.SetPlanValidAddressRange (m_func_bounds);
6903a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            break;
6913a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
6923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
6933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        // FIXME recognize the i386 picbase setup instruction sequence,
6943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        // 0x1f16:  call   0x1f1b                   ; main + 11 at /private/tmp/a.c:3
6953a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        // 0x1f1b:  popl   %eax
6963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        // and record the temporary stack movements if the CFA is not expressed in terms of ebp.
6973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
6983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        non_prologue_insn_count++;
6993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaloopnext:
7003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        m_cur_insn.SetOffset (m_cur_insn.GetOffset() + insn_len);
7013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        current_func_text_offset += insn_len;
7023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
7033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
70419e54354ca524df5f39352569cf3ec615e69e89dJason Molenda    // Now look at the byte at the end of the AddressRange for a limited attempt at describing the
705528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    // epilogue.  We're looking for the sequence
70619e54354ca524df5f39352569cf3ec615e69e89dJason Molenda
707528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    //  [ 0x5d ] mov %rbp, %rsp
708528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    //  [ 0xc3 ] ret
709528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    //  [ 0xe8 xx xx xx xx ] call __stack_chk_fail  (this is sometimes the final insn in the function)
710528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
711528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    // We want to add a Row describing how to unwind when we're stopped on the 'ret' instruction where the
712528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    // CFA is no longer defined in terms of rbp, but is now defined in terms of rsp like on function entry.
713528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
714528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    uint64_t ret_insn_offset = LLDB_INVALID_ADDRESS;
715528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    Address end_of_fun(m_func_bounds.GetBaseAddress());
716528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    end_of_fun.SetOffset (end_of_fun.GetOffset() + m_func_bounds.GetByteSize());
717528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
718528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    if (m_func_bounds.GetByteSize() > 7)
71919e54354ca524df5f39352569cf3ec615e69e89dJason Molenda    {
720528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        uint8_t bytebuf[7];
721528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        Address last_seven_bytes(end_of_fun);
722528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        last_seven_bytes.SetOffset (last_seven_bytes.GetOffset() - 7);
723528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        if (target->ReadMemory (last_seven_bytes, prefer_file_cache, bytebuf, 7, error) != -1)
72419e54354ca524df5f39352569cf3ec615e69e89dJason Molenda        {
725528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda            if (bytebuf[5] == 0x5d && bytebuf[6] == 0xc3)  // mov, ret
72619e54354ca524df5f39352569cf3ec615e69e89dJason Molenda            {
727528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda                ret_insn_offset = m_func_bounds.GetByteSize() - 1;
728528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda            }
729528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda            else if (bytebuf[0] == 0x5d && bytebuf[1] == 0xc3 && bytebuf[2] == 0xe8) // mov, ret, call
730528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda            {
731528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda                ret_insn_offset = m_func_bounds.GetByteSize() - 6;
73219e54354ca524df5f39352569cf3ec615e69e89dJason Molenda            }
73319e54354ca524df5f39352569cf3ec615e69e89dJason Molenda        }
734528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    } else if (m_func_bounds.GetByteSize() > 2)
735528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    {
736528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        uint8_t bytebuf[2];
737528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        Address last_two_bytes(end_of_fun);
738528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        last_two_bytes.SetOffset (last_two_bytes.GetOffset() - 2);
739528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        if (target->ReadMemory (last_two_bytes, prefer_file_cache, bytebuf, 2, error) != -1)
740528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        {
741528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda            if (bytebuf[0] == 0x5d && bytebuf[1] == 0xc3) // mov, ret
742528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda            {
743528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda                ret_insn_offset = m_func_bounds.GetByteSize() - 1;
744528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda            }
745528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        }
746528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    }
747528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
748528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    if (ret_insn_offset != LLDB_INVALID_ADDRESS)
749528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda    {
750528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        // Create a fresh, empty Row and RegisterLocation - don't mention any other registers
75168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda        UnwindPlan::RowSP epi_row(new UnwindPlan::Row);
752528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        UnwindPlan::Row::RegisterLocation epi_regloc;
753528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
754528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        // When the ret instruction is about to be executed, here's our state
75568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda        epi_row->SetOffset (ret_insn_offset);
75668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda        epi_row->SetCFARegister (m_lldb_sp_regnum);
75768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda        epi_row->SetCFAOffset (m_wordsize);
758528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
759528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        // caller's stack pointer value before the call insn is the CFA address
760528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        epi_regloc.SetIsCFAPlusOffset (0);
76168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda        epi_row->SetRegisterInfo (m_lldb_sp_regnum, epi_regloc);
762528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
763528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        // saved instruction pointer can be found at CFA - wordsize
764528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        epi_regloc.SetAtCFAPlusOffset (-m_wordsize);
76568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda        epi_row->SetRegisterInfo (m_lldb_ip_regnum, epi_regloc);
766528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda
767528cc2c1c4665ee0827f305ee724805813cf2ec9Jason Molenda        unwind_plan.AppendRow (epi_row);
76819e54354ca524df5f39352569cf3ec615e69e89dJason Molenda    }
76919e54354ca524df5f39352569cf3ec615e69e89dJason Molenda
7708280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    unwind_plan.SetSourceName ("assembly insn profiling");
7718280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
7723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return true;
7733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
7743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
7758280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda/* The "fast unwind plan" is valid for functions that follow the usual convention of
7768280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda   using the frame pointer register (ebp, rbp), i.e. the function prologue looks like
7778280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda     push   %rbp      [0x55]
7788280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda     mov    %rsp,%rbp [0x48 0x89 0xe5]   (this is a 2-byte insn seq on i386)
7798280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda*/
7808280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
7813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool
7828280cbe80c79bc206335831dd732e0f9fb69c519Jason MolendaAssemblyParse_x86::get_fast_unwind_plan (AddressRange& func, UnwindPlan &unwind_plan)
7833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
78468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    UnwindPlan::RowSP row(new UnwindPlan::Row);
7858280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    UnwindPlan::Row::RegisterLocation pc_reginfo;
7868280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    UnwindPlan::Row::RegisterLocation sp_reginfo;
7878280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    UnwindPlan::Row::RegisterLocation fp_reginfo;
7888280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    unwind_plan.SetRegisterKind (eRegisterKindLLDB);
7898280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
7908280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    if (!func.GetBaseAddress().IsValid())
7918280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        return false;
7928280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
793f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    Target *target = m_exe_ctx.GetTargetPtr();
794f4124deeb9532044a38c0774ced872f2709347daGreg Clayton
7958280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    uint8_t bytebuf[4];
7968280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    Error error;
79726100dcbc49648eac03fa8e8c3d7c793808fc8d6Greg Clayton    const bool prefer_file_cache = true;
798f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    if (target->ReadMemory (func.GetBaseAddress(), prefer_file_cache, bytebuf, sizeof (bytebuf), error) == -1)
7998280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        return false;
8008280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
8018280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    uint8_t i386_prologue[] = {0x55, 0x89, 0xe5};
8028280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    uint8_t x86_64_prologue[] = {0x55, 0x48, 0x89, 0xe5};
8038280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    int prologue_size;
8048280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
8058280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    if (memcmp (bytebuf, i386_prologue, sizeof (i386_prologue)) == 0)
8068280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    {
8078280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        prologue_size = sizeof (i386_prologue);
8088280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    }
8098280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    else if (memcmp (bytebuf, x86_64_prologue, sizeof (x86_64_prologue)) == 0)
8108280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    {
8118280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        prologue_size = sizeof (x86_64_prologue);
8128280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    }
8138280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    else
8148280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    {
8158280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda        return false;
8168280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    }
8178280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
8188280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    pc_reginfo.SetAtCFAPlusOffset (-m_wordsize);
81968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetRegisterInfo (m_lldb_ip_regnum, pc_reginfo);
8208280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
8218280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    sp_reginfo.SetIsCFAPlusOffset (0);
82268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetRegisterInfo (m_lldb_sp_regnum, sp_reginfo);
8238280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
8248280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    // Zero instructions into the function
82568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetCFARegister (m_lldb_sp_regnum);
82668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetCFAOffset (m_wordsize);
82768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetOffset (0);
8288280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    unwind_plan.AppendRow (row);
82968fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    UnwindPlan::Row *newrow = new UnwindPlan::Row;
83068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    *newrow = *row.get();
83168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row.reset(newrow);
8328280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
8338280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    // push %rbp has executed - stack moved, rbp now saved
83468fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetCFAOffset (2 * m_wordsize);
8358280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    fp_reginfo.SetAtCFAPlusOffset (2 * -m_wordsize);
83668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetRegisterInfo (m_lldb_fp_regnum, fp_reginfo);
83768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetOffset (1);
8388280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    unwind_plan.AppendRow (row);
8398280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
84068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    newrow = new UnwindPlan::Row;
84168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    *newrow = *row.get();
84268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row.reset(newrow);
84368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda
8448280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    // mov %rsp, %rbp has executed
84568fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetCFARegister (m_lldb_fp_regnum);
84668fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetCFAOffset (2 * m_wordsize);
84768fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row->SetOffset (prologue_size);     /// 3 or 4 bytes depending on arch
8488280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    unwind_plan.AppendRow (row);
8498280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda
85068fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    newrow = new UnwindPlan::Row;
85168fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    *newrow = *row.get();
85268fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda    row.reset(newrow);
85368fa4ec4361d1ea5a78a8a7eba2b8015e3dd68f7Jason Molenda
8548280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    unwind_plan.SetPlanValidAddressRange (func);
8558280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    return true;
8563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
8573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
8583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool
8593a4ea24572fad1e22525f8efb718d49d41e30398Jason MolendaAssemblyParse_x86::find_first_non_prologue_insn (Address &address)
8603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
8613a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    m_cur_insn = m_func_bounds.GetBaseAddress ();
862800d11d87769e1a7083f7a5545613625396deb3eJason Molenda    if (!m_cur_insn.IsValid())
863800d11d87769e1a7083f7a5545613625396deb3eJason Molenda    {
864800d11d87769e1a7083f7a5545613625396deb3eJason Molenda        return false;
865800d11d87769e1a7083f7a5545613625396deb3eJason Molenda    }
866800d11d87769e1a7083f7a5545613625396deb3eJason Molenda
86726100dcbc49648eac03fa8e8c3d7c793808fc8d6Greg Clayton    const bool prefer_file_cache = true;
868f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    Target *target = m_exe_ctx.GetTargetPtr();
8693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    while (m_func_bounds.ContainsFileAddress (m_cur_insn))
8703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    {
8713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        Error error;
8723a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        int insn_len, offset, regno;
8733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (!instruction_length (m_cur_insn, insn_len) || insn_len > kMaxInstructionByteSize || insn_len == 0)
8743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
8753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            // An error parsing the instruction, i.e. probably data/garbage - stop scanning
8763a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            break;
8773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
878f4124deeb9532044a38c0774ced872f2709347daGreg Clayton        if (target->ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes, insn_len, error) == -1)
8793a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
8803a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda           // Error reading the instruction out of the file, stop scanning
8813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda           break;
8823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
8833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
8843a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        if (push_rbp_pattern_p () || mov_rsp_rbp_pattern_p () || sub_rsp_pattern_p (offset)
8853a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            || push_reg_p (regno) || mov_reg_to_local_stack_frame_p (regno, offset))
8863a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        {
8873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            m_cur_insn.SetOffset (m_cur_insn.GetOffset() + insn_len);
8883a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda            continue;
8893a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        }
8903a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
8913a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        // Unknown non-prologue instruction - stop scanning
8923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda        break;
8933a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    }
8943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
8953a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    address = m_cur_insn;
8963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return true;
8973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
8983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
8993a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9033a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9043a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//-----------------------------------------------------------------------------------------------
9053a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//  UnwindAssemblyParser_x86 method definitions
9063a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//-----------------------------------------------------------------------------------------------
9073a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
908888a7334344778d1a4edbd58b5852ae4d53ffed9Greg ClaytonUnwindAssembly_x86::UnwindAssembly_x86 (const ArchSpec &arch, int cpu) :
909888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton    lldb_private::UnwindAssembly(arch),
910888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton    m_cpu(cpu)
911888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton{
912888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton}
913888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton
914888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton
915888a7334344778d1a4edbd58b5852ae4d53ffed9Greg ClaytonUnwindAssembly_x86::~UnwindAssembly_x86 ()
916888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton{
917888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton}
918888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton
9193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool
920f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& func, Thread& thread, UnwindPlan& unwind_plan)
9213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
922f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    ExecutionContext exe_ctx (thread.shared_from_this());
923f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, func);
9243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return asm_parse.get_non_call_site_unwind_plan (unwind_plan);
9253a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9263a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9273a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool
928f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetFastUnwindPlan (AddressRange& func, Thread& thread, UnwindPlan &unwind_plan)
9293a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
930f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    ExecutionContext exe_ctx (thread.shared_from_this());
931f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, func);
9328280cbe80c79bc206335831dd732e0f9fb69c519Jason Molenda    return asm_parse.get_fast_unwind_plan (func, unwind_plan);
9333a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9343a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9353a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendabool
936f4124deeb9532044a38c0774ced872f2709347daGreg ClaytonUnwindAssembly_x86::FirstNonPrologueInsn (AddressRange& func, const ExecutionContext &exe_ctx, Address& first_non_prologue_insn)
9373a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
938f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, func);
9393a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return asm_parse.find_first_non_prologue_insn (first_non_prologue_insn);
9403a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9413a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9428badcb2503ed2e2884a48f66099c1d48494817f4Greg ClaytonUnwindAssembly *
943f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::CreateInstance (const ArchSpec &arch)
9443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
945940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton    const llvm::Triple::ArchType cpu = arch.GetMachine ();
946940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton    if (cpu == llvm::Triple::x86)
947888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        return new UnwindAssembly_x86 (arch, k_i386);
948940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton    else if (cpu == llvm::Triple::x86_64)
949888a7334344778d1a4edbd58b5852ae4d53ffed9Greg Clayton        return new UnwindAssembly_x86 (arch, k_x86_64);
950940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton    return NULL;
9513a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9523a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9533a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9543a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//------------------------------------------------------------------
9553a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda// PluginInterface protocol in UnwindAssemblyParser_x86
9563a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda//------------------------------------------------------------------
9573a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9583a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaconst char *
959f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetPluginName()
9603a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
961f6e287a873007543f3b419a71546ab8f007be90bGreg Clayton    return "UnwindAssembly_x86";
9623a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9633a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9643a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaconst char *
965f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetShortPluginName()
9663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
967f6e287a873007543f3b419a71546ab8f007be90bGreg Clayton    return "unwindassembly.x86";
9683a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9693a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9703a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9713a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendauint32_t
972f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetPluginVersion()
9733a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
9743a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return 1;
9753a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9763a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9773a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendavoid
978f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::Initialize()
9793a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
9803a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    PluginManager::RegisterPlugin (GetPluginNameStatic(),
9813a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                                   GetPluginDescriptionStatic(),
9823a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                                   CreateInstance);
9833a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9843a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9853a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendavoid
986f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::Terminate()
9873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
9883a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    PluginManager::UnregisterPlugin (CreateInstance);
9893a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9903a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9913a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9923a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaconst char *
993f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetPluginNameStatic()
9943a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
995f6e287a873007543f3b419a71546ab8f007be90bGreg Clayton    return "UnwindAssembly_x86";
9963a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
9973a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda
9983a4ea24572fad1e22525f8efb718d49d41e30398Jason Molendaconst char *
999f6e287a873007543f3b419a71546ab8f007be90bGreg ClaytonUnwindAssembly_x86::GetPluginDescriptionStatic()
10003a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda{
10013a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    return "i386 and x86_64 assembly language profiler plugin.";
10023a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda}
1003