diff options
Diffstat (limited to 'source/Symbol')
-rw-r--r-- | source/Symbol/Block.cpp | 2 | ||||
-rw-r--r-- | source/Symbol/ClangASTContext.cpp | 54 | ||||
-rw-r--r-- | source/Symbol/ClangASTImporter.cpp | 12 | ||||
-rw-r--r-- | source/Symbol/ClangASTType.cpp | 97 | ||||
-rw-r--r-- | source/Symbol/ClangExternalASTSourceCallbacks.cpp | 13 | ||||
-rw-r--r-- | source/Symbol/CompactUnwindInfo.cpp | 77 | ||||
-rw-r--r-- | source/Symbol/CompileUnit.cpp | 25 | ||||
-rw-r--r-- | source/Symbol/DWARFCallFrameInfo.cpp | 590 | ||||
-rw-r--r-- | source/Symbol/FuncUnwinders.cpp | 57 | ||||
-rw-r--r-- | source/Symbol/LineTable.cpp | 3 | ||||
-rw-r--r-- | source/Symbol/ObjectFile.cpp | 3 | ||||
-rw-r--r-- | source/Symbol/Symbol.cpp | 62 | ||||
-rw-r--r-- | source/Symbol/SymbolContext.cpp | 47 | ||||
-rw-r--r-- | source/Symbol/SymbolVendor.cpp | 31 | ||||
-rw-r--r-- | source/Symbol/Symtab.cpp | 62 | ||||
-rw-r--r-- | source/Symbol/Type.cpp | 23 | ||||
-rw-r--r-- | source/Symbol/UnwindPlan.cpp | 141 | ||||
-rw-r--r-- | source/Symbol/Variable.cpp | 13 |
18 files changed, 758 insertions, 554 deletions
diff --git a/source/Symbol/Block.cpp b/source/Symbol/Block.cpp index 6a5c651cd017..94fa166bb265 100644 --- a/source/Symbol/Block.cpp +++ b/source/Symbol/Block.cpp @@ -9,8 +9,6 @@ #include "lldb/Symbol/Block.h" -#include "lldb/lldb-private-log.h" - #include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/Section.h" diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp index da25eb84f19e..3c3e2e51d9af 100644 --- a/source/Symbol/ClangASTContext.cpp +++ b/source/Symbol/ClangASTContext.cpp @@ -109,13 +109,8 @@ ClangASTContext::ConvertAccessTypeToAccessSpecifier (AccessType access) return AS_none; } - static void -ParseLangArgs -( - LangOptions &Opts, - InputKind IK -) +ParseLangArgs (LangOptions &Opts, InputKind IK, const char* triple) { // FIXME: Cleanup per-file based stuff. @@ -144,6 +139,7 @@ ParseLangArgs LangStd = LangStandard::lang_opencl; break; case IK_CUDA: + case IK_PreprocessedCuda: LangStd = LangStandard::lang_cuda; break; case IK_Asm: @@ -234,7 +230,7 @@ ParseLangArgs // Opts.Exceptions = Args.hasArg(OPT_fexceptions); // Opts.RTTI = !Args.hasArg(OPT_fno_rtti); // Opts.Blocks = Args.hasArg(OPT_fblocks); -// Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char); + Opts.CharIsSigned = ArchSpec(triple).CharIsSignedByDefault(); // Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar); // Opts.Freestanding = Args.hasArg(OPT_ffreestanding); // Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding; @@ -405,7 +401,14 @@ ClangASTContext::getASTContext() *getIdentifierTable(), *getSelectorTable(), *getBuiltinContext())); - m_ast_ap->InitBuiltinTypes(*getTargetInfo()); + + m_ast_ap->getDiagnostics().setClient(getDiagnosticConsumer(), false); + + // This can be NULL if we don't know anything about the architecture or if the + // target for an architecture isn't enabled in the llvm/clang that we built + TargetInfo *target_info = getTargetInfo(); + if (target_info) + m_ast_ap->InitBuiltinTypes(*target_info); if ((m_callback_tag_decl || m_callback_objc_decl) && m_callback_baton) { @@ -413,8 +416,6 @@ ClangASTContext::getASTContext() //m_ast_ap->getTranslationUnitDecl()->setHasExternalVisibleStorage(); } - m_ast_ap->getDiagnostics().setClient(getDiagnosticConsumer(), false); - GetASTMap().Insert(m_ast_ap.get(), this); } return m_ast_ap.get(); @@ -449,7 +450,7 @@ ClangASTContext::getLanguageOptions() if (m_language_options_ap.get() == nullptr) { m_language_options_ap.reset(new LangOptions()); - ParseLangArgs(*m_language_options_ap, IK_ObjCXX); + ParseLangArgs(*m_language_options_ap, IK_ObjCXX, GetTargetTriple()); // InitializeLangOptions(*m_language_options_ap, IK_ObjCXX); } return m_language_options_ap.get(); @@ -908,7 +909,8 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name if (type_name) { if (streq(type_name, "wchar_t") && - QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy)) + QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy) && + (getTargetInfo() && TargetInfo::isTypeSigned (getTargetInfo()->getWCharType()))) return ClangASTType (ast, ast->WCharTy.getAsOpaquePtr()); if (streq(type_name, "void") && QualTypeMatchesBitSize (bit_size, ast, ast->VoidTy)) @@ -951,18 +953,13 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty)) return ClangASTType (ast, ast->Int128Ty.getAsOpaquePtr()); break; - + case DW_ATE_signed_char: - if (type_name) + if (ast->getLangOpts().CharIsSigned && type_name && streq(type_name, "char")) { - if (streq(type_name, "signed char")) - { - if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy)) - return ClangASTType (ast, ast->SignedCharTy.getAsOpaquePtr()); - } + if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy)) + return ClangASTType (ast, ast->CharTy.getAsOpaquePtr()); } - if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy)) - return ClangASTType (ast, ast->CharTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy)) return ClangASTType (ast, ast->SignedCharTy.getAsOpaquePtr()); break; @@ -970,6 +967,14 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name case DW_ATE_unsigned: if (type_name) { + if (streq(type_name, "wchar_t")) + { + if (QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy)) + { + if (!(getTargetInfo() && TargetInfo::isTypeSigned (getTargetInfo()->getWCharType()))) + return ClangASTType (ast, ast->WCharTy.getAsOpaquePtr()); + } + } if (strstr(type_name, "long long")) { if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy)) @@ -1012,8 +1017,13 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty)) return ClangASTType (ast, ast->UnsignedInt128Ty.getAsOpaquePtr()); break; - + case DW_ATE_unsigned_char: + if (!ast->getLangOpts().CharIsSigned && type_name && streq(type_name, "char")) + { + if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy)) + return ClangASTType (ast, ast->CharTy.getAsOpaquePtr()); + } if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy)) return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy)) diff --git a/source/Symbol/ClangASTImporter.cpp b/source/Symbol/ClangASTImporter.cpp index a925f808f858..64a7323d25cf 100644 --- a/source/Symbol/ClangASTImporter.cpp +++ b/source/Symbol/ClangASTImporter.cpp @@ -274,7 +274,10 @@ ClangASTImporter::CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface if (minion_sp) minion_sp->ImportDefinitionTo(interface_decl, decl_origin.decl); - + + if (ObjCInterfaceDecl *super_class = interface_decl->getSuperClass()) + RequireCompleteType(clang::QualType(super_class->getTypeForDecl(), 0)); + return true; } @@ -286,7 +289,12 @@ ClangASTImporter::RequireCompleteType (clang::QualType type) if (const TagType *tag_type = type->getAs<TagType>()) { - return CompleteTagDecl(tag_type->getDecl()); + TagDecl *tag_decl = tag_type->getDecl(); + + if (tag_decl->getDefinition() || tag_decl->isBeingDefined()) + return true; + + return CompleteTagDecl(tag_decl); } if (const ObjCObjectType *objc_object_type = type->getAs<ObjCObjectType>()) { diff --git a/source/Symbol/ClangASTType.cpp b/source/Symbol/ClangASTType.cpp index eaff90ab8a0a..a62cc9f45a6b 100644 --- a/source/Symbol/ClangASTType.cpp +++ b/source/Symbol/ClangASTType.cpp @@ -7,8 +7,6 @@ // //===----------------------------------------------------------------------===// -#include "lldb/lldb-python.h" - #include "lldb/Symbol/ClangASTType.h" #include "clang/AST/ASTConsumer.h" @@ -30,6 +28,8 @@ #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/Signals.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/raw_ostream.h" @@ -43,8 +43,10 @@ #include "lldb/Core/StreamString.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/ClangExternalASTSourceCommon.h" +#include "lldb/Symbol/Type.h" #include "lldb/Symbol/VerifyDecl.h" #include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Process.h" #include <iterator> @@ -313,6 +315,18 @@ ClangASTType::IsVectorType (ClangASTType *element_type, return true; } break; + case clang::Type::ExtVector: + { + const clang::ExtVectorType *ext_vector_type = qual_type->getAs<clang::ExtVectorType>(); + if (ext_vector_type) + { + if (size) + *size = ext_vector_type->getNumElements(); + if (element_type) + *element_type = ClangASTType(m_ast, ext_vector_type->getElementType().getAsOpaquePtr()); + } + return true; + } default: break; } @@ -493,7 +507,7 @@ ClangASTType::IsHomogeneousAggregate (ClangASTType* base_type_ptr) const } else if (field_qual_type->isVectorType() || field_qual_type->isExtVectorType()) { - const clang::VectorType *array = llvm::cast<clang::VectorType>(field_qual_type.getTypePtr()); + const clang::VectorType *array = field_qual_type.getTypePtr()->getAs<clang::VectorType>(); if (array && array->getNumElements() <= 4) { if (num_fields == 0) @@ -2093,7 +2107,7 @@ ClangASTType::GetBasicTypeFromAST (lldb::BasicType basic_type) const //---------------------------------------------------------------------- uint64_t -ClangASTType::GetBitSize (ExecutionContext *exe_ctx) const +ClangASTType::GetBitSize (ExecutionContextScope *exe_scope) const { if (GetCompleteType ()) { @@ -2102,9 +2116,12 @@ ClangASTType::GetBitSize (ExecutionContext *exe_ctx) const { case clang::Type::ObjCInterface: case clang::Type::ObjCObject: - if (exe_ctx && exe_ctx->GetProcessPtr()) + { + ExecutionContext exe_ctx (exe_scope); + Process *process = exe_ctx.GetProcessPtr(); + if (process) { - ObjCLanguageRuntime *objc_runtime = exe_ctx->GetProcessPtr()->GetObjCLanguageRuntime(); + ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime(); if (objc_runtime) { uint64_t bit_size = 0; @@ -2118,14 +2135,18 @@ ClangASTType::GetBitSize (ExecutionContext *exe_ctx) const if (!g_printed) { StreamString s; - s.Printf("warning: trying to determine the size of type "); DumpTypeDescription(&s); - s.Printf("\n without a valid ExecutionContext. this is not reliable. please file a bug against LLDB.\nbacktrace:\n"); - Host::Backtrace(s, 10); - printf("%s\n", s.GetData()); + + llvm::outs() << "warning: trying to determine the size of type "; + llvm::outs() << s.GetString() << "\n"; + llvm::outs() << "without a valid ExecutionContext. this is not reliable. please file a bug against LLDB.\n"; + llvm::outs() << "backtrace:\n"; + llvm::sys::PrintStackTrace(llvm::outs()); + llvm::outs() << "\n"; g_printed = true; } } + } // fallthrough default: const uint32_t bit_size = m_ast->getTypeSize (qual_type); @@ -2143,11 +2164,12 @@ ClangASTType::GetBitSize (ExecutionContext *exe_ctx) const } uint64_t -ClangASTType::GetByteSize (ExecutionContext *exe_ctx) const +ClangASTType::GetByteSize (ExecutionContextScope *exe_scope) const { - return (GetBitSize (exe_ctx) + 7) / 8; + return (GetBitSize (exe_scope) + 7) / 8; } + size_t ClangASTType::GetTypeBitAlign () const { @@ -2224,6 +2246,24 @@ ClangASTType::GetEncoding (uint64_t &count) const case clang::BuiltinType::ObjCSel: return lldb::eEncodingUint; case clang::BuiltinType::NullPtr: return lldb::eEncodingUint; + + case clang::BuiltinType::Kind::ARCUnbridgedCast: + case clang::BuiltinType::Kind::BoundMember: + case clang::BuiltinType::Kind::BuiltinFn: + case clang::BuiltinType::Kind::Dependent: + case clang::BuiltinType::Kind::Half: + case clang::BuiltinType::Kind::OCLEvent: + case clang::BuiltinType::Kind::OCLImage1d: + case clang::BuiltinType::Kind::OCLImage1dArray: + case clang::BuiltinType::Kind::OCLImage1dBuffer: + case clang::BuiltinType::Kind::OCLImage2d: + case clang::BuiltinType::Kind::OCLImage2dArray: + case clang::BuiltinType::Kind::OCLImage3d: + case clang::BuiltinType::Kind::OCLSampler: + case clang::BuiltinType::Kind::Overload: + case clang::BuiltinType::Kind::PseudoObject: + case clang::BuiltinType::Kind::UnknownAny: + break; } break; // All pointer types are represented as unsigned integer encodings. @@ -3478,7 +3518,7 @@ ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx, child_byte_offset = bit_offset/8; ClangASTType base_class_clang_type(m_ast, base_class->getType()); child_name = base_class_clang_type.GetTypeName().AsCString(""); - uint64_t base_class_clang_type_bit_size = base_class_clang_type.GetBitSize(nullptr); + uint64_t base_class_clang_type_bit_size = base_class_clang_type.GetBitSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); // Base classes bit sizes should be a multiple of 8 bits in size assert (base_class_clang_type_bit_size % 8 == 0); @@ -3506,7 +3546,7 @@ ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx, // alignment (field_type_info.second) from the AST context. ClangASTType field_clang_type (m_ast, field->getType()); assert(field_idx < record_layout.getFieldCount()); - child_byte_size = field_clang_type.GetByteSize(exe_ctx); + child_byte_size = field_clang_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); // Figure out the field offset within the current struct/union/class type bit_offset = record_layout.getFieldOffset (field_idx); @@ -3671,7 +3711,7 @@ ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx, // We have a pointer to an simple type if (idx == 0 && pointee_clang_type.GetCompleteType()) { - child_byte_size = pointee_clang_type.GetByteSize(exe_ctx); + child_byte_size = pointee_clang_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); child_byte_offset = 0; return pointee_clang_type; } @@ -3690,9 +3730,9 @@ ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx, if (element_type.GetCompleteType()) { char element_name[64]; - ::snprintf (element_name, sizeof (element_name), "[%zu]", idx); + ::snprintf(element_name, sizeof(element_name), "[%" PRIu64 "]", static_cast<uint64_t>(idx)); child_name.assign(element_name); - child_byte_size = element_type.GetByteSize(exe_ctx); + child_byte_size = element_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); child_byte_offset = (int32_t)idx * (int32_t)child_byte_size; return element_type; } @@ -3711,9 +3751,9 @@ ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx, if (element_type.GetCompleteType()) { char element_name[64]; - ::snprintf (element_name, sizeof (element_name), "[%zu]", idx); + ::snprintf(element_name, sizeof(element_name), "[%" PRIu64 "]", static_cast<uint64_t>(idx)); child_name.assign(element_name); - child_byte_size = element_type.GetByteSize(exe_ctx); + child_byte_size = element_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); child_byte_offset = (int32_t)idx * (int32_t)child_byte_size; return element_type; } @@ -3763,7 +3803,7 @@ ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx, // We have a pointer to an simple type if (idx == 0) { - child_byte_size = pointee_clang_type.GetByteSize(exe_ctx); + child_byte_size = pointee_clang_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); child_byte_offset = 0; return pointee_clang_type; } @@ -3807,7 +3847,7 @@ ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx, // We have a pointer to an simple type if (idx == 0) { - child_byte_size = pointee_clang_type.GetByteSize(exe_ctx); + child_byte_size = pointee_clang_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); child_byte_offset = 0; return pointee_clang_type; } @@ -5136,7 +5176,7 @@ ClangASTType::AddMethodToCXXRecordType (const char *name, { // Check the number of operator parameters. Sometimes we have // seen bad DWARF that doesn't correctly describe operators and - // if we try to create a methed and add it to the class, clang + // if we try to create a method and add it to the class, clang // will assert and crash, so we need to make sure things are // acceptable. if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount (op_kind, num_params)) @@ -5358,6 +5398,7 @@ ClangASTType::AddObjCClassProperty (const char *property_name, &m_ast->Idents.get(property_name), clang::SourceLocation(), //Source Location for AT clang::SourceLocation(), //Source location for ( + ivar_decl ? ivar_decl->getType() : property_clang_type.GetQualType(), prop_type_source); if (property_decl) @@ -6123,7 +6164,7 @@ ClangASTType::DumpValue (ExecutionContext *exe_ctx, for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx) { // Print the starting squiggly bracket (if this is the - // first member) or comman (for member 2 and beyong) for + // first member) or comma (for member 2 and beyond) for // the struct/union/class member. if (child_idx == 0) s->PutChar('{'); @@ -6238,7 +6279,7 @@ ClangASTType::DumpValue (ExecutionContext *exe_ctx, for (element_idx = 0; element_idx < element_count; ++element_idx) { // Print the starting squiggly bracket (if this is the - // first member) or comman (for member 2 and beyong) for + // first member) or comma (for member 2 and beyond) for // the struct/union/class member. if (element_idx == 0) s->PutChar('{'); @@ -6345,7 +6386,7 @@ ClangASTType::DumpValue (ExecutionContext *exe_ctx, break; default: - // We are down the a scalar type that we just need to display. + // We are down to a scalar type that we just need to display. data.Dump(s, data_byte_offset, format, @@ -6454,7 +6495,7 @@ ClangASTType::DumpTypeValue (Stream *s, // format was not enum, just fall through and dump the value as requested.... default: - // We are down the a scalar type that we just need to display. + // We are down to a scalar type that we just need to display. { uint32_t item_count = 1; // A few formats, we might need to modify our size and count for depending @@ -6913,7 +6954,7 @@ ClangASTType::ReadFromMemory (lldb_private::ExecutionContext *exe_ctx, if (!GetCompleteType()) return false; - const uint64_t byte_size = GetByteSize(exe_ctx); + const uint64_t byte_size = GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); if (data.GetByteSize() < byte_size) { lldb::DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0')); @@ -6963,7 +7004,7 @@ ClangASTType::WriteToMemory (lldb_private::ExecutionContext *exe_ctx, if (!GetCompleteType()) return false; - const uint64_t byte_size = GetByteSize(exe_ctx); + const uint64_t byte_size = GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); if (byte_size > 0) { diff --git a/source/Symbol/ClangExternalASTSourceCallbacks.cpp b/source/Symbol/ClangExternalASTSourceCallbacks.cpp index bdc32654cc10..cd6972cce972 100644 --- a/source/Symbol/ClangExternalASTSourceCallbacks.cpp +++ b/source/Symbol/ClangExternalASTSourceCallbacks.cpp @@ -141,13 +141,12 @@ ClangExternalASTSourceCallbacks::CompleteType (ObjCInterfaceDecl *objc_decl) m_callback_objc_decl (m_callback_baton, objc_decl); } -bool -ClangExternalASTSourceCallbacks::layoutRecordType(const clang::RecordDecl *Record, - uint64_t &Size, - uint64_t &Alignment, - llvm::DenseMap <const clang::FieldDecl *, uint64_t> &FieldOffsets, - llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets, - llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets) +bool +ClangExternalASTSourceCallbacks::layoutRecordType( + const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets) { if (m_callback_layout_record_type) return m_callback_layout_record_type(m_callback_baton, diff --git a/source/Symbol/CompactUnwindInfo.cpp b/source/Symbol/CompactUnwindInfo.cpp index e7153446cd16..afef4e480e8e 100644 --- a/source/Symbol/CompactUnwindInfo.cpp +++ b/source/Symbol/CompactUnwindInfo.cpp @@ -13,6 +13,7 @@ #include <algorithm> #include "lldb/Core/ArchSpec.h" +#include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/Section.h" @@ -34,13 +35,15 @@ namespace lldb_private { // Constants from <mach-o/compact_unwind_encoding.h> - enum { + FLAGS_ANONYMOUS_ENUM() + { UNWIND_IS_NOT_FUNCTION_START = 0x80000000, UNWIND_HAS_LSDA = 0x40000000, UNWIND_PERSONALITY_MASK = 0x30000000, }; - enum { + FLAGS_ANONYMOUS_ENUM() + { UNWIND_X86_MODE_MASK = 0x0F000000, UNWIND_X86_MODE_EBP_FRAME = 0x01000000, UNWIND_X86_MODE_STACK_IMMD = 0x02000000, @@ -58,7 +61,8 @@ namespace lldb_private { UNWIND_X86_DWARF_SECTION_OFFSET = 0x00FFFFFF, }; - enum { + enum + { UNWIND_X86_REG_NONE = 0, UNWIND_X86_REG_EBX = 1, UNWIND_X86_REG_ECX = 2, @@ -67,7 +71,9 @@ namespace lldb_private { UNWIND_X86_REG_ESI = 5, UNWIND_X86_REG_EBP = 6, }; - enum { + + FLAGS_ANONYMOUS_ENUM() + { UNWIND_X86_64_MODE_MASK = 0x0F000000, UNWIND_X86_64_MODE_RBP_FRAME = 0x01000000, UNWIND_X86_64_MODE_STACK_IMMD = 0x02000000, @@ -85,7 +91,8 @@ namespace lldb_private { UNWIND_X86_64_DWARF_SECTION_OFFSET = 0x00FFFFFF, }; - enum { + enum + { UNWIND_X86_64_REG_NONE = 0, UNWIND_X86_64_REG_RBX = 1, UNWIND_X86_64_REG_R12 = 2, @@ -94,7 +101,7 @@ namespace lldb_private { UNWIND_X86_64_REG_R15 = 5, UNWIND_X86_64_REG_RBP = 6, }; -}; +} #ifndef UNWIND_SECOND_LEVEL_REGULAR @@ -115,7 +122,7 @@ namespace lldb_private { #define EXTRACT_BITS(value, mask) \ ( (value >> llvm::countTrailingZeros(static_cast<uint32_t>(mask), llvm::ZB_Width)) & \ - (((1 << llvm::CountPopulation_32(static_cast<uint32_t>(mask))))-1) ) + (((1 << llvm::countPopulation(static_cast<uint32_t>(mask))))-1) ) @@ -282,9 +289,17 @@ CompactUnwindInfo::ScanIndex (const ProcessSP &process_sp) uint32_t indexCount = m_unwindinfo_data.GetU32(&offset); - if (m_unwind_header.version != 1) + if (m_unwind_header.common_encodings_array_offset > m_unwindinfo_data.GetByteSize() + || m_unwind_header.personality_array_offset > m_unwindinfo_data.GetByteSize() + || indexSectionOffset > m_unwindinfo_data.GetByteSize() + || offset > m_unwindinfo_data.GetByteSize()) { + Host::SystemLog (Host::eSystemLogError, + "error: Invalid offset encountered in compact unwind info, skipping\n"); + // don't trust anything from this compact_unwind section if it looks + // blatently invalid data in the header. m_indexes_computed = eLazyBoolNo; + return; } // Parse the basic information from the indexes @@ -510,7 +525,7 @@ CompactUnwindInfo::GetCompactUnwindInfoForFunction (Target &target, Address addr } auto next_it = it + 1; - if (next_it != m_indexes.begin()) + if (next_it != m_indexes.end()) { // initialize the function offset end range to be the start of the // next index offset. If we find an entry which is at the end of @@ -720,8 +735,9 @@ CompactUnwindInfo::CreateUnwindPlan_x86_64 (Target &target, FunctionInfo &functi { case UNWIND_X86_64_MODE_RBP_FRAME: { - row->SetCFARegister (translate_to_eh_frame_regnum_x86_64 (UNWIND_X86_64_REG_RBP)); - row->SetCFAOffset (2 * wordsize); + row->GetCFAValue().SetIsRegisterPlusOffset ( + translate_to_eh_frame_regnum_x86_64 (UNWIND_X86_64_REG_RBP), + 2 * wordsize); row->SetOffset (0); row->SetRegisterLocationToAtCFAPlusOffset (x86_64_eh_regnum::rbp, wordsize * -2, true); row->SetRegisterLocationToAtCFAPlusOffset (x86_64_eh_regnum::rip, wordsize * -1, true); @@ -759,7 +775,8 @@ CompactUnwindInfo::CreateUnwindPlan_x86_64 (Target &target, FunctionInfo &functi case UNWIND_X86_64_MODE_STACK_IND: { // The clang in Xcode 6 is emitting incorrect compact unwind encodings for this - // style of unwind. It was fixed in llvm r217020. + // style of unwind. It was fixed in llvm r217020. + // The clang in Xcode 7 has this fixed. return false; } break; @@ -809,16 +826,9 @@ CompactUnwindInfo::CreateUnwindPlan_x86_64 (Target &target, FunctionInfo &functi } } - if (mode == UNWIND_X86_64_MODE_STACK_IND) - { - row->SetCFAOffset (stack_size); - } - else - { - row->SetCFAOffset (stack_size * wordsize); - } + int32_t offset = mode == UNWIND_X86_64_MODE_STACK_IND ? stack_size : stack_size * wordsize; + row->GetCFAValue().SetIsRegisterPlusOffset (x86_64_eh_regnum::rsp, offset); - row->SetCFARegister (x86_64_eh_regnum::rsp); row->SetOffset (0); row->SetRegisterLocationToAtCFAPlusOffset (x86_64_eh_regnum::rip, wordsize * -1, true); row->SetRegisterLocationToIsCFAPlusOffset (x86_64_eh_regnum::rsp, 0, true); @@ -832,7 +842,7 @@ CompactUnwindInfo::CreateUnwindPlan_x86_64 (Target &target, FunctionInfo &functi // // This is done with Lehmer code permutation, e.g. see // http://stackoverflow.com/questions/1506078/fast-permutation-number-permutation-mapping-algorithms - int permunreg[6]; + int permunreg[6] = {0, 0, 0, 0, 0, 0}; // This decodes the variable-base number in the 10 bits // and gives us the Lehmer code sequence which can then @@ -892,7 +902,7 @@ CompactUnwindInfo::CreateUnwindPlan_x86_64 (Target &target, FunctionInfo &functi // Decode the Lehmer code for this permutation of // the registers v. http://en.wikipedia.org/wiki/Lehmer_code - int registers[6]; + int registers[6] = { UNWIND_X86_64_REG_NONE, UNWIND_X86_64_REG_NONE, UNWIND_X86_64_REG_NONE, UNWIND_X86_64_REG_NONE, UNWIND_X86_64_REG_NONE, UNWIND_X86_64_REG_NONE }; bool used[7] = { false, false, false, false, false, false, false }; for (uint32_t i = 0; i < register_count; i++) { @@ -1009,8 +1019,8 @@ CompactUnwindInfo::CreateUnwindPlan_i386 (Target &target, FunctionInfo &function { case UNWIND_X86_MODE_EBP_FRAME: { - row->SetCFARegister (translate_to_eh_frame_regnum_i386 (UNWIND_X86_REG_EBP)); - row->SetCFAOffset (2 * wordsize); + row->GetCFAValue().SetIsRegisterPlusOffset ( + translate_to_eh_frame_regnum_i386 (UNWIND_X86_REG_EBP), 2 * wordsize); row->SetOffset (0); row->SetRegisterLocationToAtCFAPlusOffset (i386_eh_regnum::ebp, wordsize * -2, true); row->SetRegisterLocationToAtCFAPlusOffset (i386_eh_regnum::eip, wordsize * -1, true); @@ -1091,17 +1101,8 @@ CompactUnwindInfo::CreateUnwindPlan_i386 (Target &target, FunctionInfo &function } } - row->SetCFARegister (i386_eh_regnum::esp); - - if (mode == UNWIND_X86_MODE_STACK_IND) - { - row->SetCFAOffset (stack_size); - } - else - { - row->SetCFAOffset (stack_size * wordsize); - } - + int32_t offset = mode == UNWIND_X86_MODE_STACK_IND ? stack_size : stack_size * wordsize; + row->GetCFAValue().SetIsRegisterPlusOffset (i386_eh_regnum::esp, offset); row->SetOffset (0); row->SetRegisterLocationToAtCFAPlusOffset (i386_eh_regnum::eip, wordsize * -1, true); row->SetRegisterLocationToIsCFAPlusOffset (i386_eh_regnum::esp, 0, true); @@ -1115,7 +1116,7 @@ CompactUnwindInfo::CreateUnwindPlan_i386 (Target &target, FunctionInfo &function // // This is done with Lehmer code permutation, e.g. see // http://stackoverflow.com/questions/1506078/fast-permutation-number-permutation-mapping-algorithms - int permunreg[6]; + int permunreg[6] = {0, 0, 0, 0, 0, 0}; // This decodes the variable-base number in the 10 bits // and gives us the Lehmer code sequence which can then @@ -1175,7 +1176,7 @@ CompactUnwindInfo::CreateUnwindPlan_i386 (Target &target, FunctionInfo &function // Decode the Lehmer code for this permutation of // the registers v. http://en.wikipedia.org/wiki/Lehmer_code - int registers[6]; + int registers[6] = { UNWIND_X86_REG_NONE, UNWIND_X86_REG_NONE, UNWIND_X86_REG_NONE, UNWIND_X86_REG_NONE, UNWIND_X86_REG_NONE, UNWIND_X86_REG_NONE }; bool used[7] = { false, false, false, false, false, false, false }; for (uint32_t i = 0; i < register_count; i++) { diff --git a/source/Symbol/CompileUnit.cpp b/source/Symbol/CompileUnit.cpp index 6483258ee678..d43ef44a1376 100644 --- a/source/Symbol/CompileUnit.cpp +++ b/source/Symbol/CompileUnit.cpp @@ -149,9 +149,9 @@ CompileUnit::GetFunctionAtIndex (size_t idx) } //---------------------------------------------------------------------- -// Find functions using the a Mangled::Tokens token list. This -// function currently implements an interative approach designed to find -// all instances of certain functions. It isn't designed to the the +// Find functions using the Mangled::Tokens token list. This +// function currently implements an interactive approach designed to find +// all instances of certain functions. It isn't designed to the // quickest way to lookup functions as it will need to iterate through // all functions and see if they match, though it does provide a powerful // and context sensitive way to search for all functions with a certain @@ -292,7 +292,7 @@ CompileUnit::FindLineEntry (uint32_t start_idx, uint32_t line, const FileSpec* f else { // All the line table entries actually point to the version of the Compile - // Unit that is in the support files (the one at 0 was artifically added.) + // Unit that is in the support files (the one at 0 was artificially added.) // So prefer the one further on in the support files if it exists... FileSpecList &support_files = GetSupportFiles(); const bool full = true; @@ -436,6 +436,23 @@ CompileUnit::SetVariableList(VariableListSP &variables) m_variables = variables; } +const std::vector<ConstString> & +CompileUnit::GetImportedModules () +{ + if (m_imported_modules.empty() && + m_flags.IsClear(flagsParsedImportedModules)) + { + m_flags.Set(flagsParsedImportedModules); + if (SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor()) + { + SymbolContext sc; + CalculateSymbolContext(&sc); + symbol_vendor->ParseImportedModules(sc, m_imported_modules); + } + } + return m_imported_modules; +} + FileSpecList& CompileUnit::GetSupportFiles () { diff --git a/source/Symbol/DWARFCallFrameInfo.cpp b/source/Symbol/DWARFCallFrameInfo.cpp index 78d262307c24..a5f9017918dd 100644 --- a/source/Symbol/DWARFCallFrameInfo.cpp +++ b/source/Symbol/DWARFCallFrameInfo.cpp @@ -197,7 +197,7 @@ DWARFCallFrameInfo::ParseCIE (const dw_offset_t cie_offset) const size_t aug_str_len = strlen(cie_sp->augmentation); // A 'z' may be present as the first character of the string. // If present, the Augmentation Data field shall be present. - // The contents of the Augmentation Data shall be intepreted + // The contents of the Augmentation Data shall be interpreted // according to other characters in the Augmentation String. if (cie_sp->augmentation[0] == 'z') { @@ -276,38 +276,8 @@ DWARFCallFrameInfo::ParseCIE (const dw_offset_t cie_offset) uint8_t primary_opcode = inst & 0xC0; uint8_t extended_opcode = inst & 0x3F; - if (extended_opcode == DW_CFA_def_cfa) - { - // Takes two unsigned LEB128 operands representing a register - // number and a (non-factored) offset. The required action - // is to define the current CFA rule to use the provided - // register and offset. - uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); - int op_offset = (int32_t)m_cfi_data.GetULEB128(&offset); - cie_sp->initial_row.SetCFARegister (reg_num); - cie_sp->initial_row.SetCFAOffset (op_offset); - continue; - } - if (primary_opcode == DW_CFA_offset) - { - // 0x80 - high 2 bits are 0x2, lower 6 bits are register. - // Takes two arguments: an unsigned LEB128 constant representing a - // factored offset and a register number. The required action is to - // change the rule for the register indicated by the register number - // to be an offset(N) rule with a value of - // (N = factored offset * data_align). - uint32_t reg_num = extended_opcode; - int op_offset = (int32_t)m_cfi_data.GetULEB128(&offset) * cie_sp->data_align; - UnwindPlan::Row::RegisterLocation reg_location; - reg_location.SetAtCFAPlusOffset(op_offset); - cie_sp->initial_row.SetRegisterInfo (reg_num, reg_location); - continue; - } - if (extended_opcode == DW_CFA_nop) - { - continue; - } - break; // Stop if we hit an unrecognized opcode + if (!HandleCommonDwarfOpcode(primary_opcode, extended_opcode, cie_sp->data_align, offset, cie_sp->initial_row)) + break; // Stop if we hit an unrecognized opcode } } @@ -366,6 +336,31 @@ DWARFCallFrameInfo::GetFDEIndex () cie_offset = current_entry + 4 - cie_id; } + if (next_entry > m_cfi_data.GetByteSize() + 1) + { + Host::SystemLog (Host::eSystemLogError, + "error: Invalid fde/cie next entry offset of 0x%x found in cie/fde at 0x%x\n", + next_entry, + current_entry); + // Don't trust anything in this eh_frame section if we find blatently + // invalid data. + m_fde_index.Clear(); + m_fde_index_initialized = true; + return; + } + if (cie_offset > m_cfi_data.GetByteSize()) + { + Host::SystemLog (Host::eSystemLogError, + "error: Invalid cie offset of 0x%x found in cie/fde at 0x%x\n", + cie_offset, + current_entry); + // Don't trust anything in this eh_frame section if we find blatently + // invalid data. + m_fde_index.Clear(); + m_fde_index_initialized = true; + return; + } + if (cie_id == 0 || cie_id == UINT32_MAX || len == 0) { m_cie_map[current_entry] = ParseCIE (current_entry); @@ -490,8 +485,6 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t dwarf_offset, Address startaddr unwind_plan.SetPersonalityFunctionPtr (personality_function_ptr); } - uint32_t reg_num = 0; - int32_t op_offset = 0; uint32_t code_align = cie->code_align; int32_t data_align = cie->data_align; @@ -512,11 +505,13 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t dwarf_offset, Address startaddr uint8_t primary_opcode = inst & 0xC0; uint8_t extended_opcode = inst & 0x3F; - if (primary_opcode) + if (!HandleCommonDwarfOpcode(primary_opcode, extended_opcode, data_align, offset, *row)) { - switch (primary_opcode) + if (primary_opcode) { - case DW_CFA_advance_loc : // (Row Creation Instruction) + switch (primary_opcode) + { + case DW_CFA_advance_loc : // (Row Creation Instruction) { // 0x40 - high 2 bits are 0x1, lower 6 bits are delta // takes a single argument that represents a constant delta. The // required action is to create a new table row with a location @@ -528,29 +523,15 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t dwarf_offset, Address startaddr *newrow = *row.get(); row.reset (newrow); row->SlideOffset(extended_opcode * code_align); + break; } - break; - - case DW_CFA_offset : - { // 0x80 - high 2 bits are 0x2, lower 6 bits are register - // takes two arguments: an unsigned LEB128 constant representing a - // factored offset and a register number. The required action is to - // change the rule for the register indicated by the register number - // to be an offset(N) rule with a value of - // (N = factored offset * data_align). - reg_num = extended_opcode; - op_offset = (int32_t)m_cfi_data.GetULEB128(&offset) * data_align; - reg_location.SetAtCFAPlusOffset(op_offset); - row->SetRegisterInfo (reg_num, reg_location); - } - break; - case DW_CFA_restore : + case DW_CFA_restore : { // 0xC0 - high 2 bits are 0x3, lower 6 bits are register // takes a single argument that represents a register number. The // required action is to change the rule for the indicated register // to the rule assigned it by the initial_instructions in the CIE. - reg_num = extended_opcode; + uint32_t reg_num = extended_opcode; // We only keep enough register locations around to // unwind what is in our thread, and these are organized // by the register index in that state, so we need to convert our @@ -558,18 +539,15 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t dwarf_offset, Address startaddr if (unwind_plan.IsValidRowIndex(0) && unwind_plan.GetRowAtIndex(0)->GetRegisterInfo(reg_num, reg_location)) row->SetRegisterInfo (reg_num, reg_location); + break; } - break; + } } - } - else - { - switch (extended_opcode) + else { - case DW_CFA_nop : // 0x0 - break; - - case DW_CFA_set_loc : // 0x1 (Row Creation Instruction) + switch (extended_opcode) + { + case DW_CFA_set_loc : // 0x1 (Row Creation Instruction) { // DW_CFA_set_loc takes a single argument that represents an address. // The required action is to create a new table row using the @@ -581,10 +559,10 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t dwarf_offset, Address startaddr *newrow = *row.get(); row.reset (newrow); row->SetOffset(m_cfi_data.GetPointer(&offset) - startaddr.GetFileAddress()); + break; } - break; - case DW_CFA_advance_loc1 : // 0x2 (Row Creation Instruction) + case DW_CFA_advance_loc1 : // 0x2 (Row Creation Instruction) { // takes a single uword argument that represents a constant delta. // This instruction is identical to DW_CFA_advance_loc except for the @@ -594,10 +572,10 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t dwarf_offset, Address startaddr *newrow = *row.get(); row.reset (newrow); row->SlideOffset (m_cfi_data.GetU8(&offset) * code_align); + break; } - break; - case DW_CFA_advance_loc2 : // 0x3 (Row Creation Instruction) + case DW_CFA_advance_loc2 : // 0x3 (Row Creation Instruction) { // takes a single uword argument that represents a constant delta. // This instruction is identical to DW_CFA_advance_loc except for the @@ -607,10 +585,10 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t dwarf_offset, Address startaddr *newrow = *row.get(); row.reset (newrow); row->SlideOffset (m_cfi_data.GetU16(&offset) * code_align); + break; } - break; - case DW_CFA_advance_loc4 : // 0x4 (Row Creation Instruction) + case DW_CFA_advance_loc4 : // 0x4 (Row Creation Instruction) { // takes a single uword argument that represents a constant delta. // This instruction is identical to DW_CFA_advance_loc except for the @@ -620,68 +598,21 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t dwarf_offset, Address startaddr *newrow = *row.get(); row.reset (newrow); row->SlideOffset (m_cfi_data.GetU32(&offset) * code_align); + break; } - break; - case DW_CFA_offset_extended : // 0x5 - { - // takes two unsigned LEB128 arguments representing a register number - // and a factored offset. This instruction is identical to DW_CFA_offset - // except for the encoding and size of the register argument. - reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); - op_offset = (int32_t)m_cfi_data.GetULEB128(&offset) * data_align; - reg_location.SetAtCFAPlusOffset(op_offset); - row->SetRegisterInfo (reg_num, reg_location); - } - break; - - case DW_CFA_restore_extended : // 0x6 + case DW_CFA_restore_extended : // 0x6 { // takes a single unsigned LEB128 argument that represents a register // number. This instruction is identical to DW_CFA_restore except for // the encoding and size of the register argument. - reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); + uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); if (unwind_plan.IsValidRowIndex(0) && unwind_plan.GetRowAtIndex(0)->GetRegisterInfo(reg_num, reg_location)) row->SetRegisterInfo (reg_num, reg_location); + break; } - break; - case DW_CFA_undefined : // 0x7 - { - // takes a single unsigned LEB128 argument that represents a register - // number. The required action is to set the rule for the specified - // register to undefined. - reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); - reg_location.SetUndefined(); - row->SetRegisterInfo (reg_num, reg_location); - } - break; - - case DW_CFA_same_value : // 0x8 - { - // takes a single unsigned LEB128 argument that represents a register - // number. The required action is to set the rule for the specified - // register to same value. - reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); - reg_location.SetSame(); - row->SetRegisterInfo (reg_num, reg_location); - } - break; - - case DW_CFA_register : // 0x9 - { - // takes two unsigned LEB128 arguments representing register numbers. - // The required action is to set the rule for the first register to be - // the second register. - - reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); - uint32_t other_reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); - reg_location.SetInRegister(other_reg_num); - row->SetRegisterInfo (reg_num, reg_location); - } - break; - - case DW_CFA_remember_state : // 0xA + case DW_CFA_remember_state : // 0xA { // These instructions define a stack of information. Encountering the // DW_CFA_remember_state instruction means to save the rules for every @@ -694,184 +625,277 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t dwarf_offset, Address startaddr UnwindPlan::Row *newrow = new UnwindPlan::Row; *newrow = *row.get(); row.reset (newrow); + break; } - break; - - case DW_CFA_restore_state : // 0xB - // These instructions define a stack of information. Encountering the - // DW_CFA_remember_state instruction means to save the rules for every - // register on the current row on the stack. Encountering the - // DW_CFA_restore_state instruction means to pop the set of rules off - // the stack and place them in the current row. (This operation is - // useful for compilers that move epilogue code into the body of a - // function.) + + case DW_CFA_restore_state : // 0xB { + // These instructions define a stack of information. Encountering the + // DW_CFA_remember_state instruction means to save the rules for every + // register on the current row on the stack. Encountering the + // DW_CFA_restore_state instruction means to pop the set of rules off + // the stack and place them in the current row. (This operation is + // useful for compilers that move epilogue code into the body of a + // function.) + lldb::addr_t offset = row->GetOffset (); row = stack.back (); stack.pop_back (); + row->SetOffset (offset); + break; } - break; - case DW_CFA_def_cfa : // 0xC (CFA Definition Instruction) - { - // Takes two unsigned LEB128 operands representing a register - // number and a (non-factored) offset. The required action - // is to define the current CFA rule to use the provided - // register and offset. - reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); - op_offset = (int32_t)m_cfi_data.GetULEB128(&offset); - row->SetCFARegister (reg_num); - row->SetCFAOffset (op_offset); - } - break; + case DW_CFA_val_offset : // 0x14 + case DW_CFA_val_offset_sf : // 0x15 + default: + break; + } + } + } + } + unwind_plan.AppendRow(row); - case DW_CFA_def_cfa_register : // 0xD (CFA Definition Instruction) - { - // takes a single unsigned LEB128 argument representing a register - // number. The required action is to define the current CFA rule to - // use the provided register (but to keep the old offset). - reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); - row->SetCFARegister (reg_num); - } - break; + return true; +} - case DW_CFA_def_cfa_offset : // 0xE (CFA Definition Instruction) - { - // Takes a single unsigned LEB128 operand representing a - // (non-factored) offset. The required action is to define - // the current CFA rule to use the provided offset (but - // to keep the old register). - op_offset = (int32_t)m_cfi_data.GetULEB128(&offset); - row->SetCFAOffset (op_offset); - } - break; +bool +DWARFCallFrameInfo::HandleCommonDwarfOpcode(uint8_t primary_opcode, + uint8_t extended_opcode, + int32_t data_align, + lldb::offset_t& offset, + UnwindPlan::Row& row) +{ + UnwindPlan::Row::RegisterLocation reg_location; - case DW_CFA_def_cfa_expression : // 0xF (CFA Definition Instruction) - { - size_t block_len = (size_t)m_cfi_data.GetULEB128(&offset); - offset += (uint32_t)block_len; - } - break; + if (primary_opcode) + { + switch (primary_opcode) + { + case DW_CFA_offset: + { // 0x80 - high 2 bits are 0x2, lower 6 bits are register + // takes two arguments: an unsigned LEB128 constant representing a + // factored offset and a register number. The required action is to + // change the rule for the register indicated by the register number + // to be an offset(N) rule with a value of + // (N = factored offset * data_align). + uint8_t reg_num = extended_opcode; + int32_t op_offset = (int32_t)m_cfi_data.GetULEB128(&offset) * data_align; + reg_location.SetAtCFAPlusOffset(op_offset); + row.SetRegisterInfo(reg_num, reg_location); + return true; + } + } + } + else + { + switch (extended_opcode) + { + case DW_CFA_nop : // 0x0 + return true; - case DW_CFA_expression : // 0x10 - { - // Takes two operands: an unsigned LEB128 value representing - // a register number, and a DW_FORM_block value representing a DWARF - // expression. The required action is to change the rule for the - // register indicated by the register number to be an expression(E) - // rule where E is the DWARF expression. That is, the DWARF - // expression computes the address. The value of the CFA is - // pushed on the DWARF evaluation stack prior to execution of - // the DWARF expression. - reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); - uint32_t block_len = (uint32_t)m_cfi_data.GetULEB128(&offset); - const uint8_t *block_data = (uint8_t *)m_cfi_data.GetData(&offset, block_len); - - reg_location.SetAtDWARFExpression(block_data, block_len); - row->SetRegisterInfo (reg_num, reg_location); - } - break; + case DW_CFA_offset_extended : // 0x5 + { + // takes two unsigned LEB128 arguments representing a register number + // and a factored offset. This instruction is identical to DW_CFA_offset + // except for the encoding and size of the register argument. + uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); + int32_t op_offset = (int32_t)m_cfi_data.GetULEB128(&offset) * data_align; + UnwindPlan::Row::RegisterLocation reg_location; + reg_location.SetAtCFAPlusOffset(op_offset); + row.SetRegisterInfo(reg_num, reg_location); + return true; + } - case DW_CFA_offset_extended_sf : // 0x11 - { - // takes two operands: an unsigned LEB128 value representing a - // register number and a signed LEB128 factored offset. This - // instruction is identical to DW_CFA_offset_extended except - //that the second operand is signed and factored. - reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); - op_offset = (int32_t)m_cfi_data.GetSLEB128(&offset) * data_align; - reg_location.SetAtCFAPlusOffset(op_offset); - row->SetRegisterInfo (reg_num, reg_location); - } - break; + case DW_CFA_undefined : // 0x7 + { + // takes a single unsigned LEB128 argument that represents a register + // number. The required action is to set the rule for the specified + // register to undefined. + uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); + UnwindPlan::Row::RegisterLocation reg_location; + reg_location.SetUndefined(); + row.SetRegisterInfo(reg_num, reg_location); + return true; + } - case DW_CFA_def_cfa_sf : // 0x12 (CFA Definition Instruction) - { - // Takes two operands: an unsigned LEB128 value representing - // a register number and a signed LEB128 factored offset. - // This instruction is identical to DW_CFA_def_cfa except - // that the second operand is signed and factored. - reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); - op_offset = (int32_t)m_cfi_data.GetSLEB128(&offset) * data_align; - row->SetCFARegister (reg_num); - row->SetCFAOffset (op_offset); - } - break; + case DW_CFA_same_value : // 0x8 + { + // takes a single unsigned LEB128 argument that represents a register + // number. The required action is to set the rule for the specified + // register to same value. + uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); + UnwindPlan::Row::RegisterLocation reg_location; + reg_location.SetSame(); + row.SetRegisterInfo (reg_num, reg_location); + return true; + } - case DW_CFA_def_cfa_offset_sf : // 0x13 (CFA Definition Instruction) - { - // takes a signed LEB128 operand representing a factored - // offset. This instruction is identical to DW_CFA_def_cfa_offset - // except that the operand is signed and factored. - op_offset = (int32_t)m_cfi_data.GetSLEB128(&offset) * data_align; - row->SetCFAOffset (op_offset); - } - break; + case DW_CFA_register : // 0x9 + { + // takes two unsigned LEB128 arguments representing register numbers. + // The required action is to set the rule for the first register to be + // the second register. + uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); + uint32_t other_reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); + UnwindPlan::Row::RegisterLocation reg_location; + reg_location.SetInRegister(other_reg_num); + row.SetRegisterInfo (reg_num, reg_location); + return true; + } - case DW_CFA_val_expression : // 0x16 - { - // takes two operands: an unsigned LEB128 value representing a register - // number, and a DW_FORM_block value representing a DWARF expression. - // The required action is to change the rule for the register indicated - // by the register number to be a val_expression(E) rule where E is the - // DWARF expression. That is, the DWARF expression computes the value of - // the given register. The value of the CFA is pushed on the DWARF - // evaluation stack prior to execution of the DWARF expression. - reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); - uint32_t block_len = (uint32_t)m_cfi_data.GetULEB128(&offset); - const uint8_t* block_data = (uint8_t*)m_cfi_data.GetData(&offset, block_len); + case DW_CFA_def_cfa : // 0xC (CFA Definition Instruction) + { + // Takes two unsigned LEB128 operands representing a register + // number and a (non-factored) offset. The required action + // is to define the current CFA rule to use the provided + // register and offset. + uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); + int32_t op_offset = (int32_t)m_cfi_data.GetULEB128(&offset); + row.GetCFAValue().SetIsRegisterPlusOffset (reg_num, op_offset); + return true; + } + + case DW_CFA_def_cfa_register : // 0xD (CFA Definition Instruction) + { + // takes a single unsigned LEB128 argument representing a register + // number. The required action is to define the current CFA rule to + // use the provided register (but to keep the old offset). + uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); + row.GetCFAValue().SetIsRegisterPlusOffset (reg_num, row.GetCFAValue().GetOffset()); + return true; + } + + case DW_CFA_def_cfa_offset : // 0xE (CFA Definition Instruction) + { + // Takes a single unsigned LEB128 operand representing a + // (non-factored) offset. The required action is to define + // the current CFA rule to use the provided offset (but + // to keep the old register). + int32_t op_offset = (int32_t)m_cfi_data.GetULEB128(&offset); + row.GetCFAValue().SetIsRegisterPlusOffset(row.GetCFAValue().GetRegisterNumber(), op_offset); + return true; + } + + case DW_CFA_def_cfa_expression : // 0xF (CFA Definition Instruction) + { + size_t block_len = (size_t)m_cfi_data.GetULEB128(&offset); + const uint8_t *block_data = static_cast<const uint8_t*>(m_cfi_data.GetData(&offset, block_len)); + row.GetCFAValue().SetIsDWARFExpression(block_data, block_len); + return true; + } + + case DW_CFA_expression : // 0x10 + { + // Takes two operands: an unsigned LEB128 value representing + // a register number, and a DW_FORM_block value representing a DWARF + // expression. The required action is to change the rule for the + // register indicated by the register number to be an expression(E) + // rule where E is the DWARF expression. That is, the DWARF + // expression computes the address. The value of the CFA is + // pushed on the DWARF evaluation stack prior to execution of + // the DWARF expression. + uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); + uint32_t block_len = (uint32_t)m_cfi_data.GetULEB128(&offset); + const uint8_t *block_data = static_cast<const uint8_t*>(m_cfi_data.GetData(&offset, block_len)); + UnwindPlan::Row::RegisterLocation reg_location; + reg_location.SetAtDWARFExpression(block_data, block_len); + row.SetRegisterInfo(reg_num, reg_location); + return true; + } + + case DW_CFA_offset_extended_sf : // 0x11 + { + // takes two operands: an unsigned LEB128 value representing a + // register number and a signed LEB128 factored offset. This + // instruction is identical to DW_CFA_offset_extended except + //that the second operand is signed and factored. + uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); + int32_t op_offset = (int32_t)m_cfi_data.GetSLEB128(&offset) * data_align; + UnwindPlan::Row::RegisterLocation reg_location; + reg_location.SetAtCFAPlusOffset(op_offset); + row.SetRegisterInfo(reg_num, reg_location); + return true; + } + + case DW_CFA_def_cfa_sf : // 0x12 (CFA Definition Instruction) + { + // Takes two operands: an unsigned LEB128 value representing + // a register number and a signed LEB128 factored offset. + // This instruction is identical to DW_CFA_def_cfa except + // that the second operand is signed and factored. + uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); + int32_t op_offset = (int32_t)m_cfi_data.GetSLEB128(&offset) * data_align; + row.GetCFAValue().SetIsRegisterPlusOffset (reg_num, op_offset); + return true; + } + + case DW_CFA_def_cfa_offset_sf : // 0x13 (CFA Definition Instruction) + { + // takes a signed LEB128 operand representing a factored + // offset. This instruction is identical to DW_CFA_def_cfa_offset + // except that the operand is signed and factored. + int32_t op_offset = (int32_t)m_cfi_data.GetSLEB128(&offset) * data_align; + uint32_t cfa_regnum = row.GetCFAValue().GetRegisterNumber(); + row.GetCFAValue().SetIsRegisterPlusOffset(cfa_regnum, op_offset); + return true; + } + + case DW_CFA_val_expression : // 0x16 + { + // takes two operands: an unsigned LEB128 value representing a register + // number, and a DW_FORM_block value representing a DWARF expression. + // The required action is to change the rule for the register indicated + // by the register number to be a val_expression(E) rule where E is the + // DWARF expression. That is, the DWARF expression computes the value of + // the given register. The value of the CFA is pushed on the DWARF + // evaluation stack prior to execution of the DWARF expression. + uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset); + uint32_t block_len = (uint32_t)m_cfi_data.GetULEB128(&offset); + const uint8_t* block_data = (const uint8_t*)m_cfi_data.GetData(&offset, block_len); //#if defined(__i386__) || defined(__x86_64__) -// // The EH frame info for EIP and RIP contains code that looks for traps to -// // be a specific type and increments the PC. -// // For i386: -// // DW_CFA_val_expression where: -// // eip = DW_OP_breg6(+28), DW_OP_deref, DW_OP_dup, DW_OP_plus_uconst(0x34), -// // DW_OP_deref, DW_OP_swap, DW_OP_plus_uconst(0), DW_OP_deref, -// // DW_OP_dup, DW_OP_lit3, DW_OP_ne, DW_OP_swap, DW_OP_lit4, DW_OP_ne, -// // DW_OP_and, DW_OP_plus -// // This basically does a: -// // eip = ucontenxt.mcontext32->gpr.eip; -// // if (ucontenxt.mcontext32->exc.trapno != 3 && ucontenxt.mcontext32->exc.trapno != 4) -// // eip++; -// // -// // For x86_64: -// // DW_CFA_val_expression where: -// // rip = DW_OP_breg3(+48), DW_OP_deref, DW_OP_dup, DW_OP_plus_uconst(0x90), DW_OP_deref, -// // DW_OP_swap, DW_OP_plus_uconst(0), DW_OP_deref_size(4), DW_OP_dup, DW_OP_lit3, -// // DW_OP_ne, DW_OP_swap, DW_OP_lit4, DW_OP_ne, DW_OP_and, DW_OP_plus -// // This basically does a: -// // rip = ucontenxt.mcontext64->gpr.rip; -// // if (ucontenxt.mcontext64->exc.trapno != 3 && ucontenxt.mcontext64->exc.trapno != 4) -// // rip++; -// // The trap comparisons and increments are not needed as it hoses up the unwound PC which -// // is expected to point at least past the instruction that causes the fault/trap. So we -// // take it out by trimming the expression right at the first "DW_OP_swap" opcodes -// if (block_data != NULL && thread->GetPCRegNum(Thread::GCC) == reg_num) -// { -// if (thread->Is64Bit()) -// { -// if (block_len > 9 && block_data[8] == DW_OP_swap && block_data[9] == DW_OP_plus_uconst) -// block_len = 8; -// } -// else -// { -// if (block_len > 8 && block_data[7] == DW_OP_swap && block_data[8] == DW_OP_plus_uconst) -// block_len = 7; -// } -// } +// // The EH frame info for EIP and RIP contains code that looks for traps to +// // be a specific type and increments the PC. +// // For i386: +// // DW_CFA_val_expression where: +// // eip = DW_OP_breg6(+28), DW_OP_deref, DW_OP_dup, DW_OP_plus_uconst(0x34), +// // DW_OP_deref, DW_OP_swap, DW_OP_plus_uconst(0), DW_OP_deref, +// // DW_OP_dup, DW_OP_lit3, DW_OP_ne, DW_OP_swap, DW_OP_lit4, DW_OP_ne, +// // DW_OP_and, DW_OP_plus +// // This basically does a: +// // eip = ucontenxt.mcontext32->gpr.eip; +// // if (ucontenxt.mcontext32->exc.trapno != 3 && ucontenxt.mcontext32->exc.trapno != 4) +// // eip++; +// // +// // For x86_64: +// // DW_CFA_val_expression where: +// // rip = DW_OP_breg3(+48), DW_OP_deref, DW_OP_dup, DW_OP_plus_uconst(0x90), DW_OP_deref, +// // DW_OP_swap, DW_OP_plus_uconst(0), DW_OP_deref_size(4), DW_OP_dup, DW_OP_lit3, +// // DW_OP_ne, DW_OP_swap, DW_OP_lit4, DW_OP_ne, DW_OP_and, DW_OP_plus +// // This basically does a: +// // rip = ucontenxt.mcontext64->gpr.rip; +// // if (ucontenxt.mcontext64->exc.trapno != 3 && ucontenxt.mcontext64->exc.trapno != 4) +// // rip++; +// // The trap comparisons and increments are not needed as it hoses up the unwound PC which +// // is expected to point at least past the instruction that causes the fault/trap. So we +// // take it out by trimming the expression right at the first "DW_OP_swap" opcodes +// if (block_data != NULL && thread->GetPCRegNum(Thread::GCC) == reg_num) +// { +// if (thread->Is64Bit()) +// { +// if (block_len > 9 && block_data[8] == DW_OP_swap && block_data[9] == DW_OP_plus_uconst) +// block_len = 8; +// } +// else +// { +// if (block_len > 8 && block_data[7] == DW_OP_swap && block_data[8] == DW_OP_plus_uconst) +// block_len = 7; +// } +// } //#endif - reg_location.SetIsDWARFExpression(block_data, block_len); - row->SetRegisterInfo (reg_num, reg_location); - } - break; - - case DW_CFA_val_offset : // 0x14 - case DW_CFA_val_offset_sf : // 0x15 - default: - break; + reg_location.SetIsDWARFExpression(block_data, block_len); + row.SetRegisterInfo (reg_num, reg_location); + return true; } } } - unwind_plan.AppendRow(row); - - return true; + return false; } diff --git a/source/Symbol/FuncUnwinders.cpp b/source/Symbol/FuncUnwinders.cpp index 1eb73ee3649b..000df722bb9e 100644 --- a/source/Symbol/FuncUnwinders.cpp +++ b/source/Symbol/FuncUnwinders.cpp @@ -145,39 +145,27 @@ FuncUnwinders::GetEHFrameAugmentedUnwindPlan (Target &target, Thread &thread, in Mutex::Locker lock (m_mutex); m_tried_unwind_plan_eh_frame_augmented = true; - if (m_range.GetBaseAddress().IsValid()) + UnwindPlanSP eh_frame_plan = GetEHFrameUnwindPlan (target, current_offset); + if (!eh_frame_plan) + return m_unwind_plan_eh_frame_augmented_sp; + + m_unwind_plan_eh_frame_augmented_sp.reset(new UnwindPlan(*eh_frame_plan)); + + // Augment the eh_frame instructions with epilogue descriptions if necessary so the + // UnwindPlan can be used at any instruction in the function. + + UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler(target)); + if (assembly_profiler_sp) { - Address current_pc (m_range.GetBaseAddress ()); - if (current_offset != -1) - current_pc.SetOffset (current_pc.GetOffset() + current_offset); - DWARFCallFrameInfo *eh_frame = m_unwind_table.GetEHFrameInfo(); - if (eh_frame) + if (!assembly_profiler_sp->AugmentUnwindPlanFromCallSite (m_range, thread, *m_unwind_plan_eh_frame_augmented_sp)) { - m_unwind_plan_eh_frame_augmented_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); - if (!eh_frame->GetUnwindPlan (current_pc, *m_unwind_plan_eh_frame_augmented_sp)) - { - m_unwind_plan_eh_frame_augmented_sp.reset(); - } - else - { - // Augment the eh_frame instructions with epilogue descriptions if necessary so the - // UnwindPlan can be used at any instruction in the function. - - UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler()); - if (assembly_profiler_sp) - { - if (!assembly_profiler_sp->AugmentUnwindPlanFromCallSite (m_range, thread, *m_unwind_plan_eh_frame_augmented_sp)) - { - m_unwind_plan_eh_frame_augmented_sp.reset(); - } - } - else - { - m_unwind_plan_eh_frame_augmented_sp.reset(); - } - } + m_unwind_plan_eh_frame_augmented_sp.reset(); } } + else + { + m_unwind_plan_eh_frame_augmented_sp.reset(); + } return m_unwind_plan_eh_frame_augmented_sp; } @@ -191,7 +179,7 @@ FuncUnwinders::GetAssemblyUnwindPlan (Target &target, Thread &thread, int curren Mutex::Locker lock (m_mutex); m_tried_unwind_plan_assembly = true; - UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler()); + UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler(target)); if (assembly_profiler_sp) { m_unwind_plan_assembly_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); @@ -216,7 +204,7 @@ FuncUnwinders::GetUnwindPlanAtNonCallSite (Target& target, Thread& thread, int c } UnwindPlanSP -FuncUnwinders::GetUnwindPlanFastUnwind (Thread& thread) +FuncUnwinders::GetUnwindPlanFastUnwind (Target& target, Thread& thread) { if (m_unwind_plan_fast_sp.get() || m_tried_unwind_fast) return m_unwind_plan_fast_sp; @@ -224,7 +212,7 @@ FuncUnwinders::GetUnwindPlanFastUnwind (Thread& thread) Mutex::Locker locker (m_mutex); m_tried_unwind_fast = true; - UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler()); + UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler(target)); if (assembly_profiler_sp) { m_unwind_plan_fast_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); @@ -299,7 +287,7 @@ FuncUnwinders::GetFirstNonPrologueInsn (Target& target) Mutex::Locker locker (m_mutex); ExecutionContext exe_ctx (target.shared_from_this(), false); - UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler()); + UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler(target)); if (assembly_profiler_sp) assembly_profiler_sp->FirstNonPrologueInsn (m_range, exe_ctx, m_first_non_prologue_insn); return m_first_non_prologue_insn; @@ -312,12 +300,13 @@ FuncUnwinders::GetFunctionStartAddress () const } lldb::UnwindAssemblySP -FuncUnwinders::GetUnwindAssemblyProfiler () +FuncUnwinders::GetUnwindAssemblyProfiler (Target& target) { UnwindAssemblySP assembly_profiler_sp; ArchSpec arch; if (m_unwind_table.GetArchitecture (arch)) { + arch.MergeFrom (target.GetArchitecture ()); assembly_profiler_sp = UnwindAssembly::FindPlugin (arch); } return assembly_profiler_sp; diff --git a/source/Symbol/LineTable.cpp b/source/Symbol/LineTable.cpp index 92b243d80a91..3b951f567660 100644 --- a/source/Symbol/LineTable.cpp +++ b/source/Symbol/LineTable.cpp @@ -542,8 +542,7 @@ LineTable::LinkLineTable (const FileRangeMap &file_range_map) // This entry doesn't have a remapping and it needs to be removed. // Watch out in case we need to terminate a previous entry needs to // be terminated now that one line entry in a sequence is not longer valid. - if (!entry.is_terminal_entry && - !sequence.m_entries.empty() && + if (!sequence.m_entries.empty() && !sequence.m_entries.back().is_terminal_entry) { terminate_previous_entry = true; diff --git a/source/Symbol/ObjectFile.cpp b/source/Symbol/ObjectFile.cpp index c24e83260d4d..22a313cf6a20 100644 --- a/source/Symbol/ObjectFile.cpp +++ b/source/Symbol/ObjectFile.cpp @@ -8,7 +8,6 @@ //===----------------------------------------------------------------------===// #include "lldb/lldb-private.h" -#include "lldb/lldb-private-log.h" #include "lldb/Core/DataBuffer.h" #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/Log.h" @@ -329,7 +328,7 @@ ObjectFile::GetAddressClass (addr_t file_addr) { if (symbol->ValueIsAddress()) { - const SectionSP section_sp (symbol->GetAddress().GetSection()); + const SectionSP section_sp (symbol->GetAddressRef().GetSection()); if (section_sp) { const SectionType section_type = section_sp->GetType(); diff --git a/source/Symbol/Symbol.cpp b/source/Symbol/Symbol.cpp index b6ed94610b0a..dff15dd92613 100644 --- a/source/Symbol/Symbol.cpp +++ b/source/Symbol/Symbol.cpp @@ -36,6 +36,7 @@ Symbol::Symbol() : m_size_is_synthesized (false), m_size_is_valid (false), m_demangled_is_synthesized (false), + m_contains_linker_annotations (false), m_type (eSymbolTypeInvalid), m_mangled (), m_addr_range (), @@ -57,6 +58,7 @@ Symbol::Symbol addr_t offset, addr_t size, bool size_is_valid, + bool contains_linker_annotations, uint32_t flags ) : SymbolContextScope (), @@ -70,6 +72,7 @@ Symbol::Symbol m_size_is_synthesized (false), m_size_is_valid (size_is_valid || size > 0), m_demangled_is_synthesized (false), + m_contains_linker_annotations (contains_linker_annotations), m_type (type), m_mangled (ConstString(name), name_is_mangled), m_addr_range (section_sp, offset, size), @@ -80,8 +83,7 @@ Symbol::Symbol Symbol::Symbol ( uint32_t symID, - const char *name, - bool name_is_mangled, + const Mangled &mangled, SymbolType type, bool external, bool is_debug, @@ -89,6 +91,7 @@ Symbol::Symbol bool is_artificial, const AddressRange &range, bool size_is_valid, + bool contains_linker_annotations, uint32_t flags ) : SymbolContextScope (), @@ -102,8 +105,9 @@ Symbol::Symbol m_size_is_synthesized (false), m_size_is_valid (size_is_valid || range.GetByteSize() > 0), m_demangled_is_synthesized (false), + m_contains_linker_annotations (contains_linker_annotations), m_type (type), - m_mangled (ConstString(name), name_is_mangled), + m_mangled (mangled), m_addr_range (range), m_flags (flags) { @@ -121,6 +125,7 @@ Symbol::Symbol(const Symbol& rhs): m_size_is_synthesized (false), m_size_is_valid (rhs.m_size_is_valid), m_demangled_is_synthesized (rhs.m_demangled_is_synthesized), + m_contains_linker_annotations (rhs.m_contains_linker_annotations), m_type (rhs.m_type), m_mangled (rhs.m_mangled), m_addr_range (rhs.m_addr_range), @@ -144,6 +149,7 @@ Symbol::operator= (const Symbol& rhs) m_size_is_synthesized = rhs.m_size_is_sibling; m_size_is_valid = rhs.m_size_is_valid; m_demangled_is_synthesized = rhs.m_demangled_is_synthesized; + m_contains_linker_annotations = rhs.m_contains_linker_annotations; m_type = rhs.m_type; m_mangled = rhs.m_mangled; m_addr_range = rhs.m_addr_range; @@ -166,6 +172,7 @@ Symbol::Clear() m_size_is_synthesized = false; m_size_is_valid = false; m_demangled_is_synthesized = false; + m_contains_linker_annotations = false; m_type = eSymbolTypeInvalid; m_flags = 0; m_addr_range.Clear(); @@ -209,18 +216,13 @@ Symbol::GetReExportedSymbolSharedLibrary() const return FileSpec(); } -bool +void Symbol::SetReExportedSymbolName(const ConstString &name) { - if (m_type == eSymbolTypeReExported) - { - // For eSymbolTypeReExported, the "const char *" from a ConstString - // is used as the offset in the address range base address. - m_addr_range.GetBaseAddress().SetOffset((intptr_t)name.GetCString()); - return true; - } - return false; - + SetType (eSymbolTypeReExported); + // For eSymbolTypeReExported, the "const char *" from a ConstString + // is used as the offset in the address range base address. + m_addr_range.GetBaseAddress().SetOffset((uintptr_t)name.GetCString()); } bool @@ -230,7 +232,7 @@ Symbol::SetReExportedSymbolSharedLibrary(const FileSpec &fspec) { // For eSymbolTypeReExported, the "const char *" from a ConstString // is used as the offset in the address range base address. - m_addr_range.SetByteSize((intptr_t)ConstString(fspec.GetPath().c_str()).GetCString()); + m_addr_range.SetByteSize((uintptr_t)ConstString(fspec.GetPath().c_str()).GetCString()); return true; } return false; @@ -240,7 +242,7 @@ Symbol::SetReExportedSymbolSharedLibrary(const FileSpec &fspec) uint32_t Symbol::GetSiblingIndex() const { - return m_size_is_sibling ? m_addr_range.GetByteSize() : 0; + return m_size_is_sibling ? m_addr_range.GetByteSize() : UINT32_MAX; } bool @@ -296,10 +298,7 @@ Symbol::GetDescription (Stream *s, lldb::DescriptionLevel level, Target *target) void Symbol::Dump(Stream *s, Target *target, uint32_t index) const { -// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); -// s->Indent(); -// s->Printf("Symbol[%5u] %6u %c%c %-12s ", - s->Printf("[%5u] %6u %c%c%c %-12s ", + s->Printf("[%5u] %6u %c%c%c %-15s ", index, GetID(), m_is_debug ? 'D' : ' ', @@ -492,7 +491,7 @@ Symbol::CalculateSymbolContext (SymbolContext *sc) // Symbols can reconstruct the symbol and the module in the symbol context sc->symbol = this; if (ValueIsAddress()) - sc->module_sp = GetAddress().GetModule(); + sc->module_sp = GetAddressRef().GetModule(); else sc->module_sp.reset(); } @@ -501,7 +500,7 @@ ModuleSP Symbol::CalculateSymbolContextModule () { if (ValueIsAddress()) - return GetAddress().GetModule(); + return GetAddressRef().GetModule(); return ModuleSP(); } @@ -517,7 +516,7 @@ Symbol::DumpSymbolContext (Stream *s) bool dumped_module = false; if (ValueIsAddress()) { - ModuleSP module_sp (GetAddress().GetModule()); + ModuleSP module_sp (GetAddressRef().GetModule()); if (module_sp) { dumped_module = true; @@ -619,6 +618,25 @@ Symbol::ResolveReExportedSymbol (Target &target) const } lldb::addr_t +Symbol::GetFileAddress () const +{ + if (ValueIsAddress()) + return GetAddressRef().GetFileAddress(); + else + return LLDB_INVALID_ADDRESS; +} + +lldb::addr_t +Symbol::GetLoadAddress (Target *target) const +{ + if (ValueIsAddress()) + return GetAddressRef().GetLoadAddress(target); + else + return LLDB_INVALID_ADDRESS; +} + + +lldb::addr_t Symbol::ResolveCallableAddress(Target &target) const { if (GetType() == lldb::eSymbolTypeUndefined) diff --git a/source/Symbol/SymbolContext.cpp b/source/Symbol/SymbolContext.cpp index 62ae6ac464ce..8e4240a4587d 100644 --- a/source/Symbol/SymbolContext.cpp +++ b/source/Symbol/SymbolContext.cpp @@ -129,15 +129,15 @@ SymbolContext::Clear(bool clear_target) } bool -SymbolContext::DumpStopContext -( +SymbolContext::DumpStopContext ( Stream *s, ExecutionContextScope *exe_scope, const Address &addr, bool show_fullpaths, bool show_module, bool show_inlined_frames, - bool show_function_arguments + bool show_function_arguments, + bool show_function_name ) const { bool dumped_something = false; @@ -155,7 +155,12 @@ SymbolContext::DumpStopContext { SymbolContext inline_parent_sc; Address inline_parent_addr; - if (show_function_arguments == false && function->GetMangled().GetName(Mangled::ePreferDemangledWithoutArguments)) + if (show_function_name == false) + { + s->Printf("<"); + dumped_something = true; + } + else if (show_function_arguments == false && function->GetMangled().GetName(Mangled::ePreferDemangledWithoutArguments)) { dumped_something = true; function->GetMangled().GetName(Mangled::ePreferDemangledWithoutArguments).Dump(s); @@ -169,7 +174,13 @@ SymbolContext::DumpStopContext if (addr.IsValid()) { const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset(); - if (function_offset) + if (show_function_name == false) + { + // Print +offset even if offset is 0 + dumped_something = true; + s->Printf("+%" PRIu64 ">", function_offset); + } + else if (function_offset) { dumped_something = true; s->Printf(" + %" PRIu64, function_offset); @@ -202,7 +213,8 @@ SymbolContext::DumpStopContext { s->EOL(); s->Indent(); - return inline_parent_sc.DumpStopContext (s, exe_scope, inline_parent_addr, show_fullpaths, show_module, show_inlined_frames, show_function_arguments); + const bool show_function_name = true; + return inline_parent_sc.DumpStopContext (s, exe_scope, inline_parent_addr, show_fullpaths, show_module, show_inlined_frames, show_function_arguments, show_function_name); } } else @@ -218,7 +230,12 @@ SymbolContext::DumpStopContext } else if (symbol != nullptr) { - if (symbol->GetMangled().GetName()) + if (show_function_name == false) + { + s->Printf("<"); + dumped_something = true; + } + else if (symbol->GetMangled().GetName()) { dumped_something = true; if (symbol->GetType() == eSymbolTypeTrampoline) @@ -228,8 +245,14 @@ SymbolContext::DumpStopContext if (addr.IsValid() && symbol->ValueIsAddress()) { - const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddress().GetOffset(); - if (symbol_offset) + const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddressRef().GetOffset(); + if (show_function_name == false) + { + // Print +offset even if offset is 0 + dumped_something = true; + s->Printf("+%" PRIu64 ">", symbol_offset); + } + else if (symbol_offset) { dumped_something = true; s->Printf(" + %" PRIu64, symbol_offset); @@ -492,7 +515,7 @@ SymbolContext::GetAddressRange (uint32_t scope, { if (symbol->ValueIsAddress()) { - range.GetBaseAddress() = symbol->GetAddress(); + range.GetBaseAddress() = symbol->GetAddressRef(); range.SetByteSize (symbol->GetByteSize()); return true; } @@ -1083,7 +1106,7 @@ SymbolContextList::AppendIfUnique (const SymbolContext& sc, bool merge_symbol_in if (pos->function) { - if (pos->function->GetAddressRange().GetBaseAddress() == sc.symbol->GetAddress()) + if (pos->function->GetAddressRange().GetBaseAddress() == sc.symbol->GetAddressRef()) { // Do we already have a function with this symbol? if (pos->symbol == sc.symbol) @@ -1125,7 +1148,7 @@ SymbolContextList::MergeSymbolContextIntoFunctionContext (const SymbolContext& s if (function_sc.function) { - if (function_sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddress()) + if (function_sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddressRef()) { // Do we already have a function with this symbol? if (function_sc.symbol == symbol_sc.symbol) diff --git a/source/Symbol/SymbolVendor.cpp b/source/Symbol/SymbolVendor.cpp index a3f4104016e5..6ec9f3861ecf 100644 --- a/source/Symbol/SymbolVendor.cpp +++ b/source/Symbol/SymbolVendor.cpp @@ -198,6 +198,21 @@ SymbolVendor::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecLis return false; } +bool +SymbolVendor::ParseImportedModules (const SymbolContext &sc, + std::vector<ConstString> &imported_modules) +{ + ModuleSP module_sp(GetModule()); + if (module_sp) + { + lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + if (m_sym_file_ap.get()) + return m_sym_file_ap->ParseImportedModules(sc, imported_modules); + } + return false; + +} + size_t SymbolVendor::ParseFunctionBlocks (const SymbolContext &sc) { @@ -380,6 +395,8 @@ SymbolVendor::Dump(Stream *s) ModuleSP module_sp(GetModule()); if (module_sp) { + lldb_private::Mutex::Locker locker(module_sp->GetMutex()); + bool show_context = false; s->Printf("%p: ", static_cast<void*>(this)); @@ -423,6 +440,7 @@ SymbolVendor::GetCompileUnitAtIndex(size_t idx) ModuleSP module_sp(GetModule()); if (module_sp) { + lldb_private::Mutex::Locker locker(module_sp->GetMutex()); const size_t num_compile_units = GetNumCompileUnits(); if (idx < num_compile_units) { @@ -437,6 +455,19 @@ SymbolVendor::GetCompileUnitAtIndex(size_t idx) return cu_sp; } +FileSpec +SymbolVendor::GetMainFileSpec() const +{ + if (m_sym_file_ap.get()) + { + const ObjectFile *symfile_objfile = m_sym_file_ap->GetObjectFile(); + if (symfile_objfile) + return symfile_objfile->GetFileSpec(); + } + + return FileSpec(); +} + Symtab * SymbolVendor::GetSymtab () { diff --git a/source/Symbol/Symtab.cpp b/source/Symbol/Symtab.cpp index 907072c0d906..4cc03345d05b 100644 --- a/source/Symbol/Symtab.cpp +++ b/source/Symbol/Symtab.cpp @@ -14,6 +14,7 @@ #include "lldb/Core/Section.h" #include "lldb/Core/Timer.h" #include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/Symtab.h" #include "lldb/Target/CPPLanguageRuntime.h" @@ -201,16 +202,16 @@ Symtab::DumpSymbolHeader (Stream *s) s->Indent(" |Synthetic symbol\n"); s->Indent(" ||Externally Visible\n"); s->Indent(" |||\n"); - s->Indent("Index UserID DSX Type File Address/Value Load Address Size Flags Name\n"); - s->Indent("------- ------ --- ------------ ------------------ ------------------ ------------------ ---------- ----------------------------------\n"); + s->Indent("Index UserID DSX Type File Address/Value Load Address Size Flags Name\n"); + s->Indent("------- ------ --- --------------- ------------------ ------------------ ------------------ ---------- ----------------------------------\n"); } static int CompareSymbolID (const void *key, const void *p) { - const user_id_t match_uid = *(user_id_t*) key; - const user_id_t symbol_uid = ((Symbol *)p)->GetID(); + const user_id_t match_uid = *(const user_id_t*) key; + const user_id_t symbol_uid = ((const Symbol *)p)->GetID(); if (match_uid < symbol_uid) return -1; if (match_uid > symbol_uid) @@ -226,7 +227,7 @@ Symtab::FindSymbolByID (lldb::user_id_t symbol_uid) const Symbol *symbol = (Symbol*)::bsearch (&symbol_uid, &m_symbols[0], m_symbols.size(), - (uint8_t *)&m_symbols[1] - (uint8_t *)&m_symbols[0], + sizeof(m_symbols[0]), CompareSymbolID); return symbol; } @@ -312,6 +313,13 @@ Symtab::InitNameIndexes() if (entry.cstring && entry.cstring[0]) { m_name_to_index.Append (entry); + + if (symbol->ContainsLinkerAnnotations()) { + // If the symbol has linker annotations, also add the version without the + // annotations. + entry.cstring = ConstString(m_objfile->StripLinkerSymbolAnnotations(entry.cstring)).GetCString(); + m_name_to_index.Append (entry); + } const SymbolType symbol_type = symbol->GetType(); if (symbol_type == eSymbolTypeCode || symbol_type == eSymbolTypeResolver) @@ -371,8 +379,16 @@ Symtab::InitNameIndexes() } entry.cstring = mangled.GetDemangledName().GetCString(); - if (entry.cstring && entry.cstring[0]) + if (entry.cstring && entry.cstring[0]) { m_name_to_index.Append (entry); + + if (symbol->ContainsLinkerAnnotations()) { + // If the symbol has linker annotations, also add the version without the + // annotations. + entry.cstring = ConstString(m_objfile->StripLinkerSymbolAnnotations(entry.cstring)).GetCString(); + m_name_to_index.Append (entry); + } + } // If the demangled name turns out to be an ObjC name, and // is a category name, add the version without categories to the index too. @@ -546,9 +562,12 @@ Symtab::AppendSymbolIndexesWithType (SymbolType symbol_type, Debug symbol_debug_ uint32_t Symtab::GetIndexForSymbol (const Symbol *symbol) const { - const Symbol *first_symbol = &m_symbols[0]; - if (symbol >= first_symbol && symbol < first_symbol + m_symbols.size()) - return symbol - first_symbol; + if (!m_symbols.empty()) + { + const Symbol *first_symbol = &m_symbols[0]; + if (symbol >= first_symbol && symbol < first_symbol + m_symbols.size()) + return symbol - first_symbol; + } return UINT32_MAX; } @@ -579,14 +598,14 @@ namespace { addr_t value_a = addr_cache[index_a]; if (value_a == LLDB_INVALID_ADDRESS) { - value_a = symbols[index_a].GetAddress().GetFileAddress(); + value_a = symbols[index_a].GetAddressRef().GetFileAddress(); addr_cache[index_a] = value_a; } addr_t value_b = addr_cache[index_b]; if (value_b == LLDB_INVALID_ADDRESS) { - value_b = symbols[index_b].GetAddress().GetFileAddress(); + value_b = symbols[index_b].GetAddressRef().GetFileAddress(); addr_cache[index_b] = value_b; } @@ -883,7 +902,7 @@ SymbolWithClosestFileAddress (SymbolSearchInfo *info, const uint32_t *index_ptr) const addr_t info_file_addr = info->file_addr; if (symbol->ValueIsAddress()) { - const addr_t curr_file_addr = symbol->GetAddress().GetFileAddress(); + const addr_t curr_file_addr = symbol->GetAddressRef().GetFileAddress(); if (info_file_addr < curr_file_addr) return -1; @@ -917,7 +936,7 @@ Symtab::InitAddressIndexes() { if (pos->ValueIsAddress()) { - entry.SetRangeBase(pos->GetAddress().GetFileAddress()); + entry.SetRangeBase(pos->GetAddressRef().GetFileAddress()); entry.SetByteSize(pos->GetByteSize()); entry.data = std::distance(begin, pos); m_file_addr_to_index.Append(entry); @@ -1178,3 +1197,20 @@ Symtab::FindFunctionSymbols (const ConstString &name, return count; } + +const Symbol * +Symtab::GetParent (Symbol *child_symbol) const +{ + uint32_t child_idx = GetIndexForSymbol(child_symbol); + if (child_idx != UINT32_MAX && child_idx > 0) + { + for (uint32_t idx = child_idx - 1; idx != UINT32_MAX; --idx) + { + const Symbol *symbol = SymbolAtIndex (idx); + const uint32_t sibling_idx = symbol->GetSiblingIndex(); + if (sibling_idx != UINT32_MAX && sibling_idx > child_idx) + return symbol; + } + } + return NULL; +} diff --git a/source/Symbol/Type.cpp b/source/Symbol/Type.cpp index 6e67f4695d9f..0927d55f1ee2 100644 --- a/source/Symbol/Type.cpp +++ b/source/Symbol/Type.cpp @@ -589,16 +589,27 @@ Type::ResolveClangType (ResolveState clang_type_resolve_state) break; } } + + // When we have a EncodingUID, our "m_flags.clang_type_resolve_state" is set to eResolveStateUnresolved + // so we need to update it to say that we now have a forward declaration since that is what we created + // above. + if (m_clang_type.IsValid()) + m_flags.clang_type_resolve_state = eResolveStateForward; + } - + // Check if we have a forward reference to a class/struct/union/enum? - if (m_clang_type.IsValid() && m_flags.clang_type_resolve_state < clang_type_resolve_state) + if (clang_type_resolve_state == eResolveStateLayout || clang_type_resolve_state == eResolveStateFull) { - m_flags.clang_type_resolve_state = eResolveStateFull; - if (!m_clang_type.IsDefined ()) + // Check if we have a forward reference to a class/struct/union/enum? + if (m_clang_type.IsValid() && m_flags.clang_type_resolve_state < clang_type_resolve_state) { - // We have a forward declaration, we need to resolve it to a complete definition. - m_symbol_file->ResolveClangOpaqueTypeDefinition (m_clang_type); + m_flags.clang_type_resolve_state = eResolveStateFull; + if (!m_clang_type.IsDefined ()) + { + // We have a forward declaration, we need to resolve it to a complete definition. + m_symbol_file->ResolveClangOpaqueTypeDefinition (m_clang_type); + } } } diff --git a/source/Symbol/UnwindPlan.cpp b/source/Symbol/UnwindPlan.cpp index 87d0f49421c5..80c22c08ee4f 100644 --- a/source/Symbol/UnwindPlan.cpp +++ b/source/Symbol/UnwindPlan.cpp @@ -94,31 +94,7 @@ UnwindPlan::Row::RegisterLocation::Dump (Stream &s, const UnwindPlan* unwind_pla s.PutChar('='); if (m_type == atCFAPlusOffset) s.PutChar('['); - if (verbose) - s.Printf ("CFA%+d", m_location.offset); - - if (unwind_plan && row) - { - const uint32_t cfa_reg = row->GetCFARegister(); - const RegisterInfo *cfa_reg_info = unwind_plan->GetRegisterInfo (thread, cfa_reg); - const int32_t offset = row->GetCFAOffset() + m_location.offset; - if (verbose) - { - if (cfa_reg_info) - s.Printf (" (%s%+d)", cfa_reg_info->name, offset); - else - s.Printf (" (reg(%u)%+d)", cfa_reg, offset); - } - else - { - if (cfa_reg_info) - s.Printf ("%s", cfa_reg_info->name); - else - s.Printf ("reg(%u)", cfa_reg); - if (offset != 0) - s.Printf ("%+d", offset); - } - } + s.Printf ("CFA%+d", m_location.offset); if (m_type == atCFAPlusOffset) s.PutChar(']'); } @@ -150,38 +126,83 @@ UnwindPlan::Row::RegisterLocation::Dump (Stream &s, const UnwindPlan* unwind_pla } } +static void +DumpRegisterName (Stream &s, const UnwindPlan* unwind_plan, Thread *thread, uint32_t reg_num) { + const RegisterInfo *reg_info = unwind_plan->GetRegisterInfo (thread, reg_num); + if (reg_info) + s.PutCString (reg_info->name); + else + s.Printf ("reg(%u)", reg_num); +} + +bool +UnwindPlan::Row::CFAValue::operator == (const UnwindPlan::Row::CFAValue& rhs) const +{ + if (m_type == rhs.m_type) + { + switch (m_type) + { + case unspecified: + return true; + + case isRegisterPlusOffset: + return m_value.reg.offset == rhs.m_value.reg.offset; + + case isRegisterDereferenced: + return m_value.reg.reg_num == rhs.m_value.reg.reg_num; + + case isDWARFExpression: + if (m_value.expr.length == rhs.m_value.expr.length) + return !memcmp (m_value.expr.opcodes, rhs.m_value.expr.opcodes, m_value.expr.length); + break; + } + } + return false; +} + +void +UnwindPlan::Row::CFAValue::Dump(Stream &s, const UnwindPlan* unwind_plan, Thread* thread) const +{ + switch(m_type) { + case isRegisterPlusOffset: + DumpRegisterName(s, unwind_plan, thread, m_value.reg.reg_num); + s.Printf ("%+3d", m_value.reg.offset); + break; + case isRegisterDereferenced: + s.PutChar ('['); + DumpRegisterName(s, unwind_plan, thread, m_value.reg.reg_num); + s.PutChar (']'); + break; + case isDWARFExpression: + s.PutCString ("dwarf-expr"); + break; + default: + s.PutCString ("unspecified"); + break; + } +} + void UnwindPlan::Row::Clear () { - m_cfa_type = CFAIsRegisterPlusOffset; + m_cfa_value.SetUnspecified(); m_offset = 0; - m_cfa_reg_num = LLDB_INVALID_REGNUM; - m_cfa_offset = 0; m_register_locations.clear(); } void UnwindPlan::Row::Dump (Stream& s, const UnwindPlan* unwind_plan, Thread* thread, addr_t base_addr) const { - const RegisterInfo *reg_info = unwind_plan->GetRegisterInfo (thread, GetCFARegister()); - if (base_addr != LLDB_INVALID_ADDRESS) s.Printf ("0x%16.16" PRIx64 ": CFA=", base_addr + GetOffset()); else s.Printf ("%4" PRId64 ": CFA=", GetOffset()); - if (reg_info) - s.Printf ("%s", reg_info->name); - else - s.Printf ("reg(%u)", GetCFARegister()); - s.Printf ("%+3d => ", GetCFAOffset ()); + m_cfa_value.Dump(s, unwind_plan, thread); + s.Printf(" => "); for (collection::const_iterator idx = m_register_locations.begin (); idx != m_register_locations.end (); ++idx) { - reg_info = unwind_plan->GetRegisterInfo (thread, idx->first); - if (reg_info) - s.Printf ("%s", reg_info->name); - else - s.Printf ("reg(%u)", idx->first); + DumpRegisterName(s, unwind_plan, thread, idx->first); const bool verbose = false; idx->second.Dump(s, unwind_plan, this, thread, verbose); s.PutChar (' '); @@ -191,9 +212,7 @@ UnwindPlan::Row::Dump (Stream& s, const UnwindPlan* unwind_plan, Thread* thread, UnwindPlan::Row::Row() : m_offset (0), - m_cfa_type (CFAIsRegisterPlusOffset), - m_cfa_reg_num (LLDB_INVALID_REGNUM), - m_cfa_offset (0), + m_cfa_value (), m_register_locations () { } @@ -302,35 +321,11 @@ UnwindPlan::Row::SetRegisterLocationToSame (uint32_t reg_num, bool must_replace) return true; } -void -UnwindPlan::Row::SetCFARegister (uint32_t reg_num) -{ - m_cfa_reg_num = reg_num; -} - bool UnwindPlan::Row::operator == (const UnwindPlan::Row& rhs) const { - if (m_offset != rhs.m_offset || m_cfa_reg_num != rhs.m_cfa_reg_num || m_cfa_offset != rhs.m_cfa_offset) - return false; - - if (m_cfa_type != rhs.m_cfa_type) - return false; - - if (m_cfa_type == CFAIsRegisterPlusOffset) - { - if (m_cfa_reg_num != rhs.m_cfa_reg_num) - return false; - if (m_cfa_offset != rhs.m_cfa_offset) - return false; - } - if (m_cfa_type == CFAIsRegisterDereferenced) - { - if (m_cfa_reg_num != rhs.m_cfa_reg_num) - return false; - } - - return m_register_locations == rhs.m_register_locations; + return m_offset == rhs.m_offset && m_cfa_value == rhs.m_cfa_value && + m_register_locations == rhs.m_register_locations; } void @@ -348,11 +343,12 @@ UnwindPlan::InsertRow (const UnwindPlan::RowSP &row_sp) collection::iterator it = m_row_list.begin(); while (it != m_row_list.end()) { RowSP row = *it; - if (row->GetOffset() > row_sp->GetOffset()) + if (row->GetOffset() >= row_sp->GetOffset()) break; it++; } - m_row_list.insert(it, row_sp); + if (it == m_row_list.end() || (*it)->GetOffset() != row_sp->GetOffset()) + m_row_list.insert(it, row_sp); } UnwindPlan::RowSP @@ -439,7 +435,8 @@ UnwindPlan::PlanValidAtAddress (Address addr) // If the 0th Row of unwind instructions is missing, or if it doesn't provide // a register to use to find the Canonical Frame Address, this is not a valid UnwindPlan. - if (GetRowAtIndex(0).get() == nullptr || GetRowAtIndex(0)->GetCFARegister() == LLDB_INVALID_REGNUM) + if (GetRowAtIndex(0).get() == nullptr || + GetRowAtIndex(0)->GetCFAValue().GetValueType() == Row::CFAValue::unspecified) { Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); if (log) diff --git a/source/Symbol/Variable.cpp b/source/Symbol/Variable.cpp index 4c03a307296d..5665e4702ca6 100644 --- a/source/Symbol/Variable.cpp +++ b/source/Symbol/Variable.cpp @@ -36,7 +36,7 @@ Variable::Variable ( lldb::user_id_t uid, const char *name, - const char *mangled, // The mangled variable name for variables in namespaces + const char *mangled, // The mangled or fully qualified name of the variable. const lldb::SymbolFileTypeSP &symfile_type_sp, ValueType scope, SymbolContextScope *context, @@ -47,7 +47,7 @@ Variable::Variable ) : UserID(uid), m_name(name), - m_mangled (ConstString(mangled), true), + m_mangled (ConstString(mangled)), m_symfile_type_sp(symfile_type_sp), m_scope(scope), m_owner_scope(context), @@ -69,8 +69,9 @@ Variable::~Variable() const ConstString& Variable::GetName() const { - if (m_mangled) - return m_mangled.GetName(); + const ConstString &name = m_mangled.GetName(); + if (name) + return name; return m_name; } @@ -175,6 +176,7 @@ Variable::DumpDeclaration (Stream *s, bool show_fullpaths, bool show_module) sc.line_entry.Clear(); bool show_inlined_frames = false; const bool show_function_arguments = true; + const bool show_function_name = true; dumped_declaration_info = sc.DumpStopContext (s, nullptr, @@ -182,7 +184,8 @@ Variable::DumpDeclaration (Stream *s, bool show_fullpaths, bool show_module) show_fullpaths, show_module, show_inlined_frames, - show_function_arguments); + show_function_arguments, + show_function_name); if (sc.function) s->PutChar(':'); |