[Lldb-commits] [lldb] r303223 - [Expression parser] Look up module symbols before hunting globally

Sean Callanan via lldb-commits lldb-commits at lists.llvm.org
Tue May 16 16:46:13 PDT 2017


Author: spyffe
Date: Tue May 16 18:46:13 2017
New Revision: 303223

URL: http://llvm.org/viewvc/llvm-project?rev=303223&view=rev
Log:
[Expression parser] Look up module symbols before hunting globally

When it resolves symbol-only variables, the expression parser
currently looks only in the global module list. It should prefer
the current module.

I've fixed that behavior by making it search the current module
first, and only search globally if it finds nothing. I've also
added a test case.

After review, I moved the core of the lookup algorithm into
SymbolContext for use by other code that needs it.

Thanks to Greg Clayton and Pavel Labath for their help.

Differential Revision: https://reviews.llvm.org/D33083

Added:
    lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/
    lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/
    lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One.mk
    lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.c
    lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.h
    lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/OneConstant.c
    lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/TestConflictingSymbol.py
    lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/
    lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two.mk
    lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.c
    lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.h
    lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/TwoConstant.c
    lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/main.c
Modified:
    lldb/trunk/include/lldb/Symbol/SymbolContext.h
    lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
    lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
    lldb/trunk/source/Symbol/SymbolContext.cpp

Modified: lldb/trunk/include/lldb/Symbol/SymbolContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/SymbolContext.h?rev=303223&r1=303222&r2=303223&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/SymbolContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/SymbolContext.h Tue May 16 18:46:13 2017
@@ -235,6 +235,29 @@ public:
 
   bool GetAddressRangeFromHereToEndLine(uint32_t end_line, AddressRange &range,
                                         Status &error);
+  
+  //------------------------------------------------------------------
+  /// Find the best global data symbol visible from this context.
+  ///
+  /// Symbol priority is:
+  ///     - extern symbol in the current module if there is one
+  ///     - non-extern symbol in the current module if there is one
+  ///     - extern symbol in the target
+  ///     - non-extern symbol in the target
+  /// It is an error if the highest-priority result is ambiguous.
+  ///
+  /// @param[in] name
+  ///     The name of the symbol to search for.
+  ///
+  /// @param[out] error
+  ///     An error that will be populated with a message if there was an
+  ///     ambiguous result.  The error will not be populated if no result
+  ///     was found.
+  ///
+  /// @return
+  ///     The symbol that was found, or \b nullptr if none was found.
+  //------------------------------------------------------------------
+  const Symbol *FindBestGlobalDataSymbol(const ConstString &name, Status &error);
 
   void GetDescription(Stream *s, lldb::DescriptionLevel level,
                       Target *target) const;

Added: lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Makefile?rev=303223&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Makefile Tue May 16 18:46:13 2017
@@ -0,0 +1,18 @@
+LEVEL := ../../../make
+
+LD_EXTRAS := -L. -l$(LIB_PREFIX)One -l$(LIB_PREFIX)Two
+C_SOURCES := main.c
+
+main.o : CFLAGS_EXTRAS += -g -O0
+
+include $(LEVEL)/Makefile.rules
+
+.PHONY:
+a.out: lib_One lib_Two
+
+lib_%:
+	$(MAKE) -f $*.mk
+
+clean::
+	$(MAKE) -f One.mk clean
+	$(MAKE) -f Two.mk clean

Added: lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One.mk
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One.mk?rev=303223&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One.mk (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One.mk Tue May 16 18:46:13 2017
@@ -0,0 +1,12 @@
+LEVEL := ../../../make
+
+DYLIB_NAME := One
+DYLIB_C_SOURCES := One/One.c One/OneConstant.c
+DYLIB_ONLY := YES
+
+include $(LEVEL)/Makefile.rules
+
+CFLAGS_EXTRAS += -fPIC
+
+One/OneConstant.o: One/OneConstant.c
+	$(CC) $(CFLAGS_NO_DEBUG) -c $< -o $@

Added: lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.c?rev=303223&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.c (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.c Tue May 16 18:46:13 2017
@@ -0,0 +1,6 @@
+#include "One.h"
+#include <stdio.h>
+
+void one() {
+  printf("One\n"); // break here
+}

Added: lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.h?rev=303223&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.h (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.h Tue May 16 18:46:13 2017
@@ -0,0 +1,4 @@
+#ifndef ONE_H
+#define ONE_H
+void one();
+#endif

Added: lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/OneConstant.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/OneConstant.c?rev=303223&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/OneConstant.c (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/OneConstant.c Tue May 16 18:46:13 2017
@@ -0,0 +1 @@
+int __attribute__ ((visibility("hidden"))) conflicting_symbol = 11111;

Added: lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/TestConflictingSymbol.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/TestConflictingSymbol.py?rev=303223&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/TestConflictingSymbol.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/TestConflictingSymbol.py Tue May 16 18:46:13 2017
@@ -0,0 +1,86 @@
+"""Test that conflicting symbols in different shared libraries work correctly"""
+
+from __future__ import print_function
+
+
+import os
+import time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestConflictingSymbols(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+    NO_DEBUG_INFO_TESTCASE = True
+
+    @skipUnlessDarwin
+    def test_conflicting_symbols(self):
+        self.build()
+        self.common_setup()
+
+        One_line = line_number('One/One.c', '// break here')
+        Two_line = line_number('Two/Two.c', '// break here')
+        main_line = line_number('main.c', '// break here')
+        lldbutil.run_break_set_command(
+            self, 'breakpoint set -f One.c -l %s' % (One_line))
+        lldbutil.run_break_set_command(
+            self, 'breakpoint set -f Two.c -l %s' % (Two_line))
+        lldbutil.run_break_set_by_file_and_line(
+            self, 'main.c', main_line, num_expected_locations=1, loc_exact=True)
+
+        self.runCmd("run", RUN_SUCCEEDED)
+
+        # The stop reason of the thread should be breakpoint.
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+                    substrs=['stopped',
+                             'stop reason = breakpoint'])
+
+        self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
+                    substrs=[' resolved, hit count = 1'])
+
+        # This should display correctly.
+        self.expect(
+            "expr (unsigned long long)conflicting_symbol",
+            "Symbol from One should be found",
+            substrs=[
+                "11111"])
+
+        self.runCmd("continue", RUN_SUCCEEDED)
+
+        # The stop reason of the thread should be breakpoint.
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+                    substrs=['stopped',
+                             'stop reason = breakpoint'])
+
+        self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
+                    substrs=[' resolved, hit count = 1'])
+
+        self.expect(
+            "expr (unsigned long long)conflicting_symbol",
+            "Symbol from Two should be found",
+            substrs=[
+                "22222"])
+
+        self.runCmd("continue", RUN_SUCCEEDED)
+
+        # The stop reason of the thread should be breakpoint.
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+                    substrs=['stopped',
+                             'stop reason = breakpoint'])
+
+        self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
+                    substrs=[' resolved, hit count = 1'])
+
+        self.expect(
+            "expr (unsigned long long)conflicting_symbol",
+            "An error should be printed when symbols can't be ordered",
+            error=True,
+            substrs=[
+                "Multiple internal symbols"])
+
+    def common_setup(self):
+        exe = os.path.join(os.getcwd(), "a.out")
+        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)

