From 34132754bdfd94be8199945b3f4c8dbe8bd67cf3 Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Wed, 6 Jul 2011 04:07:21 +0000 Subject: [PATCH] Fixed some issues with ARM backtraces by not processing any push/pop instructions if they are conditional. Also fixed issues where the PC wasn't getting bit zero stripped for ARM targets when a stack frame was thumb. We now properly call through the GetOpcodeLoadAddress() functions to make sure the addresses are properly stripped for any targets that may decorate up their addresses. We now don't pass the SIGSTOP signals along. We can revisit this soon, but currently this was interfering with debugging some older ARM targets that don't have vCont support in the GDB server. llvm-svn: 134461 --- lldb/include/lldb/Core/RegisterValue.h | 6 + lldb/include/lldb/Target/StackFrame.h | 2 +- lldb/source/API/SBFrame.cpp | 2 +- lldb/source/Core/Debugger.cpp | 306 +++++++++--------- lldb/source/Core/Disassembler.cpp | 2 +- lldb/source/Core/RegisterValue.cpp | 147 +++++++++ .../Instruction/ARM/EmulateInstructionARM.cpp | 109 ++++--- .../Instruction/ARM/EmulateInstructionARM.h | 4 +- .../gdb-remote/GDBRemoteRegisterContext.cpp | 4 +- .../gdb-remote/GDBRemoteRegisterContext.h | 1 - lldb/source/Target/StackFrame.cpp | 7 +- lldb/source/Target/UnixSignals.cpp | 66 ++-- 12 files changed, 424 insertions(+), 232 deletions(-) diff --git a/lldb/include/lldb/Core/RegisterValue.h b/lldb/include/lldb/Core/RegisterValue.h index 0a0c4fcd09ee..c40d6a204e8c 100644 --- a/lldb/include/lldb/Core/RegisterValue.h +++ b/lldb/include/lldb/Core/RegisterValue.h @@ -203,6 +203,12 @@ namespace lldb_private { m_type = eTypeInvalid; } + bool + ClearBit (uint32_t bit); + + bool + SetBit (uint32_t bit); + bool operator == (const RegisterValue &rhs) const; diff --git a/lldb/include/lldb/Target/StackFrame.h b/lldb/include/lldb/Target/StackFrame.h index c93ec5b47859..4dd04c3d9c9e 100644 --- a/lldb/include/lldb/Target/StackFrame.h +++ b/lldb/include/lldb/Target/StackFrame.h @@ -74,7 +74,7 @@ public: StackID& GetStackID(); - Address& + const Address& GetFrameCodeAddress(); void diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp index 11a0eff33f19..3a0361e45ddd 100644 --- a/lldb/source/API/SBFrame.cpp +++ b/lldb/source/API/SBFrame.cpp @@ -258,7 +258,7 @@ SBFrame::GetPC () const if (m_opaque_sp) { Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex()); - addr = m_opaque_sp->GetFrameCodeAddress().GetLoadAddress (&m_opaque_sp->GetThread().GetProcess().GetTarget()); + addr = m_opaque_sp->GetFrameCodeAddress().GetOpcodeLoadAddress (&m_opaque_sp->GetThread().GetProcess().GetTarget()); } LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 18e88f6b7319..f81173e2d9d7 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -715,7 +715,7 @@ ScanFormatDescriptor(const char* var_name_begin, ValueObject::ValueObjectRepresentationStyle* val_obj_display) { *percent_position = ::strchr(var_name_begin,'%'); - if(!*percent_position || *percent_position > var_name_end) + if (!*percent_position || *percent_position > var_name_end) *var_name_final = var_name_end; else { @@ -727,10 +727,10 @@ ScanFormatDescriptor(const char* var_name_begin, *custom_format) ) { // if this is an @ sign, print ObjC description - if(*format_name == '@') + if (*format_name == '@') *val_obj_display = ValueObject::eDisplayLanguageSpecific; // if this is a V, print the value using the default format - if(*format_name == 'V') + if (*format_name == 'V') *val_obj_display = ValueObject::eDisplayValue; } // a good custom format tells us to print the value using it @@ -753,14 +753,14 @@ ScanBracketedRange(const char* var_name_begin, int64_t* index_higher) { *open_bracket_position = ::strchr(var_name_begin,'['); - if(*open_bracket_position && *open_bracket_position < var_name_final) + if (*open_bracket_position && *open_bracket_position < var_name_final) { *separator_position = ::strchr(*open_bracket_position,'-'); // might be NULL if this is a simple var[N] bitfield *close_bracket_position = ::strchr(*open_bracket_position,']'); // as usual, we assume that [] will come before % //printf("trying to expand a []\n"); *var_name_final_if_array_range = *open_bracket_position; - if(*close_bracket_position - *open_bracket_position == 1) + if (*close_bracket_position - *open_bracket_position == 1) { *index_lower = 0; } @@ -771,7 +771,7 @@ ScanBracketedRange(const char* var_name_begin, *index_higher = *index_lower; //printf("got to read low=%d high same\n",bitfield_lower); } - else if(*close_bracket_position && *close_bracket_position < var_name_end) + else if (*close_bracket_position && *close_bracket_position < var_name_end) { char *end = NULL; *index_lower = ::strtoul (*open_bracket_position+1, &end, 0); @@ -803,9 +803,9 @@ ExpandExpressionPath(ValueObject* vobj, StreamString sstring; VariableSP var_sp; - if(*do_deref_pointer) + if (*do_deref_pointer) sstring.PutChar('*'); - else if(vobj->IsDereferenceOfParent() && ClangASTContext::IsPointerType(vobj->GetParent()->GetClangType()) && !vobj->IsArrayItemForPointer()) + else if (vobj->IsDereferenceOfParent() && ClangASTContext::IsPointerType(vobj->GetParent()->GetClangType()) && !vobj->IsArrayItemForPointer()) { sstring.PutChar('*'); *do_deref_pointer = true; @@ -837,7 +837,7 @@ ExpandIndexedExpression(ValueObject* vobj, ValueObjectSP item; bool is_array = ClangASTContext::IsArrayType(vobj->GetClangType()); - if(is_array) + if (is_array) return vobj->GetChildAtIndex(index, true); else { @@ -881,7 +881,7 @@ Debugger::FormatPrompt const char *p; for (p = format; *p != '\0'; ++p) { - if(realvobj) + if (realvobj) { vobj = realvobj; realvobj = NULL; @@ -961,165 +961,169 @@ Debugger::FormatPrompt { case '*': { - if (!vobj) break; + if (!vobj) + break; do_deref_pointer = true; var_name_begin++; } + // Fall through... + case 'v': { - ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eDisplaySummary; - ValueObject* target; - lldb::Format custom_format = eFormatInvalid; - const char* var_name_final; - const char* var_name_final_if_array_range = NULL; - const char* close_bracket_position; - int64_t index_lower = -1, index_higher = -1; - bool is_array_range = false; - if (!vobj) break; - // simplest case ${var}, just print vobj's value - if (::strncmp (var_name_begin, "var}", strlen("var}")) == 0) - { - target = vobj; - val_obj_display = ValueObject::eDisplayValue; - } - else if (::strncmp(var_name_begin,"var%",strlen("var%")) == 0) - { - // this is a variable with some custom format applied to it - const char* percent_position; - target = vobj; - val_obj_display = ValueObject::eDisplayValue; - ScanFormatDescriptor(var_name_begin, - var_name_end, - &var_name_final, - &percent_position, - &custom_format, - &val_obj_display); - } - // this is ${var.something} or multiple .something nested - else if (::strncmp (var_name_begin, "var", strlen("var")) == 0) - { - - const char* percent_position; - ScanFormatDescriptor(var_name_begin, - var_name_end, - &var_name_final, - &percent_position, - &custom_format, - &val_obj_display); - - const char* open_bracket_position; - const char* separator_position; - ScanBracketedRange(var_name_begin, - var_name_end, - var_name_final, - &open_bracket_position, - &separator_position, - &close_bracket_position, - &var_name_final_if_array_range, - &index_lower, - &index_higher); - - Error error; - target = ExpandExpressionPath(vobj, - exe_ctx->frame, - &do_deref_pointer, - var_name_begin, - var_name_final, - error).get(); - - if (error.Fail() || !target) + ValueObject::ValueObjectRepresentationStyle val_obj_display = ValueObject::eDisplaySummary; + ValueObject* target = NULL; + lldb::Format custom_format = eFormatInvalid; + const char* var_name_final = NULL; + const char* var_name_final_if_array_range = NULL; + const char* close_bracket_position = NULL; + int64_t index_lower = -1; + int64_t index_higher = -1; + bool is_array_range = false; + if (!vobj) break; + // simplest case ${var}, just print vobj's value + if (::strncmp (var_name_begin, "var}", strlen("var}")) == 0) { -#ifdef VERBOSE_FORMATPROMPT_OUTPUT - printf("ERROR: %s\n",error.AsCString("unknown")); -#endif //VERBOSE_FORMATPROMPT_OUTPUT - if (var_name_final_if_array_range) + target = vobj; + val_obj_display = ValueObject::eDisplayValue; + } + else if (::strncmp(var_name_begin,"var%",strlen("var%")) == 0) + { + // this is a variable with some custom format applied to it + const char* percent_position; + target = vobj; + val_obj_display = ValueObject::eDisplayValue; + ScanFormatDescriptor (var_name_begin, + var_name_end, + &var_name_final, + &percent_position, + &custom_format, + &val_obj_display); + } + // this is ${var.something} or multiple .something nested + else if (::strncmp (var_name_begin, "var", strlen("var")) == 0) + { + + const char* percent_position; + ScanFormatDescriptor (var_name_begin, + var_name_end, + &var_name_final, + &percent_position, + &custom_format, + &val_obj_display); + + const char* open_bracket_position; + const char* separator_position; + ScanBracketedRange (var_name_begin, + var_name_end, + var_name_final, + &open_bracket_position, + &separator_position, + &close_bracket_position, + &var_name_final_if_array_range, + &index_lower, + &index_higher); + + Error error; + target = ExpandExpressionPath (vobj, + exe_ctx->frame, + &do_deref_pointer, + var_name_begin, + var_name_final, + error).get(); + + if (error.Fail() || !target) { - target = ExpandExpressionPath(vobj, - exe_ctx->frame, - &do_deref_pointer, - var_name_begin, - var_name_final_if_array_range, - error).get(); +#ifdef VERBOSE_FORMATPROMPT_OUTPUT + printf("ERROR: %s\n",error.AsCString("unknown")); +#endif //VERBOSE_FORMATPROMPT_OUTPUT + if (var_name_final_if_array_range) + { + target = ExpandExpressionPath(vobj, + exe_ctx->frame, + &do_deref_pointer, + var_name_begin, + var_name_final_if_array_range, + error).get(); + } + + IFERROR_PRINT_IT + else + is_array_range = true; } - IFERROR_PRINT_IT - else - is_array_range = true; + do_deref_pointer = false; // I have honored the request to deref + } - - do_deref_pointer = false; // I have honored the request to deref - - } - else - break; - - if(do_deref_pointer) - { - // I have not deref-ed yet, let's do it - // this happens when we are not going through GetValueForVariableExpressionPath - // to get to the target ValueObject - Error error; - target = target->Dereference(error).get(); - IFERROR_PRINT_IT - do_deref_pointer = false; - } - - if(!is_array_range) - var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format); - else - { - bool is_array = ClangASTContext::IsArrayType(vobj->GetClangType()); - bool is_pointer = ClangASTContext::IsPointerType(vobj->GetClangType()); - - if(!is_array && !is_pointer) + else break; - - char* special_directions = NULL; - if (close_bracket_position && (var_name_end-close_bracket_position > 1)) - { - int base_len = var_name_end-close_bracket_position; - special_directions = new char[8+base_len]; - special_directions[0] = '$'; - special_directions[1] = '{'; - special_directions[2] = 'v'; - special_directions[3] = 'a'; - special_directions[4] = 'r'; - memcpy(special_directions+5, close_bracket_position+1, base_len); - special_directions[base_len+7] = '\0'; -#ifdef VERBOSE_FORMATPROMPT_OUTPUT - printf("%s\n",special_directions); -#endif //VERBOSE_FORMATPROMPT_OUTPUT - } - - // let us display items index_lower thru index_higher of this array - s.PutChar('['); - var_success = true; - if(index_higher < 0) - index_higher = vobj->GetNumChildren() - 1; - - for(;index_lower<=index_higher;index_lower++) + if (do_deref_pointer) { + // I have not deref-ed yet, let's do it + // this happens when we are not going through GetValueForVariableExpressionPath + // to get to the target ValueObject Error error; - ValueObject* item = ExpandIndexedExpression(vobj, - index_lower, - exe_ctx->frame, - error).get(); - - + target = target->Dereference(error).get(); IFERROR_PRINT_IT - if (!special_directions) - var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format); - else - var_success &= FormatPrompt(special_directions, sc, exe_ctx, addr, s, NULL, item); - - if(index_lower < index_higher) - s.PutChar(','); + do_deref_pointer = false; + } + + if (!is_array_range) + var_success = target->DumpPrintableRepresentation(s,val_obj_display, custom_format); + else + { + bool is_array = ClangASTContext::IsArrayType(vobj->GetClangType()); + bool is_pointer = ClangASTContext::IsPointerType(vobj->GetClangType()); + + if (!is_array && !is_pointer) + break; + + char* special_directions = NULL; + if (close_bracket_position && (var_name_end-close_bracket_position > 1)) + { + int base_len = var_name_end-close_bracket_position; + special_directions = new char[8+base_len]; + special_directions[0] = '$'; + special_directions[1] = '{'; + special_directions[2] = 'v'; + special_directions[3] = 'a'; + special_directions[4] = 'r'; + memcpy(special_directions+5, close_bracket_position+1, base_len); + special_directions[base_len+7] = '\0'; +#ifdef VERBOSE_FORMATPROMPT_OUTPUT + printf("%s\n",special_directions); +#endif //VERBOSE_FORMATPROMPT_OUTPUT + } + + // let us display items index_lower thru index_higher of this array + s.PutChar('['); + var_success = true; + + if (index_higher < 0) + index_higher = vobj->GetNumChildren() - 1; + + for (;index_lower<=index_higher;index_lower++) + { + Error error; + ValueObject* item = ExpandIndexedExpression(vobj, + index_lower, + exe_ctx->frame, + error).get(); + + + IFERROR_PRINT_IT + if (!special_directions) + var_success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format); + else + var_success &= FormatPrompt(special_directions, sc, exe_ctx, addr, s, NULL, item); + + if (index_lower < index_higher) + s.PutChar(','); + } + s.PutChar(']'); } - s.PutChar(']'); } break; - } case 'a': if (::strncmp (var_name_begin, "addr}", strlen("addr}")) == 0) { diff --git a/lldb/source/Core/Disassembler.cpp b/lldb/source/Core/Disassembler.cpp index 6d16e35918a2..fbb0b71451b6 100644 --- a/lldb/source/Core/Disassembler.cpp +++ b/lldb/source/Core/Disassembler.cpp @@ -331,7 +331,7 @@ Disassembler::PrintInstructions SymbolContext sc; SymbolContext prev_sc; AddressRange sc_range; - Address *pc_addr_ptr = NULL; + const Address *pc_addr_ptr = NULL; ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope(); if (exe_ctx.frame) pc_addr_ptr = &exe_ctx.frame->GetFrameCodeAddress(); diff --git a/lldb/source/Core/RegisterValue.cpp b/lldb/source/Core/RegisterValue.cpp index 963027154bb2..e8638b3e678c 100644 --- a/lldb/source/Core/RegisterValue.cpp +++ b/lldb/source/Core/RegisterValue.cpp @@ -1000,3 +1000,150 @@ RegisterValue::operator != (const RegisterValue &rhs) const return true; } +bool +RegisterValue::ClearBit (uint32_t bit) +{ + switch (m_type) + { + case eTypeInvalid: + break; + + case eTypeUInt8: + if (bit < 8) + { + m_data.uint8 &= ~(1u << bit); + return true; + } + break; + + case eTypeUInt16: + if (bit < 16) + { + m_data.uint16 &= ~(1u << bit); + return true; + } + break; + + case eTypeUInt32: + if (bit < 32) + { + m_data.uint32 &= ~(1u << bit); + return true; + } + break; + + case eTypeUInt64: + if (bit < 64) + { + m_data.uint64 &= ~(1ull << (uint64_t)bit); + return true; + } + break; +#if defined (ENABLE_128_BIT_SUPPORT) + case eTypeUInt128: + if (bit < 64) + { + m_data.uint128 &= ~((__uint128_t)1ull << (__uint128_t)bit); + return true; + } +#endif + case eTypeFloat: + case eTypeDouble: + case eTypeLongDouble: + break; + + case eTypeBytes: + if (m_data.buffer.byte_order == eByteOrderBig || m_data.buffer.byte_order == eByteOrderLittle) + { + uint32_t byte_idx; + if (m_data.buffer.byte_order == eByteOrderBig) + byte_idx = m_data.buffer.length - (bit / 8) - 1; + else + byte_idx = bit / 8; + + const uint32_t byte_bit = bit % 8; + if (byte_idx < m_data.buffer.length) + { + m_data.buffer.bytes[byte_idx] &= ~(1u << byte_bit); + return true; + } + } + break; + } + return false; +} + + +bool +RegisterValue::SetBit (uint32_t bit) +{ + switch (m_type) + { + case eTypeInvalid: + break; + + case eTypeUInt8: + if (bit < 8) + { + m_data.uint8 |= (1u << bit); + return true; + } + break; + + case eTypeUInt16: + if (bit < 16) + { + m_data.uint16 |= (1u << bit); + return true; + } + break; + + case eTypeUInt32: + if (bit < 32) + { + m_data.uint32 |= (1u << bit); + return true; + } + break; + + case eTypeUInt64: + if (bit < 64) + { + m_data.uint64 |= (1ull << (uint64_t)bit); + return true; + } + break; +#if defined (ENABLE_128_BIT_SUPPORT) + case eTypeUInt128: + if (bit < 64) + { + m_data.uint128 |= ((__uint128_t)1ull << (__uint128_t)bit); + return true; + } +#endif + case eTypeFloat: + case eTypeDouble: + case eTypeLongDouble: + break; + + case eTypeBytes: + if (m_data.buffer.byte_order == eByteOrderBig || m_data.buffer.byte_order == eByteOrderLittle) + { + uint32_t byte_idx; + if (m_data.buffer.byte_order == eByteOrderBig) + byte_idx = m_data.buffer.length - (bit / 8) - 1; + else + byte_idx = bit / 8; + + const uint32_t byte_bit = bit % 8; + if (byte_idx < m_data.buffer.length) + { + m_data.buffer.bytes[byte_idx] |= (1u << byte_bit); + return true; + } + } + break; + } + return false; +} + diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp index f79f7d28e665..daaac46b3178 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -327,8 +327,9 @@ EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding enc } #endif + bool conditional = false; bool success = false; - if (ConditionPassed(opcode)) + if (ConditionPassed(opcode, &conditional)) { const uint32_t addr_byte_size = GetAddressByteSize(); const addr_t sp = ReadCoreReg (SP_REG, &success); @@ -381,7 +382,10 @@ EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding enc uint32_t i; EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextPushRegisterOnStack; + if (conditional) + context.type = EmulateInstruction::eContextRegisterStore; + else + context.type = EmulateInstruction::eContextPushRegisterOnStack; RegisterInfo reg_info; RegisterInfo sp_reg; GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); @@ -447,7 +451,9 @@ EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding enco bool success = false; - if (ConditionPassed(opcode)) { + bool conditional = false; + if (ConditionPassed(opcode, &conditional)) + { const uint32_t addr_byte_size = GetAddressByteSize(); const addr_t sp = ReadCoreReg (SP_REG, &success); if (!success) @@ -508,7 +514,10 @@ EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding enco uint32_t i, data; EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextPopRegisterOffStack; + if (conditional) + context.type = EmulateInstruction::eContextRegisterLoad; + else + context.type = EmulateInstruction::eContextPopRegisterOffStack; RegisterInfo sp_reg; GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); @@ -1847,9 +1856,9 @@ EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding } #endif + bool conditional = false; bool success = false; - - if (ConditionPassed(opcode)) + if (ConditionPassed(opcode, &conditional)) { const uint32_t addr_byte_size = GetAddressByteSize(); const addr_t sp = ReadCoreReg (SP_REG, &success); @@ -1894,7 +1903,10 @@ EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding addr = sp; EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextPushRegisterOnStack; + if (conditional) + context.type = EmulateInstruction::eContextRegisterStore; + else + context.type = EmulateInstruction::eContextPushRegisterOnStack; RegisterInfo sp_reg; RegisterInfo dwarf_reg; @@ -1955,8 +1967,8 @@ EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding en #endif bool success = false; - - if (ConditionPassed(opcode)) + bool conditional = false; + if (ConditionPassed(opcode, &conditional)) { const uint32_t addr_byte_size = GetAddressByteSize(); const addr_t sp = ReadCoreReg (SP_REG, &success); @@ -1998,7 +2010,10 @@ EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding en uint32_t i; EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextPushRegisterOnStack; + if (conditional) + context.type = EmulateInstruction::eContextRegisterStore; + else + context.type = EmulateInstruction::eContextPushRegisterOnStack; RegisterInfo dwarf_reg; RegisterInfo sp_reg; GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); @@ -2048,8 +2063,8 @@ EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding enc #endif bool success = false; - - if (ConditionPassed(opcode)) + bool conditional = false; + if (ConditionPassed(opcode, &conditional)) { const uint32_t addr_byte_size = GetAddressByteSize(); const addr_t sp = ReadCoreReg (SP_REG, &success); @@ -2092,7 +2107,10 @@ EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding enc uint64_t data; // uint64_t to accomodate 64-bit registers. EmulateInstruction::Context context; - context.type = EmulateInstruction::eContextPopRegisterOffStack; + if (conditional) + context.type = EmulateInstruction::eContextRegisterLoad; + else + context.type = EmulateInstruction::eContextPopRegisterOffStack; RegisterInfo dwarf_reg; RegisterInfo sp_reg; GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg); @@ -3303,8 +3321,8 @@ EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding enco #endif bool success = false; - - if (ConditionPassed(opcode)) + bool conditional = false; + if (ConditionPassed(opcode, &conditional)) { uint32_t n; uint32_t registers = 0; @@ -3376,7 +3394,12 @@ EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding enco context.type = EmulateInstruction::eContextRegisterPlusOffset; context.SetRegisterPlusOffset (dwarf_reg, offset); if (wback && (n == 13)) // Pop Instruction - context.type = EmulateInstruction::eContextPopRegisterOffStack; + { + if (conditional) + context.type = EmulateInstruction::eContextRegisterLoad; + else + context.type = EmulateInstruction::eContextPopRegisterOffStack; + } // R[i] = MemA [address, 4]; address = address + 4; uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success); @@ -12849,7 +12872,7 @@ EmulateInstructionARM::ArchVersion () } bool -EmulateInstructionARM::ConditionPassed (const uint32_t opcode) +EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional) { // If we are ignoring conditions, then always return true. // this allows us to iterate over disassembly code and still @@ -12857,6 +12880,9 @@ EmulateInstructionARM::ConditionPassed (const uint32_t opcode) // bits set in the CPSR register... if (m_ignore_conditions) return true; + + if (is_conditional) + *is_conditional = true; const uint32_t cond = CurrentCond (opcode); @@ -12868,33 +12894,38 @@ EmulateInstructionARM::ConditionPassed (const uint32_t opcode) { case 0: if (m_opcode_cpsr == 0) - return true; - result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; + result = true; + else + result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; break; case 1: - if (m_opcode_cpsr == 0) - return true; - result = (m_opcode_cpsr & MASK_CPSR_C) != 0; + if (m_opcode_cpsr == 0) + result = true; + else + result = (m_opcode_cpsr & MASK_CPSR_C) != 0; break; case 2: - if (m_opcode_cpsr == 0) - return true; - result = (m_opcode_cpsr & MASK_CPSR_N) != 0; + if (m_opcode_cpsr == 0) + result = true; + else + result = (m_opcode_cpsr & MASK_CPSR_N) != 0; break; case 3: - if (m_opcode_cpsr == 0) - return true; - result = (m_opcode_cpsr & MASK_CPSR_V) != 0; + if (m_opcode_cpsr == 0) + result = true; + else + result = (m_opcode_cpsr & MASK_CPSR_V) != 0; break; case 4: - if (m_opcode_cpsr == 0) - return true; - result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); + if (m_opcode_cpsr == 0) + result = true; + else + result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); break; case 5: - if (m_opcode_cpsr == 0) - return true; - else + if (m_opcode_cpsr == 0) + result = true; + else { bool n = (m_opcode_cpsr & MASK_CPSR_N); bool v = (m_opcode_cpsr & MASK_CPSR_V); @@ -12902,9 +12933,9 @@ EmulateInstructionARM::ConditionPassed (const uint32_t opcode) } break; case 6: - if (m_opcode_cpsr == 0) - return true; - else + if (m_opcode_cpsr == 0) + result = true; + else { bool n = (m_opcode_cpsr & MASK_CPSR_N); bool v = (m_opcode_cpsr & MASK_CPSR_V); @@ -12912,6 +12943,10 @@ EmulateInstructionARM::ConditionPassed (const uint32_t opcode) } break; case 7: + // Always execute (cond == 0b1110, or the special 0b1111 which gives + // opcodes different meanings, but always means execution happpens. + if (is_conditional) + *is_conditional = false; result = true; break; } diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h index d5ce73c5a984..39ba500a49ae 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h +++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h @@ -189,7 +189,9 @@ public: ArchVersion(); bool - ConditionPassed (const uint32_t opcode); + ConditionPassed (const uint32_t opcode, + bool *is_conditional = NULL); // Filled in with true if the opcode is a conditional opcode + // Filled in with false if the opcode is always executed uint32_t CurrentCond (const uint32_t opcode); diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp index ee6bff6a5d2c..7d9a146df700 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp @@ -119,7 +119,7 @@ bool GDBRemoteRegisterContext::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value) { // Read the register - if (ReadRegisterBytes (reg_info, value, m_reg_data)) + if (ReadRegisterBytes (reg_info, m_reg_data)) { const bool partial_data_ok = false; Error error (value.SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok)); @@ -156,7 +156,7 @@ GDBRemoteRegisterContext::PrivateSetRegisterValue (uint32_t reg, StringExtractor bool -GDBRemoteRegisterContext::ReadRegisterBytes (const RegisterInfo *reg_info, RegisterValue &value, DataExtractor &data) +GDBRemoteRegisterContext::ReadRegisterBytes (const RegisterInfo *reg_info, DataExtractor &data) { GDBRemoteCommunicationClient &gdb_comm (GetGDBProcess().GetGDBRemote()); diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h index 43a3a10142e8..d1955e841308 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h @@ -227,7 +227,6 @@ protected: bool ReadRegisterBytes (const lldb_private::RegisterInfo *reg_info, - lldb_private::RegisterValue &value, lldb_private::DataExtractor &data); bool diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp index ed50353fd891..ac67767b6e5a 100644 --- a/lldb/source/Target/StackFrame.cpp +++ b/lldb/source/Target/StackFrame.cpp @@ -209,7 +209,7 @@ StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope) m_id.SetSymbolContextScope (symbol_scope); } -Address& +const Address& StackFrame::GetFrameCodeAddress() { if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset()) @@ -218,10 +218,9 @@ StackFrame::GetFrameCodeAddress() // Resolve the PC into a temporary address because if ResolveLoadAddress // fails to resolve the address, it will clear the address object... - Address resolved_pc; - if (m_thread.GetProcess().GetTarget().GetSectionLoadList().ResolveLoadAddress(m_frame_code_addr.GetOffset(), resolved_pc)) + + if (m_frame_code_addr.SetOpcodeLoadAddress (m_frame_code_addr.GetOffset(), &m_thread.GetProcess().GetTarget())) { - m_frame_code_addr = resolved_pc; const Section *section = m_frame_code_addr.GetSection(); if (section) { diff --git a/lldb/source/Target/UnixSignals.cpp b/lldb/source/Target/UnixSignals.cpp index 1398639facdf..7fe81f85e857 100644 --- a/lldb/source/Target/UnixSignals.cpp +++ b/lldb/source/Target/UnixSignals.cpp @@ -59,39 +59,39 @@ UnixSignals::Reset () // order, you can either subclass this class, and use Add & Remove to change them // or you can subclass and build them afresh in your constructor; m_signals.clear(); - // SIGNO NAME SHORT NAME SUPPRESS STOP NOTIFY DESCRIPTION - // ====== ============ ========== ========= ====== ====== =================================================== - AddSignal (1, "SIGHUP", "HUP", false, true, true, "hangup"); - AddSignal (2, "SIGINT", "INT", true, true, true, "interrupt"); - AddSignal (3, "SIGQUIT", "QUIT", false, true, true, "quit"); - AddSignal (4, "SIGILL", "ILL", false, true, true, "illegal instruction"); - AddSignal (5, "SIGTRAP", "TRAP", true, true, true, "trace trap (not reset when caught)"); - AddSignal (6, "SIGABRT", "ABRT", false, true, true, "abort()"); - AddSignal (7, "SIGEMT", "EMT", false, true, true, "pollable event"); - AddSignal (8, "SIGFPE", "FPE", false, true, true, "floating point exception"); - AddSignal (9, "SIGKILL", "KILL", false, true, true, "kill"); - AddSignal (10, "SIGBUS", "BUS", false, true, true, "bus error"); - AddSignal (11, "SIGSEGV", "SEGV", false, true, true, "segmentation violation"); - AddSignal (12, "SIGSYS", "SYS", false, true, true, "bad argument to system call"); - AddSignal (13, "SIGPIPE", "PIPE", false, true, true, "write on a pipe with no one to read it"); - AddSignal (14, "SIGALRM", "ALRM", false, false, true, "alarm clock"); - AddSignal (15, "SIGTERM", "TERM", false, true, true, "software termination signal from kill"); - AddSignal (16, "SIGURG", "URG", false, false, false, "urgent condition on IO channel"); - AddSignal (17, "SIGSTOP", "STOP", false, true, true, "sendable stop signal not from tty"); - AddSignal (18, "SIGTSTP", "TSTP", false, true, true, "stop signal from tty"); - AddSignal (19, "SIGCONT", "CONT", false, true, true, "continue a stopped process"); - AddSignal (20, "SIGCHLD", "CHLD", false, false, true, "to parent on child stop or exit"); - AddSignal (21, "SIGTTIN", "TTIN", false, true, true, "to readers process group upon background tty read"); - AddSignal (22, "SIGTTOU", "TTOU", false, true, true, "to readers process group upon background tty write"); - AddSignal (23, "SIGIO", "IO", false, false, false, "input/output possible signal"); - AddSignal (24, "SIGXCPU", "XCPU", false, true, true, "exceeded CPU time limit"); - AddSignal (25, "SIGXFSZ", "XFSZ", false, true, true, "exceeded file size limit"); - AddSignal (26, "SIGVTALRM", "VTALRM", false, false, false, "virtual time alarm"); - AddSignal (27, "SIGPROF", "PROF", false, false, false, "profiling time alarm"); - AddSignal (28, "SIGWINCH", "WINCH", false, false, false, "window size changes"); - AddSignal (29, "SIGINFO", "INFO", false, true, true, "information request"); - AddSignal (30, "SIGUSR1", "USR1", false, true, true, "user defined signal 1"); - AddSignal (31, "SIGUSR2", "USR2", false, true, true, "user defined signal 2"); + // SIGNO NAME SHORT NAME SUPPRESS STOP NOTIFY DESCRIPTION + // ====== ============ ========== ======== ====== ====== =================================================== + AddSignal (1, "SIGHUP", "HUP", false, true , true , "hangup"); + AddSignal (2, "SIGINT", "INT", true , true , true , "interrupt"); + AddSignal (3, "SIGQUIT", "QUIT", false, true , true , "quit"); + AddSignal (4, "SIGILL", "ILL", false, true , true , "illegal instruction"); + AddSignal (5, "SIGTRAP", "TRAP", true , true , true , "trace trap (not reset when caught)"); + AddSignal (6, "SIGABRT", "ABRT", false, true , true , "abort()"); + AddSignal (7, "SIGEMT", "EMT", false, true , true , "pollable event"); + AddSignal (8, "SIGFPE", "FPE", false, true , true , "floating point exception"); + AddSignal (9, "SIGKILL", "KILL", false, true , true , "kill"); + AddSignal (10, "SIGBUS", "BUS", false, true , true , "bus error"); + AddSignal (11, "SIGSEGV", "SEGV", false, true , true , "segmentation violation"); + AddSignal (12, "SIGSYS", "SYS", false, true , true , "bad argument to system call"); + AddSignal (13, "SIGPIPE", "PIPE", false, true , true , "write on a pipe with no one to read it"); + AddSignal (14, "SIGALRM", "ALRM", false, false, true , "alarm clock"); + AddSignal (15, "SIGTERM", "TERM", false, true , true , "software termination signal from kill"); + AddSignal (16, "SIGURG", "URG", false, false, false, "urgent condition on IO channel"); + AddSignal (17, "SIGSTOP", "STOP", true , true , true , "sendable stop signal not from tty"); + AddSignal (18, "SIGTSTP", "TSTP", false, true , true , "stop signal from tty"); + AddSignal (19, "SIGCONT", "CONT", false, true , true , "continue a stopped process"); + AddSignal (20, "SIGCHLD", "CHLD", false, false, true , "to parent on child stop or exit"); + AddSignal (21, "SIGTTIN", "TTIN", false, true , true , "to readers process group upon background tty read"); + AddSignal (22, "SIGTTOU", "TTOU", false, true , true , "to readers process group upon background tty write"); + AddSignal (23, "SIGIO", "IO", false, false, false, "input/output possible signal"); + AddSignal (24, "SIGXCPU", "XCPU", false, true , true , "exceeded CPU time limit"); + AddSignal (25, "SIGXFSZ", "XFSZ", false, true , true , "exceeded file size limit"); + AddSignal (26, "SIGVTALRM", "VTALRM", false, false, false, "virtual time alarm"); + AddSignal (27, "SIGPROF", "PROF", false, false, false, "profiling time alarm"); + AddSignal (28, "SIGWINCH", "WINCH", false, false, false, "window size changes"); + AddSignal (29, "SIGINFO", "INFO", false, true , true , "information request"); + AddSignal (30, "SIGUSR1", "USR1", false, true , true , "user defined signal 1"); + AddSignal (31, "SIGUSR2", "USR2", false, true , true , "user defined signal 2"); } void