diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:06:29 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:06:29 +0000 | 
| commit | 94994d372d014ce4c8758b9605d63fae651bd8aa (patch) | |
| tree | 51c0b708bd59f205d6b35cb2a8c24d62f0c33d77 /source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp | |
| parent | 39be7ce23363d12ae3e49aeb1fdb2bfeb892e836 (diff) | |
Notes
Diffstat (limited to 'source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp')
| -rw-r--r-- | source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp | 344 | 
1 files changed, 252 insertions, 92 deletions
diff --git a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp index 10a56980594f..f8e70204e509 100644 --- a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp +++ b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp @@ -59,6 +59,7 @@ void x86AssemblyInspectionEngine::Initialize(RegisterContextSP ®_ctx) {      m_machine_ip_regnum = k_machine_eip;      m_machine_sp_regnum = k_machine_esp;      m_machine_fp_regnum = k_machine_ebp; +    m_machine_alt_fp_regnum = k_machine_ebx;      m_wordsize = 4;      struct lldb_reg_info reginfo; @@ -84,6 +85,7 @@ void x86AssemblyInspectionEngine::Initialize(RegisterContextSP ®_ctx) {      m_machine_ip_regnum = k_machine_rip;      m_machine_sp_regnum = k_machine_rsp;      m_machine_fp_regnum = k_machine_rbp; +    m_machine_alt_fp_regnum = k_machine_rbx;      m_wordsize = 8;      struct lldb_reg_info reginfo; @@ -135,6 +137,8 @@ void x86AssemblyInspectionEngine::Initialize(RegisterContextSP ®_ctx) {      m_lldb_sp_regnum = lldb_regno;    if (machine_regno_to_lldb_regno(m_machine_fp_regnum, lldb_regno))      m_lldb_fp_regnum = lldb_regno; +  if (machine_regno_to_lldb_regno(m_machine_alt_fp_regnum, lldb_regno)) +    m_lldb_alt_fp_regnum = lldb_regno;    if (machine_regno_to_lldb_regno(m_machine_ip_regnum, lldb_regno))      m_lldb_ip_regnum = lldb_regno; @@ -160,6 +164,7 @@ void x86AssemblyInspectionEngine::Initialize(      m_machine_ip_regnum = k_machine_eip;      m_machine_sp_regnum = k_machine_esp;      m_machine_fp_regnum = k_machine_ebp; +    m_machine_alt_fp_regnum = k_machine_ebx;      m_wordsize = 4;      struct lldb_reg_info reginfo; @@ -185,6 +190,7 @@ void x86AssemblyInspectionEngine::Initialize(      m_machine_ip_regnum = k_machine_rip;      m_machine_sp_regnum = k_machine_rsp;      m_machine_fp_regnum = k_machine_rbp; +    m_machine_alt_fp_regnum = k_machine_rbx;      m_wordsize = 8;      struct lldb_reg_info reginfo; @@ -239,6 +245,8 @@ void x86AssemblyInspectionEngine::Initialize(      m_lldb_sp_regnum = lldb_regno;    if (machine_regno_to_lldb_regno(m_machine_fp_regnum, lldb_regno))      m_lldb_fp_regnum = lldb_regno; +  if (machine_regno_to_lldb_regno(m_machine_alt_fp_regnum, lldb_regno)) +    m_lldb_alt_fp_regnum = lldb_regno;    if (machine_regno_to_lldb_regno(m_machine_ip_regnum, lldb_regno))      m_lldb_ip_regnum = lldb_regno; @@ -296,26 +304,20 @@ bool x86AssemblyInspectionEngine::nonvolatile_reg_p(int machine_regno) {  // pushq %rbp [0x55]  bool x86AssemblyInspectionEngine::push_rbp_pattern_p() {    uint8_t *p = m_cur_insn; -  if (*p == 0x55) -    return true; -  return false; +  return *p == 0x55;  }  // pushq $0 ; the first instruction in start() [0x6a 0x00]  bool x86AssemblyInspectionEngine::push_0_pattern_p() {    uint8_t *p = m_cur_insn; -  if (*p == 0x6a && *(p + 1) == 0x0) -    return true; -  return false; +  return *p == 0x6a && *(p + 1) == 0x0;  }  // pushq $0  // pushl $0  bool x86AssemblyInspectionEngine::push_imm_pattern_p() {    uint8_t *p = m_cur_insn; -  if (*p == 0x68 || *p == 0x6a) -    return true; -  return false; +  return *p == 0x68 || *p == 0x6a;  }  // pushl imm8(%esp) @@ -387,6 +389,45 @@ bool x86AssemblyInspectionEngine::mov_rsp_rbp_pattern_p() {    return false;  } +// movq %rsp, %rbx [0x48 0x8b 0xdc] or [0x48 0x89 0xe3] +// movl %esp, %ebx [0x8b 0xdc] or [0x89 0xe3] +bool x86AssemblyInspectionEngine::mov_rsp_rbx_pattern_p() { +  uint8_t *p = m_cur_insn; +  if (m_wordsize == 8 && *p == 0x48) +    p++; +  if (*(p) == 0x8b && *(p + 1) == 0xdc) +    return true; +  if (*(p) == 0x89 && *(p + 1) == 0xe3) +    return true; +  return false; +} + +// movq %rbp, %rsp [0x48 0x8b 0xe5] or [0x48 0x89 0xec] +// movl %ebp, %esp [0x8b 0xe5] or [0x89 0xec] +bool x86AssemblyInspectionEngine::mov_rbp_rsp_pattern_p() { +  uint8_t *p = m_cur_insn; +  if (m_wordsize == 8 && *p == 0x48) +    p++; +  if (*(p) == 0x8b && *(p + 1) == 0xe5) +    return true; +  if (*(p) == 0x89 && *(p + 1) == 0xec) +    return true; +  return false; +} + +// movq %rbx, %rsp [0x48 0x8b 0xe3] or [0x48 0x89 0xdc] +// movl %ebx, %esp [0x8b 0xe3] or [0x89 0xdc] +bool x86AssemblyInspectionEngine::mov_rbx_rsp_pattern_p() { +  uint8_t *p = m_cur_insn; +  if (m_wordsize == 8 && *p == 0x48) +    p++; +  if (*(p) == 0x8b && *(p + 1) == 0xe3) +    return true; +  if (*(p) == 0x89 && *(p + 1) == 0xdc) +    return true; +  return false; +} +  // subq $0x20, %rsp  bool x86AssemblyInspectionEngine::sub_rsp_pattern_p(int &amount) {    uint8_t *p = m_cur_insn; @@ -476,6 +517,46 @@ bool x86AssemblyInspectionEngine::lea_rbp_rsp_pattern_p(int &amount) {    return false;  } +// lea -0x28(%ebx), %esp +// (32-bit and 64-bit variants, 8-bit and 32-bit displacement) +bool x86AssemblyInspectionEngine::lea_rbx_rsp_pattern_p(int &amount) { +  uint8_t *p = m_cur_insn; +  if (m_wordsize == 8 && *p == 0x48) +    p++; + +  // Check opcode +  if (*p != 0x8d) +    return false; +  ++p; + +  // 8 bit displacement +  if (*p == 0x63) { +    amount = (int8_t)p[1]; +    return true; +  } + +  // 32 bit displacement +  if (*p == 0xa3) { +    amount = (int32_t)extract_4(p + 1); +    return true; +  } + +  return false; +} + +// and -0xfffffff0, %esp +// (32-bit and 64-bit variants, 8-bit and 32-bit displacement) +bool x86AssemblyInspectionEngine::and_rsp_pattern_p() { +  uint8_t *p = m_cur_insn; +  if (m_wordsize == 8 && *p == 0x48) +    p++; + +  if (*p != 0x81 && *p != 0x83) +    return false; + +  return *++p == 0xe4; +} +  // popq %rbx  // popl %ebx  bool x86AssemblyInspectionEngine::pop_reg_p(int ®no) { @@ -588,9 +669,7 @@ bool x86AssemblyInspectionEngine::mov_reg_to_local_stack_frame_p(  // ret [0xc9] or [0xc2 imm8] or [0xca imm8]  bool x86AssemblyInspectionEngine::ret_pattern_p() {    uint8_t *p = m_cur_insn; -  if (*p == 0xc9 || *p == 0xc2 || *p == 0xca || *p == 0xc3) -    return true; -  return false; +  return *p == 0xc9 || *p == 0xc2 || *p == 0xca || *p == 0xc3;  }  uint32_t x86AssemblyInspectionEngine::extract_4(uint8_t *b) { @@ -636,11 +715,12 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(    if (data == nullptr || size == 0)      return false; -  if (m_register_map_initialized == false) +  if (!m_register_map_initialized)      return false;    addr_t current_func_text_offset = 0; -  int current_sp_bytes_offset_from_cfa = 0; +  int current_sp_bytes_offset_from_fa = 0; +  bool is_aligned = false;    UnwindPlan::Row::RegisterLocation initial_regloc;    UnwindPlan::RowSP row(new UnwindPlan::Row); @@ -657,8 +737,8 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(    row->SetRegisterInfo(m_lldb_sp_regnum, initial_regloc);    // saved instruction pointer can be found at CFA - wordsize. -  current_sp_bytes_offset_from_cfa = m_wordsize; -  initial_regloc.SetAtCFAPlusOffset(-current_sp_bytes_offset_from_cfa); +  current_sp_bytes_offset_from_fa = m_wordsize; +  initial_regloc.SetAtCFAPlusOffset(-current_sp_bytes_offset_from_fa);    row->SetRegisterInfo(m_lldb_ip_regnum, initial_regloc);    unwind_plan.AppendRow(row); @@ -682,6 +762,7 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(    UnwindPlan::RowSP prologue_completed_row; // copy of prologue row of CFI    int prologue_completed_sp_bytes_offset_from_cfa; // The sp value before the                                                     // epilogue started executed +  bool prologue_completed_is_aligned;    std::vector<bool> prologue_completed_saved_registers;    while (current_func_text_offset < size) { @@ -701,22 +782,59 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(        break;      } -    if (push_rbp_pattern_p()) { -      current_sp_bytes_offset_from_cfa += m_wordsize; -      row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa); -      UnwindPlan::Row::RegisterLocation regloc; -      regloc.SetAtCFAPlusOffset(-row->GetCFAValue().GetOffset()); -      row->SetRegisterInfo(m_lldb_fp_regnum, regloc); -      saved_registers[m_machine_fp_regnum] = true; -      row_updated = true; +    auto &cfa_value = row->GetCFAValue(); +    auto &afa_value = row->GetAFAValue(); +    auto fa_value_ptr = is_aligned ? &afa_value : &cfa_value; + +    if (mov_rsp_rbp_pattern_p()) { +      if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) { +        fa_value_ptr->SetIsRegisterPlusOffset( +            m_lldb_fp_regnum, fa_value_ptr->GetOffset()); +        row_updated = true; +      } +    } + +    else if (mov_rsp_rbx_pattern_p()) { +      if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) { +        fa_value_ptr->SetIsRegisterPlusOffset( +            m_lldb_alt_fp_regnum, fa_value_ptr->GetOffset()); +        row_updated = true; +      }      } -    else if (mov_rsp_rbp_pattern_p()) { -      row->GetCFAValue().SetIsRegisterPlusOffset( -          m_lldb_fp_regnum, row->GetCFAValue().GetOffset()); +    else if (and_rsp_pattern_p()) { +      current_sp_bytes_offset_from_fa = 0; +      afa_value.SetIsRegisterPlusOffset( +          m_lldb_sp_regnum, current_sp_bytes_offset_from_fa); +      fa_value_ptr = &afa_value; +      is_aligned = true;        row_updated = true;      } +    else if (mov_rbp_rsp_pattern_p()) { +      if (is_aligned && cfa_value.GetRegisterNumber() == m_lldb_fp_regnum) +      { +        is_aligned = false; +        fa_value_ptr = &cfa_value; +        afa_value.SetUnspecified(); +        row_updated = true; +      } +      if (fa_value_ptr->GetRegisterNumber() == m_lldb_fp_regnum) +        current_sp_bytes_offset_from_fa = fa_value_ptr->GetOffset(); +    } + +    else if (mov_rbx_rsp_pattern_p()) { +      if (is_aligned && cfa_value.GetRegisterNumber() == m_lldb_alt_fp_regnum) +      { +        is_aligned = false; +        fa_value_ptr = &cfa_value; +        afa_value.SetUnspecified(); +        row_updated = true; +      } +      if (fa_value_ptr->GetRegisterNumber() == m_lldb_alt_fp_regnum) +        current_sp_bytes_offset_from_fa = fa_value_ptr->GetOffset(); +    } +      // This is the start() function (or a pthread equivalent), it starts with a      // pushl $0x0 which puts the saved pc value of 0 on the stack.  In this      // case we want to pretend we didn't see a stack movement at all -- @@ -726,21 +844,24 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(      }      else if (push_reg_p(machine_regno)) { -      current_sp_bytes_offset_from_cfa += m_wordsize; -      // the PUSH instruction has moved the stack pointer - if the CFA is set +      current_sp_bytes_offset_from_fa += m_wordsize; +      // the PUSH instruction has moved the stack pointer - if the FA is set        // in terms of the stack pointer, we need to add a new row of        // instructions. -      if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) { -        row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa); +      if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) { +        fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa);          row_updated = true;        }        // record where non-volatile (callee-saved, spilled) registers are saved        // on the stack        if (nonvolatile_reg_p(machine_regno) &&            machine_regno_to_lldb_regno(machine_regno, lldb_regno) && -          saved_registers[machine_regno] == false) { +          !saved_registers[machine_regno]) {          UnwindPlan::Row::RegisterLocation regloc; -        regloc.SetAtCFAPlusOffset(-current_sp_bytes_offset_from_cfa); +        if (is_aligned) +            regloc.SetAtAFAPlusOffset(-current_sp_bytes_offset_from_fa); +        else +            regloc.SetAtCFAPlusOffset(-current_sp_bytes_offset_from_fa);          row->SetRegisterInfo(lldb_regno, regloc);          saved_registers[machine_regno] = true;          row_updated = true; @@ -748,37 +869,37 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(      }      else if (pop_reg_p(machine_regno)) { -      current_sp_bytes_offset_from_cfa -= m_wordsize; +      current_sp_bytes_offset_from_fa -= m_wordsize;        if (nonvolatile_reg_p(machine_regno) &&            machine_regno_to_lldb_regno(machine_regno, lldb_regno) && -          saved_registers[machine_regno] == true) { +          saved_registers[machine_regno]) {          saved_registers[machine_regno] = false;          row->RemoveRegisterInfo(lldb_regno); -        if (machine_regno == (int)m_machine_fp_regnum) { -          row->GetCFAValue().SetIsRegisterPlusOffset( -              m_lldb_sp_regnum, row->GetCFAValue().GetOffset()); +        if (lldb_regno == fa_value_ptr->GetRegisterNumber()) { +          fa_value_ptr->SetIsRegisterPlusOffset( +              m_lldb_sp_regnum, fa_value_ptr->GetOffset());          }          in_epilogue = true;          row_updated = true;        } -      // the POP instruction has moved the stack pointer - if the CFA is set in +      // the POP instruction has moved the stack pointer - if the FA is set in        // terms of the stack pointer, we need to add a new row of instructions. -      if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) { -        row->GetCFAValue().SetIsRegisterPlusOffset( -            m_lldb_sp_regnum, current_sp_bytes_offset_from_cfa); +      if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) { +        fa_value_ptr->SetIsRegisterPlusOffset( +            m_lldb_sp_regnum, current_sp_bytes_offset_from_fa);          row_updated = true;        }      }      else if (pop_misc_reg_p()) { -      current_sp_bytes_offset_from_cfa -= m_wordsize; -      if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) { -        row->GetCFAValue().SetIsRegisterPlusOffset( -            m_lldb_sp_regnum, current_sp_bytes_offset_from_cfa); +      current_sp_bytes_offset_from_fa -= m_wordsize; +      if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) { +        fa_value_ptr->SetIsRegisterPlusOffset( +            m_lldb_sp_regnum, current_sp_bytes_offset_from_fa);          row_updated = true;        }      } @@ -787,41 +908,57 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(      // off the stack into rbp (restoring the caller's rbp value). It is the      // opposite of ENTER, or 'push rbp, mov rsp rbp'.      else if (leave_pattern_p()) { -      // We're going to copy the value in rbp into rsp, so re-set the sp offset -      // based on the CFAValue.  Also, adjust it to recognize that we're -      // popping the saved rbp value off the stack. -      current_sp_bytes_offset_from_cfa = row->GetCFAValue().GetOffset(); -      current_sp_bytes_offset_from_cfa -= m_wordsize; -      row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa); - -      // rbp is restored to the caller's value -      saved_registers[m_machine_fp_regnum] = false; -      row->RemoveRegisterInfo(m_lldb_fp_regnum); - -      // cfa is now in terms of rsp again. -      row->GetCFAValue().SetIsRegisterPlusOffset( -          m_lldb_sp_regnum, row->GetCFAValue().GetOffset()); -      row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa); +      if (saved_registers[m_machine_fp_regnum]) { +        saved_registers[m_machine_fp_regnum] = false; +        row->RemoveRegisterInfo(m_lldb_fp_regnum); + +        row_updated = true; +      } + +      if (is_aligned && cfa_value.GetRegisterNumber() == m_lldb_fp_regnum) +      { +        is_aligned = false; +        fa_value_ptr = &cfa_value; +        afa_value.SetUnspecified(); +        row_updated = true; +      } + +      if (fa_value_ptr->GetRegisterNumber() == m_lldb_fp_regnum) +      { +        fa_value_ptr->SetIsRegisterPlusOffset( +            m_lldb_sp_regnum, fa_value_ptr->GetOffset()); + +        current_sp_bytes_offset_from_fa = fa_value_ptr->GetOffset(); +      } + +      current_sp_bytes_offset_from_fa -= m_wordsize; + +      if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) { +        fa_value_ptr->SetIsRegisterPlusOffset( +            m_lldb_sp_regnum, current_sp_bytes_offset_from_fa); +        row_updated = true; +      }        in_epilogue = true; -      row_updated = true;      }      else if (mov_reg_to_local_stack_frame_p(machine_regno, stack_offset) &&               nonvolatile_reg_p(machine_regno) &&               machine_regno_to_lldb_regno(machine_regno, lldb_regno) && -             saved_registers[machine_regno] == false) { +             !saved_registers[machine_regno]) {        saved_registers[machine_regno] = true;        UnwindPlan::Row::RegisterLocation regloc;        // stack_offset for 'movq %r15, -80(%rbp)' will be 80. In the Row, we -      // want to express this as the offset from the CFA.  If the frame base is -      // rbp (like the above instruction), the CFA offset for rbp is probably -      // 16.  So we want to say that the value is stored at the CFA address - +      // want to express this as the offset from the FA.  If the frame base is +      // rbp (like the above instruction), the FA offset for rbp is probably +      // 16.  So we want to say that the value is stored at the FA address -        // 96. -      regloc.SetAtCFAPlusOffset( -          -(stack_offset + row->GetCFAValue().GetOffset())); +      if (is_aligned) +          regloc.SetAtAFAPlusOffset(-(stack_offset + fa_value_ptr->GetOffset())); +      else +          regloc.SetAtCFAPlusOffset(-(stack_offset + fa_value_ptr->GetOffset()));        row->SetRegisterInfo(lldb_regno, regloc); @@ -829,17 +966,17 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(      }      else if (sub_rsp_pattern_p(stack_offset)) { -      current_sp_bytes_offset_from_cfa += stack_offset; -      if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) { -        row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa); +      current_sp_bytes_offset_from_fa += stack_offset; +      if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) { +        fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa);          row_updated = true;        }      }      else if (add_rsp_pattern_p(stack_offset)) { -      current_sp_bytes_offset_from_cfa -= stack_offset; -      if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) { -        row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa); +      current_sp_bytes_offset_from_fa -= stack_offset; +      if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) { +        fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa);          row_updated = true;        }        in_epilogue = true; @@ -847,27 +984,48 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(      else if (push_extended_pattern_p() || push_imm_pattern_p() ||               push_misc_reg_p()) { -      current_sp_bytes_offset_from_cfa += m_wordsize; -      if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) { -        row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa); +      current_sp_bytes_offset_from_fa += m_wordsize; +      if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) { +        fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa);          row_updated = true;        }      }      else if (lea_rsp_pattern_p(stack_offset)) { -      current_sp_bytes_offset_from_cfa -= stack_offset; -      if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) { -        row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa); +      current_sp_bytes_offset_from_fa -= stack_offset; +      if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) { +        fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa);          row_updated = true;        }        if (stack_offset > 0)          in_epilogue = true;      } -    else if (lea_rbp_rsp_pattern_p(stack_offset) && -             row->GetCFAValue().GetRegisterNumber() == m_lldb_fp_regnum) { -      current_sp_bytes_offset_from_cfa = -          row->GetCFAValue().GetOffset() - stack_offset; +    else if (lea_rbp_rsp_pattern_p(stack_offset)) { +      if (is_aligned && +          cfa_value.GetRegisterNumber() == m_lldb_fp_regnum) { +        is_aligned = false; +        fa_value_ptr = &cfa_value; +        afa_value.SetUnspecified(); +        row_updated = true; +      } +      if (fa_value_ptr->GetRegisterNumber() == m_lldb_fp_regnum) { +        current_sp_bytes_offset_from_fa = +          fa_value_ptr->GetOffset() - stack_offset; +      } +    } + +    else if (lea_rbx_rsp_pattern_p(stack_offset)) { +      if (is_aligned && +          cfa_value.GetRegisterNumber() == m_lldb_alt_fp_regnum) { +        is_aligned = false; +        fa_value_ptr = &cfa_value; +        afa_value.SetUnspecified(); +        row_updated = true; +      } +      if (fa_value_ptr->GetRegisterNumber() == m_lldb_alt_fp_regnum) { +        current_sp_bytes_offset_from_fa = fa_value_ptr->GetOffset() - stack_offset; +      }      }      else if (ret_pattern_p() && prologue_completed_row.get()) { @@ -877,8 +1035,9 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(        UnwindPlan::Row *newrow = new UnwindPlan::Row;        *newrow = *prologue_completed_row.get();        row.reset(newrow); -      current_sp_bytes_offset_from_cfa = +      current_sp_bytes_offset_from_fa =            prologue_completed_sp_bytes_offset_from_cfa; +      is_aligned = prologue_completed_is_aligned;        saved_registers.clear();        saved_registers.resize(prologue_completed_saved_registers.size(), false); @@ -896,9 +1055,9 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(      // This is used in i386 programs to get the PIC base address for finding      // global data      else if (call_next_insn_pattern_p()) { -      current_sp_bytes_offset_from_cfa += m_wordsize; -      if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) { -        row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa); +      current_sp_bytes_offset_from_fa += m_wordsize; +      if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) { +        fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa);          row_updated = true;        }      } @@ -914,7 +1073,7 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(        }      } -    if (in_epilogue == false && row_updated) { +    if (!in_epilogue && row_updated) {        // If we're not in an epilogue sequence, save the updated Row        UnwindPlan::Row *newrow = new UnwindPlan::Row;        *newrow = *row.get(); @@ -929,9 +1088,10 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(      // We may change the sp value without adding a new Row necessarily -- keep      // track of it either way. -    if (in_epilogue == false) { +    if (!in_epilogue) {        prologue_completed_sp_bytes_offset_from_cfa = -          current_sp_bytes_offset_from_cfa; +          current_sp_bytes_offset_from_fa; +      prologue_completed_is_aligned = is_aligned;      }      m_cur_insn = m_cur_insn + insn_len; @@ -1194,7 +1354,7 @@ bool x86AssemblyInspectionEngine::FindFirstNonPrologueInstruction(      uint8_t *data, size_t size, size_t &offset) {    offset = 0; -  if (m_register_map_initialized == false) +  if (!m_register_map_initialized)      return false;    while (offset < size) {  | 
