Author: spyffe Date: Tue Sep 26 10:25:34 2017 New Revision: 314225 URL: http://llvm.org/viewvc/llvm-project?rev=314225&view=rev Log: [Expression Parser] Inhibit global lookups for symbols in the IR dynamic checks
The IR dynamic checks are self-contained functions whose job is to - verify that pointers referenced in an expression are valid at runtime; and - verify that selectors sent to Objective-C objects by an expression are actually supported by that object. These dynamic checks forward-declare all the functions they use and should not require any external debug information. The way they ensure this is by marking all the names they use with a dollar sign ($). The expression parser recognizes such symbols and perform no lookups for them. This patch fixes three issues surrounding the use of the dollar sign: - to fix a MIPS issue, the name of the pointer checker was changed from starting with $ to starting with _$, but this was not properly ignored; and - the Objective-C object checker used a temporary variable that did not start with $. - the Objective-C object checker used an externally-defined struct (struct objc_selector) but didn't need to. The patch also implements some cleanup in the area: - it reformats the string containing the Objective-C object checker, which was mangled horribly when the code was transformed to a uniform width of 80 columns, and - it factors out the logic for ignoring global $-symbols into common code shared between ClangASTSource and ClangExpressionDeclMap. Differential Revision: https://reviews.llvm.org/D38153 Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.h lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp?rev=314225&r1=314224&r2=314225&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp (original) +++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp Tue Sep 26 10:25:34 2017 @@ -623,6 +623,25 @@ void ClangASTSource::FindExternalVisible } } +bool ClangASTSource::IgnoreName(const ConstString name, + bool ignore_all_dollar_names) { + static const ConstString id_name("id"); + static const ConstString Class_name("Class"); + + if (name == id_name || name == Class_name) + return true; + + StringRef name_string_ref = name.GetStringRef(); + + // The ClangASTSource is not responsible for finding $-names. + if (name_string_ref.empty() || + (ignore_all_dollar_names && name_string_ref.startswith("$")) || + name_string_ref.startswith("_$")) + return true; + + return false; +} + void ClangASTSource::FindExternalVisibleDecls( NameSearchContext &context, lldb::ModuleSP module_sp, CompilerDeclContext &namespace_decl, unsigned int current_id) { @@ -633,20 +652,7 @@ void ClangASTSource::FindExternalVisible SymbolContextList sc_list; const ConstString name(context.m_decl_name.getAsString().c_str()); - - const char *name_unique_cstr = name.GetCString(); - - static ConstString id_name("id"); - static ConstString Class_name("Class"); - - if (name == id_name || name == Class_name) - return; - - if (name_unique_cstr == NULL) - return; - - // The ClangASTSource is not responsible for finding $-names. - if (name_unique_cstr[0] == '$') + if (IgnoreName(name, true)) return; if (module_sp && namespace_decl) { Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.h?rev=314225&r1=314224&r2=314225&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.h (original) +++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.h Tue Sep 26 10:25:34 2017 @@ -376,6 +376,22 @@ protected: //------------------------------------------------------------------ CompilerType GuardedCopyType(const CompilerType &src_type); + + //------------------------------------------------------------------ + /// Returns true if a name should be ignored by name lookup. + /// + /// @param[in] name + /// The name to be considered. + /// + /// @param[in] ignore_all_dollar_nmmes + /// True if $-names of all sorts should be ignored. + /// + /// @return + /// True if the name is one of a class of names that are ignored by + /// global lookup for performance reasons. + //------------------------------------------------------------------ + bool IgnoreName(const ConstString name, bool ignore_all_dollar_names); + friend struct NameSearchContext; bool m_import_in_progress; Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp?rev=314225&r1=314224&r2=314225&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp (original) +++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp Tue Sep 26 10:25:34 2017 @@ -739,16 +739,7 @@ void ClangExpressionDeclMap::FindExterna SymbolContextList sc_list; const ConstString name(context.m_decl_name.getAsString().c_str()); - - const char *name_unique_cstr = name.GetCString(); - - if (name_unique_cstr == NULL) - return; - - static ConstString id_name("id"); - static ConstString Class_name("Class"); - - if (name == id_name || name == Class_name) + if (IgnoreName(name, false)) return; // Only look for functions by name out in our symbols if the function @@ -809,7 +800,7 @@ void ClangExpressionDeclMap::FindExterna } while (0); } - if (name_unique_cstr[0] == '$' && !namespace_decl) { + if (name.GetCString()[0] == '$' && !namespace_decl) { static ConstString g_lldb_class_name("$__lldb_class"); if (name == g_lldb_class_name) { @@ -1041,7 +1032,7 @@ void ClangExpressionDeclMap::FindExterna if (ast) { clang::NamespaceDecl *namespace_decl = ClangASTContext::GetUniqueNamespaceDeclaration( - m_ast_context, name_unique_cstr, nullptr); + m_ast_context, name.GetCString(), nullptr); if (namespace_decl) { context.AddNamedDecl(namespace_decl); clang::DeclContext *clang_decl_ctx = @@ -1056,7 +1047,7 @@ void ClangExpressionDeclMap::FindExterna } // any other $__lldb names should be weeded out now - if (!::strncmp(name_unique_cstr, "$__lldb", sizeof("$__lldb") - 1)) + if (name.GetStringRef().startswith("$__lldb")) return; ExpressionVariableSP pvar_sp( Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp?rev=314225&r1=314224&r2=314225&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp Tue Sep 26 10:25:34 2017 @@ -811,85 +811,43 @@ UtilityFunction *AppleObjCRuntimeV2::Cre int len = 0; if (m_has_object_getClass) { - len = ::snprintf(check_function_code, sizeof(check_function_code), - "extern \"C\" void *gdb_object_getClass(void *); " - " \n" - "extern \"C\" int printf(const char *format, ...); " - " \n" - "extern \"C\" void " - " \n" - "%s(void *$__lldb_arg_obj, void *$__lldb_arg_selector) " - " \n" - "{ " - " \n" - " if ($__lldb_arg_obj == (void *)0) " - " \n" - " return; // nil is ok " - " \n" - " if (!gdb_object_getClass($__lldb_arg_obj)) " - " \n" - " *((volatile int *)0) = 'ocgc'; " - " \n" - " else if ($__lldb_arg_selector != (void *)0) " - " \n" - " { " - " \n" - " signed char responds = (signed char) [(id) " - "$__lldb_arg_obj \n" - " " - "respondsToSelector: \n" - " (struct " - "objc_selector *) $__lldb_arg_selector]; \n" - " if (responds == (signed char) 0) " - " \n" - " *((volatile int *)0) = 'ocgc'; " - " \n" - " } " - " \n" - "} " - " \n", - name); + len = ::snprintf(check_function_code, sizeof(check_function_code), R"( + extern "C" void *gdb_object_getClass(void *); + extern "C" int printf(const char *format, ...); + extern "C" void + %s(void *$__lldb_arg_obj, void *$__lldb_arg_selector) { + if ($__lldb_arg_obj == (void *)0) + return; // nil is ok + if (!gdb_object_getClass($__lldb_arg_obj)) { + *((volatile int *)0) = 'ocgc'; + } else if ($__lldb_arg_selector != (void *)0) { + signed char $responds = (signed char) + [(id)$__lldb_arg_obj respondsToSelector: + (void *) $__lldb_arg_selector]; + if ($responds == (signed char) 0) + *((volatile int *)0) = 'ocgc'; + } + })", name); } else { - len = ::snprintf(check_function_code, sizeof(check_function_code), - "extern \"C\" void *gdb_class_getClass(void *); " - " \n" - "extern \"C\" int printf(const char *format, ...); " - " \n" - "extern \"C\" void " - " \n" - "%s(void *$__lldb_arg_obj, void *$__lldb_arg_selector) " - " \n" - "{ " - " \n" - " if ($__lldb_arg_obj == (void *)0) " - " \n" - " return; // nil is ok " - " \n" - " void **$isa_ptr = (void **)$__lldb_arg_obj; " - " \n" - " if (*$isa_ptr == (void *)0 || " - "!gdb_class_getClass(*$isa_ptr)) \n" - " *((volatile int *)0) = 'ocgc'; " - " \n" - " else if ($__lldb_arg_selector != (void *)0) " - " \n" - " { " - " \n" - " signed char responds = (signed char) [(id) " - "$__lldb_arg_obj \n" - " " - "respondsToSelector: \n" - " (struct " - "objc_selector *) $__lldb_arg_selector]; \n" - " if (responds == (signed char) 0) " - " \n" - " *((volatile int *)0) = 'ocgc'; " - " \n" - " } " - " \n" - "} " - " \n", - name); + len = ::snprintf(check_function_code, sizeof(check_function_code), R"( + extern "C" void *gdb_class_getClass(void *); + extern "C" int printf(const char *format, ...); + extern "C" void + %s(void *$__lldb_arg_obj, void *$__lldb_arg_selector) { + if ($__lldb_arg_obj == (void *)0) + return; // nil is ok + void **$isa_ptr = (void **)$__lldb_arg_obj; + if (*$isa_ptr == (void *)0 || + !gdb_class_getClass(*$isa_ptr)) + *((volatile int *)0) = 'ocgc'; + else if ($__lldb_arg_selector != (void *)0) { + signed char $responds = (signed char) + [(id)$__lldb_arg_obj respondsToSelector: + (void *) $__lldb_arg_selector]; + if ($responds == (signed char) 0) + *((volatile int *)0) = 'ocgc'; + } + })", name); } assert(len < (int)sizeof(check_function_code)); _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits