aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-05-17 20:23:22 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-05-17 20:23:22 +0000
commit5a5de6ea3962782b02221b96b27dd064b25d381f (patch)
tree6138b29ea914e803d8430f444a764b7d29f8df12
parentb76161e41bc2c07cd47f9c61f875d1be95e26d10 (diff)
downloadsrc-5a5de6ea3962782b02221b96b27dd064b25d381f.tar.gz
src-5a5de6ea3962782b02221b96b27dd064b25d381f.zip
Vendor import of lldb trunk r303291:vendor/lldb/lldb-trunk-r303291
Notes
Notes: svn path=/vendor/lldb/dist/; revision=318424 svn path=/vendor/lldb/lldb-trunk-r303291/; revision=318425; tag=vendor/lldb/lldb-trunk-r303291
-rw-r--r--include/lldb/Symbol/SymbolContext.h23
-rw-r--r--packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Makefile18
-rw-r--r--packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One.mk12
-rw-r--r--packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.c6
-rw-r--r--packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.h4
-rw-r--r--packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/OneConstant.c1
-rw-r--r--packages/Python/lldbsuite/test/lang/c/conflicting-symbol/TestConflictingSymbol.py90
-rw-r--r--packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two.mk12
-rw-r--r--packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.c6
-rw-r--r--packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.h4
-rw-r--r--packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/TwoConstant.c1
-rw-r--r--packages/Python/lldbsuite/test/lang/c/conflicting-symbol/main.c11
-rw-r--r--packages/Python/lldbsuite/test/lldbtest.py2
-rw-r--r--source/Breakpoint/Breakpoint.cpp4
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp112
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h18
-rw-r--r--source/Symbol/SymbolContext.cpp157
17 files changed, 360 insertions, 121 deletions
diff --git a/include/lldb/Symbol/SymbolContext.h b/include/lldb/Symbol/SymbolContext.h
index e4dcc73bb52b..f84b7cf916fe 100644
--- a/include/lldb/Symbol/SymbolContext.h
+++ b/include/lldb/Symbol/SymbolContext.h
@@ -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;
diff --git a/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Makefile b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Makefile
new file mode 100644
index 000000000000..f8a04bd32b90
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Makefile
@@ -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
diff --git a/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One.mk b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One.mk
new file mode 100644
index 000000000000..04f894c595e8
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One.mk
@@ -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 $@
diff --git a/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.c b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.c
new file mode 100644
index 000000000000..6bd729f65700
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.c
@@ -0,0 +1,6 @@
+#include "One.h"
+#include <stdio.h>
+
+void one() {
+ printf("One\n"); // break here
+}
diff --git a/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.h b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.h
new file mode 100644
index 000000000000..b59f5ad13f22
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.h
@@ -0,0 +1,4 @@
+#ifndef ONE_H
+#define ONE_H
+void one();
+#endif
diff --git a/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/OneConstant.c b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/OneConstant.c
new file mode 100644
index 000000000000..8255c2fce995
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/OneConstant.c
@@ -0,0 +1 @@
+int __attribute__ ((visibility("hidden"))) conflicting_symbol = 11111;
diff --git a/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/TestConflictingSymbol.py b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/TestConflictingSymbol.py
new file mode 100644
index 000000000000..d3327700bfd2
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/TestConflictingSymbol.py
@@ -0,0 +1,90 @@
+"""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
+
+ def test_conflicting_symbols(self):
+ self.build()
+ exe = os.path.join(os.getcwd(), "a.out")
+ target = self.dbg.CreateTarget("a.out")
+ self.assertTrue(target, VALID_TARGET)
+
+ # Register our shared libraries for remote targets so they get
+ # automatically uploaded
+ environment = self.registerSharedLibrariesWithTarget(
+ target, ['One', 'Two'])
+
+ 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)
+
+ process = target.LaunchSimple(
+ None, environment, self.get_process_working_directory())
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # 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"])
diff --git a/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two.mk b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two.mk
new file mode 100644
index 000000000000..117d9e00d443
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two.mk
@@ -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 $@
diff --git a/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.c b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.c
new file mode 100644
index 000000000000..8d8d668b8c31
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.c
@@ -0,0 +1,6 @@
+#include "Two.h"
+#include <stdio.h>
+
+void two() {
+ printf("Two\n"); // break here
+}
diff --git a/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.h b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.h
new file mode 100644
index 000000000000..8d5bd6a32330
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.h
@@ -0,0 +1,4 @@
+#ifndef TWO_H
+#define TWO_H
+void two();
+#endif
diff --git a/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/TwoConstant.c b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/TwoConstant.c
new file mode 100644
index 000000000000..9fc7c4b79515
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/TwoConstant.c
@@ -0,0 +1 @@
+int __attribute__ ((visibility("hidden"))) conflicting_symbol = 22222;
diff --git a/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/main.c b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/main.c
new file mode 100644
index 000000000000..4dcd443c0492
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/main.c
@@ -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);
+}
diff --git a/packages/Python/lldbsuite/test/lldbtest.py b/packages/Python/lldbsuite/test/lldbtest.py
index bc0fb1b686ad..f1d65cf2076d 100644
--- a/packages/Python/lldbsuite/test/lldbtest.py
+++ b/packages/Python/lldbsuite/test/lldbtest.py
@@ -1934,7 +1934,7 @@ class TestBase(Base):
# "libFoo.dylib" or "libFoo.so", or "Foo.so" for "Foo.so" or "libFoo.so", or just a
# basename like "libFoo.so". So figure out which one it is and resolve the local copy
# of the shared library accordingly
- if os.path.exists(name):
+ if os.path.isfile(name):
local_shlib_path = name # name is the full path to the local shared library
else:
# Check relative names
diff --git a/source/Breakpoint/Breakpoint.cpp b/source/Breakpoint/Breakpoint.cpp
index 4c58f8231344..17c104ba0c60 100644
--- a/source/Breakpoint/Breakpoint.cpp
+++ b/source/Breakpoint/Breakpoint.cpp
@@ -837,8 +837,8 @@ bool Breakpoint::AddName(llvm::StringRef new_name, Status &error) {
if (new_name.empty())
return false;
if (!BreakpointID::StringIsBreakpointName(new_name, error)) {
- error.SetErrorStringWithFormat("input name \"%s\" not a breakpoint name.",
- new_name);
+ error.SetErrorStringWithFormatv("input name \"{0}\" not a breakpoint name.",
+ new_name);
return false;
}
if (!error.Success())
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index 256d46a15420..8fde41052192 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -591,103 +591,6 @@ addr_t ClangExpressionDeclMap::GetSymbolAddress(const ConstString &name,
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::FindExternalVisibleDecls(
// 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());
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
index ac88c1d6b891..e8a9ba6862db 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
@@ -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.
///
diff --git a/source/Symbol/SymbolContext.cpp b/source/Symbol/SymbolContext.cpp
index 5ea6f91200c1..4ac35010c74c 100644
--- a/source/Symbol/SymbolContext.cpp
+++ b/source/Symbol/SymbolContext.cpp
@@ -799,6 +799,163 @@ bool SymbolContext::GetAddressRangeFromHereToEndLine(uint32_t end_line,
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