aboutsummaryrefslogtreecommitdiff
path: root/source/Symbol
diff options
context:
space:
mode:
Diffstat (limited to 'source/Symbol')
-rw-r--r--source/Symbol/Block.cpp2
-rw-r--r--source/Symbol/ClangASTContext.cpp54
-rw-r--r--source/Symbol/ClangASTImporter.cpp12
-rw-r--r--source/Symbol/ClangASTType.cpp97
-rw-r--r--source/Symbol/ClangExternalASTSourceCallbacks.cpp13
-rw-r--r--source/Symbol/CompactUnwindInfo.cpp77
-rw-r--r--source/Symbol/CompileUnit.cpp25
-rw-r--r--source/Symbol/DWARFCallFrameInfo.cpp590
-rw-r--r--source/Symbol/FuncUnwinders.cpp57
-rw-r--r--source/Symbol/LineTable.cpp3
-rw-r--r--source/Symbol/ObjectFile.cpp3
-rw-r--r--source/Symbol/Symbol.cpp62
-rw-r--r--source/Symbol/SymbolContext.cpp47
-rw-r--r--source/Symbol/SymbolVendor.cpp31
-rw-r--r--source/Symbol/Symtab.cpp62
-rw-r--r--source/Symbol/Type.cpp23
-rw-r--r--source/Symbol/UnwindPlan.cpp141
-rw-r--r--source/Symbol/Variable.cpp13
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(':');