Added: lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two.mk
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two.mk?rev=303223&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two.mk (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two.mk Tue May 16 18:46:13 2017
@@ -0,0 +1,12 @@
+LEVEL := ../../../make
+
+DYLIB_NAME := Two
+DYLIB_C_SOURCES := Two/Two.c Two/TwoConstant.c
+DYLIB_ONLY := YES
+
+include $(LEVEL)/Makefile.rules
+
+CFLAGS_EXTRAS += -fPIC
+
+Two/TwoConstant.o: Two/TwoConstant.c
+	$(CC) $(CFLAGS_NO_DEBUG) -c $< -o $@

Added: lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.c?rev=303223&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.c (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.c Tue May 16 18:46:13 2017
@@ -0,0 +1,6 @@
+#include "Two.h"
+#include <stdio.h>
+
+void two() {
+  printf("Two\n"); // break here
+}

Added: lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.h?rev=303223&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.h (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.h Tue May 16 18:46:13 2017
@@ -0,0 +1,4 @@
+#ifndef TWO_H
+#define TWO_H
+void two();
+#endif

Added: lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/TwoConstant.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/TwoConstant.c?rev=303223&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/TwoConstant.c (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/TwoConstant.c Tue May 16 18:46:13 2017
@@ -0,0 +1 @@
+int __attribute__ ((visibility("hidden"))) conflicting_symbol = 22222;

Added: lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/main.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/main.c?rev=303223&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/main.c (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/main.c Tue May 16 18:46:13 2017
@@ -0,0 +1,11 @@
+#include "One/One.h"
+#include "Two/Two.h"
+
+#include <stdio.h>
+
+int main() {
+  one();
+  two();
+  printf("main\n"); // break here
+  return(0); 
+}

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=303223&r1=303222&r2=303223&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp Tue May 16 18:46:13 2017
@@ -591,103 +591,6 @@ addr_t ClangExpressionDeclMap::GetSymbol
                           symbol_type);
 }
 
-const Symbol *ClangExpressionDeclMap::FindGlobalDataSymbol(
-    Target &target, const ConstString &name, lldb_private::Module *module) {
-  SymbolContextList sc_list;
-
-  if (module)
-    module->FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list);
-  else
-    target.GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny,
-                                                  sc_list);
-
-  const uint32_t matches = sc_list.GetSize();
-  for (uint32_t i = 0; i < matches; ++i) {
-    SymbolContext sym_ctx;
-    sc_list.GetContextAtIndex(i, sym_ctx);
-    if (sym_ctx.symbol) {
-      const Symbol *symbol = sym_ctx.symbol;
-      const Address sym_address = symbol->GetAddress();
-
-      if (sym_address.IsValid()) {
-        switch (symbol->GetType()) {
-        case eSymbolTypeData:
-        case eSymbolTypeRuntime:
-        case eSymbolTypeAbsolute:
-        case eSymbolTypeObjCClass:
-        case eSymbolTypeObjCMetaClass:
-        case eSymbolTypeObjCIVar:
-          if (symbol->GetDemangledNameIsSynthesized()) {
-            // If the demangled name was synthesized, then don't use it
-            // for expressions. Only let the symbol match if the mangled
-            // named matches for these symbols.
-            if (symbol->GetMangled().GetMangledName() != name)
-              break;
-          }
-          return symbol;
-
-        case eSymbolTypeReExported: {
-          ConstString reexport_name = symbol->GetReExportedSymbolName();
-          if (reexport_name) {
-            ModuleSP reexport_module_sp;
-            ModuleSpec reexport_module_spec;
-            reexport_module_spec.GetPlatformFileSpec() =
-                symbol->GetReExportedSymbolSharedLibrary();
-            if (reexport_module_spec.GetPlatformFileSpec()) {
-              reexport_module_sp =
-                  target.GetImages().FindFirstModule(reexport_module_spec);
-              if (!reexport_module_sp) {
-                reexport_module_spec.GetPlatformFileSpec()
-                    .GetDirectory()
-                    .Clear();
-                reexport_module_sp =
-                    target.GetImages().FindFirstModule(reexport_module_spec);
-              }
-            }
-            // Don't allow us to try and resolve a re-exported symbol if it is
-            // the same
-            // as the current symbol
-            if (name == symbol->GetReExportedSymbolName() &&
-                module == reexport_module_sp.get())
-              return NULL;
-
-            return FindGlobalDataSymbol(target,
-                                        symbol->GetReExportedSymbolName(),
-                                        reexport_module_sp.get());
-          }
-        } break;
-
-        case eSymbolTypeCode: // We already lookup functions elsewhere
-        case eSymbolTypeVariable:
-        case eSymbolTypeLocal:
-        case eSymbolTypeParam:
-        case eSymbolTypeTrampoline:
-        case eSymbolTypeInvalid:
-        case eSymbolTypeException:
-        case eSymbolTypeSourceFile:
-        case eSymbolTypeHeaderFile:
-        case eSymbolTypeObjectFile:
-        case eSymbolTypeCommonBlock:
-        case eSymbolTypeBlock:
-        case eSymbolTypeVariableType:
-        case eSymbolTypeLineEntry:
-        case eSymbolTypeLineHeader:
-        case eSymbolTypeScopeBegin:
-        case eSymbolTypeScopeEnd:
-        case eSymbolTypeAdditional:
-        case eSymbolTypeCompiler:
-        case eSymbolTypeInstrumentation:
-        case eSymbolTypeUndefined:
-        case eSymbolTypeResolver:
-          break;
-        }
-      }
-    }
-  }
-
-  return NULL;
-}
-
 lldb::VariableSP ClangExpressionDeclMap::FindGlobalVariable(
     Target &target, ModuleSP &module, const ConstString &name,
     CompilerDeclContext *namespace_decl, TypeFromUser *type) {
@@ -1526,9 +1429,18 @@ void ClangExpressionDeclMap::FindExterna
       // We couldn't find a non-symbol variable for this.  Now we'll hunt for
       // a generic
       // data symbol, and -- if it is found -- treat it as a variable.
-
-      const Symbol *data_symbol = FindGlobalDataSymbol(*target, name);
-
+      Status error;
+      
+      const Symbol *data_symbol =
+          m_parser_vars->m_sym_ctx.FindBestGlobalDataSymbol(name, error);
+      
+      if (!error.Success()) {
+        const unsigned diag_id =
+            m_ast_context->getDiagnostics().getCustomDiagID(
+                clang::DiagnosticsEngine::Level::Error, "%0");
+        m_ast_context->getDiagnostics().Report(diag_id) << error.AsCString();
+      }
+                                          
       if (data_symbol) {
         std::string warning("got name from symbols: ");
         warning.append(name.AsCString());

Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h?rev=303223&r1=303222&r2=303223&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h Tue May 16 18:46:13 2017
@@ -448,24 +448,6 @@ private:
   uint64_t GetParserID() { return (uint64_t) this; }
 
   //------------------------------------------------------------------
-  /// Given a target, find a data symbol that has the given name.
-  ///
-  /// @param[in] target
-  ///     The target to use as the basis for the search.
-  ///
-  /// @param[in] name
-  ///     The name as a plain C string.
-  ///
-  /// @param[in] module
-  ///     The module to limit the search to. This can be NULL
-  ///
-  /// @return
-  ///     The LLDB Symbol found, or NULL if none was found.
-  //------------------------------------------------------------------
-  const Symbol *FindGlobalDataSymbol(Target &target, const ConstString &name,
-                                     Module *module = NULL);
-
-  //------------------------------------------------------------------
   /// Given a target, find a variable that matches the given name and
   /// type.
   ///

Modified: lldb/trunk/source/Symbol/SymbolContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/SymbolContext.cpp?rev=303223&r1=303222&r2=303223&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/SymbolContext.cpp (original)
+++ lldb/trunk/source/Symbol/SymbolContext.cpp Tue May 16 18:46:13 2017
@@ -799,6 +799,163 @@ bool SymbolContext::GetAddressRangeFromH
   return true;
 }
 
+const Symbol *
+SymbolContext::FindBestGlobalDataSymbol(const ConstString &name, Status &error) {
+  error.Clear();
+  
+  if (!target_sp) {
+    return nullptr;
+  }
+  
+  Target &target = *target_sp;
+  Module *module = module_sp.get();
+  
+  auto ProcessMatches = [this, &name, &target, module]
+  (SymbolContextList &sc_list, Status &error) -> const Symbol* {
+    llvm::SmallVector<const Symbol *, 1> external_symbols;
+    llvm::SmallVector<const Symbol *, 1> internal_symbols;
+    const uint32_t matches = sc_list.GetSize();
+    for (uint32_t i = 0; i < matches; ++i) {
+      SymbolContext sym_ctx;
+      sc_list.GetContextAtIndex(i, sym_ctx);
+      if (sym_ctx.symbol) {
+        const Symbol *symbol = sym_ctx.symbol;
+        const Address sym_address = symbol->GetAddress();
+        
+        if (sym_address.IsValid()) {
+          switch (symbol->GetType()) {
+            case eSymbolTypeData:
+            case eSymbolTypeRuntime:
+            case eSymbolTypeAbsolute:
+            case eSymbolTypeObjCClass:
+            case eSymbolTypeObjCMetaClass:
+            case eSymbolTypeObjCIVar:
+              if (symbol->GetDemangledNameIsSynthesized()) {
+                // If the demangled name was synthesized, then don't use it
+                // for expressions. Only let the symbol match if the mangled
+                // named matches for these symbols.
+                if (symbol->GetMangled().GetMangledName() != name)
+                  break;
+              }
+              if (symbol->IsExternal()) {
+                external_symbols.push_back(symbol);
+              } else {
+                internal_symbols.push_back(symbol);
+              }
+              break;
+            case eSymbolTypeReExported: {
+              ConstString reexport_name = symbol->GetReExportedSymbolName();
+              if (reexport_name) {
+                ModuleSP reexport_module_sp;
+                ModuleSpec reexport_module_spec;
+                reexport_module_spec.GetPlatformFileSpec() =
+                symbol->GetReExportedSymbolSharedLibrary();
+                if (reexport_module_spec.GetPlatformFileSpec()) {
+                  reexport_module_sp =
+                  target.GetImages().FindFirstModule(reexport_module_spec);
+                  if (!reexport_module_sp) {
+                    reexport_module_spec.GetPlatformFileSpec()
+                    .GetDirectory()
+                    .Clear();
+                    reexport_module_sp =
+                    target.GetImages().FindFirstModule(reexport_module_spec);
+                  }
+                }
+                // Don't allow us to try and resolve a re-exported symbol if it is
+                // the same as the current symbol
+                if (name == symbol->GetReExportedSymbolName() &&
+                    module == reexport_module_sp.get())
+                  return nullptr;
+                
+                return FindBestGlobalDataSymbol(
+                    symbol->GetReExportedSymbolName(), error);
+              }
+            } break;
+              
+            case eSymbolTypeCode: // We already lookup functions elsewhere
+            case eSymbolTypeVariable:
+            case eSymbolTypeLocal:
+            case eSymbolTypeParam:
+            case eSymbolTypeTrampoline:
+            case eSymbolTypeInvalid:
+            case eSymbolTypeException:
+            case eSymbolTypeSourceFile:
+            case eSymbolTypeHeaderFile:
+            case eSymbolTypeObjectFile:
+            case eSymbolTypeCommonBlock:
+            case eSymbolTypeBlock:
+            case eSymbolTypeVariableType:
+            case eSymbolTypeLineEntry:
+            case eSymbolTypeLineHeader:
+            case eSymbolTypeScopeBegin:
+            case eSymbolTypeScopeEnd:
+            case eSymbolTypeAdditional:
+            case eSymbolTypeCompiler:
+            case eSymbolTypeInstrumentation:
+            case eSymbolTypeUndefined:
+            case eSymbolTypeResolver:
+              break;
+          }
+        }
+      }
+    }
+    
+    if (external_symbols.size() > 1) {
+      StreamString ss;
+      ss.Printf("Multiple external symbols found for '%s'\n", name.AsCString());
+      for (const Symbol *symbol : external_symbols) {
+        symbol->GetDescription(&ss, eDescriptionLevelFull, &target);
+      }
+      ss.PutChar('\n');
+      error.SetErrorString(ss.GetData());
+      return nullptr;
+    } else if (external_symbols.size()) {
+      return external_symbols[0];
+    } else if (internal_symbols.size() > 1) {
+      StreamString ss;
+      ss.Printf("Multiple internal symbols found for '%s'\n", name.AsCString());
+      for (const Symbol *symbol : internal_symbols) {
+        symbol->GetDescription(&ss, eDescriptionLevelVerbose, &target);
+        ss.PutChar('\n');
+      }
+      error.SetErrorString(ss.GetData());
+      return nullptr;
+    } else if (internal_symbols.size()) {
+      return internal_symbols[0];
+    } else {
+      return nullptr;
+    }
+  };
+  
+  if (module) {
+    SymbolContextList sc_list;
+    module->FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list);
+    const Symbol *const module_symbol = ProcessMatches(sc_list, error);
+    
+    if (!error.Success()) {
+      return nullptr;
+    } else if (module_symbol) {
+      return module_symbol;
+    }
+  }
+  
+  {
+    SymbolContextList sc_list;
+    target.GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny,
+                                                  sc_list);
+    const Symbol *const target_symbol = ProcessMatches(sc_list, error);
+    
+    if (!error.Success()) {
+      return nullptr;
+    } else if (target_symbol) {
+      return target_symbol;
+    }
+  }
+  
+  return nullptr; // no error; we just didn't find anything
+}
+
+
 //----------------------------------------------------------------------
 //
 //  SymbolContextSpecifier




More information about the lldb-commits mailing list