brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.4 KiB · 8d52bd9 Raw
201 lines · python
1import lldb2import re3 4 5def parse_linespec(linespec, frame, result):6    """Handles a subset of GDB-style linespecs.  Specifically:7 8    number           - A line in the current file9    +offset          - The line /offset/ lines after this line10    -offset          - The line /offset/ lines before this line11    filename:number  - Line /number/ in file /filename/12    function         - The start of /function/13    *address         - The pointer target of /address/, which must be a literal (but see `` in LLDB)14 15    We explicitly do not handle filename:function because it is ambiguous in Objective-C.16 17    This function returns a list of addresses."""18 19    breakpoint = None20    target = frame.GetThread().GetProcess().GetTarget()21 22    matched = False23 24    if not matched:25        mo = re.match("^([0-9]+)$", linespec)26        if mo is not None:27            matched = True28            # print "Matched <linenum>"29            line_number = int(mo.group(1))30            line_entry = frame.GetLineEntry()31            if not line_entry.IsValid():32                result.AppendMessage(33                    "Specified a line in the current file, but the current frame doesn't have line table information."34                )35                return36            breakpoint = target.BreakpointCreateByLocation(37                line_entry.GetFileSpec(), line_number38            )39 40    if not matched:41        mo = re.match(r"^\+([0-9]+)$", linespec)42        if mo is not None:43            matched = True44            # print "Matched +<count>"45            line_number = int(mo.group(1))46            line_entry = frame.GetLineEntry()47            if not line_entry.IsValid():48                result.AppendMessage(49                    "Specified a line in the current file, but the current frame doesn't have line table information."50                )51                return52            breakpoint = target.BreakpointCreateByLocation(53                line_entry.GetFileSpec(), (line_entry.GetLine() + line_number)54            )55 56    if not matched:57        mo = re.match(r"^\-([0-9]+)$", linespec)58        if mo is not None:59            matched = True60            # print "Matched -<count>"61            line_number = int(mo.group(1))62            line_entry = frame.GetLineEntry()63            if not line_entry.IsValid():64                result.AppendMessage(65                    "Specified a line in the current file, but the current frame doesn't have line table information."66                )67                return68            breakpoint = target.BreakpointCreateByLocation(69                line_entry.GetFileSpec(), (line_entry.GetLine() - line_number)70            )71 72    if not matched:73        mo = re.match("^(.*):([0-9]+)$", linespec)74        if mo is not None:75            matched = True76            # print "Matched <filename>:<linenum>"77            file_name = mo.group(1)78            line_number = int(mo.group(2))79            breakpoint = target.BreakpointCreateByLocation(file_name, line_number)80 81    if not matched:82        mo = re.match(r"\*((0x)?([0-9a-f]+))$", linespec)83        if mo is not None:84            matched = True85            # print "Matched <address-expression>"86            address = int(mo.group(1), base=0)87            breakpoint = target.BreakpointCreateByAddress(address)88 89    if not matched:90        # print "Trying <function-name>"91        breakpoint = target.BreakpointCreateByName(linespec)92 93    num_locations = breakpoint.GetNumLocations()94 95    if num_locations == 0:96        result.AppendMessage(97            "The line specification provided doesn't resolve to any addresses."98        )99 100    addr_list = []101 102    for location_index in range(num_locations):103        location = breakpoint.GetLocationAtIndex(location_index)104        addr_list.append(location.GetAddress())105 106    target.BreakpointDelete(breakpoint.GetID())107 108    return addr_list109 110 111def usage_string():112    return """   Sets the program counter to a specific address.113 114Syntax: jump <linespec> [<location-id>]115 116Command Options Usage:117  jump <linenum>118  jump +<count>119  jump -<count>120  jump <filename>:<linenum>121  jump <function-name>122  jump *<address-expression>123 124<location-id> serves to disambiguate when multiple locations could be meant."""125 126 127def jump(debugger, command, result, internal_dict):128    if command == "":129        result.AppendMessage(usage_string())130 131    args = command.split()132 133    if not debugger.IsValid():134        result.AppendMessage("Invalid debugger!")135        return136 137    target = debugger.GetSelectedTarget()138    if not target.IsValid():139        result.AppendMessage("jump requires a valid target.")140        return141 142    process = target.GetProcess()143    if not process.IsValid():144        result.AppendMessage("jump requires a valid process.")145        return146 147    thread = process.GetSelectedThread()148    if not thread.IsValid():149        result.AppendMessage("jump requires a valid thread.")150        return151 152    frame = thread.GetSelectedFrame()153    if not frame.IsValid():154        result.AppendMessage("jump requires a valid frame.")155        return156 157    addresses = parse_linespec(args[0], frame, result)158 159    stream = lldb.SBStream()160 161    if len(addresses) == 0:162        return163 164    desired_address = addresses[0]165 166    if len(addresses) > 1:167        if len(args) == 2:168            desired_index = int(args[1])169            if (desired_index >= 0) and (desired_index < len(addresses)):170                desired_address = addresses[desired_index]171            else:172                result.AppendMessage(173                    "Desired index " + args[1] + " is not one of the options."174                )175                return176        else:177            index = 0178            result.AppendMessage("The specified location resolves to multiple targets.")179            for address in addresses:180                stream.Clear()181                address.GetDescription(stream)182                result.AppendMessage(183                    "  Location ID " + str(index) + ": " + stream.GetData()184                )185                index = index + 1186            result.AppendMessage(187                "Please type 'jump " + command + " <location-id>' to choose one."188            )189            return190 191    frame.SetPC(desired_address.GetLoadAddress(target))192 193 194def __lldb_init_module(debugger, internal_dict):195    # Module is being run inside the LLDB interpreter196    jump.__doc__ = usage_string()197    debugger.HandleCommand("command script add -o -f jump.jump jump")198    print(199        'The "jump" command has been installed, type "help jump" or "jump <ENTER>" for detailed help.'200    )201