"""
Test the lldb disassemble command on lib stdc++.
"""

import os, time
import unittest2
import lldb
from lldbtest import *
import lldbutil

class StdCXXDisassembleTestCase(TestBase):

    mydir = os.path.join("lang", "cpp", "stl")

    def setUp(self):
        # Call super's setUp().
        TestBase.setUp(self)
        # Find the line number to break inside main().
        self.line = line_number('main.cpp', '// Set break point at this line.')

    # rdar://problem/8504895
    # Crash while doing 'disassemble -n "-[NSNumber descriptionWithLocale:]"
    @unittest2.skipIf(TestBase.skipLongRunningTest(), "Skip this long running test")
    def test_stdcxx_disasm(self):
        """Do 'disassemble' on each and every 'Code' symbol entry from the std c++ lib."""
        self.buildDefault()
        exe = os.path.join(os.getcwd(), "a.out")
        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)

        # rdar://problem/8543077
        # test/stl: clang built binaries results in the breakpoint locations = 3,
        # is this a problem with clang generated debug info?
        #
        # Break on line 13 of main.cpp.
        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)

        self.runCmd("run", RUN_SUCCEEDED)

        # Now let's get the target as well as the process objects.
        target = self.dbg.GetSelectedTarget()
        process = target.GetProcess()

        # The process should be in a 'stopped' state.
        self.expect(str(process), STOPPED_DUE_TO_BREAKPOINT, exe=False,
            substrs = ["a.out",
                       "stopped"])

        # Disassemble the functions on the call stack.
        self.runCmd("thread backtrace")
        thread = process.GetThreadAtIndex(0)
        depth = thread.GetNumFrames()
        for i in range(depth - 1):
            frame = thread.GetFrameAtIndex(i)
            function = frame.GetFunction()
            self.runCmd("disassemble -n '%s'" % function.GetName())

        # Iterate through the available modules, looking for stdc++ library...
        for i in range(target.GetNumModules()):
            module = target.GetModuleAtIndex(i)
            fs = module.GetFileSpec()
            if (fs.GetFilename().startswith("libstdc++")):
                lib_stdcxx = str(fs)
                break

        # At this point, lib_stdcxx is the full path to the stdc++ library and
        # module is the corresponding SBModule.

        self.expect(fs.GetFilename(), "Libraray StdC++ is located", exe=False,
            substrs = ["libstdc++"])

        self.runCmd("image dump symtab %s" % str(fs))
        raw_output = self.res.GetOutput()
        # Now, look for every 'Code' symbol and feed its load address into the
        # command: 'disassemble -s load_address -e end_address', where the
        # end_address is taken from the next consecutive 'Code' symbol entry's
        # load address.
        #
        # The load address column comes after the file address column, with both
        # looks like '0xhhhhhhhh', i.e., 8 hexadecimal digits.
        codeRE = re.compile(r"""
                             \ Code\ {9}      # ' Code' followed by 9 SPCs,
                             0x[0-9a-f]{16}   # the file address column, and
                             \                # a SPC, and
                             (0x[0-9a-f]{16}) # the load address column, and
                             .*               # the rest.
                             """, re.VERBOSE)
        # Maintain a start address variable; if we arrive at a consecutive Code
        # entry, then the load address of the that entry is fed as the end
        # address to the 'disassemble -s SA -e LA' command.
        SA = None
        for line in raw_output.split(os.linesep):
            match = codeRE.search(line)
            if match:
                LA = match.group(1)
                if self.TraceOn():
                    print "line:", line
                    print "load address:", LA
                    print "SA:", SA
                if SA and LA:
                    if int(LA, 16) > int(SA, 16):
                        self.runCmd("disassemble -s %s -e %s" % (SA, LA))
                SA = LA
            else:
                # This entry is not a Code entry.  Reset SA = None.
                SA = None


if __name__ == '__main__':
    import atexit
    lldb.SBDebugger.Initialize()
    atexit.register(lambda: lldb.SBDebugger.Terminate())
    unittest2.main()
