Home | History | Annotate | Download | only in x86
      1 //===-- UnwindAssembly-x86.cpp ----------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "UnwindAssembly-x86.h"
     11 
     12 #include "llvm-c/Disassembler.h"
     13 #include "llvm/Support/TargetSelect.h"
     14 
     15 #include "lldb/Core/Address.h"
     16 #include "lldb/Core/Error.h"
     17 #include "lldb/Core/ArchSpec.h"
     18 #include "lldb/Core/PluginManager.h"
     19 #include "lldb/Symbol/UnwindPlan.h"
     20 #include "lldb/Target/ExecutionContext.h"
     21 #include "lldb/Target/Process.h"
     22 #include "lldb/Target/RegisterContext.h"
     23 #include "lldb/Target/Thread.h"
     24 #include "lldb/Target/Target.h"
     25 #include "lldb/Target/UnwindAssembly.h"
     26 
     27 using namespace lldb;
     28 using namespace lldb_private;
     29 
     30 enum CPU {
     31     k_i386,
     32     k_x86_64
     33 };
     34 
     35 enum i386_register_numbers {
     36     k_machine_eax = 0,
     37     k_machine_ecx = 1,
     38     k_machine_edx = 2,
     39     k_machine_ebx = 3,
     40     k_machine_esp = 4,
     41     k_machine_ebp = 5,
     42     k_machine_esi = 6,
     43     k_machine_edi = 7,
     44     k_machine_eip = 8
     45 };
     46 
     47 enum x86_64_register_numbers {
     48     k_machine_rax = 0,
     49     k_machine_rcx = 1,
     50     k_machine_rdx = 2,
     51     k_machine_rbx = 3,
     52     k_machine_rsp = 4,
     53     k_machine_rbp = 5,
     54     k_machine_rsi = 6,
     55     k_machine_rdi = 7,
     56     k_machine_r8 = 8,
     57     k_machine_r9 = 9,
     58     k_machine_r10 = 10,
     59     k_machine_r11 = 11,
     60     k_machine_r12 = 12,
     61     k_machine_r13 = 13,
     62     k_machine_r14 = 14,
     63     k_machine_r15 = 15,
     64     k_machine_rip = 16
     65 };
     66 
     67 struct regmap_ent {
     68     const char *name;
     69     int machine_regno;
     70     int lldb_regno;
     71 };
     72 
     73 static struct regmap_ent i386_register_map[] = {
     74     {"eax", k_machine_eax, -1},
     75     {"ecx", k_machine_ecx, -1},
     76     {"edx", k_machine_edx, -1},
     77     {"ebx", k_machine_ebx, -1},
     78     {"esp", k_machine_esp, -1},
     79     {"ebp", k_machine_ebp, -1},
     80     {"esi", k_machine_esi, -1},
     81     {"edi", k_machine_edi, -1},
     82     {"eip", k_machine_eip, -1}
     83 };
     84 
     85 const int size_of_i386_register_map = sizeof (i386_register_map) / sizeof (struct regmap_ent);
     86 
     87 static int i386_register_map_initialized = 0;
     88 
     89 static struct regmap_ent x86_64_register_map[] = {
     90     {"rax", k_machine_rax, -1},
     91     {"rcx", k_machine_rcx, -1},
     92     {"rdx", k_machine_rdx, -1},
     93     {"rbx", k_machine_rbx, -1},
     94     {"rsp", k_machine_rsp, -1},
     95     {"rbp", k_machine_rbp, -1},
     96     {"rsi", k_machine_rsi, -1},
     97     {"rdi", k_machine_rdi, -1},
     98     {"r8", k_machine_r8, -1},
     99     {"r9", k_machine_r9, -1},
    100     {"r10", k_machine_r10, -1},
    101     {"r11", k_machine_r11, -1},
    102     {"r12", k_machine_r12, -1},
    103     {"r13", k_machine_r13, -1},
    104     {"r14", k_machine_r14, -1},
    105     {"r15", k_machine_r15, -1},
    106     {"rip", k_machine_rip, -1}
    107 };
    108 
    109 const int size_of_x86_64_register_map = sizeof (x86_64_register_map) / sizeof (struct regmap_ent);
    110 
    111 static int x86_64_register_map_initialized = 0;
    112 
    113 //-----------------------------------------------------------------------------------------------
    114 //  AssemblyParse_x86 local-file class definition & implementation functions
    115 //-----------------------------------------------------------------------------------------------
    116 
    117 class AssemblyParse_x86 {
    118 public:
    119 
    120     AssemblyParse_x86 (const ExecutionContext &exe_ctx, int cpu, ArchSpec &arch, AddressRange func);
    121 
    122     ~AssemblyParse_x86 ();
    123 
    124     bool get_non_call_site_unwind_plan (UnwindPlan &unwind_plan);
    125 
    126     bool get_fast_unwind_plan (AddressRange& func, UnwindPlan &unwind_plan);
    127 
    128     bool find_first_non_prologue_insn (Address &address);
    129 
    130 private:
    131     enum { kMaxInstructionByteSize = 32 };
    132 
    133     bool nonvolatile_reg_p (int machine_regno);
    134     bool push_rbp_pattern_p ();
    135     bool push_0_pattern_p ();
    136     bool mov_rsp_rbp_pattern_p ();
    137     bool sub_rsp_pattern_p (int& amount);
    138     bool push_reg_p (int& regno);
    139     bool mov_reg_to_local_stack_frame_p (int& regno, int& fp_offset);
    140     bool ret_pattern_p ();
    141     uint32_t extract_4 (uint8_t *b);
    142     bool machine_regno_to_lldb_regno (int machine_regno, uint32_t& lldb_regno);
    143     bool instruction_length (Address addr, int &length);
    144 
    145     const ExecutionContext m_exe_ctx;
    146 
    147     AddressRange m_func_bounds;
    148 
    149     Address m_cur_insn;
    150     uint8_t m_cur_insn_bytes[kMaxInstructionByteSize];
    151 
    152     int m_machine_ip_regnum;
    153     int m_machine_sp_regnum;
    154     int m_machine_fp_regnum;
    155 
    156     int m_lldb_ip_regnum;
    157     int m_lldb_sp_regnum;
    158     int m_lldb_fp_regnum;
    159 
    160     int m_wordsize;
    161     int m_cpu;
    162     ArchSpec m_arch;
    163     ::LLVMDisasmContextRef m_disasm_context;
    164 
    165     DISALLOW_COPY_AND_ASSIGN (AssemblyParse_x86);
    166 };
    167 
    168 AssemblyParse_x86::AssemblyParse_x86 (const ExecutionContext &exe_ctx, int cpu, ArchSpec &arch, AddressRange func) :
    169     m_exe_ctx (exe_ctx),
    170     m_func_bounds(func),
    171     m_cur_insn (),
    172     m_machine_ip_regnum (LLDB_INVALID_REGNUM),
    173     m_machine_sp_regnum (LLDB_INVALID_REGNUM),
    174     m_machine_fp_regnum (LLDB_INVALID_REGNUM),
    175     m_lldb_ip_regnum (LLDB_INVALID_REGNUM),
    176     m_lldb_sp_regnum (LLDB_INVALID_REGNUM),
    177     m_lldb_fp_regnum (LLDB_INVALID_REGNUM),
    178     m_wordsize (-1),
    179     m_cpu(cpu),
    180     m_arch(arch)
    181 {
    182     int *initialized_flag = NULL;
    183     if (cpu == k_i386)
    184     {
    185         m_machine_ip_regnum = k_machine_eip;
    186         m_machine_sp_regnum = k_machine_esp;
    187         m_machine_fp_regnum = k_machine_ebp;
    188         m_wordsize = 4;
    189         initialized_flag = &i386_register_map_initialized;
    190     }
    191     else
    192     {
    193         m_machine_ip_regnum = k_machine_rip;
    194         m_machine_sp_regnum = k_machine_rsp;
    195         m_machine_fp_regnum = k_machine_rbp;
    196         m_wordsize = 8;
    197         initialized_flag = &x86_64_register_map_initialized;
    198     }
    199 
    200     // we only look at prologue - it will be complete earlier than 512 bytes into func
    201     if (m_func_bounds.GetByteSize() == 0)
    202         m_func_bounds.SetByteSize(512);
    203 
    204     Thread *thread = m_exe_ctx.GetThreadPtr();
    205     if (thread && *initialized_flag == 0)
    206     {
    207         RegisterContext *reg_ctx = thread->GetRegisterContext().get();
    208         if (reg_ctx)
    209         {
    210             struct regmap_ent *ent;
    211             int count, i;
    212             if (cpu == k_i386)
    213             {
    214                 ent = i386_register_map;
    215                 count = size_of_i386_register_map;
    216             }
    217             else
    218             {
    219                 ent = x86_64_register_map;
    220                 count = size_of_x86_64_register_map;
    221             }
    222             for (i = 0; i < count; i++, ent++)
    223             {
    224                 const RegisterInfo *ri = reg_ctx->GetRegisterInfoByName (ent->name);
    225                 if (ri)
    226                     ent->lldb_regno = ri->kinds[eRegisterKindLLDB];
    227             }
    228             *initialized_flag = 1;
    229         }
    230     }
    231 
    232    // on initial construction we may not have a Thread so these have to remain
    233    // uninitialized until we can get a RegisterContext to set up the register map table
    234    if (*initialized_flag == 1)
    235    {
    236        uint32_t lldb_regno;
    237        if (machine_regno_to_lldb_regno (m_machine_sp_regnum, lldb_regno))
    238            m_lldb_sp_regnum = lldb_regno;
    239        if (machine_regno_to_lldb_regno (m_machine_fp_regnum, lldb_regno))
    240            m_lldb_fp_regnum = lldb_regno;
    241        if (machine_regno_to_lldb_regno (m_machine_ip_regnum, lldb_regno))
    242            m_lldb_ip_regnum = lldb_regno;
    243    }
    244 
    245    m_disasm_context = ::LLVMCreateDisasm(m_arch.GetTriple().getTriple().c_str(),
    246                                           (void*)this,
    247                                           /*TagType=*/1,
    248                                           NULL,
    249                                           NULL);
    250 }
    251 
    252 AssemblyParse_x86::~AssemblyParse_x86 ()
    253 {
    254     ::LLVMDisasmDispose(m_disasm_context);
    255 }
    256 
    257 // This function expects an x86 native register number (i.e. the bits stripped out of the
    258 // actual instruction), not an lldb register number.
    259 
    260 bool
    261 AssemblyParse_x86::nonvolatile_reg_p (int machine_regno)
    262 {
    263     if (m_cpu == k_i386)
    264     {
    265           switch (machine_regno) {
    266               case k_machine_ebx:
    267               case k_machine_ebp:  // not actually a nonvolatile but often treated as such by convention
    268               case k_machine_esi:
    269               case k_machine_edi:
    270               case k_machine_esp:
    271                   return true;
    272               default:
    273                   return false;
    274           }
    275     }
    276     if (m_cpu == k_x86_64)
    277     {
    278           switch (machine_regno) {
    279               case k_machine_rbx:
    280               case k_machine_rsp:
    281               case k_machine_rbp:  // not actually a nonvolatile but often treated as such by convention
    282               case k_machine_r12:
    283               case k_machine_r13:
    284               case k_machine_r14:
    285               case k_machine_r15:
    286                   return true;
    287               default:
    288                   return false;
    289           }
    290     }
    291     return false;
    292 }
    293 
    294 
    295 // Macro to detect if this is a REX mode prefix byte.
    296 #define REX_W_PREFIX_P(opcode) (((opcode) & (~0x5)) == 0x48)
    297 
    298 // The high bit which should be added to the source register number (the "R" bit)
    299 #define REX_W_SRCREG(opcode) (((opcode) & 0x4) >> 2)
    300 
    301 // The high bit which should be added to the destination register number (the "B" bit)
    302 #define REX_W_DSTREG(opcode) ((opcode) & 0x1)
    303 
    304 // pushq %rbp [0x55]
    305 bool AssemblyParse_x86::push_rbp_pattern_p () {
    306     uint8_t *p = m_cur_insn_bytes;
    307     if (*p == 0x55)
    308       return true;
    309     return false;
    310 }
    311 
    312 // pushq $0 ; the first instruction in start() [0x6a 0x00]
    313 bool AssemblyParse_x86::push_0_pattern_p ()
    314 {
    315     uint8_t *p = m_cur_insn_bytes;
    316     if (*p == 0x6a && *(p + 1) == 0x0)
    317         return true;
    318     return false;
    319 }
    320 
    321 // movq %rsp, %rbp [0x48 0x8b 0xec] or [0x48 0x89 0xe5]
    322 // movl %esp, %ebp [0x8b 0xec] or [0x89 0xe5]
    323 bool AssemblyParse_x86::mov_rsp_rbp_pattern_p () {
    324     uint8_t *p = m_cur_insn_bytes;
    325     if (m_wordsize == 8 && *p == 0x48)
    326       p++;
    327     if (*(p) == 0x8b && *(p + 1) == 0xec)
    328         return true;
    329     if (*(p) == 0x89 && *(p + 1) == 0xe5)
    330         return true;
    331     return false;
    332 }
    333 
    334 // subq $0x20, %rsp
    335 bool AssemblyParse_x86::sub_rsp_pattern_p (int& amount) {
    336     uint8_t *p = m_cur_insn_bytes;
    337     if (m_wordsize == 8 && *p == 0x48)
    338       p++;
    339     // 8-bit immediate operand
    340     if (*p == 0x83 && *(p + 1) == 0xec) {
    341         amount = (int8_t) *(p + 2);
    342         return true;
    343     }
    344     // 32-bit immediate operand
    345     if (*p == 0x81 && *(p + 1) == 0xec) {
    346         amount = (int32_t) extract_4 (p + 2);
    347         return true;
    348     }
    349     // Not handled:  [0x83 0xc4] for imm8 with neg values
    350     // [0x81 0xc4] for imm32 with neg values
    351     return false;
    352 }
    353 
    354 // pushq %rbx
    355 // pushl $ebx
    356 bool AssemblyParse_x86::push_reg_p (int& regno) {
    357     uint8_t *p = m_cur_insn_bytes;
    358     int regno_prefix_bit = 0;
    359     // If we have a rex prefix byte, check to see if a B bit is set
    360     if (m_wordsize == 8 && *p == 0x41) {
    361         regno_prefix_bit = 1 << 3;
    362         p++;
    363     }
    364     if (*p >= 0x50 && *p <= 0x57) {
    365         regno = (*p - 0x50) | regno_prefix_bit;
    366         return true;
    367     }
    368     return false;
    369 }
    370 
    371 // Look for an instruction sequence storing a nonvolatile register
    372 // on to the stack frame.
    373 
    374 //  movq %rax, -0x10(%rbp) [0x48 0x89 0x45 0xf0]
    375 //  movl %eax, -0xc(%ebp)  [0x89 0x45 0xf4]
    376 bool AssemblyParse_x86::mov_reg_to_local_stack_frame_p (int& regno, int& rbp_offset) {
    377     uint8_t *p = m_cur_insn_bytes;
    378     int src_reg_prefix_bit = 0;
    379     int target_reg_prefix_bit = 0;
    380 
    381     if (m_wordsize == 8 && REX_W_PREFIX_P (*p)) {
    382         src_reg_prefix_bit = REX_W_SRCREG (*p) << 3;
    383         target_reg_prefix_bit = REX_W_DSTREG (*p) << 3;
    384         if (target_reg_prefix_bit == 1) {
    385             // rbp/ebp don't need a prefix bit - we know this isn't the
    386             // reg we care about.
    387             return false;
    388         }
    389         p++;
    390     }
    391 
    392     if (*p == 0x89) {
    393         /* Mask off the 3-5 bits which indicate the destination register
    394            if this is a ModR/M byte.  */
    395         int opcode_destreg_masked_out = *(p + 1) & (~0x38);
    396 
    397         /* Is this a ModR/M byte with Mod bits 01 and R/M bits 101
    398            and three bits between them, e.g. 01nnn101
    399            We're looking for a destination of ebp-disp8 or ebp-disp32.   */
    400         int immsize;
    401         if (opcode_destreg_masked_out == 0x45)
    402           immsize = 2;
    403         else if (opcode_destreg_masked_out == 0x85)
    404           immsize = 4;
    405         else
    406           return false;
    407 
    408         int offset = 0;
    409         if (immsize == 2)
    410           offset = (int8_t) *(p + 2);
    411         if (immsize == 4)
    412              offset = (uint32_t) extract_4 (p + 2);
    413         if (offset > 0)
    414           return false;
    415 
    416         regno = ((*(p + 1) >> 3) & 0x7) | src_reg_prefix_bit;
    417         rbp_offset = offset > 0 ? offset : -offset;
    418         return true;
    419     }
    420     return false;
    421 }
    422 
    423 // ret [0xc9] or [0xc2 imm8] or [0xca imm8]
    424 bool
    425 AssemblyParse_x86::ret_pattern_p ()
    426 {
    427     uint8_t *p = m_cur_insn_bytes;
    428     if (*p == 0xc9 || *p == 0xc2 || *p == 0xca || *p == 0xc3)
    429         return true;
    430     return false;
    431 }
    432 
    433 uint32_t
    434 AssemblyParse_x86::extract_4 (uint8_t *b)
    435 {
    436     uint32_t v = 0;
    437     for (int i = 3; i >= 0; i--)
    438         v = (v << 8) | b[i];
    439     return v;
    440 }
    441 
    442 bool
    443 AssemblyParse_x86::machine_regno_to_lldb_regno (int machine_regno, uint32_t &lldb_regno)
    444 {
    445     struct regmap_ent *ent;
    446     int count, i;
    447     if (m_cpu == k_i386)
    448     {
    449         ent = i386_register_map;
    450         count = size_of_i386_register_map;
    451     }
    452     else
    453     {
    454         ent = x86_64_register_map;
    455         count = size_of_x86_64_register_map;
    456     }
    457     for (i = 0; i < count; i++, ent++)
    458     {
    459         if (ent->machine_regno == machine_regno)
    460             if (ent->lldb_regno != -1)
    461             {
    462                 lldb_regno = ent->lldb_regno;
    463                 return true;
    464             }
    465     }
    466     return false;
    467 }
    468 
    469 bool
    470 AssemblyParse_x86::instruction_length (Address addr, int &length)
    471 {
    472     const uint32_t max_op_byte_size = m_arch.GetMaximumOpcodeByteSize();
    473     llvm::SmallVector <uint8_t, 32> opcode_data;
    474     opcode_data.resize (max_op_byte_size);
    475 
    476     if (!addr.IsValid())
    477         return false;
    478 
    479     const bool prefer_file_cache = true;
    480     Error error;
    481     Target *target = m_exe_ctx.GetTargetPtr();
    482     if (target->ReadMemory (addr, prefer_file_cache, opcode_data.data(), max_op_byte_size, error) == -1)
    483     {
    484         return false;
    485     }
    486 
    487     char out_string[512];
    488     const addr_t pc = addr.GetFileAddress();
    489     const size_t inst_size = ::LLVMDisasmInstruction (m_disasm_context,
    490                                                       opcode_data.data(),
    491                                                       max_op_byte_size,
    492                                                       pc, // PC value
    493                                                       out_string,
    494                                                       sizeof(out_string));
    495 
    496     length = inst_size;
    497     return true;
    498 }
    499 
    500 
    501 bool
    502 AssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan)
    503 {
    504     UnwindPlan::RowSP row(new UnwindPlan::Row);
    505     int non_prologue_insn_count = 0;
    506     m_cur_insn = m_func_bounds.GetBaseAddress ();
    507     int current_func_text_offset = 0;
    508     int current_sp_bytes_offset_from_cfa = 0;
    509     UnwindPlan::Row::RegisterLocation initial_regloc;
    510     Error error;
    511 
    512     if (!m_cur_insn.IsValid())
    513     {
    514         return false;
    515     }
    516 
    517     unwind_plan.SetPlanValidAddressRange (m_func_bounds);
    518     unwind_plan.SetRegisterKind (eRegisterKindLLDB);
    519 
    520     // At the start of the function, find the CFA by adding wordsize to the SP register
    521     row->SetOffset (current_func_text_offset);
    522     row->SetCFARegister (m_lldb_sp_regnum);
    523     row->SetCFAOffset (m_wordsize);
    524 
    525     // caller's stack pointer value before the call insn is the CFA address
    526     initial_regloc.SetIsCFAPlusOffset (0);
    527     row->SetRegisterInfo (m_lldb_sp_regnum, initial_regloc);
    528 
    529     // saved instruction pointer can be found at CFA - wordsize.
    530     current_sp_bytes_offset_from_cfa = m_wordsize;
    531     initial_regloc.SetAtCFAPlusOffset (-current_sp_bytes_offset_from_cfa);
    532     row->SetRegisterInfo (m_lldb_ip_regnum, initial_regloc);
    533 
    534     unwind_plan.AppendRow (row);
    535 
    536     // Allocate a new Row, populate it with the existing Row contents.
    537     UnwindPlan::Row *newrow = new UnwindPlan::Row;
    538     *newrow = *row.get();
    539     row.reset(newrow);
    540 
    541     const bool prefer_file_cache = true;
    542 
    543     Target *target = m_exe_ctx.GetTargetPtr();
    544     while (m_func_bounds.ContainsFileAddress (m_cur_insn) && non_prologue_insn_count < 10)
    545     {
    546         int stack_offset, insn_len;
    547         int machine_regno;          // register numbers masked directly out of instructions
    548         uint32_t lldb_regno;        // register numbers in lldb's eRegisterKindLLDB numbering scheme
    549 
    550         if (!instruction_length (m_cur_insn, insn_len) || insn_len == 0 || insn_len > kMaxInstructionByteSize)
    551         {
    552             // An unrecognized/junk instruction
    553             break;
    554         }
    555         if (target->ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes, insn_len, error) == -1)
    556         {
    557            // Error reading the instruction out of the file, stop scanning
    558            break;
    559         }
    560 
    561         if (push_rbp_pattern_p ())
    562         {
    563             row->SetOffset (current_func_text_offset + insn_len);
    564             current_sp_bytes_offset_from_cfa += m_wordsize;
    565             row->SetCFAOffset (current_sp_bytes_offset_from_cfa);
    566             UnwindPlan::Row::RegisterLocation regloc;
    567             regloc.SetAtCFAPlusOffset (-row->GetCFAOffset());
    568             row->SetRegisterInfo (m_lldb_fp_regnum, regloc);
    569             unwind_plan.AppendRow (row);
    570             // Allocate a new Row, populate it with the existing Row contents.
    571             newrow = new UnwindPlan::Row;
    572             *newrow = *row.get();
    573             row.reset(newrow);
    574             goto loopnext;
    575         }
    576 
    577         if (mov_rsp_rbp_pattern_p ())
    578         {
    579             row->SetOffset (current_func_text_offset + insn_len);
    580             row->SetCFARegister (m_lldb_fp_regnum);
    581             unwind_plan.AppendRow (row);
    582             // Allocate a new Row, populate it with the existing Row contents.
    583             newrow = new UnwindPlan::Row;
    584             *newrow = *row.get();
    585             row.reset(newrow);
    586             goto loopnext;
    587         }
    588 
    589         // This is the start() function (or a pthread equivalent), it starts with a pushl $0x0 which puts the
    590         // saved pc value of 0 on the stack.  In this case we want to pretend we didn't see a stack movement at all --
    591         // normally the saved pc value is already on the stack by the time the function starts executing.
    592         if (push_0_pattern_p ())
    593         {
    594             goto loopnext;
    595         }
    596 
    597         if (push_reg_p (machine_regno))
    598         {
    599             current_sp_bytes_offset_from_cfa += m_wordsize;
    600             if (nonvolatile_reg_p (machine_regno) && machine_regno_to_lldb_regno (machine_regno, lldb_regno))
    601             {
    602                 row->SetOffset (current_func_text_offset + insn_len);
    603                 if (row->GetCFARegister() == m_lldb_sp_regnum)
    604                 {
    605                     row->SetCFAOffset (current_sp_bytes_offset_from_cfa);
    606                 }
    607                 UnwindPlan::Row::RegisterLocation regloc;
    608                 regloc.SetAtCFAPlusOffset (-current_sp_bytes_offset_from_cfa);
    609                 row->SetRegisterInfo (lldb_regno, regloc);
    610                 unwind_plan.AppendRow (row);
    611                 // Allocate a new Row, populate it with the existing Row contents.
    612                 newrow = new UnwindPlan::Row;
    613                 *newrow = *row.get();
    614                 row.reset(newrow);
    615             }
    616             goto loopnext;
    617         }
    618 
    619         if (mov_reg_to_local_stack_frame_p (machine_regno, stack_offset) && nonvolatile_reg_p (machine_regno))
    620         {
    621             if (machine_regno_to_lldb_regno (machine_regno, lldb_regno))
    622             {
    623                 row->SetOffset (current_func_text_offset + insn_len);
    624                 UnwindPlan::Row::RegisterLocation regloc;
    625                 regloc.SetAtCFAPlusOffset (-row->GetCFAOffset());
    626                 row->SetRegisterInfo (lldb_regno, regloc);
    627                 unwind_plan.AppendRow (row);
    628                 // Allocate a new Row, populate it with the existing Row contents.
    629                 newrow = new UnwindPlan::Row;
    630                 *newrow = *row.get();
    631                 row.reset(newrow);
    632                 goto loopnext;
    633             }
    634         }
    635 
    636         if (sub_rsp_pattern_p (stack_offset))
    637         {
    638             current_sp_bytes_offset_from_cfa += stack_offset;
    639             if (row->GetCFARegister() == m_lldb_sp_regnum)
    640             {
    641                 row->SetOffset (current_func_text_offset + insn_len);
    642                 row->SetCFAOffset (current_sp_bytes_offset_from_cfa);
    643                 unwind_plan.AppendRow (row);
    644                 // Allocate a new Row, populate it with the existing Row contents.
    645                 newrow = new UnwindPlan::Row;
    646                 *newrow = *row.get();
    647                 row.reset(newrow);
    648             }
    649             goto loopnext;
    650         }
    651 
    652         if (ret_pattern_p ())
    653         {
    654             // we know where the end of the function is; set the limit on the PlanValidAddressRange
    655             // in case our initial "high pc" value was overly large
    656             // int original_size = m_func_bounds.GetByteSize();
    657             // int calculated_size = m_cur_insn.GetOffset() - m_func_bounds.GetBaseAddress().GetOffset() + insn_len + 1;
    658             // m_func_bounds.SetByteSize (calculated_size);
    659             // unwind_plan.SetPlanValidAddressRange (m_func_bounds);
    660             break;
    661         }
    662 
    663         // FIXME recognize the i386 picbase setup instruction sequence,
    664         // 0x1f16:  call   0x1f1b                   ; main + 11 at /private/tmp/a.c:3
    665         // 0x1f1b:  popl   %eax
    666         // and record the temporary stack movements if the CFA is not expressed in terms of ebp.
    667 
    668         non_prologue_insn_count++;
    669 loopnext:
    670         m_cur_insn.SetOffset (m_cur_insn.GetOffset() + insn_len);
    671         current_func_text_offset += insn_len;
    672     }
    673 
    674     // Now look at the byte at the end of the AddressRange for a limited attempt at describing the
    675     // epilogue.  We're looking for the sequence
    676 
    677     //  [ 0x5d ] mov %rbp, %rsp
    678     //  [ 0xc3 ] ret
    679     //  [ 0xe8 xx xx xx xx ] call __stack_chk_fail  (this is sometimes the final insn in the function)
    680 
    681     // We want to add a Row describing how to unwind when we're stopped on the 'ret' instruction where the
    682     // CFA is no longer defined in terms of rbp, but is now defined in terms of rsp like on function entry.
    683 
    684     uint64_t ret_insn_offset = LLDB_INVALID_ADDRESS;
    685     Address end_of_fun(m_func_bounds.GetBaseAddress());
    686     end_of_fun.SetOffset (end_of_fun.GetOffset() + m_func_bounds.GetByteSize());
    687 
    688     if (m_func_bounds.GetByteSize() > 7)
    689     {
    690         uint8_t bytebuf[7];
    691         Address last_seven_bytes(end_of_fun);
    692         last_seven_bytes.SetOffset (last_seven_bytes.GetOffset() - 7);
    693         if (target->ReadMemory (last_seven_bytes, prefer_file_cache, bytebuf, 7, error) != -1)
    694         {
    695             if (bytebuf[5] == 0x5d && bytebuf[6] == 0xc3)  // mov, ret
    696             {
    697                 ret_insn_offset = m_func_bounds.GetByteSize() - 1;
    698             }
    699             else if (bytebuf[0] == 0x5d && bytebuf[1] == 0xc3 && bytebuf[2] == 0xe8) // mov, ret, call
    700             {
    701                 ret_insn_offset = m_func_bounds.GetByteSize() - 6;
    702             }
    703         }
    704     } else if (m_func_bounds.GetByteSize() > 2)
    705     {
    706         uint8_t bytebuf[2];
    707         Address last_two_bytes(end_of_fun);
    708         last_two_bytes.SetOffset (last_two_bytes.GetOffset() - 2);
    709         if (target->ReadMemory (last_two_bytes, prefer_file_cache, bytebuf, 2, error) != -1)
    710         {
    711             if (bytebuf[0] == 0x5d && bytebuf[1] == 0xc3) // mov, ret
    712             {
    713                 ret_insn_offset = m_func_bounds.GetByteSize() - 1;
    714             }
    715         }
    716     }
    717 
    718     if (ret_insn_offset != LLDB_INVALID_ADDRESS)
    719     {
    720         // Create a fresh, empty Row and RegisterLocation - don't mention any other registers
    721         UnwindPlan::RowSP epi_row(new UnwindPlan::Row);
    722         UnwindPlan::Row::RegisterLocation epi_regloc;
    723 
    724         // When the ret instruction is about to be executed, here's our state
    725         epi_row->SetOffset (ret_insn_offset);
    726         epi_row->SetCFARegister (m_lldb_sp_regnum);
    727         epi_row->SetCFAOffset (m_wordsize);
    728 
    729         // caller's stack pointer value before the call insn is the CFA address
    730         epi_regloc.SetIsCFAPlusOffset (0);
    731         epi_row->SetRegisterInfo (m_lldb_sp_regnum, epi_regloc);
    732 
    733         // saved instruction pointer can be found at CFA - wordsize
    734         epi_regloc.SetAtCFAPlusOffset (-m_wordsize);
    735         epi_row->SetRegisterInfo (m_lldb_ip_regnum, epi_regloc);
    736 
    737         unwind_plan.AppendRow (epi_row);
    738     }
    739 
    740     unwind_plan.SetSourceName ("assembly insn profiling");
    741     unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
    742     unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
    743 
    744     return true;
    745 }
    746 
    747 /* The "fast unwind plan" is valid for functions that follow the usual convention of
    748    using the frame pointer register (ebp, rbp), i.e. the function prologue looks like
    749      push   %rbp      [0x55]
    750      mov    %rsp,%rbp [0x48 0x89 0xe5]   (this is a 2-byte insn seq on i386)
    751 */
    752 
    753 bool
    754 AssemblyParse_x86::get_fast_unwind_plan (AddressRange& func, UnwindPlan &unwind_plan)
    755 {
    756     UnwindPlan::RowSP row(new UnwindPlan::Row);
    757     UnwindPlan::Row::RegisterLocation pc_reginfo;
    758     UnwindPlan::Row::RegisterLocation sp_reginfo;
    759     UnwindPlan::Row::RegisterLocation fp_reginfo;
    760     unwind_plan.SetRegisterKind (eRegisterKindLLDB);
    761 
    762     if (!func.GetBaseAddress().IsValid())
    763         return false;
    764 
    765     Target *target = m_exe_ctx.GetTargetPtr();
    766 
    767     uint8_t bytebuf[4];
    768     Error error;
    769     const bool prefer_file_cache = true;
    770     if (target->ReadMemory (func.GetBaseAddress(), prefer_file_cache, bytebuf, sizeof (bytebuf), error) == -1)
    771         return false;
    772 
    773     uint8_t i386_prologue[] = {0x55, 0x89, 0xe5};
    774     uint8_t x86_64_prologue[] = {0x55, 0x48, 0x89, 0xe5};
    775     int prologue_size;
    776 
    777     if (memcmp (bytebuf, i386_prologue, sizeof (i386_prologue)) == 0)
    778     {
    779         prologue_size = sizeof (i386_prologue);
    780     }
    781     else if (memcmp (bytebuf, x86_64_prologue, sizeof (x86_64_prologue)) == 0)
    782     {
    783         prologue_size = sizeof (x86_64_prologue);
    784     }
    785     else
    786     {
    787         return false;
    788     }
    789 
    790     pc_reginfo.SetAtCFAPlusOffset (-m_wordsize);
    791     row->SetRegisterInfo (m_lldb_ip_regnum, pc_reginfo);
    792 
    793     sp_reginfo.SetIsCFAPlusOffset (0);
    794     row->SetRegisterInfo (m_lldb_sp_regnum, sp_reginfo);
    795 
    796     // Zero instructions into the function
    797     row->SetCFARegister (m_lldb_sp_regnum);
    798     row->SetCFAOffset (m_wordsize);
    799     row->SetOffset (0);
    800     unwind_plan.AppendRow (row);
    801     UnwindPlan::Row *newrow = new UnwindPlan::Row;
    802     *newrow = *row.get();
    803     row.reset(newrow);
    804 
    805     // push %rbp has executed - stack moved, rbp now saved
    806     row->SetCFAOffset (2 * m_wordsize);
    807     fp_reginfo.SetAtCFAPlusOffset (2 * -m_wordsize);
    808     row->SetRegisterInfo (m_lldb_fp_regnum, fp_reginfo);
    809     row->SetOffset (1);
    810     unwind_plan.AppendRow (row);
    811 
    812     newrow = new UnwindPlan::Row;
    813     *newrow = *row.get();
    814     row.reset(newrow);
    815 
    816     // mov %rsp, %rbp has executed
    817     row->SetCFARegister (m_lldb_fp_regnum);
    818     row->SetCFAOffset (2 * m_wordsize);
    819     row->SetOffset (prologue_size);     /// 3 or 4 bytes depending on arch
    820     unwind_plan.AppendRow (row);
    821 
    822     newrow = new UnwindPlan::Row;
    823     *newrow = *row.get();
    824     row.reset(newrow);
    825 
    826     unwind_plan.SetPlanValidAddressRange (func);
    827     unwind_plan.SetSourceName ("fast unwind assembly profiling");
    828     unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
    829     unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
    830     return true;
    831 }
    832 
    833 bool
    834 AssemblyParse_x86::find_first_non_prologue_insn (Address &address)
    835 {
    836     m_cur_insn = m_func_bounds.GetBaseAddress ();
    837     if (!m_cur_insn.IsValid())
    838     {
    839         return false;
    840     }
    841 
    842     const bool prefer_file_cache = true;
    843     Target *target = m_exe_ctx.GetTargetPtr();
    844     while (m_func_bounds.ContainsFileAddress (m_cur_insn))
    845     {
    846         Error error;
    847         int insn_len, offset, regno;
    848         if (!instruction_length (m_cur_insn, insn_len) || insn_len > kMaxInstructionByteSize || insn_len == 0)
    849         {
    850             // An error parsing the instruction, i.e. probably data/garbage - stop scanning
    851             break;
    852         }
    853         if (target->ReadMemory (m_cur_insn, prefer_file_cache, m_cur_insn_bytes, insn_len, error) == -1)
    854         {
    855            // Error reading the instruction out of the file, stop scanning
    856            break;
    857         }
    858 
    859         if (push_rbp_pattern_p () || mov_rsp_rbp_pattern_p () || sub_rsp_pattern_p (offset)
    860             || push_reg_p (regno) || mov_reg_to_local_stack_frame_p (regno, offset))
    861         {
    862             m_cur_insn.SetOffset (m_cur_insn.GetOffset() + insn_len);
    863             continue;
    864         }
    865 
    866         // Unknown non-prologue instruction - stop scanning
    867         break;
    868     }
    869 
    870     address = m_cur_insn;
    871     return true;
    872 }
    873 
    874 
    875 
    876 
    877 
    878 
    879 //-----------------------------------------------------------------------------------------------
    880 //  UnwindAssemblyParser_x86 method definitions
    881 //-----------------------------------------------------------------------------------------------
    882 
    883 UnwindAssembly_x86::UnwindAssembly_x86 (const ArchSpec &arch, int cpu) :
    884     lldb_private::UnwindAssembly(arch),
    885     m_cpu(cpu),
    886     m_arch(arch)
    887 {
    888 }
    889 
    890 
    891 UnwindAssembly_x86::~UnwindAssembly_x86 ()
    892 {
    893 }
    894 
    895 bool
    896 UnwindAssembly_x86::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& func, Thread& thread, UnwindPlan& unwind_plan)
    897 {
    898     ExecutionContext exe_ctx (thread.shared_from_this());
    899     AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func);
    900     return asm_parse.get_non_call_site_unwind_plan (unwind_plan);
    901 }
    902 
    903 bool
    904 UnwindAssembly_x86::GetFastUnwindPlan (AddressRange& func, Thread& thread, UnwindPlan &unwind_plan)
    905 {
    906     ExecutionContext exe_ctx (thread.shared_from_this());
    907     AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func);
    908     return asm_parse.get_fast_unwind_plan (func, unwind_plan);
    909 }
    910 
    911 bool
    912 UnwindAssembly_x86::FirstNonPrologueInsn (AddressRange& func, const ExecutionContext &exe_ctx, Address& first_non_prologue_insn)
    913 {
    914     AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func);
    915     return asm_parse.find_first_non_prologue_insn (first_non_prologue_insn);
    916 }
    917 
    918 UnwindAssembly *
    919 UnwindAssembly_x86::CreateInstance (const ArchSpec &arch)
    920 {
    921     const llvm::Triple::ArchType cpu = arch.GetMachine ();
    922     if (cpu == llvm::Triple::x86)
    923         return new UnwindAssembly_x86 (arch, k_i386);
    924     else if (cpu == llvm::Triple::x86_64)
    925         return new UnwindAssembly_x86 (arch, k_x86_64);
    926     return NULL;
    927 }
    928 
    929 
    930 //------------------------------------------------------------------
    931 // PluginInterface protocol in UnwindAssemblyParser_x86
    932 //------------------------------------------------------------------
    933 
    934 ConstString
    935 UnwindAssembly_x86::GetPluginName()
    936 {
    937     return GetPluginNameStatic();
    938 }
    939 
    940 
    941 uint32_t
    942 UnwindAssembly_x86::GetPluginVersion()
    943 {
    944     return 1;
    945 }
    946 
    947 void
    948 UnwindAssembly_x86::Initialize()
    949 {
    950     PluginManager::RegisterPlugin (GetPluginNameStatic(),
    951                                    GetPluginDescriptionStatic(),
    952                                    CreateInstance);
    953 }
    954 
    955 void
    956 UnwindAssembly_x86::Terminate()
    957 {
    958     PluginManager::UnregisterPlugin (CreateInstance);
    959 }
    960 
    961 
    962 lldb_private::ConstString
    963 UnwindAssembly_x86::GetPluginNameStatic()
    964 {
    965     static ConstString g_name("x86");
    966     return g_name;
    967 }
    968 
    969 const char *
    970 UnwindAssembly_x86::GetPluginDescriptionStatic()
    971 {
    972     return "i386 and x86_64 assembly language profiler plugin.";
    973 }
    974