1"""
2Test some SBModule and SBSection APIs.
3"""
4
5from __future__ import print_function
6
7
8import lldb
9from lldbsuite.test.decorators import *
10from lldbsuite.test.lldbtest import *
11from lldbsuite.test import lldbutil
12from lldbsuite.test.lldbutil import symbol_type_to_str
13
14
15class ModuleAndSectionAPIsTestCase(TestBase):
16
17    mydir = TestBase.compute_mydir(__file__)
18
19    # Py3 asserts due to a bug in SWIG.  A fix for this was upstreamed into
20    # SWIG 3.0.8.
21    @skipIf(py_version=['>=', (3, 0)], swig_version=['<', (3, 0, 8)])
22    @add_test_categories(['pyapi'])
23    def test_module_and_section(self):
24        """Test module and section APIs."""
25        self.build()
26        exe = self.getBuildArtifact("a.out")
27
28        target = self.dbg.CreateTarget(exe)
29        self.assertTrue(target, VALID_TARGET)
30        self.assertTrue(target.GetNumModules() > 0)
31
32        # Hide stdout if not running with '-t' option.
33        if not self.TraceOn():
34            self.HideStdout()
35
36        print("Number of modules for the target: %d" % target.GetNumModules())
37        for module in target.module_iter():
38            print(module)
39
40        # Get the executable module at index 0.
41        exe_module = target.GetModuleAtIndex(0)
42
43        print("Exe module: %s" % str(exe_module))
44        print("Number of sections: %d" % exe_module.GetNumSections())
45        print("Number of symbols: %d" % len(exe_module))
46        INDENT = ' ' * 4
47        INDENT2 = INDENT * 2
48        for sec in exe_module.section_iter():
49            print(sec)
50            print(
51                INDENT +
52                "Number of subsections: %d" %
53                sec.GetNumSubSections())
54            if sec.GetNumSubSections() == 0:
55                for sym in exe_module.symbol_in_section_iter(sec):
56                    print(INDENT + str(sym))
57                    print(
58                        INDENT +
59                        "symbol type: %s" %
60                        symbol_type_to_str(
61                            sym.GetType()))
62            else:
63                for subsec in sec:
64                    print(INDENT + str(subsec))
65                    # Now print the symbols belonging to the subsection....
66                    for sym in exe_module.symbol_in_section_iter(subsec):
67                        print(INDENT2 + str(sym))
68                        print(
69                            INDENT2 +
70                            "symbol type: %s" %
71                            symbol_type_to_str(
72                                sym.GetType()))
73
74    @add_test_categories(['pyapi'])
75    def test_module_and_section_boundary_condition(self):
76        """Test module and section APIs by passing None when it expects a Python string."""
77        self.build()
78        exe = self.getBuildArtifact("a.out")
79
80        target = self.dbg.CreateTarget(exe)
81        self.assertTrue(target, VALID_TARGET)
82        self.assertTrue(target.GetNumModules() > 0)
83
84        # Hide stdout if not running with '-t' option.
85        if not self.TraceOn():
86            self.HideStdout()
87
88        print("Number of modules for the target: %d" % target.GetNumModules())
89        for module in target.module_iter():
90            print(module)
91
92        # Get the executable module at index 0.
93        exe_module = target.GetModuleAtIndex(0)
94
95        print("Exe module: %s" % str(exe_module))
96        print("Number of sections: %d" % exe_module.GetNumSections())
97
98        # Boundary condition testings.  Should not crash lldb!
99        exe_module.FindFirstType(None)
100        exe_module.FindTypes(None)
101        exe_module.FindGlobalVariables(target, None, 1)
102        exe_module.FindFunctions(None, 0)
103        exe_module.FindSection(None)
104
105        # Get the section at index 1.
106        if exe_module.GetNumSections() > 1:
107            sec1 = exe_module.GetSectionAtIndex(1)
108            print(sec1)
109        else:
110            sec1 = None
111
112        if sec1:
113            sec1.FindSubSection(None)
114
115    @add_test_categories(['pyapi'])
116    def test_module_compile_unit_iter(self):
117        """Test module's compile unit iterator APIs."""
118        self.build()
119        exe = self.getBuildArtifact("a.out")
120
121        target = self.dbg.CreateTarget(exe)
122        self.assertTrue(target, VALID_TARGET)
123        self.assertTrue(target.GetNumModules() > 0)
124
125        # Hide stdout if not running with '-t' option.
126        if not self.TraceOn():
127            self.HideStdout()
128
129        print("Number of modules for the target: %d" % target.GetNumModules())
130        for module in target.module_iter():
131            print(module)
132
133        # Get the executable module at index 0.
134        exe_module = target.GetModuleAtIndex(0)
135
136        print("Exe module: %s" % str(exe_module))
137        print("Number of compile units: %d" % exe_module.GetNumCompileUnits())
138        INDENT = ' ' * 4
139        INDENT2 = INDENT * 2
140        for cu in exe_module.compile_unit_iter():
141            print(cu)
142
143    @add_test_categories(['pyapi'])
144    def test_find_compile_units(self):
145        """Exercise SBModule.FindCompileUnits() API."""
146        d = {'EXE': 'b.out'}
147        self.build(dictionary=d)
148        self.setTearDownCleanup(dictionary=d)
149        self.find_compile_units(self.getBuildArtifact('b.out'))
150
151    def find_compile_units(self, exe):
152        """Exercise SBModule.FindCompileUnits() API."""
153        source_name_list = ["main.cpp", "b.cpp", "c.cpp"]
154
155        # Create a target by the debugger.
156        target = self.dbg.CreateTarget(exe)
157        self.assertTrue(target, VALID_TARGET)
158
159        num_modules = target.GetNumModules()
160        for i in range(num_modules):
161            module = target.GetModuleAtIndex(i)
162            for source_name in source_name_list:
163                list = module.FindCompileUnits(lldb.SBFileSpec(source_name, False))
164                for sc in list:
165                    self.assertTrue(
166                        sc.GetCompileUnit().GetFileSpec().GetFilename() ==
167                        source_name)
168