diff options
Diffstat (limited to 'include/lldb/Symbol')
-rw-r--r-- | include/lldb/Symbol/ClangASTContext.h | 2 | ||||
-rw-r--r-- | include/lldb/Symbol/ClangASTType.h | 4 | ||||
-rw-r--r-- | include/lldb/Symbol/ClangExternalASTSourceCallbacks.h | 76 | ||||
-rw-r--r-- | include/lldb/Symbol/CompileUnit.h | 25 | ||||
-rw-r--r-- | include/lldb/Symbol/DWARFCallFrameInfo.h | 10 | ||||
-rw-r--r-- | include/lldb/Symbol/FuncUnwinders.h | 4 | ||||
-rw-r--r-- | include/lldb/Symbol/ObjectFile.h | 7 | ||||
-rw-r--r-- | include/lldb/Symbol/Symbol.h | 88 | ||||
-rw-r--r-- | include/lldb/Symbol/SymbolContext.h | 29 | ||||
-rw-r--r-- | include/lldb/Symbol/SymbolFile.h | 1 | ||||
-rw-r--r-- | include/lldb/Symbol/SymbolVendor.h | 7 | ||||
-rw-r--r-- | include/lldb/Symbol/Symtab.h | 8 | ||||
-rw-r--r-- | include/lldb/Symbol/Type.h | 12 | ||||
-rw-r--r-- | include/lldb/Symbol/UnwindPlan.h | 248 | ||||
-rw-r--r-- | include/lldb/Symbol/Variable.h | 2 |
15 files changed, 399 insertions, 124 deletions
diff --git a/include/lldb/Symbol/ClangASTContext.h b/include/lldb/Symbol/ClangASTContext.h index a9096fe66151..a411e42fe0c5 100644 --- a/include/lldb/Symbol/ClangASTContext.h +++ b/include/lldb/Symbol/ClangASTContext.h @@ -235,7 +235,7 @@ public: clang::IdentifierInfo &myIdent = ast->Idents.get(type_name.GetCString()); clang::DeclarationName myName = ast->DeclarationNames.getIdentifier(&myIdent); - clang::DeclContext::lookup_const_result result = ast->getTranslationUnitDecl()->lookup(myName); + clang::DeclContext::lookup_result result = ast->getTranslationUnitDecl()->lookup(myName); if (!result.empty()) { diff --git a/include/lldb/Symbol/ClangASTType.h b/include/lldb/Symbol/ClangASTType.h index 94c768780a00..2524751e092e 100644 --- a/include/lldb/Symbol/ClangASTType.h +++ b/include/lldb/Symbol/ClangASTType.h @@ -351,10 +351,10 @@ public: //---------------------------------------------------------------------- uint64_t - GetByteSize (ExecutionContext *exe_ctx) const; + GetByteSize (ExecutionContextScope *exe_scope) const; uint64_t - GetBitSize (ExecutionContext *exe_ctx) const; + GetBitSize (ExecutionContextScope *exe_scope) const; lldb::Encoding GetEncoding (uint64_t &count) const; diff --git a/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h b/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h index 0c8121135ef0..41bb235636f0 100644 --- a/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h +++ b/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h @@ -34,13 +34,11 @@ public: typedef void (*CompleteTagDeclCallback)(void *baton, clang::TagDecl *); typedef void (*CompleteObjCInterfaceDeclCallback)(void *baton, clang::ObjCInterfaceDecl *); typedef void (*FindExternalVisibleDeclsByNameCallback)(void *baton, const clang::DeclContext *DC, clang::DeclarationName Name, llvm::SmallVectorImpl <clang::NamedDecl *> *results); - typedef bool (*LayoutRecordTypeCallback)(void *baton, - 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); + typedef bool (*LayoutRecordTypeCallback)( + void *baton, 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); ClangExternalASTSourceCallbacks (CompleteTagDeclCallback tag_decl_callback, CompleteObjCInterfaceDeclCallback objc_decl_callback, @@ -59,39 +57,39 @@ public: // clang::ExternalASTSource //------------------------------------------------------------------ - virtual clang::Decl * - GetExternalDecl (uint32_t ID) + clang::Decl * + GetExternalDecl(uint32_t ID) override { // This method only needs to be implemented if the AST source ever // passes back decl sets as VisibleDeclaration objects. return 0; } - - virtual clang::Stmt * - GetExternalDeclStmt (uint64_t Offset) + + clang::Stmt * + GetExternalDeclStmt(uint64_t Offset) override { // This operation is meant to be used via a LazyOffsetPtr. It only // needs to be implemented if the AST source uses methods like // FunctionDecl::setLazyBody when building decls. return 0; } - - virtual clang::Selector - GetExternalSelector (uint32_t ID) + + clang::Selector + GetExternalSelector(uint32_t ID) override { // This operation only needs to be implemented if the AST source // returns non-zero for GetNumKnownSelectors(). return clang::Selector(); } - virtual uint32_t - GetNumExternalSelectors() + uint32_t + GetNumExternalSelectors() override { return 0; } - - virtual clang::CXXBaseSpecifier * - GetExternalCXXBaseSpecifiers(uint64_t Offset) + + clang::CXXBaseSpecifier * + GetExternalCXXBaseSpecifiers(uint64_t Offset) override { return NULL; } @@ -101,34 +99,26 @@ public: { return; } - - virtual clang::ExternalLoadResult - FindExternalLexicalDecls (const clang::DeclContext *decl_ctx, - bool (*isKindWeWant)(clang::Decl::Kind), - llvm::SmallVectorImpl<clang::Decl*> &decls) + + clang::ExternalLoadResult + FindExternalLexicalDecls(const clang::DeclContext *decl_ctx, bool (*isKindWeWant)(clang::Decl::Kind), + llvm::SmallVectorImpl<clang::Decl *> &decls) override { // This is used to support iterating through an entire lexical context, // which isn't something the debugger should ever need to do. return clang::ELR_Failure; } - - virtual bool - FindExternalVisibleDeclsByName (const clang::DeclContext *decl_ctx, - clang::DeclarationName decl_name); - - virtual void - CompleteType (clang::TagDecl *tag_decl); - - virtual void - CompleteType (clang::ObjCInterfaceDecl *objc_decl); - - bool - 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 FindExternalVisibleDeclsByName(const clang::DeclContext *decl_ctx, clang::DeclarationName decl_name) override; + + void CompleteType(clang::TagDecl *tag_decl) override; + + void CompleteType(clang::ObjCInterfaceDecl *objc_decl) override; + + bool 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) override; void SetExternalSourceCallbacks (CompleteTagDeclCallback tag_decl_callback, CompleteObjCInterfaceDeclCallback objc_decl_callback, diff --git a/include/lldb/Symbol/CompileUnit.h b/include/lldb/Symbol/CompileUnit.h index f9238ebba18c..e0c069352bf4 100644 --- a/include/lldb/Symbol/CompileUnit.h +++ b/include/lldb/Symbol/CompileUnit.h @@ -256,6 +256,18 @@ public: //------------------------------------------------------------------ FileSpecList& GetSupportFiles (); + + //------------------------------------------------------------------ + /// Get the compile unit's imported module list. + /// + /// This reports all the imports that the compile unit made, + /// including the current module. + /// + /// @return + /// A list of imported module names. + //------------------------------------------------------------------ + const std::vector<ConstString> & + GetImportedModules (); //------------------------------------------------------------------ /// Get the SymbolFile plug-in user data. @@ -400,6 +412,8 @@ protected: Flags m_flags; ///< Compile unit flags that help with partial parsing. std::vector<lldb::FunctionSP> m_functions; ///< The sparsely populated list of shared pointers to functions ///< that gets populated as functions get partially parsed. + std::vector<ConstString> m_imported_modules; ///< All modules, including the current module, imported by this + ///< compile unit. FileSpecList m_support_files; ///< Files associated with this compile unit's line table and declarations. std::unique_ptr<LineTable> m_line_table_ap; ///< Line table that will get parsed on demand. lldb::VariableListSP m_variables; ///< Global and static variable list that will get parsed on demand. @@ -407,11 +421,12 @@ protected: private: enum { - flagsParsedAllFunctions = (1u << 0), ///< Have we already parsed all our functions - flagsParsedVariables = (1u << 1), ///< Have we already parsed globals and statics? - flagsParsedSupportFiles = (1u << 2), ///< Have we already parsed the support files for this compile unit? - flagsParsedLineTable = (1u << 3), ///< Have we parsed the line table already? - flagsParsedLanguage = (1u << 4) ///< Have we parsed the line table already? + flagsParsedAllFunctions = (1u << 0), ///< Have we already parsed all our functions + flagsParsedVariables = (1u << 1), ///< Have we already parsed globals and statics? + flagsParsedSupportFiles = (1u << 2), ///< Have we already parsed the support files for this compile unit? + flagsParsedLineTable = (1u << 3), ///< Have we parsed the line table already? + flagsParsedLanguage = (1u << 4), ///< Have we parsed the line table already? + flagsParsedImportedModules = (1u << 5) ///< Have we parsed the imported modules already? }; DISALLOW_COPY_AND_ASSIGN (CompileUnit); diff --git a/include/lldb/Symbol/DWARFCallFrameInfo.h b/include/lldb/Symbol/DWARFCallFrameInfo.h index 27d1a52b49f8..cc497c039a4e 100644 --- a/include/lldb/Symbol/DWARFCallFrameInfo.h +++ b/include/lldb/Symbol/DWARFCallFrameInfo.h @@ -131,6 +131,16 @@ private: void GetCFIData(); + // Applies the specified DWARF opcode to the given row. This function handle the commands + // operates only on a single row (these are the ones what can appear both in CIE and in FDE). + // Returns true if the opcode is handled and false otherwise. + bool + HandleCommonDwarfOpcode(uint8_t primary_opcode, + uint8_t extended_opcode, + int32_t data_align, + lldb::offset_t& offset, + UnwindPlan::Row& row); + ObjectFile& m_objfile; lldb::SectionSP m_section_sp; lldb::RegisterKind m_reg_kind; diff --git a/include/lldb/Symbol/FuncUnwinders.h b/include/lldb/Symbol/FuncUnwinders.h index 1e579c42acb8..0d4aabb5fd57 100644 --- a/include/lldb/Symbol/FuncUnwinders.h +++ b/include/lldb/Symbol/FuncUnwinders.h @@ -50,7 +50,7 @@ public: GetUnwindPlanAtNonCallSite (Target& target, lldb_private::Thread& thread, int current_offset); lldb::UnwindPlanSP - GetUnwindPlanFastUnwind (lldb_private::Thread& Thread); + GetUnwindPlanFastUnwind (Target& target, lldb_private::Thread& thread); lldb::UnwindPlanSP GetUnwindPlanArchitectureDefault (lldb_private::Thread& thread); @@ -111,7 +111,7 @@ public: private: lldb::UnwindAssemblySP - GetUnwindAssemblyProfiler (); + GetUnwindAssemblyProfiler (Target& target); UnwindTable& m_unwind_table; AddressRange m_range; diff --git a/include/lldb/Symbol/ObjectFile.h b/include/lldb/Symbol/ObjectFile.h index 8bcf92de42e5..ff00ac26e67e 100644 --- a/include/lldb/Symbol/ObjectFile.h +++ b/include/lldb/Symbol/ObjectFile.h @@ -836,6 +836,13 @@ public: { return m_memory_addr != LLDB_INVALID_ADDRESS; } + + // Strip linker annotations (such as @@VERSION) from symbol names. + virtual std::string + StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const + { + return symbol_name.str(); + } protected: //------------------------------------------------------------------ diff --git a/include/lldb/Symbol/Symbol.h b/include/lldb/Symbol/Symbol.h index 0dd04b7112bc..ad11563634ea 100644 --- a/include/lldb/Symbol/Symbol.h +++ b/include/lldb/Symbol/Symbol.h @@ -39,11 +39,11 @@ public: lldb::addr_t value, lldb::addr_t size, bool size_is_valid, + bool contains_linker_annotations, uint32_t flags); Symbol (uint32_t symID, - const char *name, - bool name_is_mangled, + const Mangled &mangled, lldb::SymbolType type, bool external, bool is_debug, @@ -51,6 +51,7 @@ public: bool is_artificial, const AddressRange &range, bool size_is_valid, + bool contains_linker_annotations, uint32_t flags); Symbol (const Symbol& rhs); @@ -71,25 +72,81 @@ public: ValueIsAddress() const; //------------------------------------------------------------------ - // Access the address value. Do NOT hand out the AddressRange as an - // object as the byte size of the address range may not be filled in - // and it should be accessed via GetByteSize(). + // The GetAddressRef() accessor functions should only be called if + // you previously call ValueIsAddress() otherwise you might get an + // reference to an Address object that contains an constant integer + // value in m_addr_range.m_base_addr.m_offset which could be + // incorrectly used to represent an absolute address since it has + // no section. //------------------------------------------------------------------ Address & - GetAddress() + GetAddressRef() + { + return m_addr_range.GetBaseAddress(); + } + + const Address & + GetAddressRef() const { return m_addr_range.GetBaseAddress(); } //------------------------------------------------------------------ + // Makes sure the symbol's value is an address and returns the file + // address. Returns LLDB_INVALID_ADDRESS if the symbol's value isn't + // an address. + //------------------------------------------------------------------ + lldb::addr_t + GetFileAddress () const; + + //------------------------------------------------------------------ + // Makes sure the symbol's value is an address and gets the load + // address using \a target if it is. Returns LLDB_INVALID_ADDRESS + // if the symbol's value isn't an address or if the section isn't + // loaded in \a target. + //------------------------------------------------------------------ + lldb::addr_t + GetLoadAddress (Target *target) const; + + //------------------------------------------------------------------ // Access the address value. Do NOT hand out the AddressRange as an // object as the byte size of the address range may not be filled in // and it should be accessed via GetByteSize(). //------------------------------------------------------------------ - const Address & + Address GetAddress() const { - return m_addr_range.GetBaseAddress(); + // Make sure the our value is an address before we hand a copy out. + // We use the Address inside m_addr_range to contain the value for + // symbols that are not address based symbols so we are using it + // for more than just addresses. For example undefined symbols on + // MacOSX have a nlist.n_value of 0 (zero) and this will get placed + // into m_addr_range.m_base_addr.m_offset and it will have no section. + // So in the GetAddress() accessor, we need to hand out an invalid + // address if the symbol's value isn't an address. + if (ValueIsAddress()) + return m_addr_range.GetBaseAddress(); + else + return Address(); + } + + // When a symbol's value isn't an address, we need to access the raw + // value. This function will ensure this symbol's value isn't an address + // and return the integer value if this checks out, otherwise it will + // return "fail_value" if the symbol is an address value. + uint64_t + GetIntegerValue (uint64_t fail_value = 0) const + { + if (ValueIsAddress()) + { + // This symbol's value is an address. Use Symbol::GetAddress() to get the address. + return fail_value; + } + else + { + // The value is stored in the base address' offset + return m_addr_range.GetBaseAddress().GetOffset(); + } } lldb::addr_t @@ -131,7 +188,7 @@ public: FileSpec GetReExportedSymbolSharedLibrary () const; - bool + void SetReExportedSymbolName(const ConstString &name); bool @@ -272,6 +329,16 @@ public: m_demangled_is_synthesized = b; } + bool + ContainsLinkerAnnotations() const + { + return m_contains_linker_annotations; + } + void + SetContainsLinkerAnnotations(bool b) + { + m_contains_linker_annotations = b; + } //------------------------------------------------------------------ /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*) /// @@ -325,7 +392,8 @@ protected: m_size_is_synthesized:1,// non-zero if this symbol's size was calculated using a delta between this symbol and the next m_size_is_valid:1, m_demangled_is_synthesized:1, // The demangled name was created should not be used for expressions or other lookups - m_type:8; + m_contains_linker_annotations:1, // The symbol name contains linker annotations, which are optional when doing name lookups + m_type:7; Mangled m_mangled; // uniqued symbol name/mangled name pair AddressRange m_addr_range; // Contains the value, or the section offset address when the value is an address in a section, and the size (if any) uint32_t m_flags; // A copy of the flags from the original symbol table, the ObjectFile plug-in can interpret these diff --git a/include/lldb/Symbol/SymbolContext.h b/include/lldb/Symbol/SymbolContext.h index 64490627b84d..c48505e1064a 100644 --- a/include/lldb/Symbol/SymbolContext.h +++ b/include/lldb/Symbol/SymbolContext.h @@ -161,6 +161,32 @@ public: /// /// @param[in] so_addr /// The resolved section offset address. + /// + /// @param[in] show_fullpaths + /// When printing file paths (with the Module), whether the + /// base name of the Module should be printed or the full path. + /// + /// @param[in] show_module + /// Whether the module name should be printed followed by a + /// grave accent "`" character. + /// + /// @param[in] show_inlined_frames + /// If a given pc is in inlined function(s), whether the inlined + /// functions should be printed on separate lines in addition to + /// the concrete function containing the pc. + /// + /// @param[in] show_function_arguments + /// If false, this method will try to elide the function argument + /// types when printing the function name. This may be ambiguous + /// for languages that have function overloading - but it may + /// make the "function name" too long to include all the argument + /// types. + /// + /// @param[in] show_function_name + /// Normally this should be true - the function/symbol name should + /// be printed. In disassembly formatting, where we want a format + /// like "<*+36>", this should be false and "*" will be printed + /// instead. //------------------------------------------------------------------ bool DumpStopContext (Stream *s, @@ -169,7 +195,8 @@ public: bool show_fullpaths, bool show_module, bool show_inlined_frames, - bool show_function_arguments) const; + bool show_function_arguments, + bool show_function_name) const; //------------------------------------------------------------------ /// Get the address range contained within a symbol context. diff --git a/include/lldb/Symbol/SymbolFile.h b/include/lldb/Symbol/SymbolFile.h index 6df3d49fc464..0efe034235d5 100644 --- a/include/lldb/Symbol/SymbolFile.h +++ b/include/lldb/Symbol/SymbolFile.h @@ -124,6 +124,7 @@ public: virtual size_t ParseCompileUnitFunctions (const SymbolContext& sc) = 0; virtual bool ParseCompileUnitLineTable (const SymbolContext& sc) = 0; virtual bool ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files) = 0; + virtual bool ParseImportedModules (const SymbolContext &sc, std::vector<ConstString> &imported_modules) = 0; virtual size_t ParseFunctionBlocks (const SymbolContext& sc) = 0; virtual size_t ParseTypes (const SymbolContext& sc) = 0; virtual size_t ParseVariablesForContext (const SymbolContext& sc) = 0; diff --git a/include/lldb/Symbol/SymbolVendor.h b/include/lldb/Symbol/SymbolVendor.h index 82f902d4e07b..248918af2833 100644 --- a/include/lldb/Symbol/SymbolVendor.h +++ b/include/lldb/Symbol/SymbolVendor.h @@ -66,6 +66,10 @@ public: virtual bool ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files); + + virtual bool + ParseImportedModules (const SymbolContext &sc, + std::vector<ConstString> &imported_modules); virtual size_t ParseFunctionBlocks (const SymbolContext& sc); @@ -164,6 +168,9 @@ public: return m_sym_file_ap.get(); } + FileSpec + GetMainFileSpec() const; + // Get module unified section list symbol table. virtual Symtab * GetSymtab (); diff --git a/include/lldb/Symbol/Symtab.h b/include/lldb/Symbol/Symtab.h index dc08333e22fb..cf28c7e87ac5 100644 --- a/include/lldb/Symbol/Symtab.h +++ b/include/lldb/Symbol/Symtab.h @@ -58,6 +58,14 @@ public: Symbol * SymbolAtIndex (size_t idx); const Symbol * SymbolAtIndex (size_t idx) const; Symbol * FindSymbolWithType (lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, uint32_t &start_idx); + //---------------------------------------------------------------------- + /// Get the parent symbol for the given symbol. + /// + /// Many symbols in symbol tables are scoped by other symbols that + /// contain one or more symbol. This function will look for such a + /// containing symbol and return it if there is one. + //---------------------------------------------------------------------- + const Symbol * GetParent (Symbol *symbol) const; uint32_t AppendSymbolIndexesWithType (lldb::SymbolType symbol_type, std::vector<uint32_t>& indexes, uint32_t start_idx = 0, uint32_t end_index = UINT32_MAX) const; uint32_t AppendSymbolIndexesWithTypeAndFlagsValue (lldb::SymbolType symbol_type, uint32_t flags_value, std::vector<uint32_t>& indexes, uint32_t start_idx = 0, uint32_t end_index = UINT32_MAX) const; uint32_t AppendSymbolIndexesWithType (lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& matches, uint32_t start_idx = 0, uint32_t end_index = UINT32_MAX) const; diff --git a/include/lldb/Symbol/Type.h b/include/lldb/Symbol/Type.h index 51bd3dd82c92..c1784cb364a8 100644 --- a/include/lldb/Symbol/Type.h +++ b/include/lldb/Symbol/Type.h @@ -71,7 +71,12 @@ public: eEncodingIsSyntheticUID } EncodingDataType; - typedef enum ResolveStateTag + // We must force the underlying type of the enum to be unsigned here. Not all compilers + // behave the same with regards to the default underlying type of an enum, but because + // this enum is used in an enum bitfield and integer comparisons are done with the value + // we need to guarantee that it's always unsigned so that, for example, eResolveStateFull + // doesn't compare less than eResolveStateUnresolved when used in a 2-bit bitfield. + typedef enum ResolveStateTag : unsigned { eResolveStateUnresolved = 0, eResolveStateForward = 1, @@ -300,7 +305,12 @@ protected: ClangASTType m_clang_type; struct Flags { +#ifdef __GNUC__ + // using unsigned type here to work around a very noisy gcc warning + unsigned clang_type_resolve_state : 2; +#else ResolveState clang_type_resolve_state : 2; +#endif bool is_complete_objc_class : 1; } m_flags; diff --git a/include/lldb/Symbol/UnwindPlan.h b/include/lldb/Symbol/UnwindPlan.h index c482739cb8f6..bfc008a5b6bc 100644 --- a/include/lldb/Symbol/UnwindPlan.h +++ b/include/lldb/Symbol/UnwindPlan.h @@ -237,17 +237,178 @@ public: } m_location; }; + class CFAValue + { + public: + + enum ValueType + { + unspecified, // not specified + isRegisterPlusOffset, // CFA = register + offset + isRegisterDereferenced, // CFA = [reg] + isDWARFExpression // CFA = eval(dwarf_expr) + }; + + CFAValue() : + m_type(unspecified), + m_value() + { + } + + bool + operator == (const CFAValue& rhs) const; + + bool + operator != (const CFAValue &rhs) const + { + return !(*this == rhs); + } + + void + SetUnspecified() + { + m_type = unspecified; + } + + bool + IsUnspecified () const + { + return m_type == unspecified; + } + + bool + IsRegisterPlusOffset () const + { + return m_type == isRegisterPlusOffset; + } + + void + SetIsRegisterPlusOffset (uint32_t reg_num, int32_t offset) + { + m_type = isRegisterPlusOffset; + m_value.reg.reg_num = reg_num; + m_value.reg.offset = offset; + } + + bool + IsRegisterDereferenced () const + { + return m_type == isRegisterDereferenced; + } + + void + SetIsRegisterDereferenced (uint32_t reg_num) + { + m_type = isRegisterDereferenced; + m_value.reg.reg_num = reg_num; + } + + bool + IsDWARFExpression () const + { + return m_type == isDWARFExpression; + } + + void + SetIsDWARFExpression (const uint8_t *opcodes, uint32_t len) + { + m_type = isDWARFExpression; + m_value.expr.opcodes = opcodes; + m_value.expr.length = len; + } + + uint32_t + GetRegisterNumber () const + { + if (m_type == isRegisterDereferenced || m_type == isRegisterPlusOffset) + return m_value.reg.reg_num; + return LLDB_INVALID_REGNUM; + } + + ValueType + GetValueType () const + { + return m_type; + } + + int32_t + GetOffset () const + { + if (m_type == isRegisterPlusOffset) + return m_value.reg.offset; + return 0; + } + + void IncOffset (int32_t delta) + { + if (m_type == isRegisterPlusOffset) + m_value.reg.offset += delta; + } + + void SetOffset (int32_t offset) + { + if (m_type == isRegisterPlusOffset) + m_value.reg.offset = offset; + } + + void + GetDWARFExpr (const uint8_t **opcodes, uint16_t& len) const + { + if (m_type == isDWARFExpression) + { + *opcodes = m_value.expr.opcodes; + len = m_value.expr.length; + } + else + { + *opcodes = NULL; + len = 0; + } + } + + const uint8_t * + GetDWARFExpressionBytes () + { + if (m_type == isDWARFExpression) + return m_value.expr.opcodes; + return NULL; + } + + int + GetDWARFExpressionLength () + { + if (m_type == isDWARFExpression) + return m_value.expr.length; + return 0; + } + + void + Dump (Stream &s, + const UnwindPlan* unwind_plan, + Thread* thread) const; + + private: + ValueType m_type; // How do we compute CFA value? + union + { + struct { + // For m_type == isRegisterPlusOffset or m_type == isRegisterDereferenced + uint32_t reg_num; // The register number + // For m_type == isRegisterPlusOffset + int32_t offset; + } reg; + // For m_type == isDWARFExpression + struct { + const uint8_t *opcodes; + uint16_t length; + } expr; + } m_value; + }; // class CFAValue + public: Row (); - - Row (const UnwindPlan::Row& rhs) : - m_offset (rhs.m_offset), - m_cfa_type (rhs.m_cfa_type), - m_cfa_reg_num (rhs.m_cfa_reg_num), - m_cfa_offset (rhs.m_cfa_offset), - m_register_locations (rhs.m_register_locations) - { - } + + Row (const UnwindPlan::Row& rhs) = default; bool operator == (const Row &rhs) const; @@ -279,47 +440,9 @@ public: m_offset += offset; } - // How we can reconstruct the CFA address for this stack frame, at this location - enum CFAType - { - CFAIsRegisterPlusOffset, // the CFA value in a register plus (or minus) an offset - CFAIsRegisterDereferenced // the address in a register is dereferenced to get CFA value - }; - - CFAType - GetCFAType () const - { - return m_cfa_type; - } - - void - SetCFAType (CFAType cfa_type) + CFAValue& GetCFAValue() { - m_cfa_type = cfa_type; - } - - // If GetCFAType() is CFAIsRegisterPlusOffset, add GetCFAOffset to the reg value to get CFA value - // If GetCFAType() is CFAIsRegisterDereferenced, dereference the addr in the reg to get CFA value - uint32_t - GetCFARegister () const - { - return m_cfa_reg_num; - } - - void - SetCFARegister (uint32_t reg_num); - - // This should not be used when GetCFAType() is CFAIsRegisterDereferenced; will return 0 in that case. - int32_t - GetCFAOffset () const - { - return m_cfa_offset; - } - - void - SetCFAOffset (int32_t offset) - { - m_cfa_offset = offset; + return m_cfa_value; } bool @@ -360,14 +483,7 @@ public: typedef std::map<uint32_t, RegisterLocation> collection; lldb::addr_t m_offset; // Offset into the function for this row - CFAType m_cfa_type; - - // If m_cfa_type == CFAIsRegisterPlusOffset, the CFA address is computed as m_cfa_reg_num + m_cfa_offset - // If m_cfa_type == CFAIsRegisterDereferenced, the CFA address is computed as *(m_cfa_reg_num) - i.e. the - // address in m_cfa_reg_num is dereferenced and the pointer value read is the CFA addr. - uint32_t m_cfa_reg_num; // The Call Frame Address register number - int32_t m_cfa_offset; // The offset from the CFA for this row - + CFAValue m_cfa_value; collection m_register_locations; }; // class Row @@ -388,6 +504,22 @@ public: { } + // Performs a deep copy of the plan, including all the rows (expensive). + UnwindPlan (const UnwindPlan &rhs) : + m_plan_valid_address_range (rhs.m_plan_valid_address_range), + m_register_kind (rhs.m_register_kind), + m_return_addr_register (rhs.m_return_addr_register), + m_source_name (rhs.m_source_name), + m_plan_is_sourced_from_compiler (rhs.m_plan_is_sourced_from_compiler), + m_plan_is_valid_at_all_instruction_locations (rhs.m_plan_is_valid_at_all_instruction_locations), + m_lsda_address (rhs.m_lsda_address), + m_personality_func_addr (rhs.m_personality_func_addr) + { + m_row_list.reserve (rhs.m_row_list.size()); + for (const RowSP &row_sp: rhs.m_row_list) + m_row_list.emplace_back (new Row (*row_sp)); + } + ~UnwindPlan () { } @@ -437,7 +569,7 @@ public: { if (m_row_list.empty()) return LLDB_INVALID_REGNUM; - return m_row_list.front()->GetCFARegister(); + return m_row_list.front()->GetCFAValue().GetRegisterNumber(); } // This UnwindPlan may not be valid at every address of the function span. diff --git a/include/lldb/Symbol/Variable.h b/include/lldb/Symbol/Variable.h index 07295d090ee6..a345bcb8c23a 100644 --- a/include/lldb/Symbol/Variable.h +++ b/include/lldb/Symbol/Variable.h @@ -29,7 +29,7 @@ public: //------------------------------------------------------------------ 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, lldb::ValueType scope, SymbolContextScope *owner_scope, |