1"""
2Test that SBProcess.LoadImageUsingPaths uses RTLD_LAZY
3"""
4
5
6
7import os
8import shutil
9import lldb
10from lldbsuite.test.decorators import *
11from lldbsuite.test.lldbtest import *
12from lldbsuite.test import lldbutil
13
14
15class LoadUsingLazyBind(TestBase):
16    NO_DEBUG_INFO_TESTCASE = True
17
18    @skipIfRemote
19    @skipIfWindows # The Windows platform doesn't implement DoLoadImage.
20    @skipIf(oslist=["linux"], archs=["arm"]) # Fails on arm/linux
21    # Failing for unknown reasons on Linux, see
22    # https://bugs.llvm.org/show_bug.cgi?id=49656.
23    def test_load_using_lazy_bind(self):
24        """Test that we load using RTLD_LAZY"""
25
26        self.build()
27        wd = os.path.realpath(self.getBuildDir())
28
29        def make_lib_name(name):
30            return (self.platformContext.shlib_prefix + name + "." +
31                    self.platformContext.shlib_extension)
32
33        def make_lib_path(name):
34            libpath = os.path.join(wd, make_lib_name(name))
35            self.assertTrue(os.path.exists(libpath))
36            return libpath
37
38        libt2_0 = make_lib_path('t2_0')
39        libt2_1 = make_lib_path('t2_1')
40
41        # Overwrite t2_0 with t2_1 to delete the definition of `use`.
42        shutil.copy(libt2_1, libt2_0)
43
44        # Launch a process and break
45        (target, process, thread, _) = lldbutil.run_to_source_breakpoint(self,
46                                                "break here",
47                                                lldb.SBFileSpec("main.cpp"),
48                                                extra_images=["t1"])
49
50        # Load libt1; should fail unless we use RTLD_LAZY
51        error = lldb.SBError()
52        lib_spec = lldb.SBFileSpec(make_lib_name('t1'))
53        paths = lldb.SBStringList()
54        paths.AppendString(wd)
55        out_spec = lldb.SBFileSpec()
56        token = process.LoadImageUsingPaths(lib_spec, paths, out_spec, error)
57        self.assertNotEqual(token, lldb.LLDB_INVALID_IMAGE_TOKEN, "Got a valid token")
58
59        # Calling `f1()` should return 5.
60        frame = thread.GetFrameAtIndex(0)
61        val = frame.EvaluateExpression("f1()")
62        self.assertTrue(val.IsValid())
63        self.assertEquals(val.GetValueAsSigned(-1), 5)
64