1"""
2Test that we read the exported symbols from the dyld trie
3"""
4
5import lldb
6from lldbsuite.test.decorators import *
7from lldbsuite.test.lldbtest import *
8from lldbsuite.test import lldbutil
9
10class DyldTrieSymbolsTestCase(TestBase):
11
12    mydir = TestBase.compute_mydir(__file__)
13
14    NO_DEBUG_INFO_TESTCASE = True
15
16    @skipIfRemote
17    @skipUnlessDarwin
18
19    def test_dyld_trie_symbols(self):
20        """Test that we make create symbol table entries from the dyld trie data structure."""
21        self.build()
22        unstripped_exe = self.getBuildArtifact("a.out")
23        stripped_exe = self.getBuildArtifact("a.out-stripped")
24
25        unstripped_target = self.dbg.CreateTarget(unstripped_exe)
26        self.assertTrue(unstripped_target.IsValid(), "Got a vaid stripped target.")
27
28        # Verify that the expected symbols are present in an unstripped
29        # binary, and that we didn't duplicate the entries in the symbol
30        # table.
31        unstripped_bazval_symbols = unstripped_target.FindSymbols("bazval")
32        self.assertEqual(unstripped_bazval_symbols.GetSize(), 1)
33        unstripped_patval_symbols = unstripped_target.FindSymbols("patval")
34        self.assertEqual(unstripped_patval_symbols.GetSize(), 1)
35        unstripped_Z3foo_symbols = unstripped_target.FindSymbols("_Z3foov")
36        self.assertEqual(unstripped_Z3foo_symbols.GetSize(), 1)
37        unstripped_foo_symbols = unstripped_target.FindSymbols("foo")
38        self.assertEqual(unstripped_foo_symbols.GetSize(), 1)
39
40        # make sure we can look up the mangled name, demangled base name,
41        # demangled name with argument.
42        unstripped_Z3pat_symbols = unstripped_target.FindSymbols("_Z3pati")
43        self.assertEqual(unstripped_Z3pat_symbols.GetSize(), 1)
44        unstripped_pat_symbols = unstripped_target.FindSymbols("pat")
45        self.assertEqual(unstripped_pat_symbols.GetSize(), 1)
46        unstripped_patint_symbols = unstripped_target.FindSymbols("pat(int)")
47        self.assertEqual(unstripped_patint_symbols.GetSize(), 1)
48
49        unstripped_bar_symbols = unstripped_target.FindSymbols("bar")
50        self.assertEqual(unstripped_bar_symbols.GetSize(), 1)
51
52
53
54        # Verify that we can retrieve all the symbols with external
55        # linkage after the binary has been stripped; they should not
56        # exist in the nlist records at this point and can only be
57        # retrieved from the dyld trie structure.
58
59        stripped_target = self.dbg.CreateTarget(stripped_exe)
60        self.assertTrue(stripped_target.IsValid(), "Got a vaid stripped target.")
61
62        # Check that we're able to still retrieve all the symbols after
63        # the binary has been stripped. Check that one we know will be
64        # removed is absent.
65        stripped_bazval_symbols = stripped_target.FindSymbols("bazval")
66        self.assertEqual(stripped_bazval_symbols.GetSize(), 1)
67        stripped_patval_symbols = stripped_target.FindSymbols("patval")
68        self.assertEqual(stripped_patval_symbols.GetSize(), 1)
69        stripped_Z3foo_symbols = stripped_target.FindSymbols("_Z3foov")
70        self.assertEqual(stripped_Z3foo_symbols.GetSize(), 1)
71        stripped_foo_symbols = stripped_target.FindSymbols("foo")
72        self.assertEqual(stripped_foo_symbols.GetSize(), 1)
73
74        # make sure we can look up the mangled name, demangled base name,
75        # demangled name with argument.
76        stripped_Z3pat_symbols = stripped_target.FindSymbols("_Z3pati")
77        self.assertEqual(stripped_Z3pat_symbols.GetSize(), 1)
78        stripped_pat_symbols = stripped_target.FindSymbols("pat")
79        self.assertEqual(stripped_pat_symbols.GetSize(), 1)
80        stripped_patint_symbols = stripped_target.FindSymbols("pat(int)")
81        self.assertEqual(stripped_patint_symbols.GetSize(), 1)
82
83        # bar should have been strippped.  We should not find it, or the
84        # stripping went wrong.
85        stripped_bar_symbols = stripped_target.FindSymbols("bar")
86        self.assertEqual(stripped_bar_symbols.GetSize(), 0)
87
88        # confirm that we classified objc runtime symbols correctly and
89        # stripped off the objc prefix from the symbol names.
90        syms_ctx = stripped_target.FindSymbols("SourceBase")
91        self.assertEqual(syms_ctx.GetSize(), 2)
92
93        # The next part if not deterministic and potentially causes replay to
94        # fail when the order is different during capture and replay.
95        if not configuration.is_reproducer():
96            sym1 = syms_ctx.GetContextAtIndex(0).GetSymbol()
97            sym2 = syms_ctx.GetContextAtIndex(1).GetSymbol()
98
99            # one of these should be a lldb.eSymbolTypeObjCClass, the other
100            # should be lldb.eSymbolTypeObjCMetaClass.
101            if sym1.GetType() == lldb.eSymbolTypeObjCMetaClass:
102                self.assertEqual(sym2.GetType(), lldb.eSymbolTypeObjCClass)
103            else:
104                if sym1.GetType() == lldb.eSymbolTypeObjCClass:
105                    self.assertEqual(sym2.GetType(), lldb.eSymbolTypeObjCMetaClass)
106                else:
107                    self.assertTrue(sym1.GetType() == lldb.eSymbolTypeObjCMetaClass or sym1.GetType() == lldb.eSymbolTypeObjCClass)
108
109            syms_ctx = stripped_target.FindSymbols("SourceDerived._derivedValue")
110            self.assertEqual(syms_ctx.GetSize(), 1)
111            sym = syms_ctx.GetContextAtIndex(0).GetSymbol()
112            self.assertEqual(sym.GetType(), lldb.eSymbolTypeObjCIVar)
113