diff --git a/.ci/metrics/requirements.lock.txt b/.ci/metrics/requirements.lock.txt index 1aa21e190f546..bc894d6e1fc95 100644 --- a/.ci/metrics/requirements.lock.txt +++ b/.ci/metrics/requirements.lock.txt @@ -186,34 +186,9 @@ charset-normalizer==3.4.0 \ --hash=sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079 \ --hash=sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482 # via requests -cryptography==43.0.3 \ - --hash=sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362 \ - --hash=sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4 \ - --hash=sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa \ - --hash=sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83 \ - --hash=sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff \ - --hash=sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805 \ - --hash=sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6 \ - --hash=sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664 \ - --hash=sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08 \ - --hash=sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e \ - --hash=sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18 \ - --hash=sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f \ - --hash=sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73 \ - --hash=sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5 \ - --hash=sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984 \ - --hash=sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd \ - --hash=sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3 \ - --hash=sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e \ - --hash=sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405 \ - --hash=sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2 \ - --hash=sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c \ - --hash=sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995 \ - --hash=sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73 \ - --hash=sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16 \ - --hash=sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7 \ - --hash=sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd \ - --hash=sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7 +cryptography==46.0.1 \ + # Hashes need to be regenerated for cryptography==46.0.1 + # via pyjwt # via pyjwt deprecated==1.2.15 \ --hash=sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320 \ @@ -251,9 +226,9 @@ python-dateutil==2.9.0.post0 \ --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 # via -r ./requirements.txt -requests==2.32.3 \ - --hash=sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760 \ - --hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6 +requests==2.32.5 \ + # Hashes need to be regenerated for requests==2.32.5 + # via pygithub # via pygithub six==1.17.0 \ --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ @@ -263,9 +238,11 @@ typing-extensions==4.12.2 \ --hash=sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d \ --hash=sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8 # via pygithub -urllib3==2.2.3 \ - --hash=sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac \ - --hash=sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9 +urllib3==2.5.0 \ + # Hashes need to be regenerated for urllib3==2.5.0 + # via + # pygithub + # requests # via # pygithub # requests diff --git a/.ci/metrics/requirements.txt b/.ci/metrics/requirements.txt index 91c9c317a7e46..3be3b9de63ae1 100644 --- a/.ci/metrics/requirements.txt +++ b/.ci/metrics/requirements.txt @@ -1,2 +1,2 @@ -pygithub==2.5.0 +pygithub==2.8.1 python-dateutil==2.9.0.post0 diff --git a/.ci/requirements.txt b/.ci/requirements.txt index 2fec1baf25fdc..016fbf7047aa4 100644 --- a/.ci/requirements.txt +++ b/.ci/requirements.txt @@ -1,2 +1,2 @@ junitparser==3.2.0 -google-cloud-storage==3.3.0 +google-cloud-storage==3.4.0 diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000000..c4ea68910e461 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + +version: 2 +updates: + - package-ecosystem: "" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" diff --git a/.github/workflows/gha-codeql.yml b/.github/workflows/gha-codeql.yml index 63388ebc706bd..82d6eb3e6a610 100644 --- a/.github/workflows/gha-codeql.yml +++ b/.github/workflows/gha-codeql.yml @@ -31,7 +31,11 @@ jobs: - name: Initialize CodeQL uses: github/codeql-action/init@303c0aef88fc2fe5ff6d63d3b1596bfd83dfa1f9 # v3.30.4 with: - languages: actions + languages: actions, swift queries: security-extended + - name: Build Swift code + run: | + swiftc llvm/test/tools/opt-viewer/Inputs/suppress/s.swift + swiftc llvm/test/tools/opt-viewer/Inputs/unicode-function-name/s.swift - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@303c0aef88fc2fe5ff6d63d3b1596bfd83dfa1f9 # v3.30.4 diff --git a/.github/workflows/libcxx-run-benchmarks.yml b/.github/workflows/libcxx-run-benchmarks.yml index 9e8f55859fc7a..de318765042e7 100644 --- a/.github/workflows/libcxx-run-benchmarks.yml +++ b/.github/workflows/libcxx-run-benchmarks.yml @@ -70,7 +70,7 @@ jobs: source .venv/bin/activate && cd repo python -m pip install -r libcxx/utils/requirements.txt baseline_commit=$(git merge-base ${{ steps.vars.outputs.pr_base }} ${{ steps.vars.outputs.pr_head }}) - ./libcxx/utils/test-at-commit --commit ${baseline_commit} -B build/baseline -- -sv -j1 --param optimization=speed "$BENCHMARKS" + ./libcxx/utils/consolidate-benchmarks build/baseline | tee baseline.lnt - name: Run candidate @@ -78,7 +78,7 @@ jobs: BENCHMARKS: ${{ steps.vars.outputs.benchmarks }} run: | source .venv/bin/activate && cd repo - ./libcxx/utils/test-at-commit --commit ${{ steps.vars.outputs.pr_head }} -B build/candidate -- -sv -j1 --param optimization=speed "$BENCHMARKS" + ./libcxx/utils/consolidate-benchmarks build/candidate | tee candidate.lnt - name: Compare baseline and candidate runs diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 8579e51e45697..c8200544410ba 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -4072,12 +4072,17 @@ bool FunctionDecl::isInlineDefinitionExternallyVisible() const { ASTContext &Context = getASTContext(); if (Context.getLangOpts().GNUInline || hasAttr()) { + // GNU inline semantics: + // + // A function defined 'inline' is externally visible. + // A function defined 'extern inline' is not externally visible. + // + // If any declaration is 'inline' but not 'extern', the definition is + // externally visible. This is the only case that matters for a function + // defined 'extern inline'. + // // Note: If you change the logic here, please change // doesDeclarationForceExternallyVisibleDefinition as well. - // - // If it's not the case that both 'inline' and 'extern' are - // specified on the definition, then this inline definition is - // externally visible. if (Context.getLangOpts().CPlusPlus) return false; if (!(isInlineSpecified() && getStorageClass() == SC_Extern)) diff --git a/lldb/examples/python/gdbremote.py b/lldb/examples/python/gdbremote.py index 0bbfc1a0f1eed..a667622ac47b3 100755 --- a/lldb/examples/python/gdbremote.py +++ b/lldb/examples/python/gdbremote.py @@ -1,1835 +1,1835 @@ -#!/usr/bin/env python - -# ---------------------------------------------------------------------- -# This module will enable GDB remote packet logging when the -# 'start_gdb_log' command is called with a filename to log to. When the -# 'stop_gdb_log' command is called, it will disable the logging and -# print out statistics about how long commands took to execute and also -# will primnt ou -# Be sure to add the python path that points to the LLDB shared library. -# -# To use this in the embedded python interpreter using "lldb" just -# import it with the full path using the "command script import" -# command. This can be done from the LLDB command line: -# (lldb) command script import /path/to/gdbremote.py -# Or it can be added to your ~/.lldbinit file so this module is always -# available. -# ---------------------------------------------------------------------- - -import binascii -import subprocess -import json -import math -import optparse -import os -import re -import shlex -import string -import sys -import tempfile -import xml.etree.ElementTree as ET - -# ---------------------------------------------------------------------- -# Global variables -# ---------------------------------------------------------------------- -g_log_file = "" -g_byte_order = "little" -g_number_regex = re.compile("^(0x[0-9a-fA-F]+|[0-9]+)") -g_thread_id_regex = re.compile("^(-1|[0-9a-fA-F]+|0)") - - -class TerminalColors: - """Simple terminal colors class""" - - def __init__(self, enabled=True): - # TODO: discover terminal type from "file" and disable if - # it can't handle the color codes - self.enabled = enabled - - def reset(self): - """Reset all terminal colors and formatting.""" - if self.enabled: - return "\x1b[0m" - return "" - - def bold(self, on=True): - """Enable or disable bold depending on the "on" parameter.""" - if self.enabled: - if on: - return "\x1b[1m" - else: - return "\x1b[22m" - return "" - - def italics(self, on=True): - """Enable or disable italics depending on the "on" parameter.""" - if self.enabled: - if on: - return "\x1b[3m" - else: - return "\x1b[23m" - return "" - - def underline(self, on=True): - """Enable or disable underline depending on the "on" parameter.""" - if self.enabled: - if on: - return "\x1b[4m" - else: - return "\x1b[24m" - return "" - - def inverse(self, on=True): - """Enable or disable inverse depending on the "on" parameter.""" - if self.enabled: - if on: - return "\x1b[7m" - else: - return "\x1b[27m" - return "" - - def strike(self, on=True): - """Enable or disable strike through depending on the "on" parameter.""" - if self.enabled: - if on: - return "\x1b[9m" - else: - return "\x1b[29m" - return "" - - def black(self, fg=True): - """Set the foreground or background color to black. - The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False. - """ - if self.enabled: - if fg: - return "\x1b[30m" - else: - return "\x1b[40m" - return "" - - def red(self, fg=True): - """Set the foreground or background color to red. - The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False. - """ - if self.enabled: - if fg: - return "\x1b[31m" - else: - return "\x1b[41m" - return "" - - def green(self, fg=True): - """Set the foreground or background color to green. - The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False. - """ - if self.enabled: - if fg: - return "\x1b[32m" - else: - return "\x1b[42m" - return "" - - def yellow(self, fg=True): - """Set the foreground or background color to yellow. - The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False. - """ - if self.enabled: - if fg: - return "\x1b[33m" - else: - return "\x1b[43m" - return "" - - def blue(self, fg=True): - """Set the foreground or background color to blue. - The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False. - """ - if self.enabled: - if fg: - return "\x1b[34m" - else: - return "\x1b[44m" - return "" - - def magenta(self, fg=True): - """Set the foreground or background color to magenta. - The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False. - """ - if self.enabled: - if fg: - return "\x1b[35m" - else: - return "\x1b[45m" - return "" - - def cyan(self, fg=True): - """Set the foreground or background color to cyan. - The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False. - """ - if self.enabled: - if fg: - return "\x1b[36m" - else: - return "\x1b[46m" - return "" - - def white(self, fg=True): - """Set the foreground or background color to white. - The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False. - """ - if self.enabled: - if fg: - return "\x1b[37m" - else: - return "\x1b[47m" - return "" - - def default(self, fg=True): - """Set the foreground or background color to the default. - The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False. - """ - if self.enabled: - if fg: - return "\x1b[39m" - else: - return "\x1b[49m" - return "" - - -def start_gdb_log(debugger, command, result, dict): - """Start logging GDB remote packets by enabling logging with timestamps and - thread safe logging. Follow a call to this function with a call to "stop_gdb_log" - in order to dump out the commands.""" - global g_log_file - command_args = shlex.split(command) - usage = "usage: start_gdb_log [options] []" - description = """The command enables GDB remote packet logging with timestamps. The packets will be logged to if supplied, or a temporary file will be used. Logging stops when stop_gdb_log is called and the packet times will - be aggregated and displayed.""" - parser = optparse.OptionParser( - description=description, prog="start_gdb_log", usage=usage - ) - parser.add_option( - "-v", - "--verbose", - action="store_true", - dest="verbose", - help="display verbose debug info", - default=False, - ) - try: - (options, args) = parser.parse_args(command_args) - except: - return - - if g_log_file: - result.PutCString( - 'error: logging is already in progress with file "%s"' % g_log_file - ) - else: - args_len = len(args) - if args_len == 0: - g_log_file = tempfile.mktemp() - elif len(args) == 1: - g_log_file = args[0] - - if g_log_file: - debugger.HandleCommand( - 'log enable --threadsafe --timestamp --file "%s" gdb-remote packets' - % g_log_file - ) - result.PutCString( - "GDB packet logging enable with log file '%s'\nUse the 'stop_gdb_log' command to stop logging and show packet statistics." - % g_log_file - ) - return - - result.PutCString("error: invalid log file path") - result.PutCString(usage) - - -def stop_gdb_log(debugger, command, result, dict): - """Stop logging GDB remote packets to the file that was specified in a call - to "start_gdb_log" and normalize the timestamps to be relative to the first - timestamp in the log file. Also print out statistics for how long each - command took to allow performance bottlenecks to be determined.""" - global g_log_file - # Any commands whose names might be followed by more valid C identifier - # characters must be listed here - command_args = shlex.split(command) - usage = "usage: stop_gdb_log [options]" - description = """The command stops a previously enabled GDB remote packet logging command. Packet logging must have been previously enabled with a call to start_gdb_log.""" - parser = optparse.OptionParser( - description=description, prog="stop_gdb_log", usage=usage - ) - parser.add_option( - "-v", - "--verbose", - action="store_true", - dest="verbose", - help="display verbose debug info", - default=False, - ) - parser.add_option( - "--plot", - action="store_true", - dest="plot", - help="plot packet latencies by packet type", - default=False, - ) - parser.add_option( - "-q", - "--quiet", - action="store_true", - dest="quiet", - help="display verbose debug info", - default=False, - ) - parser.add_option( - "-C", - "--color", - action="store_true", - dest="color", - help="add terminal colors", - default=False, - ) - parser.add_option( - "-c", - "--sort-by-count", - action="store_true", - dest="sort_count", - help="display verbose debug info", - default=False, - ) - parser.add_option( - "-s", - "--symbolicate", - action="store_true", - dest="symbolicate", - help='symbolicate addresses in log using current "lldb.target"', - default=False, - ) - try: - (options, args) = parser.parse_args(command_args) - except: - return - options.colors = TerminalColors(options.color) - options.symbolicator = None - if options.symbolicate: - if lldb.target: - import lldb.utils.symbolication - - options.symbolicator = lldb.utils.symbolication.Symbolicator() - options.symbolicator.target = lldb.target - else: - print("error: can't symbolicate without a target") - - if not g_log_file: - result.PutCString( - 'error: logging must have been previously enabled with a call to "stop_gdb_log"' - ) - elif os.path.exists(g_log_file): - if len(args) == 0: - debugger.HandleCommand("log disable gdb-remote packets") - result.PutCString( - "GDB packet logging disabled. Logged packets are in '%s'" % g_log_file - ) - parse_gdb_log_file(g_log_file, options) - else: - result.PutCString(usage) - else: - print('error: the GDB packet log file "%s" does not exist' % g_log_file) - - -def is_hex_byte(str): - if len(str) == 2: - return str[0] in string.hexdigits and str[1] in string.hexdigits - return False - - -def get_hex_string_if_all_printable(str): - try: - s = binascii.unhexlify(str).decode() - if all(c in string.printable for c in s): - return s - except (TypeError, binascii.Error, UnicodeDecodeError): - pass - return None - - -# global register info list -g_register_infos = list() -g_max_register_info_name_len = 0 - - -class RegisterInfo: - """Class that represents register information""" - - def __init__(self, kvp): - self.info = dict() - for kv in kvp: - key = kv[0] - value = kv[1] - self.info[key] = value - - def name(self): - """Get the name of the register.""" - if self.info and "name" in self.info: - return self.info["name"] - return None - - def bit_size(self): - """Get the size in bits of the register.""" - if self.info and "bitsize" in self.info: - return int(self.info["bitsize"]) - return 0 - - def byte_size(self): - """Get the size in bytes of the register.""" - return self.bit_size() / 8 - - def get_value_from_hex_string(self, hex_str): - """Dump the register value given a native byte order encoded hex ASCII byte string.""" - encoding = self.info["encoding"] - bit_size = self.bit_size() - packet = Packet(hex_str) - if encoding == "uint": - uval = packet.get_hex_uint(g_byte_order) - if bit_size == 8: - return "0x%2.2x" % (uval) - elif bit_size == 16: - return "0x%4.4x" % (uval) - elif bit_size == 32: - return "0x%8.8x" % (uval) - elif bit_size == 64: - return "0x%16.16x" % (uval) - bytes = list() - uval = packet.get_hex_uint8() - while uval is not None: - bytes.append(uval) - uval = packet.get_hex_uint8() - value_str = "0x" - if g_byte_order == "little": - bytes.reverse() - for byte in bytes: - value_str += "%2.2x" % byte - return "%s" % (value_str) - - def __str__(self): - """Dump the register info key/value pairs""" - s = "" - for key in self.info.keys(): - if s: - s += ", " - s += "%s=%s " % (key, self.info[key]) - return s - - -class Packet: - """Class that represents a packet that contains string data""" - - def __init__(self, packet_str): - self.str = packet_str - - def peek_char(self): - ch = 0 - if self.str: - ch = self.str[0] - return ch - - def get_char(self): - ch = 0 - if self.str: - ch = self.str[0] - self.str = self.str[1:] - return ch - - def skip_exact_string(self, s): - if self.str and self.str.startswith(s): - self.str = self.str[len(s) :] - return True - else: - return False - - def get_thread_id(self, fail_value=-1): - match = g_number_regex.match(self.str) - if match: - number_str = match.group(1) - self.str = self.str[len(number_str) :] - return int(number_str, 0) - else: - return fail_value - - def get_hex_uint8(self): - if ( - self.str - and len(self.str) >= 2 - and self.str[0] in string.hexdigits - and self.str[1] in string.hexdigits - ): - uval = int(self.str[0:2], 16) - self.str = self.str[2:] - return uval - return None - - def get_hex_uint16(self, byte_order): - uval = 0 - if byte_order == "big": - uval |= self.get_hex_uint8() << 8 - uval |= self.get_hex_uint8() - else: - uval |= self.get_hex_uint8() - uval |= self.get_hex_uint8() << 8 - return uval - - def get_hex_uint32(self, byte_order): - uval = 0 - if byte_order == "big": - uval |= self.get_hex_uint8() << 24 - uval |= self.get_hex_uint8() << 16 - uval |= self.get_hex_uint8() << 8 - uval |= self.get_hex_uint8() - else: - uval |= self.get_hex_uint8() - uval |= self.get_hex_uint8() << 8 - uval |= self.get_hex_uint8() << 16 - uval |= self.get_hex_uint8() << 24 - return uval - - def get_hex_uint64(self, byte_order): - uval = 0 - if byte_order == "big": - uval |= self.get_hex_uint8() << 56 - uval |= self.get_hex_uint8() << 48 - uval |= self.get_hex_uint8() << 40 - uval |= self.get_hex_uint8() << 32 - uval |= self.get_hex_uint8() << 24 - uval |= self.get_hex_uint8() << 16 - uval |= self.get_hex_uint8() << 8 - uval |= self.get_hex_uint8() - else: - uval |= self.get_hex_uint8() - uval |= self.get_hex_uint8() << 8 - uval |= self.get_hex_uint8() << 16 - uval |= self.get_hex_uint8() << 24 - uval |= self.get_hex_uint8() << 32 - uval |= self.get_hex_uint8() << 40 - uval |= self.get_hex_uint8() << 48 - uval |= self.get_hex_uint8() << 56 - return uval - - def get_number(self, fail_value=-1): - """Get a number from the packet. The number must be in big endian format and should be parsed - according to its prefix (starts with "0x" means hex, starts with "0" means octal, starts with - [1-9] means decimal, etc)""" - match = g_number_regex.match(self.str) - if match: - number_str = match.group(1) - self.str = self.str[len(number_str) :] - return int(number_str, 0) - else: - return fail_value - - def get_hex_ascii_str(self, n=0): - hex_chars = self.get_hex_chars(n) - if hex_chars: - return binascii.unhexlify(hex_chars) - else: - return None - - def get_hex_chars(self, n=0): - str_len = len(self.str) - if n == 0: - # n was zero, so we need to determine all hex chars and - # stop when we hit the end of the string of a non-hex character - while n < str_len and self.str[n] in string.hexdigits: - n = n + 1 - else: - if n > str_len: - return None # Not enough chars - # Verify all chars are hex if a length was specified - for i in range(n): - if self.str[i] not in string.hexdigits: - return None # Not all hex digits - if n == 0: - return None - hex_str = self.str[0:n] - self.str = self.str[n:] - return hex_str - - def get_hex_uint(self, byte_order, n=0): - if byte_order == "big": - hex_str = self.get_hex_chars(n) - if hex_str is None: - return None - return int(hex_str, 16) - else: - uval = self.get_hex_uint8() - if uval is None: - return None - uval_result = 0 - shift = 0 - while uval is not None: - uval_result |= uval << shift - shift += 8 - uval = self.get_hex_uint8() - return uval_result - - def get_key_value_pairs(self): - kvp = list() - if ";" in self.str: - key_value_pairs = self.str.split(";") - for key_value_pair in key_value_pairs: - if len(key_value_pair): - kvp.append(key_value_pair.split(":", 1)) - return kvp - - def split(self, ch): - return self.str.split(ch) - - def split_hex(self, ch, byte_order): - hex_values = list() - strings = self.str.split(ch) - for str in strings: - hex_values.append(Packet(str).get_hex_uint(byte_order)) - return hex_values - - def __str__(self): - return self.str - - def __len__(self): - return len(self.str) - - -g_thread_suffix_regex = re.compile(";thread:([0-9a-fA-F]+);") - - -def get_thread_from_thread_suffix(str): - if str: - match = g_thread_suffix_regex.match(str) - if match: - return int(match.group(1), 16) - return None - - -def cmd_qThreadStopInfo(options, cmd, args): - packet = Packet(args) - tid = packet.get_hex_uint("big") - print("get_thread_stop_info (tid = 0x%x)" % (tid)) - - -def cmd_stop_reply(options, cmd, args): - print("get_last_stop_info()") - return False - - -def rsp_stop_reply(options, cmd, cmd_args, rsp): - global g_byte_order - packet = Packet(rsp) - stop_type = packet.get_char() - if stop_type == "T" or stop_type == "S": - signo = packet.get_hex_uint8() - key_value_pairs = packet.get_key_value_pairs() - for key_value_pair in key_value_pairs: - key = key_value_pair[0] - if is_hex_byte(key): - reg_num = Packet(key).get_hex_uint8() - if reg_num < len(g_register_infos): - reg_info = g_register_infos[reg_num] - key_value_pair[0] = reg_info.name() - key_value_pair[1] = reg_info.get_value_from_hex_string( - key_value_pair[1] - ) - elif key == "jthreads" or key == "jstopinfo": - key_value_pair[1] = binascii.unhexlify(key_value_pair[1]) - key_value_pairs.insert(0, ["signal", signo]) - print("stop_reply():") - dump_key_value_pairs(key_value_pairs) - elif stop_type == "W": - exit_status = packet.get_hex_uint8() - print("stop_reply(): exit (status=%i)" % exit_status) - elif stop_type == "O": - print('stop_reply(): stdout = "%s"' % packet.str) - - -def cmd_unknown_packet(options, cmd, args): - if args: - print("cmd: %s, args: %s", cmd, args) - else: - print("cmd: %s", cmd) - return False - - -def cmd_qSymbol(options, cmd, args): - if args == ":": - print("ready to serve symbols") - else: - packet = Packet(args) - symbol_addr = packet.get_hex_uint("big") - if symbol_addr is None: - if packet.skip_exact_string(":"): - symbol_name = packet.get_hex_ascii_str() - print('lookup_symbol("%s") -> symbol not available yet' % (symbol_name)) - else: - print("error: bad command format") - else: - if packet.skip_exact_string(":"): - symbol_name = packet.get_hex_ascii_str() - print('lookup_symbol("%s") -> 0x%x' % (symbol_name, symbol_addr)) - else: - print("error: bad command format") - - -def cmd_QSetWithHexString(options, cmd, args): - print('%s("%s")' % (cmd[:-1], binascii.unhexlify(args))) - - -def cmd_QSetWithString(options, cmd, args): - print('%s("%s")' % (cmd[:-1], args)) - - -def cmd_QSetWithUnsigned(options, cmd, args): - print("%s(%i)" % (cmd[:-1], int(args))) - - -def rsp_qSymbol(options, cmd, cmd_args, rsp): - if len(rsp) == 0: - print("Unsupported") - else: - if rsp == "OK": - print("No more symbols to lookup") - else: - packet = Packet(rsp) - if packet.skip_exact_string("qSymbol:"): - symbol_name = packet.get_hex_ascii_str() - print('lookup_symbol("%s")' % (symbol_name)) - else: - print( - 'error: response string should start with "qSymbol:": respnse is "%s"' - % (rsp) - ) - - -def cmd_qXfer(options, cmd, args): - # $qXfer:features:read:target.xml:0,1ffff#14 - print("read target special data %s" % (args)) - return True - - -def rsp_qXfer(options, cmd, cmd_args, rsp): - data = cmd_args.split(":") - if data[0] == "features": - if data[1] == "read": - filename, extension = os.path.splitext(data[2]) - if extension == ".xml": - response = Packet(rsp) - xml_string = response.get_hex_ascii_str() - if xml_string: - ch = xml_string[0] - if ch == "l": - xml_string = xml_string[1:] - xml_root = ET.fromstring(xml_string) - for reg_element in xml_root.findall("./feature/reg"): - if not "value_regnums" in reg_element.attrib: - reg_info = RegisterInfo([]) - if "name" in reg_element.attrib: - reg_info.info["name"] = reg_element.attrib["name"] - else: - reg_info.info["name"] = "unspecified" - if "encoding" in reg_element.attrib: - reg_info.info["encoding"] = reg_element.attrib[ - "encoding" - ] - else: - reg_info.info["encoding"] = "uint" - if "offset" in reg_element.attrib: - reg_info.info["offset"] = reg_element.attrib[ - "offset" - ] - if "bitsize" in reg_element.attrib: - reg_info.info["bitsize"] = reg_element.attrib[ - "bitsize" - ] - g_register_infos.append(reg_info) - print('XML for "%s":' % (data[2])) - ET.dump(xml_root) - - -def cmd_A(options, cmd, args): - print("launch process:") - packet = Packet(args) - while True: - arg_len = packet.get_number() - if arg_len == -1: - break - if not packet.skip_exact_string(","): - break - arg_idx = packet.get_number() - if arg_idx == -1: - break - if not packet.skip_exact_string(","): - break - arg_value = packet.get_hex_ascii_str(arg_len) - print('argv[%u] = "%s"' % (arg_idx, arg_value)) - - -def cmd_qC(options, cmd, args): - print("query_current_thread_id()") - - -def rsp_qC(options, cmd, cmd_args, rsp): - packet = Packet(rsp) - if packet.skip_exact_string("QC"): - tid = packet.get_thread_id() - print("current_thread_id = %#x" % (tid)) - else: - print("current_thread_id = old thread ID") - - -def cmd_query_packet(options, cmd, args): - if args: - print("%s%s" % (cmd, args)) - else: - print("%s" % (cmd)) - return False - - -def rsp_ok_error(rsp): - print("rsp: ", rsp) - - -def rsp_ok_means_supported(options, cmd, cmd_args, rsp): - if rsp == "OK": - print("%s%s is supported" % (cmd, cmd_args)) - elif rsp == "": - print("%s%s is not supported" % (cmd, cmd_args)) - else: - print("%s%s -> %s" % (cmd, cmd_args, rsp)) - - -def rsp_ok_means_success(options, cmd, cmd_args, rsp): - if rsp == "OK": - print("success") - elif rsp == "": - print("%s%s is not supported" % (cmd, cmd_args)) - else: - print("%s%s -> %s" % (cmd, cmd_args, rsp)) - - -def dump_key_value_pairs(key_value_pairs): - max_key_len = 0 - for key_value_pair in key_value_pairs: - key_len = len(key_value_pair[0]) - if max_key_len < key_len: - max_key_len = key_len - for key_value_pair in key_value_pairs: - key = key_value_pair[0] - value = key_value_pair[1] - unhex_value = get_hex_string_if_all_printable(value) - if unhex_value: - print("%*s = %s (%s)" % (max_key_len, key, value, unhex_value)) - else: - print("%*s = %s" % (max_key_len, key, value)) - - -def rsp_dump_key_value_pairs(options, cmd, cmd_args, rsp): - if rsp: - print("%s response:" % (cmd)) - packet = Packet(rsp) - key_value_pairs = packet.get_key_value_pairs() - dump_key_value_pairs(key_value_pairs) - else: - print("not supported") - - -def cmd_c(options, cmd, args): - print("continue()") - return False - - -def cmd_s(options, cmd, args): - print("step()") - return False - - -def cmd_qSpeedTest(options, cmd, args): - print(("qSpeedTest: cmd='%s', args='%s'" % (cmd, args))) - - -def rsp_qSpeedTest(options, cmd, cmd_args, rsp): - print(("qSpeedTest: rsp='%s' cmd='%s', args='%s'" % (rsp, cmd, args))) - - -def cmd_vCont(options, cmd, args): - if args == "?": - print("%s: get supported extended continue modes" % (cmd)) - else: - got_other_threads = 0 - s = "" - for thread_action in args[1:].split(";"): - (short_action, thread) = thread_action.split(":", 1) - tid = int(thread, 16) - if short_action == "c": - action = "continue" - elif short_action == "s": - action = "step" - elif short_action[0] == "C": - action = "continue with signal 0x%s" % (short_action[1:]) - elif short_action == "S": - action = "step with signal 0x%s" % (short_action[1:]) - else: - action = short_action - if s: - s += ", " - if tid == -1: - got_other_threads = 1 - s += "other-threads:" - else: - s += "thread 0x%4.4x: %s" % (tid, action) - if got_other_threads: - print("extended_continue (%s)" % (s)) - else: - print("extended_continue (%s, other-threads: suspend)" % (s)) - return False - - -def rsp_vCont(options, cmd, cmd_args, rsp): - if cmd_args == "?": - # Skip the leading 'vCont;' - rsp = rsp[6:] - modes = rsp.split(";") - s = "%s: supported extended continue modes include: " % (cmd) - - for i, mode in enumerate(modes): - if i: - s += ", " - if mode == "c": - s += "continue" - elif mode == "C": - s += "continue with signal" - elif mode == "s": - s += "step" - elif mode == "S": - s += "step with signal" - elif mode == "t": - s += "stop" - # else: - # s += 'unrecognized vCont mode: ', str(mode) - print(s) - elif rsp: - if rsp[0] == "T" or rsp[0] == "S" or rsp[0] == "W" or rsp[0] == "X": - rsp_stop_reply(options, cmd, cmd_args, rsp) - return - if rsp[0] == "O": - print("stdout: %s" % (rsp)) - return - else: - print( - "not supported (cmd = '%s', args = '%s', rsp = '%s')" % (cmd, cmd_args, rsp) - ) - - -def cmd_vAttach(options, cmd, args): - (extra_command, args) = args.split(";") - if extra_command: - print("%s%s(%s)" % (cmd, extra_command, args)) - else: - print("attach(pid = %u)" % int(args, 16)) - return False - - -def cmd_qRegisterInfo(options, cmd, args): - print("query_register_info(reg_num=%i)" % (int(args, 16))) - return False - - -def rsp_qRegisterInfo(options, cmd, cmd_args, rsp): - global g_max_register_info_name_len - print("query_register_info(reg_num=%i):" % (int(cmd_args, 16)), end=" ") - if len(rsp) == 3 and rsp[0] == "E": - g_max_register_info_name_len = 0 - for reg_info in g_register_infos: - name_len = len(reg_info.name()) - if g_max_register_info_name_len < name_len: - g_max_register_info_name_len = name_len - print(" DONE") - else: - packet = Packet(rsp) - reg_info = RegisterInfo(packet.get_key_value_pairs()) - g_register_infos.append(reg_info) - print(reg_info) - return False - - -def cmd_qThreadInfo(options, cmd, args): - if cmd == "qfThreadInfo": - query_type = "first" - else: - query_type = "subsequent" - print("get_current_thread_list(type=%s)" % (query_type)) - return False - - -def rsp_qThreadInfo(options, cmd, cmd_args, rsp): - packet = Packet(rsp) - response_type = packet.get_char() - if response_type == "m": - tids = packet.split_hex(";", "big") - for i, tid in enumerate(tids): - if i: - print(",", end=" ") - print("0x%x" % (tid), end=" ") - print() - elif response_type == "l": - print("END") - - -def rsp_hex_big_endian(options, cmd, cmd_args, rsp): - if rsp == "": - print("%s%s is not supported" % (cmd, cmd_args)) - else: - packet = Packet(rsp) - uval = packet.get_hex_uint("big") - print("%s: 0x%x" % (cmd, uval)) - - -def cmd_read_mem_bin(options, cmd, args): - # x0x7fff5fc39200,0x200 - packet = Packet(args) - addr = packet.get_hex_uint("big") - comma = packet.get_char() - size = packet.get_hex_uint("big") - print("binary_read_memory (addr = 0x%16.16x, size = %u)" % (addr, size)) - return False - - -def rsp_mem_bin_bytes(options, cmd, cmd_args, rsp): - packet = Packet(cmd_args) - addr = packet.get_hex_uint("big") - comma = packet.get_char() - size = packet.get_hex_uint("big") - print("memory:") - if size > 0: - dump_hex_memory_buffer(addr, rsp) - - -def cmd_read_memory(options, cmd, args): - packet = Packet(args) - addr = packet.get_hex_uint("big") - comma = packet.get_char() - size = packet.get_hex_uint("big") - print("read_memory (addr = 0x%16.16x, size = %u)" % (addr, size)) - return False - - -def dump_hex_memory_buffer(addr, hex_byte_str): - packet = Packet(hex_byte_str) - idx = 0 - ascii = "" - uval = packet.get_hex_uint8() - while uval is not None: - if (idx % 16) == 0: - if ascii: - print(" ", ascii) - ascii = "" - print("0x%x:" % (addr + idx), end=" ") - print("%2.2x" % (uval), end=" ") - if 0x20 <= uval and uval < 0x7F: - ascii += "%c" % uval - else: - ascii += "." - uval = packet.get_hex_uint8() - idx = idx + 1 - if ascii: - print(" ", ascii) - ascii = "" - - -def cmd_write_memory(options, cmd, args): - packet = Packet(args) - addr = packet.get_hex_uint("big") - if packet.get_char() != ",": - print("error: invalid write memory command (missing comma after address)") - return - size = packet.get_hex_uint("big") - if packet.get_char() != ":": - print("error: invalid write memory command (missing colon after size)") - return - print("write_memory (addr = 0x%16.16x, size = %u, data:" % (addr, size)) - dump_hex_memory_buffer(addr, packet.str) - return False - - -def cmd_alloc_memory(options, cmd, args): - packet = Packet(args) - byte_size = packet.get_hex_uint("big") - if packet.get_char() != ",": - print("error: invalid allocate memory command (missing comma after address)") - return - print( - "allocate_memory (byte-size = %u (0x%x), permissions = %s)" - % (byte_size, byte_size, packet.str) - ) - return False - - -def rsp_alloc_memory(options, cmd, cmd_args, rsp): - packet = Packet(rsp) - addr = packet.get_hex_uint("big") - print("addr = 0x%x" % addr) - - -def cmd_dealloc_memory(options, cmd, args): - packet = Packet(args) - addr = packet.get_hex_uint("big") - if packet.get_char() != ",": - print("error: invalid allocate memory command (missing comma after address)") - else: - print("deallocate_memory (addr = 0x%x, permissions = %s)" % (addr, packet.str)) - return False - - -def rsp_memory_bytes(options, cmd, cmd_args, rsp): - addr = Packet(cmd_args).get_hex_uint("big") - dump_hex_memory_buffer(addr, rsp) - - -def get_register_name_equal_value(options, reg_num, hex_value_str): - if reg_num < len(g_register_infos): - reg_info = g_register_infos[reg_num] - value_str = reg_info.get_value_from_hex_string(hex_value_str) - s = reg_info.name() + " = " - if options.symbolicator: - symbolicated_addresses = options.symbolicator.symbolicate(int(value_str, 0)) - if symbolicated_addresses: - s += options.colors.magenta() - s += "%s" % symbolicated_addresses[0] - s += options.colors.reset() - return s - s += value_str - return s - else: - reg_value = Packet(hex_value_str).get_hex_uint(g_byte_order) - return "reg(%u) = 0x%x" % (reg_num, reg_value) - - -def cmd_read_one_reg(options, cmd, args): - packet = Packet(args) - reg_num = packet.get_hex_uint("big") - tid = get_thread_from_thread_suffix(packet.str) - name = None - if reg_num < len(g_register_infos): - name = g_register_infos[reg_num].name() - if packet.str: - packet.get_char() # skip ; - thread_info = packet.get_key_value_pairs() - tid = int(thread_info[0][1], 16) - s = "read_register (reg_num=%u" % reg_num - if name: - s += " (%s)" % (name) - if tid is not None: - s += ", tid = 0x%4.4x" % (tid) - s += ")" - print(s) - return False - - -def rsp_read_one_reg(options, cmd, cmd_args, rsp): - packet = Packet(cmd_args) - reg_num = packet.get_hex_uint("big") - print(get_register_name_equal_value(options, reg_num, rsp)) - - -def cmd_write_one_reg(options, cmd, args): - packet = Packet(args) - reg_num = packet.get_hex_uint("big") - if packet.get_char() != "=": - print("error: invalid register write packet") - else: - name = None - hex_value_str = packet.get_hex_chars() - tid = get_thread_from_thread_suffix(packet.str) - s = "write_register (reg_num=%u" % reg_num - if name: - s += " (%s)" % (name) - s += ", value = " - s += get_register_name_equal_value(options, reg_num, hex_value_str) - if tid is not None: - s += ", tid = 0x%4.4x" % (tid) - s += ")" - print(s) - return False - - -def dump_all_regs(packet): - for reg_info in g_register_infos: - nibble_size = reg_info.bit_size() / 4 - hex_value_str = packet.get_hex_chars(nibble_size) - if hex_value_str is not None: - value = reg_info.get_value_from_hex_string(hex_value_str) - print("%*s = %s" % (g_max_register_info_name_len, reg_info.name(), value)) - else: - return - - -def cmd_read_all_regs(cmd, cmd_args): - packet = Packet(cmd_args) - packet.get_char() # toss the 'g' command character - tid = get_thread_from_thread_suffix(packet.str) - if tid is not None: - print("read_all_register(thread = 0x%4.4x)" % tid) - else: - print("read_all_register()") - return False - - -def rsp_read_all_regs(options, cmd, cmd_args, rsp): - packet = Packet(rsp) - dump_all_regs(packet) - - -def cmd_write_all_regs(options, cmd, args): - packet = Packet(args) - print("write_all_registers()") - dump_all_regs(packet) - return False - - -g_bp_types = ["software_bp", "hardware_bp", "write_wp", "read_wp", "access_wp"] - - -def cmd_bp(options, cmd, args): - if cmd == "Z": - s = "set_" - else: - s = "clear_" - packet = Packet(args) - bp_type = packet.get_hex_uint("big") - packet.get_char() # Skip , - bp_addr = packet.get_hex_uint("big") - packet.get_char() # Skip , - bp_size = packet.get_hex_uint("big") - s += g_bp_types[bp_type] - s += " (addr = 0x%x, size = %u)" % (bp_addr, bp_size) - print(s) - return False - - -def cmd_mem_rgn_info(options, cmd, args): - packet = Packet(args) - packet.get_char() # skip ':' character - addr = packet.get_hex_uint("big") - print("get_memory_region_info (addr=0x%x)" % (addr)) - return False - - -def cmd_kill(options, cmd, args): - print("kill_process()") - return False - - -def cmd_jThreadsInfo(options, cmd, args): - print("jThreadsInfo()") - return False - - -def cmd_jGetLoadedDynamicLibrariesInfos(options, cmd, args): - print("jGetLoadedDynamicLibrariesInfos()") - return False - - -def decode_packet(s, start_index=0): - # print '\ndecode_packet("%s")' % (s[start_index:]) - index = s.find("}", start_index) - have_escapes = index != -1 - if have_escapes: - normal_s = s[start_index:index] - else: - normal_s = s[start_index:] - # print 'normal_s = "%s"' % (normal_s) - if have_escapes: - escape_char = "%c" % (ord(s[index + 1]) ^ 0x20) - # print 'escape_char for "%s" = %c' % (s[index:index+2], escape_char) - return normal_s + escape_char + decode_packet(s, index + 2) - else: - return normal_s - - -def rsp_json(options, cmd, cmd_args, rsp): - print("%s() reply:" % (cmd)) - if not rsp: - return - try: - json_tree = json.loads(rsp) - print(json.dumps(json_tree, indent=4, separators=(",", ": "))) - except json.JSONDecodeError: - return - - -def rsp_jGetLoadedDynamicLibrariesInfos(options, cmd, cmd_args, rsp): - if cmd_args: - rsp_json(options, cmd, cmd_args, rsp) - else: - rsp_ok_means_supported(options, cmd, cmd_args, rsp) - - -gdb_remote_commands = { - "\\?": {"cmd": cmd_stop_reply, "rsp": rsp_stop_reply, "name": "stop reply pacpket"}, - "qThreadStopInfo": { - "cmd": cmd_qThreadStopInfo, - "rsp": rsp_stop_reply, - "name": "stop reply pacpket", - }, - "QStartNoAckMode": { - "cmd": cmd_query_packet, - "rsp": rsp_ok_means_supported, - "name": "query if no ack mode is supported", - }, - "QThreadSuffixSupported": { - "cmd": cmd_query_packet, - "rsp": rsp_ok_means_supported, - "name": "query if thread suffix is supported", - }, - "QListThreadsInStopReply": { - "cmd": cmd_query_packet, - "rsp": rsp_ok_means_supported, - "name": "query if threads in stop reply packets are supported", - }, - "QSetDetachOnError:": { - "cmd": cmd_QSetWithUnsigned, - "rsp": rsp_ok_means_success, - "name": "set if we should detach on error", - }, - "QSetDisableASLR:": { - "cmd": cmd_QSetWithUnsigned, - "rsp": rsp_ok_means_success, - "name": "set if we should disable ASLR", - }, - "qLaunchSuccess": { - "cmd": cmd_query_packet, - "rsp": rsp_ok_means_success, - "name": "check on launch success for the A packet", - }, - "A": {"cmd": cmd_A, "rsp": rsp_ok_means_success, "name": "launch process"}, - "QLaunchArch:": { - "cmd": cmd_QSetWithString, - "rsp": rsp_ok_means_supported, - "name": "set the arch to launch in case the file contains multiple architectures", - }, - "qVAttachOrWaitSupported": { - "cmd": cmd_query_packet, - "rsp": rsp_ok_means_supported, - "name": "set the launch architecture", - }, - "qHostInfo": { - "cmd": cmd_query_packet, - "rsp": rsp_dump_key_value_pairs, - "name": "get host information", - }, - "qC": {"cmd": cmd_qC, "rsp": rsp_qC, "name": "return the current thread ID"}, - "vCont": {"cmd": cmd_vCont, "rsp": rsp_vCont, "name": "extended continue command"}, - "qSpeedTest": { - "cmd": cmd_qSpeedTest, - "rsp": rsp_qSpeedTest, - "name": "speed test packdet", - }, - "vAttach": {"cmd": cmd_vAttach, "rsp": rsp_stop_reply, "name": "attach to process"}, - "c": {"cmd": cmd_c, "rsp": rsp_stop_reply, "name": "continue"}, - "s": {"cmd": cmd_s, "rsp": rsp_stop_reply, "name": "step"}, - "qRegisterInfo": { - "cmd": cmd_qRegisterInfo, - "rsp": rsp_qRegisterInfo, - "name": "query register info", - }, - "qfThreadInfo": { - "cmd": cmd_qThreadInfo, - "rsp": rsp_qThreadInfo, - "name": "get current thread list", - }, - "qsThreadInfo": { - "cmd": cmd_qThreadInfo, - "rsp": rsp_qThreadInfo, - "name": "get current thread list", - }, - "qShlibInfoAddr": { - "cmd": cmd_query_packet, - "rsp": rsp_hex_big_endian, - "name": "get shared library info address", - }, - "qMemoryRegionInfo": { - "cmd": cmd_mem_rgn_info, - "rsp": rsp_dump_key_value_pairs, - "name": "get memory region information", - }, - "qProcessInfo": { - "cmd": cmd_query_packet, - "rsp": rsp_dump_key_value_pairs, - "name": "get process info", - }, - "qSupported": { - "cmd": cmd_query_packet, - "rsp": rsp_ok_means_supported, - "name": "query supported", - }, - "qXfer:": {"cmd": cmd_qXfer, "rsp": rsp_qXfer, "name": "qXfer"}, - "qSymbol:": {"cmd": cmd_qSymbol, "rsp": rsp_qSymbol, "name": "qSymbol"}, - "QSetSTDIN:": { - "cmd": cmd_QSetWithHexString, - "rsp": rsp_ok_means_success, - "name": "set STDIN prior to launching with A packet", - }, - "QSetSTDOUT:": { - "cmd": cmd_QSetWithHexString, - "rsp": rsp_ok_means_success, - "name": "set STDOUT prior to launching with A packet", - }, - "QSetSTDERR:": { - "cmd": cmd_QSetWithHexString, - "rsp": rsp_ok_means_success, - "name": "set STDERR prior to launching with A packet", - }, - "QEnvironment:": { - "cmd": cmd_QSetWithString, - "rsp": rsp_ok_means_success, - "name": "set an environment variable prior to launching with A packet", - }, - "QEnvironmentHexEncoded:": { - "cmd": cmd_QSetWithHexString, - "rsp": rsp_ok_means_success, - "name": "set an environment variable prior to launching with A packet", - }, - "x": { - "cmd": cmd_read_mem_bin, - "rsp": rsp_mem_bin_bytes, - "name": "read memory binary", - }, - "X": { - "cmd": cmd_write_memory, - "rsp": rsp_ok_means_success, - "name": "write memory binary", - }, - "m": {"cmd": cmd_read_memory, "rsp": rsp_memory_bytes, "name": "read memory"}, - "M": {"cmd": cmd_write_memory, "rsp": rsp_ok_means_success, "name": "write memory"}, - "_M": {"cmd": cmd_alloc_memory, "rsp": rsp_alloc_memory, "name": "allocate memory"}, - "_m": { - "cmd": cmd_dealloc_memory, - "rsp": rsp_ok_means_success, - "name": "deallocate memory", - }, - "p": { - "cmd": cmd_read_one_reg, - "rsp": rsp_read_one_reg, - "name": "read single register", - }, - "P": { - "cmd": cmd_write_one_reg, - "rsp": rsp_ok_means_success, - "name": "write single register", - }, - "g": { - "cmd": cmd_read_all_regs, - "rsp": rsp_read_all_regs, - "name": "read all registers", - }, - "G": { - "cmd": cmd_write_all_regs, - "rsp": rsp_ok_means_success, - "name": "write all registers", - }, - "z": { - "cmd": cmd_bp, - "rsp": rsp_ok_means_success, - "name": "clear breakpoint or watchpoint", - }, - "Z": { - "cmd": cmd_bp, - "rsp": rsp_ok_means_success, - "name": "set breakpoint or watchpoint", - }, - "k": {"cmd": cmd_kill, "rsp": rsp_stop_reply, "name": "kill process"}, - "jThreadsInfo": { - "cmd": cmd_jThreadsInfo, - "rsp": rsp_json, - "name": "JSON get all threads info", - }, - "jGetLoadedDynamicLibrariesInfos:": { - "cmd": cmd_jGetLoadedDynamicLibrariesInfos, - "rsp": rsp_jGetLoadedDynamicLibrariesInfos, - "name": "JSON get loaded dynamic libraries", - }, -} - - -def calculate_mean_and_standard_deviation(floats): - sum = 0.0 - count = len(floats) - if count == 0: - return (0.0, 0.0) - for f in floats: - sum += f - mean = sum / count - accum = 0.0 - for f in floats: - delta = f - mean - accum += delta * delta - - std_dev = math.sqrt(accum / (count - 1)) - return (mean, std_dev) - - -def parse_gdb_log_file(path, options): - f = open(path) - parse_gdb_log(f, options) - f.close() - - -def round_up(n, incr): - return float(((int(n) + incr) / incr) * incr) - - -def plot_latencies(sec_times): - # import numpy as np - import matplotlib.pyplot as plt - - for i, name in enumerate(sec_times.keys()): - times = sec_times[name] - if len(times) <= 1: - continue - plt.subplot(2, 1, 1) - plt.title('Packet "%s" Times' % (name)) - plt.xlabel("Packet") - units = "ms" - adj_times = [] - max_time = 0.0 - for time in times: - time = time * 1000.0 - adj_times.append(time) - if time > max_time: - max_time = time - if max_time < 1.0: - units = "us" - max_time = 0.0 - for i in range(len(adj_times)): - adj_times[i] *= 1000.0 - if adj_times[i] > max_time: - max_time = adj_times[i] - plt.ylabel("Time (%s)" % (units)) - max_y = None - for i in [5.0, 10.0, 25.0, 50.0]: - if max_time < i: - max_y = round_up(max_time, i) - break - if max_y is None: - max_y = round_up(max_time, 100.0) - plt.ylim(0.0, max_y) - plt.plot(adj_times, "o-") - plt.show() - - -def parse_gdb_log(file, options): - """Parse a GDB log file that was generated by enabling logging with: - (lldb) log enable --threadsafe --timestamp --file gdb-remote packets - This log file will contain timestamps and this function will then normalize - those packets to be relative to the first value timestamp that is found and - show delta times between log lines and also keep track of how long it takes - for GDB remote commands to make a send/receive round trip. This can be - handy when trying to figure out why some operation in the debugger is taking - a long time during a preset set of debugger commands.""" - - tricky_commands = ["qRegisterInfo"] - timestamp_regex = re.compile(r"(\s*)([1-9][0-9]+\.[0-9]+)([^0-9].*)$") - packet_name_regex = re.compile("([A-Za-z_]+)[^a-z]") - packet_transmit_name_regex = re.compile( - "(?Psend|read) packet: (?P.*)" - ) - packet_contents_name_regex = re.compile(r"\$([^#]*)#[0-9a-fA-F]{2}") - packet_checksum_regex = re.compile(".*#[0-9a-fA-F]{2}$") - packet_names_regex_str = "(" + "|".join(gdb_remote_commands.keys()) + ")(.*)" - packet_names_regex = re.compile(packet_names_regex_str) - - base_time = 0.0 - last_time = 0.0 - min_time = 100000000.0 - packet_total_times = {} - all_packet_times = [] - packet_times = {} - packet_counts = {} - lines = file.read().splitlines() - last_command = None - last_command_args = None - last_command_packet = None - hide_next_response = False - num_lines = len(lines) - skip_count = 0 - for line_index, line in enumerate(lines): - # See if we need to skip any lines - if skip_count > 0: - skip_count -= 1 - continue - m = packet_transmit_name_regex.search(line) - is_command = False - direction = None - if m: - direction = m.group("direction") - is_command = direction == "send" - packet = m.group("packet") - sys.stdout.write(options.colors.green()) - if not options.quiet and not hide_next_response: - print("# ", line) - sys.stdout.write(options.colors.reset()) - - # print 'direction = "%s", packet = "%s"' % (direction, packet) - - if packet[0] == "+": - if is_command: - print("-->", end=" ") - else: - print("<--", end=" ") - if not options.quiet: - print("ACK") - continue - elif packet[0] == "-": - if is_command: - print("-->", end=" ") - else: - print("<--", end=" ") - if not options.quiet: - print("NACK") - continue - elif packet[0] == "$": - m = packet_contents_name_regex.match(packet) - if not m and packet[0] == "$": - multiline_packet = packet - idx = line_index + 1 - while idx < num_lines: - if not options.quiet and not hide_next_response: - print("# ", lines[idx]) - multiline_packet += lines[idx] - m = packet_contents_name_regex.match(multiline_packet) - if m: - packet = multiline_packet - skip_count = idx - line_index - break - else: - idx += 1 - if m: - if is_command: - print("-->", end=" ") - else: - print("<--", end=" ") - contents = decode_packet(m.group(1)) - if is_command: - hide_next_response = False - m = packet_names_regex.match(contents) - if m: - last_command = m.group(1) - if last_command == "?": - last_command = "\\?" - packet_name = last_command - last_command_args = m.group(2) - last_command_packet = contents - hide_next_response = gdb_remote_commands[last_command][ - "cmd" - ](options, last_command, last_command_args) - else: - packet_match = packet_name_regex.match(contents) - if packet_match: - packet_name = packet_match.group(1) - for tricky_cmd in tricky_commands: - if packet_name.find(tricky_cmd) == 0: - packet_name = tricky_cmd - else: - packet_name = contents - last_command = None - last_command_args = None - last_command_packet = None - elif last_command: - gdb_remote_commands[last_command]["rsp"]( - options, last_command, last_command_args, contents - ) - else: - print('error: invalid packet: "', packet, '"') - else: - print("???") - else: - print("## ", line) - match = timestamp_regex.match(line) - if match: - curr_time = float(match.group(2)) - if last_time and not is_command: - delta = curr_time - last_time - all_packet_times.append(delta) - delta = 0.0 - if base_time: - delta = curr_time - last_time - else: - base_time = curr_time - - if not is_command: - if line.find("read packet: $") >= 0 and packet_name: - if packet_name in packet_total_times: - packet_total_times[packet_name] += delta - packet_counts[packet_name] += 1 - else: - packet_total_times[packet_name] = delta - packet_counts[packet_name] = 1 - if packet_name not in packet_times: - packet_times[packet_name] = [] - packet_times[packet_name].append(delta) - packet_name = None - if min_time > delta: - min_time = delta - - if not options or not options.quiet: - print( - "%s%.6f %+.6f%s" - % (match.group(1), curr_time - base_time, delta, match.group(3)) - ) - last_time = curr_time - # else: - # print line - (average, std_dev) = calculate_mean_and_standard_deviation(all_packet_times) - if average and std_dev: - print( - "%u packets with average packet time of %f and standard deviation of %f" - % (len(all_packet_times), average, std_dev) - ) - if packet_total_times: - total_packet_time = 0.0 - total_packet_count = 0 - for key, vvv in packet_total_times.items(): - # print ' key = (%s) "%s"' % (type(key), key) - # print 'value = (%s) %s' % (type(vvv), vvv) - # if type(vvv) == 'float': - total_packet_time += vvv - for key, vvv in packet_counts.items(): - total_packet_count += vvv - - print("#------------------------------------------------------------") - print("# Packet timing summary:") - print( - "# Totals: time = %6f, count = %6d" - % (total_packet_time, total_packet_count) - ) - print("# Min packet time: time = %6f" % (min_time)) - print("#------------------------------------------------------------") - print("# Packet Time (sec) Percent Count Latency") - print("#------------------------- ----------- ------- ------ -------") - if options and options.sort_count: - res = sorted(packet_counts, key=packet_counts.__getitem__, reverse=True) - else: - res = sorted( - packet_total_times, key=packet_total_times.__getitem__, reverse=True - ) - - if last_time > 0.0: - for item in res: - packet_total_time = packet_total_times[item] - packet_percent = (packet_total_time / total_packet_time) * 100.0 - packet_count = packet_counts[item] - print( - " %24s %11.6f %5.2f%% %6d %9.6f" - % ( - item, - packet_total_time, - packet_percent, - packet_count, - float(packet_total_time) / float(packet_count), - ) - ) - if options and options.plot: - plot_latencies(packet_times) - - -if __name__ == "__main__": - usage = "usage: gdbremote [options]" - description = """The command disassembles a GDB remote packet log.""" - parser = optparse.OptionParser( - description=description, prog="gdbremote", usage=usage - ) - parser.add_option( - "-v", - "--verbose", - action="store_true", - dest="verbose", - help="display verbose debug info", - default=False, - ) - parser.add_option( - "-q", - "--quiet", - action="store_true", - dest="quiet", - help="display verbose debug info", - default=False, - ) - parser.add_option( - "-C", - "--color", - action="store_true", - dest="color", - help="add terminal colors", - default=False, - ) - parser.add_option( - "-c", - "--sort-by-count", - action="store_true", - dest="sort_count", - help="display verbose debug info", - default=False, - ) - parser.add_option( - "--crashlog", - type="string", - dest="crashlog", - help="symbolicate using a darwin crash log file", - default=False, - ) - try: - (options, args) = parser.parse_args(sys.argv[1:]) - except: - print("error: argument error") - sys.exit(1) - - options.colors = TerminalColors(options.color) - options.symbolicator = None - if options.crashlog: - import lldb - - lldb.debugger = lldb.SBDebugger.Create() - import lldb.macosx.crashlog - - options.symbolicator = lldb.macosx.crashlog.CrashLog(options.crashlog) - print("%s" % (options.symbolicator)) - - # This script is being run from the command line, create a debugger in case we are - # going to use any debugger functions in our function. - if len(args): - for file in args: - print( - "#----------------------------------------------------------------------" - ) - print("# GDB remote log file: '%s'" % file) - print( - "#----------------------------------------------------------------------" - ) - parse_gdb_log_file(file, options) - if options.symbolicator: - print("%s" % (options.symbolicator)) - else: - parse_gdb_log(sys.stdin, options) - - -def __lldb_init_module(debugger, internal_dict): - # This initializer is being run from LLDB in the embedded command interpreter - # Add any commands contained in this module to LLDB - debugger.HandleCommand( - "command script add -o -f gdbremote.start_gdb_log start_gdb_log" - ) - debugger.HandleCommand( - "command script add -o -f gdbremote.stop_gdb_log stop_gdb_log" - ) - print( - 'The "start_gdb_log" and "stop_gdb_log" commands are now installed and ready for use, type "start_gdb_log --help" or "stop_gdb_log --help" for more information' - ) +#!/usr/bin/env python + +# ---------------------------------------------------------------------- +# This module will enable GDB remote packet logging when the +# 'start_gdb_log' command is called with a filename to log to. When the +# 'stop_gdb_log' command is called, it will disable the logging and +# print out statistics about how long commands took to execute and also +# will primnt ou +# Be sure to add the python path that points to the LLDB shared library. +# +# To use this in the embedded python interpreter using "lldb" just +# import it with the full path using the "command script import" +# command. This can be done from the LLDB command line: +# (lldb) command script import /path/to/gdbremote.py +# Or it can be added to your ~/.lldbinit file so this module is always +# available. +# ---------------------------------------------------------------------- + +import binascii +import subprocess +import json +import math +import optparse +import os +import re +import shlex +import string +import sys +import tempfile +import xml.etree.ElementTree as ET + +# ---------------------------------------------------------------------- +# Global variables +# ---------------------------------------------------------------------- +g_log_file = "" +g_byte_order = "little" +g_number_regex = re.compile("^(0x[0-9a-fA-F]+|[0-9]+)") +g_thread_id_regex = re.compile("^(-1|[0-9a-fA-F]+|0)") + + +class TerminalColors: + """Simple terminal colors class""" + + def __init__(self, enabled=True): + # TODO: discover terminal type from "file" and disable if + # it can't handle the color codes + self.enabled = enabled + + def reset(self): + """Reset all terminal colors and formatting.""" + if self.enabled: + return "\x1b[0m" + return "" + + def bold(self, on=True): + """Enable or disable bold depending on the "on" parameter.""" + if self.enabled: + if on: + return "\x1b[1m" + else: + return "\x1b[22m" + return "" + + def italics(self, on=True): + """Enable or disable italics depending on the "on" parameter.""" + if self.enabled: + if on: + return "\x1b[3m" + else: + return "\x1b[23m" + return "" + + def underline(self, on=True): + """Enable or disable underline depending on the "on" parameter.""" + if self.enabled: + if on: + return "\x1b[4m" + else: + return "\x1b[24m" + return "" + + def inverse(self, on=True): + """Enable or disable inverse depending on the "on" parameter.""" + if self.enabled: + if on: + return "\x1b[7m" + else: + return "\x1b[27m" + return "" + + def strike(self, on=True): + """Enable or disable strike through depending on the "on" parameter.""" + if self.enabled: + if on: + return "\x1b[9m" + else: + return "\x1b[29m" + return "" + + def black(self, fg=True): + """Set the foreground or background color to black. + The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False. + """ + if self.enabled: + if fg: + return "\x1b[30m" + else: + return "\x1b[40m" + return "" + + def red(self, fg=True): + """Set the foreground or background color to red. + The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False. + """ + if self.enabled: + if fg: + return "\x1b[31m" + else: + return "\x1b[41m" + return "" + + def green(self, fg=True): + """Set the foreground or background color to green. + The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False. + """ + if self.enabled: + if fg: + return "\x1b[32m" + else: + return "\x1b[42m" + return "" + + def yellow(self, fg=True): + """Set the foreground or background color to yellow. + The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False. + """ + if self.enabled: + if fg: + return "\x1b[33m" + else: + return "\x1b[43m" + return "" + + def blue(self, fg=True): + """Set the foreground or background color to blue. + The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False. + """ + if self.enabled: + if fg: + return "\x1b[34m" + else: + return "\x1b[44m" + return "" + + def magenta(self, fg=True): + """Set the foreground or background color to magenta. + The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False. + """ + if self.enabled: + if fg: + return "\x1b[35m" + else: + return "\x1b[45m" + return "" + + def cyan(self, fg=True): + """Set the foreground or background color to cyan. + The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False. + """ + if self.enabled: + if fg: + return "\x1b[36m" + else: + return "\x1b[46m" + return "" + + def white(self, fg=True): + """Set the foreground or background color to white. + The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False. + """ + if self.enabled: + if fg: + return "\x1b[37m" + else: + return "\x1b[47m" + return "" + + def default(self, fg=True): + """Set the foreground or background color to the default. + The foreground color will be set if "fg" tests True. The background color will be set if "fg" tests False. + """ + if self.enabled: + if fg: + return "\x1b[39m" + else: + return "\x1b[49m" + return "" + + +def start_gdb_log(debugger, command, result, dict): + """Start logging GDB remote packets by enabling logging with timestamps and + thread safe logging. Follow a call to this function with a call to "stop_gdb_log" + in order to dump out the commands.""" + global g_log_file + command_args = shlex.split(command) + usage = "usage: start_gdb_log [options] []" + description = """The command enables GDB remote packet logging with timestamps. The packets will be logged to if supplied, or a temporary file will be used. Logging stops when stop_gdb_log is called and the packet times will + be aggregated and displayed.""" + parser = optparse.OptionParser( + description=description, prog="start_gdb_log", usage=usage + ) + parser.add_option( + "-v", + "--verbose", + action="store_true", + dest="verbose", + help="display verbose debug info", + default=False, + ) + try: + (options, args) = parser.parse_args(command_args) + except: + return + + if g_log_file: + result.PutCString( + 'error: logging is already in progress with file "%s"' % g_log_file + ) + else: + args_len = len(args) + if args_len == 0: + g_log_file = tempfile.NamedTemporaryFile(delete=False).name + elif len(args) == 1: + g_log_file = args[0] + + if g_log_file: + debugger.HandleCommand( + 'log enable --threadsafe --timestamp --file "%s" gdb-remote packets' + % g_log_file + ) + result.PutCString( + "GDB packet logging enable with log file '%s'\nUse the 'stop_gdb_log' command to stop logging and show packet statistics." + % g_log_file + ) + return + + result.PutCString("error: invalid log file path") + result.PutCString(usage) + + +def stop_gdb_log(debugger, command, result, dict): + """Stop logging GDB remote packets to the file that was specified in a call + to "start_gdb_log" and normalize the timestamps to be relative to the first + timestamp in the log file. Also print out statistics for how long each + command took to allow performance bottlenecks to be determined.""" + global g_log_file + # Any commands whose names might be followed by more valid C identifier + # characters must be listed here + command_args = shlex.split(command) + usage = "usage: stop_gdb_log [options]" + description = """The command stops a previously enabled GDB remote packet logging command. Packet logging must have been previously enabled with a call to start_gdb_log.""" + parser = optparse.OptionParser( + description=description, prog="stop_gdb_log", usage=usage + ) + parser.add_option( + "-v", + "--verbose", + action="store_true", + dest="verbose", + help="display verbose debug info", + default=False, + ) + parser.add_option( + "--plot", + action="store_true", + dest="plot", + help="plot packet latencies by packet type", + default=False, + ) + parser.add_option( + "-q", + "--quiet", + action="store_true", + dest="quiet", + help="display verbose debug info", + default=False, + ) + parser.add_option( + "-C", + "--color", + action="store_true", + dest="color", + help="add terminal colors", + default=False, + ) + parser.add_option( + "-c", + "--sort-by-count", + action="store_true", + dest="sort_count", + help="display verbose debug info", + default=False, + ) + parser.add_option( + "-s", + "--symbolicate", + action="store_true", + dest="symbolicate", + help='symbolicate addresses in log using current "lldb.target"', + default=False, + ) + try: + (options, args) = parser.parse_args(command_args) + except: + return + options.colors = TerminalColors(options.color) + options.symbolicator = None + if options.symbolicate: + if lldb.target: + import lldb.utils.symbolication + + options.symbolicator = lldb.utils.symbolication.Symbolicator() + options.symbolicator.target = lldb.target + else: + print("error: can't symbolicate without a target") + + if not g_log_file: + result.PutCString( + 'error: logging must have been previously enabled with a call to "stop_gdb_log"' + ) + elif os.path.exists(g_log_file): + if len(args) == 0: + debugger.HandleCommand("log disable gdb-remote packets") + result.PutCString( + "GDB packet logging disabled. Logged packets are in '%s'" % g_log_file + ) + parse_gdb_log_file(g_log_file, options) + else: + result.PutCString(usage) + else: + print('error: the GDB packet log file "%s" does not exist' % g_log_file) + + +def is_hex_byte(str): + if len(str) == 2: + return str[0] in string.hexdigits and str[1] in string.hexdigits + return False + + +def get_hex_string_if_all_printable(str): + try: + s = binascii.unhexlify(str).decode() + if all(c in string.printable for c in s): + return s + except (TypeError, binascii.Error, UnicodeDecodeError): + pass + return None + + +# global register info list +g_register_infos = list() +g_max_register_info_name_len = 0 + + +class RegisterInfo: + """Class that represents register information""" + + def __init__(self, kvp): + self.info = dict() + for kv in kvp: + key = kv[0] + value = kv[1] + self.info[key] = value + + def name(self): + """Get the name of the register.""" + if self.info and "name" in self.info: + return self.info["name"] + return None + + def bit_size(self): + """Get the size in bits of the register.""" + if self.info and "bitsize" in self.info: + return int(self.info["bitsize"]) + return 0 + + def byte_size(self): + """Get the size in bytes of the register.""" + return self.bit_size() / 8 + + def get_value_from_hex_string(self, hex_str): + """Dump the register value given a native byte order encoded hex ASCII byte string.""" + encoding = self.info["encoding"] + bit_size = self.bit_size() + packet = Packet(hex_str) + if encoding == "uint": + uval = packet.get_hex_uint(g_byte_order) + if bit_size == 8: + return "0x%2.2x" % (uval) + elif bit_size == 16: + return "0x%4.4x" % (uval) + elif bit_size == 32: + return "0x%8.8x" % (uval) + elif bit_size == 64: + return "0x%16.16x" % (uval) + bytes = list() + uval = packet.get_hex_uint8() + while uval is not None: + bytes.append(uval) + uval = packet.get_hex_uint8() + value_str = "0x" + if g_byte_order == "little": + bytes.reverse() + for byte in bytes: + value_str += "%2.2x" % byte + return "%s" % (value_str) + + def __str__(self): + """Dump the register info key/value pairs""" + s = "" + for key in self.info.keys(): + if s: + s += ", " + s += "%s=%s " % (key, self.info[key]) + return s + + +class Packet: + """Class that represents a packet that contains string data""" + + def __init__(self, packet_str): + self.str = packet_str + + def peek_char(self): + ch = 0 + if self.str: + ch = self.str[0] + return ch + + def get_char(self): + ch = 0 + if self.str: + ch = self.str[0] + self.str = self.str[1:] + return ch + + def skip_exact_string(self, s): + if self.str and self.str.startswith(s): + self.str = self.str[len(s) :] + return True + else: + return False + + def get_thread_id(self, fail_value=-1): + match = g_number_regex.match(self.str) + if match: + number_str = match.group(1) + self.str = self.str[len(number_str) :] + return int(number_str, 0) + else: + return fail_value + + def get_hex_uint8(self): + if ( + self.str + and len(self.str) >= 2 + and self.str[0] in string.hexdigits + and self.str[1] in string.hexdigits + ): + uval = int(self.str[0:2], 16) + self.str = self.str[2:] + return uval + return None + + def get_hex_uint16(self, byte_order): + uval = 0 + if byte_order == "big": + uval |= self.get_hex_uint8() << 8 + uval |= self.get_hex_uint8() + else: + uval |= self.get_hex_uint8() + uval |= self.get_hex_uint8() << 8 + return uval + + def get_hex_uint32(self, byte_order): + uval = 0 + if byte_order == "big": + uval |= self.get_hex_uint8() << 24 + uval |= self.get_hex_uint8() << 16 + uval |= self.get_hex_uint8() << 8 + uval |= self.get_hex_uint8() + else: + uval |= self.get_hex_uint8() + uval |= self.get_hex_uint8() << 8 + uval |= self.get_hex_uint8() << 16 + uval |= self.get_hex_uint8() << 24 + return uval + + def get_hex_uint64(self, byte_order): + uval = 0 + if byte_order == "big": + uval |= self.get_hex_uint8() << 56 + uval |= self.get_hex_uint8() << 48 + uval |= self.get_hex_uint8() << 40 + uval |= self.get_hex_uint8() << 32 + uval |= self.get_hex_uint8() << 24 + uval |= self.get_hex_uint8() << 16 + uval |= self.get_hex_uint8() << 8 + uval |= self.get_hex_uint8() + else: + uval |= self.get_hex_uint8() + uval |= self.get_hex_uint8() << 8 + uval |= self.get_hex_uint8() << 16 + uval |= self.get_hex_uint8() << 24 + uval |= self.get_hex_uint8() << 32 + uval |= self.get_hex_uint8() << 40 + uval |= self.get_hex_uint8() << 48 + uval |= self.get_hex_uint8() << 56 + return uval + + def get_number(self, fail_value=-1): + """Get a number from the packet. The number must be in big endian format and should be parsed + according to its prefix (starts with "0x" means hex, starts with "0" means octal, starts with + [1-9] means decimal, etc)""" + match = g_number_regex.match(self.str) + if match: + number_str = match.group(1) + self.str = self.str[len(number_str) :] + return int(number_str, 0) + else: + return fail_value + + def get_hex_ascii_str(self, n=0): + hex_chars = self.get_hex_chars(n) + if hex_chars: + return binascii.unhexlify(hex_chars) + else: + return None + + def get_hex_chars(self, n=0): + str_len = len(self.str) + if n == 0: + # n was zero, so we need to determine all hex chars and + # stop when we hit the end of the string of a non-hex character + while n < str_len and self.str[n] in string.hexdigits: + n = n + 1 + else: + if n > str_len: + return None # Not enough chars + # Verify all chars are hex if a length was specified + for i in range(n): + if self.str[i] not in string.hexdigits: + return None # Not all hex digits + if n == 0: + return None + hex_str = self.str[0:n] + self.str = self.str[n:] + return hex_str + + def get_hex_uint(self, byte_order, n=0): + if byte_order == "big": + hex_str = self.get_hex_chars(n) + if hex_str is None: + return None + return int(hex_str, 16) + else: + uval = self.get_hex_uint8() + if uval is None: + return None + uval_result = 0 + shift = 0 + while uval is not None: + uval_result |= uval << shift + shift += 8 + uval = self.get_hex_uint8() + return uval_result + + def get_key_value_pairs(self): + kvp = list() + if ";" in self.str: + key_value_pairs = self.str.split(";") + for key_value_pair in key_value_pairs: + if len(key_value_pair): + kvp.append(key_value_pair.split(":", 1)) + return kvp + + def split(self, ch): + return self.str.split(ch) + + def split_hex(self, ch, byte_order): + hex_values = list() + strings = self.str.split(ch) + for str in strings: + hex_values.append(Packet(str).get_hex_uint(byte_order)) + return hex_values + + def __str__(self): + return self.str + + def __len__(self): + return len(self.str) + + +g_thread_suffix_regex = re.compile(";thread:([0-9a-fA-F]+);") + + +def get_thread_from_thread_suffix(str): + if str: + match = g_thread_suffix_regex.match(str) + if match: + return int(match.group(1), 16) + return None + + +def cmd_qThreadStopInfo(options, cmd, args): + packet = Packet(args) + tid = packet.get_hex_uint("big") + print("get_thread_stop_info (tid = 0x%x)" % (tid)) + + +def cmd_stop_reply(options, cmd, args): + print("get_last_stop_info()") + return False + + +def rsp_stop_reply(options, cmd, cmd_args, rsp): + global g_byte_order + packet = Packet(rsp) + stop_type = packet.get_char() + if stop_type == "T" or stop_type == "S": + signo = packet.get_hex_uint8() + key_value_pairs = packet.get_key_value_pairs() + for key_value_pair in key_value_pairs: + key = key_value_pair[0] + if is_hex_byte(key): + reg_num = Packet(key).get_hex_uint8() + if reg_num < len(g_register_infos): + reg_info = g_register_infos[reg_num] + key_value_pair[0] = reg_info.name() + key_value_pair[1] = reg_info.get_value_from_hex_string( + key_value_pair[1] + ) + elif key == "jthreads" or key == "jstopinfo": + key_value_pair[1] = binascii.unhexlify(key_value_pair[1]) + key_value_pairs.insert(0, ["signal", signo]) + print("stop_reply():") + dump_key_value_pairs(key_value_pairs) + elif stop_type == "W": + exit_status = packet.get_hex_uint8() + print("stop_reply(): exit (status=%i)" % exit_status) + elif stop_type == "O": + print('stop_reply(): stdout = "%s"' % packet.str) + + +def cmd_unknown_packet(options, cmd, args): + if args: + print("cmd: %s, args: %s", cmd, args) + else: + print("cmd: %s", cmd) + return False + + +def cmd_qSymbol(options, cmd, args): + if args == ":": + print("ready to serve symbols") + else: + packet = Packet(args) + symbol_addr = packet.get_hex_uint("big") + if symbol_addr is None: + if packet.skip_exact_string(":"): + symbol_name = packet.get_hex_ascii_str() + print('lookup_symbol("%s") -> symbol not available yet' % (symbol_name)) + else: + print("error: bad command format") + else: + if packet.skip_exact_string(":"): + symbol_name = packet.get_hex_ascii_str() + print('lookup_symbol("%s") -> 0x%x' % (symbol_name, symbol_addr)) + else: + print("error: bad command format") + + +def cmd_QSetWithHexString(options, cmd, args): + print('%s("%s")' % (cmd[:-1], binascii.unhexlify(args))) + + +def cmd_QSetWithString(options, cmd, args): + print('%s("%s")' % (cmd[:-1], args)) + + +def cmd_QSetWithUnsigned(options, cmd, args): + print("%s(%i)" % (cmd[:-1], int(args))) + + +def rsp_qSymbol(options, cmd, cmd_args, rsp): + if len(rsp) == 0: + print("Unsupported") + else: + if rsp == "OK": + print("No more symbols to lookup") + else: + packet = Packet(rsp) + if packet.skip_exact_string("qSymbol:"): + symbol_name = packet.get_hex_ascii_str() + print('lookup_symbol("%s")' % (symbol_name)) + else: + print( + 'error: response string should start with "qSymbol:": respnse is "%s"' + % (rsp) + ) + + +def cmd_qXfer(options, cmd, args): + # $qXfer:features:read:target.xml:0,1ffff#14 + print("read target special data %s" % (args)) + return True + + +def rsp_qXfer(options, cmd, cmd_args, rsp): + data = cmd_args.split(":") + if data[0] == "features": + if data[1] == "read": + filename, extension = os.path.splitext(data[2]) + if extension == ".xml": + response = Packet(rsp) + xml_string = response.get_hex_ascii_str() + if xml_string: + ch = xml_string[0] + if ch == "l": + xml_string = xml_string[1:] + xml_root = ET.fromstring(xml_string) + for reg_element in xml_root.findall("./feature/reg"): + if not "value_regnums" in reg_element.attrib: + reg_info = RegisterInfo([]) + if "name" in reg_element.attrib: + reg_info.info["name"] = reg_element.attrib["name"] + else: + reg_info.info["name"] = "unspecified" + if "encoding" in reg_element.attrib: + reg_info.info["encoding"] = reg_element.attrib[ + "encoding" + ] + else: + reg_info.info["encoding"] = "uint" + if "offset" in reg_element.attrib: + reg_info.info["offset"] = reg_element.attrib[ + "offset" + ] + if "bitsize" in reg_element.attrib: + reg_info.info["bitsize"] = reg_element.attrib[ + "bitsize" + ] + g_register_infos.append(reg_info) + print('XML for "%s":' % (data[2])) + ET.dump(xml_root) + + +def cmd_A(options, cmd, args): + print("launch process:") + packet = Packet(args) + while True: + arg_len = packet.get_number() + if arg_len == -1: + break + if not packet.skip_exact_string(","): + break + arg_idx = packet.get_number() + if arg_idx == -1: + break + if not packet.skip_exact_string(","): + break + arg_value = packet.get_hex_ascii_str(arg_len) + print('argv[%u] = "%s"' % (arg_idx, arg_value)) + + +def cmd_qC(options, cmd, args): + print("query_current_thread_id()") + + +def rsp_qC(options, cmd, cmd_args, rsp): + packet = Packet(rsp) + if packet.skip_exact_string("QC"): + tid = packet.get_thread_id() + print("current_thread_id = %#x" % (tid)) + else: + print("current_thread_id = old thread ID") + + +def cmd_query_packet(options, cmd, args): + if args: + print("%s%s" % (cmd, args)) + else: + print("%s" % (cmd)) + return False + + +def rsp_ok_error(rsp): + print("rsp: ", rsp) + + +def rsp_ok_means_supported(options, cmd, cmd_args, rsp): + if rsp == "OK": + print("%s%s is supported" % (cmd, cmd_args)) + elif rsp == "": + print("%s%s is not supported" % (cmd, cmd_args)) + else: + print("%s%s -> %s" % (cmd, cmd_args, rsp)) + + +def rsp_ok_means_success(options, cmd, cmd_args, rsp): + if rsp == "OK": + print("success") + elif rsp == "": + print("%s%s is not supported" % (cmd, cmd_args)) + else: + print("%s%s -> %s" % (cmd, cmd_args, rsp)) + + +def dump_key_value_pairs(key_value_pairs): + max_key_len = 0 + for key_value_pair in key_value_pairs: + key_len = len(key_value_pair[0]) + if max_key_len < key_len: + max_key_len = key_len + for key_value_pair in key_value_pairs: + key = key_value_pair[0] + value = key_value_pair[1] + unhex_value = get_hex_string_if_all_printable(value) + if unhex_value: + print("%*s = %s (%s)" % (max_key_len, key, value, unhex_value)) + else: + print("%*s = %s" % (max_key_len, key, value)) + + +def rsp_dump_key_value_pairs(options, cmd, cmd_args, rsp): + if rsp: + print("%s response:" % (cmd)) + packet = Packet(rsp) + key_value_pairs = packet.get_key_value_pairs() + dump_key_value_pairs(key_value_pairs) + else: + print("not supported") + + +def cmd_c(options, cmd, args): + print("continue()") + return False + + +def cmd_s(options, cmd, args): + print("step()") + return False + + +def cmd_qSpeedTest(options, cmd, args): + print(("qSpeedTest: cmd='%s', args='%s'" % (cmd, args))) + + +def rsp_qSpeedTest(options, cmd, cmd_args, rsp): + print(("qSpeedTest: rsp='%s' cmd='%s', args='%s'" % (rsp, cmd, args))) + + +def cmd_vCont(options, cmd, args): + if args == "?": + print("%s: get supported extended continue modes" % (cmd)) + else: + got_other_threads = 0 + s = "" + for thread_action in args[1:].split(";"): + (short_action, thread) = thread_action.split(":", 1) + tid = int(thread, 16) + if short_action == "c": + action = "continue" + elif short_action == "s": + action = "step" + elif short_action[0] == "C": + action = "continue with signal 0x%s" % (short_action[1:]) + elif short_action == "S": + action = "step with signal 0x%s" % (short_action[1:]) + else: + action = short_action + if s: + s += ", " + if tid == -1: + got_other_threads = 1 + s += "other-threads:" + else: + s += "thread 0x%4.4x: %s" % (tid, action) + if got_other_threads: + print("extended_continue (%s)" % (s)) + else: + print("extended_continue (%s, other-threads: suspend)" % (s)) + return False + + +def rsp_vCont(options, cmd, cmd_args, rsp): + if cmd_args == "?": + # Skip the leading 'vCont;' + rsp = rsp[6:] + modes = rsp.split(";") + s = "%s: supported extended continue modes include: " % (cmd) + + for i, mode in enumerate(modes): + if i: + s += ", " + if mode == "c": + s += "continue" + elif mode == "C": + s += "continue with signal" + elif mode == "s": + s += "step" + elif mode == "S": + s += "step with signal" + elif mode == "t": + s += "stop" + # else: + # s += 'unrecognized vCont mode: ', str(mode) + print(s) + elif rsp: + if rsp[0] == "T" or rsp[0] == "S" or rsp[0] == "W" or rsp[0] == "X": + rsp_stop_reply(options, cmd, cmd_args, rsp) + return + if rsp[0] == "O": + print("stdout: %s" % (rsp)) + return + else: + print( + "not supported (cmd = '%s', args = '%s', rsp = '%s')" % (cmd, cmd_args, rsp) + ) + + +def cmd_vAttach(options, cmd, args): + (extra_command, args) = args.split(";") + if extra_command: + print("%s%s(%s)" % (cmd, extra_command, args)) + else: + print("attach(pid = %u)" % int(args, 16)) + return False + + +def cmd_qRegisterInfo(options, cmd, args): + print("query_register_info(reg_num=%i)" % (int(args, 16))) + return False + + +def rsp_qRegisterInfo(options, cmd, cmd_args, rsp): + global g_max_register_info_name_len + print("query_register_info(reg_num=%i):" % (int(cmd_args, 16)), end=" ") + if len(rsp) == 3 and rsp[0] == "E": + g_max_register_info_name_len = 0 + for reg_info in g_register_infos: + name_len = len(reg_info.name()) + if g_max_register_info_name_len < name_len: + g_max_register_info_name_len = name_len + print(" DONE") + else: + packet = Packet(rsp) + reg_info = RegisterInfo(packet.get_key_value_pairs()) + g_register_infos.append(reg_info) + print(reg_info) + return False + + +def cmd_qThreadInfo(options, cmd, args): + if cmd == "qfThreadInfo": + query_type = "first" + else: + query_type = "subsequent" + print("get_current_thread_list(type=%s)" % (query_type)) + return False + + +def rsp_qThreadInfo(options, cmd, cmd_args, rsp): + packet = Packet(rsp) + response_type = packet.get_char() + if response_type == "m": + tids = packet.split_hex(";", "big") + for i, tid in enumerate(tids): + if i: + print(",", end=" ") + print("0x%x" % (tid), end=" ") + print() + elif response_type == "l": + print("END") + + +def rsp_hex_big_endian(options, cmd, cmd_args, rsp): + if rsp == "": + print("%s%s is not supported" % (cmd, cmd_args)) + else: + packet = Packet(rsp) + uval = packet.get_hex_uint("big") + print("%s: 0x%x" % (cmd, uval)) + + +def cmd_read_mem_bin(options, cmd, args): + # x0x7fff5fc39200,0x200 + packet = Packet(args) + addr = packet.get_hex_uint("big") + comma = packet.get_char() + size = packet.get_hex_uint("big") + print("binary_read_memory (addr = 0x%16.16x, size = %u)" % (addr, size)) + return False + + +def rsp_mem_bin_bytes(options, cmd, cmd_args, rsp): + packet = Packet(cmd_args) + addr = packet.get_hex_uint("big") + comma = packet.get_char() + size = packet.get_hex_uint("big") + print("memory:") + if size > 0: + dump_hex_memory_buffer(addr, rsp) + + +def cmd_read_memory(options, cmd, args): + packet = Packet(args) + addr = packet.get_hex_uint("big") + comma = packet.get_char() + size = packet.get_hex_uint("big") + print("read_memory (addr = 0x%16.16x, size = %u)" % (addr, size)) + return False + + +def dump_hex_memory_buffer(addr, hex_byte_str): + packet = Packet(hex_byte_str) + idx = 0 + ascii = "" + uval = packet.get_hex_uint8() + while uval is not None: + if (idx % 16) == 0: + if ascii: + print(" ", ascii) + ascii = "" + print("0x%x:" % (addr + idx), end=" ") + print("%2.2x" % (uval), end=" ") + if 0x20 <= uval and uval < 0x7F: + ascii += "%c" % uval + else: + ascii += "." + uval = packet.get_hex_uint8() + idx = idx + 1 + if ascii: + print(" ", ascii) + ascii = "" + + +def cmd_write_memory(options, cmd, args): + packet = Packet(args) + addr = packet.get_hex_uint("big") + if packet.get_char() != ",": + print("error: invalid write memory command (missing comma after address)") + return + size = packet.get_hex_uint("big") + if packet.get_char() != ":": + print("error: invalid write memory command (missing colon after size)") + return + print("write_memory (addr = 0x%16.16x, size = %u, data:" % (addr, size)) + dump_hex_memory_buffer(addr, packet.str) + return False + + +def cmd_alloc_memory(options, cmd, args): + packet = Packet(args) + byte_size = packet.get_hex_uint("big") + if packet.get_char() != ",": + print("error: invalid allocate memory command (missing comma after address)") + return + print( + "allocate_memory (byte-size = %u (0x%x), permissions = %s)" + % (byte_size, byte_size, packet.str) + ) + return False + + +def rsp_alloc_memory(options, cmd, cmd_args, rsp): + packet = Packet(rsp) + addr = packet.get_hex_uint("big") + print("addr = 0x%x" % addr) + + +def cmd_dealloc_memory(options, cmd, args): + packet = Packet(args) + addr = packet.get_hex_uint("big") + if packet.get_char() != ",": + print("error: invalid allocate memory command (missing comma after address)") + else: + print("deallocate_memory (addr = 0x%x, permissions = %s)" % (addr, packet.str)) + return False + + +def rsp_memory_bytes(options, cmd, cmd_args, rsp): + addr = Packet(cmd_args).get_hex_uint("big") + dump_hex_memory_buffer(addr, rsp) + + +def get_register_name_equal_value(options, reg_num, hex_value_str): + if reg_num < len(g_register_infos): + reg_info = g_register_infos[reg_num] + value_str = reg_info.get_value_from_hex_string(hex_value_str) + s = reg_info.name() + " = " + if options.symbolicator: + symbolicated_addresses = options.symbolicator.symbolicate(int(value_str, 0)) + if symbolicated_addresses: + s += options.colors.magenta() + s += "%s" % symbolicated_addresses[0] + s += options.colors.reset() + return s + s += value_str + return s + else: + reg_value = Packet(hex_value_str).get_hex_uint(g_byte_order) + return "reg(%u) = 0x%x" % (reg_num, reg_value) + + +def cmd_read_one_reg(options, cmd, args): + packet = Packet(args) + reg_num = packet.get_hex_uint("big") + tid = get_thread_from_thread_suffix(packet.str) + name = None + if reg_num < len(g_register_infos): + name = g_register_infos[reg_num].name() + if packet.str: + packet.get_char() # skip ; + thread_info = packet.get_key_value_pairs() + tid = int(thread_info[0][1], 16) + s = "read_register (reg_num=%u" % reg_num + if name: + s += " (%s)" % (name) + if tid is not None: + s += ", tid = 0x%4.4x" % (tid) + s += ")" + print(s) + return False + + +def rsp_read_one_reg(options, cmd, cmd_args, rsp): + packet = Packet(cmd_args) + reg_num = packet.get_hex_uint("big") + print(get_register_name_equal_value(options, reg_num, rsp)) + + +def cmd_write_one_reg(options, cmd, args): + packet = Packet(args) + reg_num = packet.get_hex_uint("big") + if packet.get_char() != "=": + print("error: invalid register write packet") + else: + name = None + hex_value_str = packet.get_hex_chars() + tid = get_thread_from_thread_suffix(packet.str) + s = "write_register (reg_num=%u" % reg_num + if name: + s += " (%s)" % (name) + s += ", value = " + s += get_register_name_equal_value(options, reg_num, hex_value_str) + if tid is not None: + s += ", tid = 0x%4.4x" % (tid) + s += ")" + print(s) + return False + + +def dump_all_regs(packet): + for reg_info in g_register_infos: + nibble_size = reg_info.bit_size() / 4 + hex_value_str = packet.get_hex_chars(nibble_size) + if hex_value_str is not None: + value = reg_info.get_value_from_hex_string(hex_value_str) + print("%*s = %s" % (g_max_register_info_name_len, reg_info.name(), value)) + else: + return + + +def cmd_read_all_regs(cmd, cmd_args): + packet = Packet(cmd_args) + packet.get_char() # toss the 'g' command character + tid = get_thread_from_thread_suffix(packet.str) + if tid is not None: + print("read_all_register(thread = 0x%4.4x)" % tid) + else: + print("read_all_register()") + return False + + +def rsp_read_all_regs(options, cmd, cmd_args, rsp): + packet = Packet(rsp) + dump_all_regs(packet) + + +def cmd_write_all_regs(options, cmd, args): + packet = Packet(args) + print("write_all_registers()") + dump_all_regs(packet) + return False + + +g_bp_types = ["software_bp", "hardware_bp", "write_wp", "read_wp", "access_wp"] + + +def cmd_bp(options, cmd, args): + if cmd == "Z": + s = "set_" + else: + s = "clear_" + packet = Packet(args) + bp_type = packet.get_hex_uint("big") + packet.get_char() # Skip , + bp_addr = packet.get_hex_uint("big") + packet.get_char() # Skip , + bp_size = packet.get_hex_uint("big") + s += g_bp_types[bp_type] + s += " (addr = 0x%x, size = %u)" % (bp_addr, bp_size) + print(s) + return False + + +def cmd_mem_rgn_info(options, cmd, args): + packet = Packet(args) + packet.get_char() # skip ':' character + addr = packet.get_hex_uint("big") + print("get_memory_region_info (addr=0x%x)" % (addr)) + return False + + +def cmd_kill(options, cmd, args): + print("kill_process()") + return False + + +def cmd_jThreadsInfo(options, cmd, args): + print("jThreadsInfo()") + return False + + +def cmd_jGetLoadedDynamicLibrariesInfos(options, cmd, args): + print("jGetLoadedDynamicLibrariesInfos()") + return False + + +def decode_packet(s, start_index=0): + # print '\ndecode_packet("%s")' % (s[start_index:]) + index = s.find("}", start_index) + have_escapes = index != -1 + if have_escapes: + normal_s = s[start_index:index] + else: + normal_s = s[start_index:] + # print 'normal_s = "%s"' % (normal_s) + if have_escapes: + escape_char = "%c" % (ord(s[index + 1]) ^ 0x20) + # print 'escape_char for "%s" = %c' % (s[index:index+2], escape_char) + return normal_s + escape_char + decode_packet(s, index + 2) + else: + return normal_s + + +def rsp_json(options, cmd, cmd_args, rsp): + print("%s() reply:" % (cmd)) + if not rsp: + return + try: + json_tree = json.loads(rsp) + print(json.dumps(json_tree, indent=4, separators=(",", ": "))) + except json.JSONDecodeError: + return + + +def rsp_jGetLoadedDynamicLibrariesInfos(options, cmd, cmd_args, rsp): + if cmd_args: + rsp_json(options, cmd, cmd_args, rsp) + else: + rsp_ok_means_supported(options, cmd, cmd_args, rsp) + + +gdb_remote_commands = { + "\\?": {"cmd": cmd_stop_reply, "rsp": rsp_stop_reply, "name": "stop reply pacpket"}, + "qThreadStopInfo": { + "cmd": cmd_qThreadStopInfo, + "rsp": rsp_stop_reply, + "name": "stop reply pacpket", + }, + "QStartNoAckMode": { + "cmd": cmd_query_packet, + "rsp": rsp_ok_means_supported, + "name": "query if no ack mode is supported", + }, + "QThreadSuffixSupported": { + "cmd": cmd_query_packet, + "rsp": rsp_ok_means_supported, + "name": "query if thread suffix is supported", + }, + "QListThreadsInStopReply": { + "cmd": cmd_query_packet, + "rsp": rsp_ok_means_supported, + "name": "query if threads in stop reply packets are supported", + }, + "QSetDetachOnError:": { + "cmd": cmd_QSetWithUnsigned, + "rsp": rsp_ok_means_success, + "name": "set if we should detach on error", + }, + "QSetDisableASLR:": { + "cmd": cmd_QSetWithUnsigned, + "rsp": rsp_ok_means_success, + "name": "set if we should disable ASLR", + }, + "qLaunchSuccess": { + "cmd": cmd_query_packet, + "rsp": rsp_ok_means_success, + "name": "check on launch success for the A packet", + }, + "A": {"cmd": cmd_A, "rsp": rsp_ok_means_success, "name": "launch process"}, + "QLaunchArch:": { + "cmd": cmd_QSetWithString, + "rsp": rsp_ok_means_supported, + "name": "set the arch to launch in case the file contains multiple architectures", + }, + "qVAttachOrWaitSupported": { + "cmd": cmd_query_packet, + "rsp": rsp_ok_means_supported, + "name": "set the launch architecture", + }, + "qHostInfo": { + "cmd": cmd_query_packet, + "rsp": rsp_dump_key_value_pairs, + "name": "get host information", + }, + "qC": {"cmd": cmd_qC, "rsp": rsp_qC, "name": "return the current thread ID"}, + "vCont": {"cmd": cmd_vCont, "rsp": rsp_vCont, "name": "extended continue command"}, + "qSpeedTest": { + "cmd": cmd_qSpeedTest, + "rsp": rsp_qSpeedTest, + "name": "speed test packdet", + }, + "vAttach": {"cmd": cmd_vAttach, "rsp": rsp_stop_reply, "name": "attach to process"}, + "c": {"cmd": cmd_c, "rsp": rsp_stop_reply, "name": "continue"}, + "s": {"cmd": cmd_s, "rsp": rsp_stop_reply, "name": "step"}, + "qRegisterInfo": { + "cmd": cmd_qRegisterInfo, + "rsp": rsp_qRegisterInfo, + "name": "query register info", + }, + "qfThreadInfo": { + "cmd": cmd_qThreadInfo, + "rsp": rsp_qThreadInfo, + "name": "get current thread list", + }, + "qsThreadInfo": { + "cmd": cmd_qThreadInfo, + "rsp": rsp_qThreadInfo, + "name": "get current thread list", + }, + "qShlibInfoAddr": { + "cmd": cmd_query_packet, + "rsp": rsp_hex_big_endian, + "name": "get shared library info address", + }, + "qMemoryRegionInfo": { + "cmd": cmd_mem_rgn_info, + "rsp": rsp_dump_key_value_pairs, + "name": "get memory region information", + }, + "qProcessInfo": { + "cmd": cmd_query_packet, + "rsp": rsp_dump_key_value_pairs, + "name": "get process info", + }, + "qSupported": { + "cmd": cmd_query_packet, + "rsp": rsp_ok_means_supported, + "name": "query supported", + }, + "qXfer:": {"cmd": cmd_qXfer, "rsp": rsp_qXfer, "name": "qXfer"}, + "qSymbol:": {"cmd": cmd_qSymbol, "rsp": rsp_qSymbol, "name": "qSymbol"}, + "QSetSTDIN:": { + "cmd": cmd_QSetWithHexString, + "rsp": rsp_ok_means_success, + "name": "set STDIN prior to launching with A packet", + }, + "QSetSTDOUT:": { + "cmd": cmd_QSetWithHexString, + "rsp": rsp_ok_means_success, + "name": "set STDOUT prior to launching with A packet", + }, + "QSetSTDERR:": { + "cmd": cmd_QSetWithHexString, + "rsp": rsp_ok_means_success, + "name": "set STDERR prior to launching with A packet", + }, + "QEnvironment:": { + "cmd": cmd_QSetWithString, + "rsp": rsp_ok_means_success, + "name": "set an environment variable prior to launching with A packet", + }, + "QEnvironmentHexEncoded:": { + "cmd": cmd_QSetWithHexString, + "rsp": rsp_ok_means_success, + "name": "set an environment variable prior to launching with A packet", + }, + "x": { + "cmd": cmd_read_mem_bin, + "rsp": rsp_mem_bin_bytes, + "name": "read memory binary", + }, + "X": { + "cmd": cmd_write_memory, + "rsp": rsp_ok_means_success, + "name": "write memory binary", + }, + "m": {"cmd": cmd_read_memory, "rsp": rsp_memory_bytes, "name": "read memory"}, + "M": {"cmd": cmd_write_memory, "rsp": rsp_ok_means_success, "name": "write memory"}, + "_M": {"cmd": cmd_alloc_memory, "rsp": rsp_alloc_memory, "name": "allocate memory"}, + "_m": { + "cmd": cmd_dealloc_memory, + "rsp": rsp_ok_means_success, + "name": "deallocate memory", + }, + "p": { + "cmd": cmd_read_one_reg, + "rsp": rsp_read_one_reg, + "name": "read single register", + }, + "P": { + "cmd": cmd_write_one_reg, + "rsp": rsp_ok_means_success, + "name": "write single register", + }, + "g": { + "cmd": cmd_read_all_regs, + "rsp": rsp_read_all_regs, + "name": "read all registers", + }, + "G": { + "cmd": cmd_write_all_regs, + "rsp": rsp_ok_means_success, + "name": "write all registers", + }, + "z": { + "cmd": cmd_bp, + "rsp": rsp_ok_means_success, + "name": "clear breakpoint or watchpoint", + }, + "Z": { + "cmd": cmd_bp, + "rsp": rsp_ok_means_success, + "name": "set breakpoint or watchpoint", + }, + "k": {"cmd": cmd_kill, "rsp": rsp_stop_reply, "name": "kill process"}, + "jThreadsInfo": { + "cmd": cmd_jThreadsInfo, + "rsp": rsp_json, + "name": "JSON get all threads info", + }, + "jGetLoadedDynamicLibrariesInfos:": { + "cmd": cmd_jGetLoadedDynamicLibrariesInfos, + "rsp": rsp_jGetLoadedDynamicLibrariesInfos, + "name": "JSON get loaded dynamic libraries", + }, +} + + +def calculate_mean_and_standard_deviation(floats): + sum = 0.0 + count = len(floats) + if count == 0: + return (0.0, 0.0) + for f in floats: + sum += f + mean = sum / count + accum = 0.0 + for f in floats: + delta = f - mean + accum += delta * delta + + std_dev = math.sqrt(accum / (count - 1)) + return (mean, std_dev) + + +def parse_gdb_log_file(path, options): + f = open(path) + parse_gdb_log(f, options) + f.close() + + +def round_up(n, incr): + return float(((int(n) + incr) / incr) * incr) + + +def plot_latencies(sec_times): + # import numpy as np + import matplotlib.pyplot as plt + + for i, name in enumerate(sec_times.keys()): + times = sec_times[name] + if len(times) <= 1: + continue + plt.subplot(2, 1, 1) + plt.title('Packet "%s" Times' % (name)) + plt.xlabel("Packet") + units = "ms" + adj_times = [] + max_time = 0.0 + for time in times: + time = time * 1000.0 + adj_times.append(time) + if time > max_time: + max_time = time + if max_time < 1.0: + units = "us" + max_time = 0.0 + for i in range(len(adj_times)): + adj_times[i] *= 1000.0 + if adj_times[i] > max_time: + max_time = adj_times[i] + plt.ylabel("Time (%s)" % (units)) + max_y = None + for i in [5.0, 10.0, 25.0, 50.0]: + if max_time < i: + max_y = round_up(max_time, i) + break + if max_y is None: + max_y = round_up(max_time, 100.0) + plt.ylim(0.0, max_y) + plt.plot(adj_times, "o-") + plt.show() + + +def parse_gdb_log(file, options): + """Parse a GDB log file that was generated by enabling logging with: + (lldb) log enable --threadsafe --timestamp --file gdb-remote packets + This log file will contain timestamps and this function will then normalize + those packets to be relative to the first value timestamp that is found and + show delta times between log lines and also keep track of how long it takes + for GDB remote commands to make a send/receive round trip. This can be + handy when trying to figure out why some operation in the debugger is taking + a long time during a preset set of debugger commands.""" + + tricky_commands = ["qRegisterInfo"] + timestamp_regex = re.compile(r"(\s*)([1-9][0-9]+\.[0-9]+)([^0-9].*)$") + packet_name_regex = re.compile("([A-Za-z_]+)[^a-z]") + packet_transmit_name_regex = re.compile( + "(?Psend|read) packet: (?P.*)" + ) + packet_contents_name_regex = re.compile(r"\$([^#]*)#[0-9a-fA-F]{2}") + packet_checksum_regex = re.compile(".*#[0-9a-fA-F]{2}$") + packet_names_regex_str = "(" + "|".join(gdb_remote_commands.keys()) + ")(.*)" + packet_names_regex = re.compile(packet_names_regex_str) + + base_time = 0.0 + last_time = 0.0 + min_time = 100000000.0 + packet_total_times = {} + all_packet_times = [] + packet_times = {} + packet_counts = {} + lines = file.read().splitlines() + last_command = None + last_command_args = None + last_command_packet = None + hide_next_response = False + num_lines = len(lines) + skip_count = 0 + for line_index, line in enumerate(lines): + # See if we need to skip any lines + if skip_count > 0: + skip_count -= 1 + continue + m = packet_transmit_name_regex.search(line) + is_command = False + direction = None + if m: + direction = m.group("direction") + is_command = direction == "send" + packet = m.group("packet") + sys.stdout.write(options.colors.green()) + if not options.quiet and not hide_next_response: + print("# ", line) + sys.stdout.write(options.colors.reset()) + + # print 'direction = "%s", packet = "%s"' % (direction, packet) + + if packet[0] == "+": + if is_command: + print("-->", end=" ") + else: + print("<--", end=" ") + if not options.quiet: + print("ACK") + continue + elif packet[0] == "-": + if is_command: + print("-->", end=" ") + else: + print("<--", end=" ") + if not options.quiet: + print("NACK") + continue + elif packet[0] == "$": + m = packet_contents_name_regex.match(packet) + if not m and packet[0] == "$": + multiline_packet = packet + idx = line_index + 1 + while idx < num_lines: + if not options.quiet and not hide_next_response: + print("# ", lines[idx]) + multiline_packet += lines[idx] + m = packet_contents_name_regex.match(multiline_packet) + if m: + packet = multiline_packet + skip_count = idx - line_index + break + else: + idx += 1 + if m: + if is_command: + print("-->", end=" ") + else: + print("<--", end=" ") + contents = decode_packet(m.group(1)) + if is_command: + hide_next_response = False + m = packet_names_regex.match(contents) + if m: + last_command = m.group(1) + if last_command == "?": + last_command = "\\?" + packet_name = last_command + last_command_args = m.group(2) + last_command_packet = contents + hide_next_response = gdb_remote_commands[last_command][ + "cmd" + ](options, last_command, last_command_args) + else: + packet_match = packet_name_regex.match(contents) + if packet_match: + packet_name = packet_match.group(1) + for tricky_cmd in tricky_commands: + if packet_name.find(tricky_cmd) == 0: + packet_name = tricky_cmd + else: + packet_name = contents + last_command = None + last_command_args = None + last_command_packet = None + elif last_command: + gdb_remote_commands[last_command]["rsp"]( + options, last_command, last_command_args, contents + ) + else: + print('error: invalid packet: "', packet, '"') + else: + print("???") + else: + print("## ", line) + match = timestamp_regex.match(line) + if match: + curr_time = float(match.group(2)) + if last_time and not is_command: + delta = curr_time - last_time + all_packet_times.append(delta) + delta = 0.0 + if base_time: + delta = curr_time - last_time + else: + base_time = curr_time + + if not is_command: + if line.find("read packet: $") >= 0 and packet_name: + if packet_name in packet_total_times: + packet_total_times[packet_name] += delta + packet_counts[packet_name] += 1 + else: + packet_total_times[packet_name] = delta + packet_counts[packet_name] = 1 + if packet_name not in packet_times: + packet_times[packet_name] = [] + packet_times[packet_name].append(delta) + packet_name = None + if min_time > delta: + min_time = delta + + if not options or not options.quiet: + print( + "%s%.6f %+.6f%s" + % (match.group(1), curr_time - base_time, delta, match.group(3)) + ) + last_time = curr_time + # else: + # print line + (average, std_dev) = calculate_mean_and_standard_deviation(all_packet_times) + if average and std_dev: + print( + "%u packets with average packet time of %f and standard deviation of %f" + % (len(all_packet_times), average, std_dev) + ) + if packet_total_times: + total_packet_time = 0.0 + total_packet_count = 0 + for key, vvv in packet_total_times.items(): + # print ' key = (%s) "%s"' % (type(key), key) + # print 'value = (%s) %s' % (type(vvv), vvv) + # if type(vvv) == 'float': + total_packet_time += vvv + for key, vvv in packet_counts.items(): + total_packet_count += vvv + + print("#------------------------------------------------------------") + print("# Packet timing summary:") + print( + "# Totals: time = %6f, count = %6d" + % (total_packet_time, total_packet_count) + ) + print("# Min packet time: time = %6f" % (min_time)) + print("#------------------------------------------------------------") + print("# Packet Time (sec) Percent Count Latency") + print("#------------------------- ----------- ------- ------ -------") + if options and options.sort_count: + res = sorted(packet_counts, key=packet_counts.__getitem__, reverse=True) + else: + res = sorted( + packet_total_times, key=packet_total_times.__getitem__, reverse=True + ) + + if last_time > 0.0: + for item in res: + packet_total_time = packet_total_times[item] + packet_percent = (packet_total_time / total_packet_time) * 100.0 + packet_count = packet_counts[item] + print( + " %24s %11.6f %5.2f%% %6d %9.6f" + % ( + item, + packet_total_time, + packet_percent, + packet_count, + float(packet_total_time) / float(packet_count), + ) + ) + if options and options.plot: + plot_latencies(packet_times) + + +if __name__ == "__main__": + usage = "usage: gdbremote [options]" + description = """The command disassembles a GDB remote packet log.""" + parser = optparse.OptionParser( + description=description, prog="gdbremote", usage=usage + ) + parser.add_option( + "-v", + "--verbose", + action="store_true", + dest="verbose", + help="display verbose debug info", + default=False, + ) + parser.add_option( + "-q", + "--quiet", + action="store_true", + dest="quiet", + help="display verbose debug info", + default=False, + ) + parser.add_option( + "-C", + "--color", + action="store_true", + dest="color", + help="add terminal colors", + default=False, + ) + parser.add_option( + "-c", + "--sort-by-count", + action="store_true", + dest="sort_count", + help="display verbose debug info", + default=False, + ) + parser.add_option( + "--crashlog", + type="string", + dest="crashlog", + help="symbolicate using a darwin crash log file", + default=False, + ) + try: + (options, args) = parser.parse_args(sys.argv[1:]) + except: + print("error: argument error") + sys.exit(1) + + options.colors = TerminalColors(options.color) + options.symbolicator = None + if options.crashlog: + import lldb + + lldb.debugger = lldb.SBDebugger.Create() + import lldb.macosx.crashlog + + options.symbolicator = lldb.macosx.crashlog.CrashLog(options.crashlog) + print("%s" % (options.symbolicator)) + + # This script is being run from the command line, create a debugger in case we are + # going to use any debugger functions in our function. + if len(args): + for file in args: + print( + "#----------------------------------------------------------------------" + ) + print("# GDB remote log file: '%s'" % file) + print( + "#----------------------------------------------------------------------" + ) + parse_gdb_log_file(file, options) + if options.symbolicator: + print("%s" % (options.symbolicator)) + else: + parse_gdb_log(sys.stdin, options) + + +def __lldb_init_module(debugger, internal_dict): + # This initializer is being run from LLDB in the embedded command interpreter + # Add any commands contained in this module to LLDB + debugger.HandleCommand( + "command script add -o -f gdbremote.start_gdb_log start_gdb_log" + ) + debugger.HandleCommand( + "command script add -o -f gdbremote.stop_gdb_log stop_gdb_log" + ) + print( + 'The "start_gdb_log" and "stop_gdb_log" commands are now installed and ready for use, type "start_gdb_log --help" or "stop_gdb_log --help" for more information' + ) diff --git a/llvm/docs/requirements-hashed.txt b/llvm/docs/requirements-hashed.txt index 07e051ca4a8ba..a3c4414a47b40 100644 --- a/llvm/docs/requirements-hashed.txt +++ b/llvm/docs/requirements-hashed.txt @@ -16,9 +16,9 @@ beautifulsoup4==4.12.2 \ --hash=sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da \ --hash=sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a # via furo -certifi==2023.11.17 \ - --hash=sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1 \ - --hash=sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474 +certifi==2025.8.3 \ + # Hashes need to be regenerated for certifi==2025.8.3 + # via requests # via requests charset-normalizer==3.3.2 \ --hash=sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027 \ @@ -128,17 +128,19 @@ furo==2024.1.29 \ --hash=sha256:3548be2cef45a32f8cdc0272d415fcb3e5fa6a0eb4ddfe21df3ecf1fe45a13cf \ --hash=sha256:4d6b2fe3f10a6e36eb9cc24c1e7beb38d7a23fc7b3c382867503b7fcac8a1e02 # via -r requirements.txt -idna==3.6 \ - --hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \ - --hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f +idna==3.10 \ + # Hashes need to be regenerated for idna==3.10 + # via requests # via requests imagesize==1.4.1 \ --hash=sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b \ --hash=sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a # via sphinx -jinja2==3.1.2 \ - --hash=sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852 \ - --hash=sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61 +jinja2==3.1.6 \ + # Hashes need to be regenerated for jinja2==3.1.6 + # via + # myst-parser + # sphinx # via # myst-parser # sphinx @@ -292,9 +294,9 @@ recommonmark==0.7.1 \ --hash=sha256:1b1db69af0231efce3fa21b94ff627ea33dee7079a01dd0a7f8482c3da148b3f \ --hash=sha256:bdb4db649f2222dcd8d2d844f0006b958d627f732415d399791ee436a3686d67 # via -r requirements.txt -requests==2.31.0 \ - --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \ - --hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1 +requests==2.32.5 \ + # Hashes need to be regenerated for requests==2.32.5 + # via sphinx # via sphinx snowballstemmer==2.2.0 \ --hash=sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1 \ @@ -365,7 +367,7 @@ sphinxcontrib-serializinghtml==1.1.9 \ --hash=sha256:0c64ff898339e1fac29abd2bf5f11078f3ec413cfe9c046d3120d7ca65530b54 \ --hash=sha256:9b36e503703ff04f20e9675771df105e58aa029cfcbc23b8ed716019b7416ae1 # via sphinx -urllib3==2.1.0 \ - --hash=sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3 \ - --hash=sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54 +urllib3==2.5.0 \ + # Hashes need to be regenerated for urllib3==2.5.0 + # via requests # via requests diff --git a/llvm/tools/sancov/coverage-report-server.py b/llvm/tools/sancov/coverage-report-server.py index 7b0b494218cc1..56c8ea8a916d5 100755 --- a/llvm/tools/sancov/coverage-report-server.py +++ b/llvm/tools/sancov/coverage-report-server.py @@ -162,8 +162,15 @@ def do_GET(self): self.wfile.write(response.encode("UTF-8", "replace")) elif self.symcov_data.has_file(norm_path): filename = norm_path - filepath = os.path.join(self.src_path, filename) - if not os.path.exists(filepath): + # Construct the full file path, normalizing it to avoid traversal + abs_src_path = os.path.realpath(self.src_path) + abs_file_path = os.path.realpath(os.path.join(self.src_path, filename)) + # Check containment: file must reside within src_path + if not abs_file_path.startswith(abs_src_path + os.sep): + self.send_response(403) + self.end_headers() + return + if not os.path.exists(abs_file_path): self.send_response(404) self.end_headers() return @@ -174,7 +181,7 @@ def do_GET(self): linemap = self.symcov_data.compute_linemap(filename) - with open(filepath, "r", encoding="utf8") as f: + with open(abs_file_path, "r", encoding="utf8") as f: content = "\n".join( [ "{line} ".format( diff --git a/llvm/utils/git/requirements.txt b/llvm/utils/git/requirements.txt index bbb9059b6b260..d4141c0873fb5 100644 --- a/llvm/utils/git/requirements.txt +++ b/llvm/utils/git/requirements.txt @@ -4,9 +4,11 @@ # # pip-compile --generate-hashes --output-file=requirements.txt requirements.txt.in # -certifi==2024.8.30 \ - --hash=sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8 \ - --hash=sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9 +certifi==2025.8.3 \ + # Hashes need to be regenerated for certifi==2025.8.3 + # via + # -r requirements.txt.in + # requests # via # -r requirements.txt.in # requests @@ -173,34 +175,9 @@ charset-normalizer==3.3.2 \ --hash=sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519 \ --hash=sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561 # via requests -cryptography==43.0.1 \ - --hash=sha256:014f58110f53237ace6a408b5beb6c427b64e084eb451ef25a28308270086494 \ - --hash=sha256:1bbcce1a551e262dfbafb6e6252f1ae36a248e615ca44ba302df077a846a8806 \ - --hash=sha256:203e92a75716d8cfb491dc47c79e17d0d9207ccffcbcb35f598fbe463ae3444d \ - --hash=sha256:27e613d7077ac613e399270253259d9d53872aaf657471473ebfc9a52935c062 \ - --hash=sha256:2bd51274dcd59f09dd952afb696bf9c61a7a49dfc764c04dd33ef7a6b502a1e2 \ - --hash=sha256:38926c50cff6f533f8a2dae3d7f19541432610d114a70808f0926d5aaa7121e4 \ - --hash=sha256:511f4273808ab590912a93ddb4e3914dfd8a388fed883361b02dea3791f292e1 \ - --hash=sha256:58d4e9129985185a06d849aa6df265bdd5a74ca6e1b736a77959b498e0505b85 \ - --hash=sha256:5b43d1ea6b378b54a1dc99dd8a2b5be47658fe9a7ce0a58ff0b55f4b43ef2b84 \ - --hash=sha256:61ec41068b7b74268fa86e3e9e12b9f0c21fcf65434571dbb13d954bceb08042 \ - --hash=sha256:666ae11966643886c2987b3b721899d250855718d6d9ce41b521252a17985f4d \ - --hash=sha256:68aaecc4178e90719e95298515979814bda0cbada1256a4485414860bd7ab962 \ - --hash=sha256:7c05650fe8023c5ed0d46793d4b7d7e6cd9c04e68eabe5b0aeea836e37bdcec2 \ - --hash=sha256:80eda8b3e173f0f247f711eef62be51b599b5d425c429b5d4ca6a05e9e856baa \ - --hash=sha256:8385d98f6a3bf8bb2d65a73e17ed87a3ba84f6991c155691c51112075f9ffc5d \ - --hash=sha256:88cce104c36870d70c49c7c8fd22885875d950d9ee6ab54df2745f83ba0dc365 \ - --hash=sha256:9d3cdb25fa98afdd3d0892d132b8d7139e2c087da1712041f6b762e4f807cc96 \ - --hash=sha256:a575913fb06e05e6b4b814d7f7468c2c660e8bb16d8d5a1faf9b33ccc569dd47 \ - --hash=sha256:ac119bb76b9faa00f48128b7f5679e1d8d437365c5d26f1c2c3f0da4ce1b553d \ - --hash=sha256:c1332724be35d23a854994ff0b66530119500b6053d0bd3363265f7e5e77288d \ - --hash=sha256:d03a475165f3134f773d1388aeb19c2d25ba88b6a9733c5c590b9ff7bbfa2e0c \ - --hash=sha256:d75601ad10b059ec832e78823b348bfa1a59f6b8d545db3a24fd44362a1564cb \ - --hash=sha256:de41fd81a41e53267cb020bb3a7212861da53a7d39f863585d13ea11049cf277 \ - --hash=sha256:e710bf40870f4db63c3d7d929aa9e09e4e7ee219e703f949ec4073b4294f6172 \ - --hash=sha256:ea25acb556320250756e53f9e20a4177515f012c9eaea17eb7587a8c4d8ae034 \ - --hash=sha256:f98bf604c82c416bc829e490c700ca1553eafdf2912a91e23a79d97d9801372a \ - --hash=sha256:fba1007b3ef89946dbbb515aeeb41e30203b004f0b4b00e5e16078b518563289 +cryptography==46.0.1 \ + # Hashes need to be regenerated for cryptography==46.0.1 + # via pyjwt # via pyjwt deprecated==1.2.14 \ --hash=sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c \ @@ -214,9 +191,9 @@ gitpython==3.1.43 \ --hash=sha256:35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c \ --hash=sha256:eec7ec56b92aad751f9912a73404bc02ba212a23adb2c7098ee668417051a1ff # via -r requirements.txt.in -idna==3.8 \ - --hash=sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac \ - --hash=sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603 +idna==3.10 \ + # Hashes need to be regenerated for idna==3.10 + # via requests # via requests pycparser==2.22 \ --hash=sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6 \ @@ -226,9 +203,9 @@ pygithub==2.4.0 \ --hash=sha256:6601e22627e87bac192f1e2e39c6e6f69a43152cfb8f307cee575879320b3051 \ --hash=sha256:81935aa4bdc939fba98fee1cb47422c09157c56a27966476ff92775602b9ee24 # via -r requirements.txt.in -pyjwt[crypto]==2.9.0 \ - --hash=sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850 \ - --hash=sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c +pyjwt[crypto]==2.10.1 \ + # Hashes need to be regenerated for pyjwt[crypto]==2.10.1 + # via pygithub # via pygithub pynacl==1.5.0 \ --hash=sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858 \ @@ -242,9 +219,9 @@ pynacl==1.5.0 \ --hash=sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b \ --hash=sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543 # via pygithub -requests==2.32.3 \ - --hash=sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760 \ - --hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6 +requests==2.32.5 \ + # Hashes need to be regenerated for requests==2.32.5 + # via pygithub # via pygithub smmap==5.0.1 \ --hash=sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62 \ @@ -254,9 +231,11 @@ typing-extensions==4.12.2 \ --hash=sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d \ --hash=sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8 # via pygithub -urllib3==2.2.3 \ - --hash=sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac \ - --hash=sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9 +urllib3==2.5.0 \ + # Hashes need to be regenerated for urllib3==2.5.0 + # via + # pygithub + # requests # via # pygithub # requests diff --git a/llvm/utils/git/requirements_formatting.txt b/llvm/utils/git/requirements_formatting.txt index 18e2626c79460..dd22d7782bcf6 100644 --- a/llvm/utils/git/requirements_formatting.txt +++ b/llvm/utils/git/requirements_formatting.txt @@ -4,29 +4,11 @@ # # pip-compile --generate-hashes --output-file=requirements_formatting.txt requirements_formatting.txt.in # -black==23.12.1 \ - --hash=sha256:0808494f2b2df923ffc5723ed3c7b096bd76341f6213989759287611e9837d50 \ - --hash=sha256:1fa88a0f74e50e4487477bc0bb900c6781dbddfdfa32691e780bf854c3b4a47f \ - --hash=sha256:25e57fd232a6d6ff3f4478a6fd0580838e47c93c83eaf1ccc92d4faf27112c4e \ - --hash=sha256:2d9e13db441c509a3763a7a3d9a49ccc1b4e974a47be4e08ade2a228876500ec \ - --hash=sha256:3e1b38b3135fd4c025c28c55ddfc236b05af657828a8a6abe5deec419a0b7055 \ - --hash=sha256:3fa4be75ef2a6b96ea8d92b1587dd8cb3a35c7e3d51f0738ced0781c3aa3a5a3 \ - --hash=sha256:4ce3ef14ebe8d9509188014d96af1c456a910d5b5cbf434a09fef7e024b3d0d5 \ - --hash=sha256:4f0031eaa7b921db76decd73636ef3a12c942ed367d8c3841a0739412b260a54 \ - --hash=sha256:602cfb1196dc692424c70b6507593a2b29aac0547c1be9a1d1365f0d964c353b \ - --hash=sha256:6d1bd9c210f8b109b1762ec9fd36592fdd528485aadb3f5849b2740ef17e674e \ - --hash=sha256:78baad24af0f033958cad29731e27363183e140962595def56423e626f4bee3e \ - --hash=sha256:8d4df77958a622f9b5a4c96edb4b8c0034f8434032ab11077ec6c56ae9f384ba \ - --hash=sha256:97e56155c6b737854e60a9ab1c598ff2533d57e7506d97af5481141671abf3ea \ - --hash=sha256:9c4352800f14be5b4864016882cdba10755bd50805c95f728011bcb47a4afd59 \ - --hash=sha256:a4d6a9668e45ad99d2f8ec70d5c8c04ef4f32f648ef39048d010b0689832ec6d \ - --hash=sha256:a920b569dc6b3472513ba6ddea21f440d4b4c699494d2e972a1753cdc25df7b0 \ - --hash=sha256:ae76c22bde5cbb6bfd211ec343ded2163bba7883c7bc77f6b756a1049436fbb9 \ - --hash=sha256:b18fb2ae6c4bb63eebe5be6bd869ba2f14fd0259bda7d18a46b764d8fb86298a \ - --hash=sha256:c04b6d9d20e9c13f43eee8ea87d44156b8505ca8a3c878773f68b4e4812a421e \ - --hash=sha256:c88b3711d12905b74206227109272673edce0cb29f27e1385f33b0163c414bba \ - --hash=sha256:dd15245c8b68fe2b6bd0f32c1556509d11bb33aec9b5d0866dd8e2ed3dba09c2 \ - --hash=sha256:e0aaf6041986767a5e0ce663c7a2f0e9eaf21e6ff87a5f95cbf3675bfd4c41d2 +black==25.9.0 \ + # Hashes need to be regenerated for black==25.9.0 + # via + # -r requirements_formatting.txt.in + # darker # via # -r requirements_formatting.txt.in # darker @@ -205,34 +187,9 @@ colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 # via click -cryptography==43.0.0 \ - --hash=sha256:0663585d02f76929792470451a5ba64424acc3cd5227b03921dab0e2f27b1709 \ - --hash=sha256:08a24a7070b2b6804c1940ff0f910ff728932a9d0e80e7814234269f9d46d069 \ - --hash=sha256:232ce02943a579095a339ac4b390fbbe97f5b5d5d107f8a08260ea2768be8cc2 \ - --hash=sha256:2905ccf93a8a2a416f3ec01b1a7911c3fe4073ef35640e7ee5296754e30b762b \ - --hash=sha256:299d3da8e00b7e2b54bb02ef58d73cd5f55fb31f33ebbf33bd00d9aa6807df7e \ - --hash=sha256:2c6d112bf61c5ef44042c253e4859b3cbbb50df2f78fa8fae6747a7814484a70 \ - --hash=sha256:31e44a986ceccec3d0498e16f3d27b2ee5fdf69ce2ab89b52eaad1d2f33d8778 \ - --hash=sha256:3d9a1eca329405219b605fac09ecfc09ac09e595d6def650a437523fcd08dd22 \ - --hash=sha256:3dcdedae5c7710b9f97ac6bba7e1052b95c7083c9d0e9df96e02a1932e777895 \ - --hash=sha256:47ca71115e545954e6c1d207dd13461ab81f4eccfcb1345eac874828b5e3eaaf \ - --hash=sha256:4a997df8c1c2aae1e1e5ac49c2e4f610ad037fc5a3aadc7b64e39dea42249431 \ - --hash=sha256:51956cf8730665e2bdf8ddb8da0056f699c1a5715648c1b0144670c1ba00b48f \ - --hash=sha256:5bcb8a5620008a8034d39bce21dc3e23735dfdb6a33a06974739bfa04f853947 \ - --hash=sha256:64c3f16e2a4fc51c0d06af28441881f98c5d91009b8caaff40cf3548089e9c74 \ - --hash=sha256:6e2b11c55d260d03a8cf29ac9b5e0608d35f08077d8c087be96287f43af3ccdc \ - --hash=sha256:7b3f5fe74a5ca32d4d0f302ffe6680fcc5c28f8ef0dc0ae8f40c0f3a1b4fca66 \ - --hash=sha256:844b6d608374e7d08f4f6e6f9f7b951f9256db41421917dfb2d003dde4cd6b66 \ - --hash=sha256:9a8d6802e0825767476f62aafed40532bd435e8a5f7d23bd8b4f5fd04cc80ecf \ - --hash=sha256:aae4d918f6b180a8ab8bf6511a419473d107df4dbb4225c7b48c5c9602c38c7f \ - --hash=sha256:ac1955ce000cb29ab40def14fd1bbfa7af2017cca696ee696925615cafd0dce5 \ - --hash=sha256:b88075ada2d51aa9f18283532c9f60e72170041bba88d7f37e49cbb10275299e \ - --hash=sha256:cb013933d4c127349b3948aa8aaf2f12c0353ad0eccd715ca789c8a0f671646f \ - --hash=sha256:cc70b4b581f28d0a254d006f26949245e3657d40d8857066c2ae22a61222ef55 \ - --hash=sha256:e9c5266c432a1e23738d178e51c2c7a5e2ddf790f248be939448c0ba2021f9d1 \ - --hash=sha256:ea9e57f8ea880eeea38ab5abf9fbe39f923544d7884228ec67d666abd60f5a47 \ - --hash=sha256:ee0c405832ade84d4de74b9029bedb7b31200600fa524d218fc29bfa371e97f5 \ - --hash=sha256:fdcb265de28585de5b859ae13e3846a8e805268a823a12a4da2597f1f5afc9f0 +cryptography==46.0.1 \ + # Hashes need to be regenerated for cryptography==46.0.1 + # via pyjwt # via pyjwt darker==1.7.2 \ --hash=sha256:ec5b7c382d9537611c164f3ecca2e1b8a7923bc5a02bf22f6e7f6c8bcbdf593a \ @@ -242,9 +199,9 @@ deprecated==1.2.14 \ --hash=sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c \ --hash=sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3 # via pygithub -idna==3.8 \ - --hash=sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac \ - --hash=sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603 +idna==3.10 \ + # Hashes need to be regenerated for idna==3.10 + # via requests # via requests mypy-extensions==1.0.0 \ --hash=sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d \ @@ -286,17 +243,17 @@ pynacl==1.5.0 \ --hash=sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b \ --hash=sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543 # via pygithub -requests==2.32.3 \ - --hash=sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760 \ - --hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6 +requests==2.32.5 \ + # Hashes need to be regenerated for requests==2.32.5 + # via pygithub # via pygithub toml==0.10.2 \ --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \ --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f # via darker -urllib3==2.2.2 \ - --hash=sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472 \ - --hash=sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168 +urllib3==2.5.0 \ + # Hashes need to be regenerated for urllib3==2.5.0 + # via requests # via requests wrapt==1.16.0 \ --hash=sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc \ diff --git a/llvm/utils/git/requirements_formatting.txt.in b/llvm/utils/git/requirements_formatting.txt.in index 4aac571af1cf5..b41d77ea3c1f2 100644 --- a/llvm/utils/git/requirements_formatting.txt.in +++ b/llvm/utils/git/requirements_formatting.txt.in @@ -1,3 +1,3 @@ black~=23.0 darker==1.7.2 -PyGithub==1.59.1 +PyGithub==2.8.1 diff --git a/llvm/utils/git/requirements_linting.txt b/llvm/utils/git/requirements_linting.txt index b985b80aa869e..425a9f154f1ea 100644 --- a/llvm/utils/git/requirements_linting.txt +++ b/llvm/utils/git/requirements_linting.txt @@ -211,7 +211,7 @@ pycparser==2.22 \ --hash=sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6 \ --hash=sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc # via cffi -pygithub==1.59.1 \ +pygithub==2.8.1 \ --hash=sha256:3d87a822e6c868142f0c2c4bf16cce4696b5a7a4d142a7bd160e1bdf75bc54a9 \ --hash=sha256:c44e3a121c15bf9d3a5cc98d94c9a047a5132a9b01d22264627f58ade9ddc217 # via -r requirements_linting.txt.in diff --git a/llvm/utils/git/requirements_linting.txt.in b/llvm/utils/git/requirements_linting.txt.in index 33c997c022315..b8896605eb006 100644 --- a/llvm/utils/git/requirements_linting.txt.in +++ b/llvm/utils/git/requirements_linting.txt.in @@ -1 +1 @@ -PyGithub==1.59.1 +PyGithub==2.8.1 diff --git a/mlir/utils/vscode/package-lock.json b/mlir/utils/vscode/package-lock.json index 28454c680177b..5f16b56824e0e 100644 --- a/mlir/utils/vscode/package-lock.json +++ b/mlir/utils/vscode/package-lock.json @@ -1,12 +1,12 @@ { "name": "vscode-mlir", - "version": "0.0.11", + "version": "0.0.12", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "vscode-mlir", - "version": "0.0.11", + "version": "0.0.12", "dependencies": { "base64-js": "^1.5.1", "chokidar": "3.5.2", @@ -20,7 +20,7 @@ "@types/vscode": "~1.67.0", "@vscode/vsce": "^2.19.0", "clang-format": "^1.8.0", - "typescript": "^4.6.4", + "typescript": "^4.9.5", "vscode-test": "^1.3.0" }, "engines": { @@ -287,15 +287,6 @@ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", "dev": true }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", @@ -359,19 +350,6 @@ "node": ">=0.2.0" } }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/chainsaw": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", @@ -822,20 +800,6 @@ "wide-align": "^1.1.0" } }, - "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", @@ -901,18 +865,6 @@ "node": ">=4" } }, - "node_modules/has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", @@ -1218,6 +1170,15 @@ "node": "*" } }, + "node_modules/minimatch/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/minimist": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", @@ -1335,15 +1296,6 @@ "node": ">=0.10.0" } }, - "node_modules/object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -1447,6 +1399,19 @@ "node": ">=10" } }, + "node_modules/tar-fs": { + "version": "3.1.1", + "resolved": "", + "integrity": "", + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -1465,19 +1430,8 @@ } }, "node_modules/qs": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", - "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "version": "6.14.0", + "dev": true }, "node_modules/rc": { "version": "1.2.8", @@ -1601,20 +1555,6 @@ "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", "dev": true }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -1728,19 +1668,6 @@ "node": ">=4" } }, - "node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dev": true, - "optional": true, - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, "node_modules/tar-stream": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", @@ -1774,15 +1701,12 @@ } }, "node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", "dev": true, - "dependencies": { - "rimraf": "^3.0.0" - }, "engines": { - "node": ">=8.17.0" + "node": ">=14.14" } }, "node_modules/to-regex-range": { @@ -1839,9 +1763,9 @@ } }, "node_modules/typescript": { - "version": "4.6.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", - "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -2203,15 +2127,6 @@ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", "dev": true }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", @@ -2249,16 +2164,6 @@ "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", "dev": true }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, "chainsaw": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", @@ -2610,17 +2515,6 @@ "wide-align": "^1.1.0" } }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, "github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", @@ -2671,12 +2565,6 @@ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true - }, "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", @@ -2905,6 +2793,17 @@ "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", "requires": { "brace-expansion": "^1.1.7" + }, + "dependencies": { + "brace-expansion": { + "version": "4.0.1", + "resolved": "", + "integrity": "", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + } } }, "minimist": { @@ -3006,12 +2905,6 @@ "dev": true, "optional": true }, - "object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", - "dev": true - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -3096,6 +2989,21 @@ "simple-get": "^4.0.0", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" + }, + "dependencies": { + "tar-fs": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", + "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + } } }, "process-nextick-args": { @@ -3116,13 +3024,8 @@ } }, "qs": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", - "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } + "version": "6.14.0", + "dev": true }, "rc": { "version": "1.2.8", @@ -3221,17 +3124,6 @@ "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", "dev": true }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, "signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -3305,19 +3197,6 @@ "has-flag": "^3.0.0" } }, - "tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, "tar-stream": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", @@ -3347,13 +3226,10 @@ } }, "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "requires": { - "rimraf": "^3.0.0" - } + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", + "dev": true }, "to-regex-range": { "version": "5.0.1", @@ -3397,9 +3273,9 @@ } }, "typescript": { - "version": "4.6.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", - "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true }, "uc.micro": {