| from abc import ABCMeta, abstractmethod | |
| from typing import Any, Optional, Union | |
| import lldb | |
| import json, struct, signal | |
| class ScriptedProcess(metaclass=ABCMeta): | |
| """ | |
| The base class for a scripted process. | |
| Most of the base class methods are `@abstractmethod` that need to be | |
| overwritten by the inheriting class. | |
| """ | |
| capabilities: Optional[dict[str, bool]] = None | |
| memory_regions: Optional[list[lldb.SBMemoryRegionInfo]] = None | |
| loaded_images: Optional[list[dict]] = None | |
| threads: Optional[dict[int, "lldb.plugins.scripted_process.ScriptedThread"]] = None | |
| metadata: Optional[dict[str, Any]] = None | |
| target: lldb.SBTarget | |
| args: lldb.SBStructuredData | |
| arch: str | |
| dbg: lldb.SBDebugger | |
| pid: int | |
| @abstractmethod | |
| def __init__(self, exe_ctx: lldb.SBExecutionContext, args: lldb.SBStructuredData): | |
| """Construct a scripted process. | |
| Args: | |
| exe_ctx (lldb.SBExecutionContext): The execution context for the scripted process. | |
| args (lldb.SBStructuredData): A Dictionary holding arbitrary | |
| key/value pairs used by the scripted process. | |
| """ | |
| target = None | |
| self.target = None | |
| self.args = None | |
| self.arch = None | |
| if isinstance(exe_ctx, lldb.SBExecutionContext): | |
| target = exe_ctx.target | |
| if isinstance(target, lldb.SBTarget) and target.IsValid(): | |
| self.target = target | |
| self.arch = target.arch_name | |
| self.dbg = target.GetDebugger() | |
| if isinstance(args, lldb.SBStructuredData) and args.IsValid(): | |
| self.args = args | |
| self.threads = {} | |
| self.loaded_images = [] | |
| self.metadata = {} | |
| self.capabilities = {} | |
| self.pid = 42 | |
| def get_capabilities(self) -> dict[str, bool]: | |
| """Get a dictionary containing the process capabilities. | |
| Returns: | |
| Dict[str:bool]: The dictionary of capability, with the capability | |
| name as the key and a boolean flag as the value. | |
| The dictionary can be empty. | |
| """ | |
| return self.capabilities | |
| def get_memory_region_containing_address( | |
| self, addr: int | |
| ) -> Optional[lldb.SBMemoryRegionInfo]: | |
| """Get the memory region for the scripted process, containing a | |
| specific address. | |
| Args: | |
| addr (int): Address to look for in the scripted process memory | |
| regions. | |
| Returns: | |
| lldb.SBMemoryRegionInfo: The memory region containing the address. | |
| None if out of bounds. | |
| """ | |
| return None | |
| def get_threads_info(self) -> dict[int, "lldb.plugins.scripted_process.ScriptedThread"]: | |
| """Get the dictionary describing the process' Scripted Threads. | |
| Returns: | |
| Dict: The dictionary of threads, with the thread ID as the key and | |
| a Scripted Thread instance as the value. | |
| The dictionary can be empty. | |
| """ | |
| return self.threads | |
| @abstractmethod | |
| def read_memory_at_address( | |
| self, addr: int, size: int, error: lldb.SBError | |
| ) -> lldb.SBData: | |
| """Get a memory buffer from the scripted process at a certain address, | |
| of a certain size. | |
| Args: | |
| addr (int): Address from which we should start reading. | |
| size (int): Size of the memory to read. | |
| error (lldb.SBError): Error object. | |
| Returns: | |
| lldb.SBData: An `lldb.SBData` buffer with the target byte size and | |
| byte order storing the memory read. | |
| """ | |
| pass | |
| def write_memory_at_address( | |
| self, addr: int, data: lldb.SBData, error: lldb.SBError | |
| ) -> int: | |
| """Write a buffer to the scripted process memory. | |
| Args: | |
| addr (int): Address from which we should start reading. | |
| data (lldb.SBData): An `lldb.SBData` buffer to write to the process | |
| memory. | |
| error (lldb.SBError): Error object. | |
| Returns: | |
| size (int): Size of the memory to read. | |
| """ | |
| error.SetErrorString( | |
| "%s doesn't support memory writes." % self.__class__.__name__ | |
| ) | |
| return 0 | |
| def get_loaded_images(self) -> Optional[list[dict]]: | |
| """Get the list of loaded images for the scripted process. | |
| .. code-block:: python | |
| scripted_image = { | |
| uuid = "c6ea2b64-f77c-3d27-9528-74f507b9078b", | |
| path = "/usr/lib/dyld" | |
| load_addr = 0xbadc0ffee | |
| } | |
| Returns: | |
| List[scripted_image]: A list of `scripted_image` dictionaries | |
| containing for each entry the library UUID or its file path | |
| and its load address. | |
| None if the list is empty. | |
| """ | |
| return self.loaded_images | |
| def get_process_id(self) -> int: | |
| """Get the scripted process identifier. | |
| Returns: | |
| int: The scripted process identifier. | |
| """ | |
| return self.pid | |
| def launch(self) -> lldb.SBError: | |
| """Simulate the scripted process launch. | |
| Returns: | |
| lldb.SBError: An `lldb.SBError` with error code 0. | |
| """ | |
| return lldb.SBError() | |
| def attach(self, attach_info: lldb.SBAttachInfo) -> lldb.SBError: | |
| """Simulate the scripted process attach. | |
| Args: | |
| attach_info (lldb.SBAttachInfo): The information related to the | |
| process we're attaching to. | |
| Returns: | |
| lldb.SBError: An `lldb.SBError` with error code 0. | |
| """ | |
| return lldb.SBError() | |
| def resume(self, should_stop: bool = True) -> lldb.SBError: | |
| """Simulate the scripted process resume. | |
| Args: | |
| should_stop (bool): If True, resume will also force the process | |
| state to stopped after running it. | |
| Returns: | |
| lldb.SBError: An `lldb.SBError` with error code 0. | |
| """ | |
| process = self.target.GetProcess() | |
| if not process: | |
| error = lldb.SBError() | |
| error.SetErrorString("Invalid process.") | |
| return error | |
| process.ForceScriptedState(lldb.eStateRunning) | |
| if should_stop: | |
| process.ForceScriptedState(lldb.eStateStopped) | |
| return lldb.SBError() | |
| @abstractmethod | |
| def is_alive(self) -> bool: | |
| """Check if the scripted process is alive. | |
| Returns: | |
| bool: True if scripted process is alive. False otherwise. | |
| """ | |
| pass | |
| @abstractmethod | |
| def get_scripted_thread_plugin(self) -> str: | |
| """Get scripted thread plugin name. | |
| Returns: | |
| str: Name of the scripted thread plugin. | |
| """ | |
| return None | |
| def get_process_metadata(self) -> Optional[dict[str, Any]]: | |
| """Get some metadata for the scripted process. | |
| The optional "addressable_bits" key holds the number of bits this | |
| process uses for addressing, as a dictionary with optional "lowmem" | |
| and "highmem" keys. "highmem" defaults to "lowmem" when it is missing. | |
| LLDB strips the remaining bits off every code and data address, the | |
| way the `LC_NOTE "addrable bits"` corefile note and the `qHostInfo` | |
| `addressing_bits` key do for corefiles and live processes. This key is | |
| read before the first stop is reported, so the threads and backtraces | |
| built from that stop already have the mask applied. When it is | |
| missing, the process keeps the masks it inherits from the target. | |
| Returns: | |
| Dict: A dictionary containing metadata for the scripted process. | |
| None if the process as no metadata. | |
| """ | |
| return self.metadata | |
| def create_breakpoint( | |
| self, addr: int, error: lldb.SBError | |
| ) -> Union[lldb.SBBreakpoint, bool]: | |
| """Create a breakpoint in the scripted process from an address. | |
| This is mainly used with interactive scripted process debugging. | |
| Args: | |
| addr (int): Address at which the breakpoint should be set. | |
| error (lldb.SBError): Error object. | |
| Returns: | |
| SBBreakpoint: A valid breakpoint object that was created a the specified | |
| address. None if the breakpoint creation failed. | |
| """ | |
| error.SetErrorString( | |
| "%s doesn't support creating breakpoints." % self.__class__.__name__ | |
| ) | |
| return False | |
| class ScriptedThread(metaclass=ABCMeta): | |
| """ | |
| The base class for a scripted thread. | |
| Most of the base class methods are `@abstractmethod` that need to be | |
| overwritten by the inheriting class. | |
| """ | |
| target: lldb.SBTarget | |
| arch: str | |
| originating_process: Union["lldb.plugins.scripted_process.ScriptedProcess", lldb.SBProcess] | |
| process: lldb.SBProcess | |
| args: lldb.SBStructuredData | |
| idx: int | |
| tid: int | |
| name: str | |
| queue: str | |
| state: int | |
| stop_reason: dict[str, Any] | |
| register_info: dict[str, Any] | |
| register_ctx: dict[str, int] | |
| frames: list[dict] | |
| extended_info: list[dict] | |
| @abstractmethod | |
| def __init__( | |
| self, | |
| process: Union["lldb.plugins.scripted_process.ScriptedProcess", lldb.SBProcess], | |
| args: Optional[lldb.SBStructuredData], | |
| ): | |
| """Construct a scripted thread. | |
| Args: | |
| process (ScriptedProcess/lldb.SBProcess): The process owning this thread. | |
| args (lldb.SBStructuredData): A Dictionary holding arbitrary | |
| key/value pairs used by the scripted thread. | |
| """ | |
| self.target = None | |
| self.arch = None | |
| self.originating_process = None | |
| self.process = None | |
| self.args = None | |
| self.idx = 0 | |
| self.tid = 0 | |
| self.idx = None | |
| self.name = None | |
| self.queue = None | |
| self.state = None | |
| self.stop_reason = None | |
| self.register_info = None | |
| self.register_ctx = {} | |
| self.frames = [] | |
| self.extended_info = [] | |
| if ( | |
| isinstance(process, ScriptedProcess) | |
| or isinstance(process, lldb.SBProcess) | |
| and process.IsValid() | |
| ): | |
| self.target = process.target | |
| triple = self.target.triple | |
| if triple: | |
| self.arch = triple.split("-")[0] | |
| self.originating_process = process | |
| self.process = self.target.GetProcess() | |
| self.get_register_info() | |
| def get_thread_idx(self) -> int: | |
| """Get the scripted thread index. | |
| Returns: | |
| int: The index of the scripted thread in the scripted process. | |
| """ | |
| return self.idx | |
| def get_thread_id(self) -> int: | |
| """Get the scripted thread identifier. | |
| Returns: | |
| int: The identifier of the scripted thread. | |
| """ | |
| return self.tid | |
| def get_name(self) -> str: | |
| """Get the scripted thread name. | |
| Returns: | |
| str: The name of the scripted thread. | |
| """ | |
| return self.name | |
| def get_state(self) -> int: | |
| """Get the scripted thread state type. | |
| .. code-block:: python | |
| eStateStopped, ///< Process or thread is stopped and can be examined. | |
| eStateRunning, ///< Process or thread is running and can't be examined. | |
| eStateStepping, ///< Process or thread is in the process of stepping and | |
| /// can not be examined. | |
| eStateCrashed, ///< Process or thread has crashed and can be examined. | |
| Returns: | |
| int: The state type of the scripted thread. | |
| Returns lldb.eStateStopped by default. | |
| """ | |
| return lldb.eStateStopped | |
| def get_queue(self) -> str: | |
| """Get the scripted thread associated queue name. | |
| This method is optional. | |
| Returns: | |
| str: The queue name associated with the scripted thread. | |
| """ | |
| return self.queue | |
| @abstractmethod | |
| def get_stop_reason(self) -> dict[str, Any]: | |
| """Get the dictionary describing the stop reason type with some data. | |
| This method is optional. | |
| Returns: | |
| Dict: The dictionary holding the stop reason type and the possibly | |
| the stop reason data. | |
| """ | |
| pass | |
| def get_stackframes(self) -> list[dict]: | |
| """Get the list of stack frames for the scripted thread. | |
| .. code-block:: python | |
| scripted_frame = { | |
| idx = 0, | |
| pc = 0xbadc0ffee | |
| } | |
| Returns: | |
| List[scripted_frame]: A list of `scripted_frame` dictionaries | |
| containing at least for each entry, the frame index and | |
| the program counter value for that frame. | |
| The list can be empty. | |
| """ | |
| return self.frames | |
| def get_register_info(self) -> dict[str, Any]: | |
| """Get the register info dictionary describing the scripted thread's | |
| registers. Lazily populated on first call from a per-architecture | |
| general-purpose register layout keyed off `self.arch`. | |
| Returns: | |
| Dict: The register info dictionary with `sets` and `registers` | |
| keys. `sets` is a list of register set names and `registers` | |
| is a list of register descriptions. | |
| Raises: | |
| ValueError: If `self.arch` is not one of the architectures | |
| the base class ships a register layout for. | |
| """ | |
| if self.register_info is None: | |
| self.register_info = dict() | |
| if "x86_64" in self.arch: | |
| self.register_info["sets"] = ["General Purpose Registers"] | |
| self.register_info["registers"] = INTEL64_GPR | |
| elif "arm64" in self.arch or self.arch == "aarch64": | |
| self.register_info["sets"] = ["General Purpose Registers"] | |
| self.register_info["registers"] = ARM64_GPR | |
| elif "arm" in self.arch or "thumb" in self.arch: | |
| self.register_info["sets"] = ["General Purpose Registers"] | |
| self.register_info["registers"] = ARM32_GPR | |
| elif "hexagon" in self.arch: | |
| self.register_info["sets"] = ["General Purpose Registers"] | |
| self.register_info["registers"] = HEXAGON_GPR | |
| else: | |
| raise ValueError("Unknown architecture", self.arch) | |
| return self.register_info | |
| @abstractmethod | |
| def get_register_context(self) -> str: | |
| """Get the scripted thread register context | |
| Returns: | |
| str: A byte representing all register's value. | |
| """ | |
| pass | |
| def get_extended_info(self) -> list[dict]: | |
| """Get scripted thread extended information. | |
| Returns: | |
| List: A list containing the extended information for the scripted process. | |
| None if the thread as no extended information. | |
| """ | |
| return self.extended_info | |
| def get_scripted_frame_plugin(self) -> Optional[str]: | |
| """Get scripted frame plugin name. | |
| Returns: | |
| str: Name of the scripted frame plugin. | |
| """ | |
| return None | |
| class ScriptedFrame(metaclass=ABCMeta): | |
| """ | |
| The base class for a scripted frame. | |
| Most of the base class methods are `@abstractmethod` that need to be | |
| overwritten by the inheriting class. | |
| """ | |
| target: lldb.SBTarget | |
| arch: str | |
| originating_thread: Union["lldb.plugins.scripted_process.ScriptedThread", lldb.SBThread] | |
| thread: lldb.SBThread | |
| process: lldb.SBProcess | |
| args: lldb.SBStructuredData | |
| id: int | |
| name: str | |
| register_info: dict[str, Any] | |
| register_ctx: dict[str, int] | |
| variables: list[lldb.SBValue] | |
| @abstractmethod | |
| def __init__( | |
| self, thread: Union["lldb.plugins.scripted_process.ScriptedThread", lldb.SBThread], args: lldb.SBStructuredData | |
| ): | |
| """Construct a scripted frame. | |
| Args: | |
| thread (ScriptedThread/lldb.SBThread): The thread owning this frame. | |
| args (lldb.SBStructuredData): A Dictionary holding arbitrary | |
| key/value pairs used by the scripted frame. | |
| """ | |
| self.target = None | |
| self.arch = None | |
| self.originating_thread = None | |
| self.thread = None | |
| self.args = None | |
| self.id = None | |
| self.name = None | |
| self.register_info = None | |
| self.register_ctx = {} | |
| self.variables = [] | |
| if isinstance(thread, ScriptedThread) or ( | |
| isinstance(thread, lldb.SBThread) and thread.IsValid() | |
| ): | |
| self.process = thread.process | |
| self.target = self.process.target | |
| triple = self.target.triple | |
| if triple: | |
| self.arch = triple.split("-")[0] | |
| tid = thread.tid if isinstance(thread, ScriptedThread) else thread.id | |
| self.originating_thread = thread | |
| self.thread = self.process.GetThreadByID(tid) | |
| self.get_register_info() | |
| @abstractmethod | |
| def get_id(self) -> int: | |
| """Get the scripted frame identifier. | |
| Returns: | |
| int: The identifier of the scripted frame in the scripted thread. | |
| """ | |
| pass | |
| def get_pc(self) -> Optional[int]: | |
| """Get the scripted frame address. | |
| Returns: | |
| int: The optional address of the scripted frame in the scripted thread. | |
| """ | |
| return None | |
| def get_cfa(self) -> int: | |
| """Get the Call Frame Address for this frame. | |
| By default pass the ID of this frame so the CFA's and the | |
| ID's order the same way on this stop. This won't support | |
| step-in and step-out, for those the frames have to have a | |
| stable CFA. | |
| """ | |
| return self.get_id() | |
| def get_symbol_context(self) -> Optional[lldb.SBSymbolContext]: | |
| """Get the scripted frame symbol context. | |
| Returns: | |
| lldb.SBSymbolContext: The symbol context of the scripted frame in the scripted thread. | |
| """ | |
| return None | |
| def is_inlined(self) -> bool: | |
| """Check if the scripted frame is inlined. | |
| Returns: | |
| bool: True if scripted frame is inlined. False otherwise. | |
| """ | |
| return False | |
| def is_artificial(self) -> bool: | |
| """Check if the scripted frame is artificial. | |
| Returns: | |
| bool: True if scripted frame is artificial. False otherwise. | |
| """ | |
| return True | |
| def is_hidden(self) -> bool: | |
| """Check if the scripted frame is hidden. | |
| Returns: | |
| bool: True if scripted frame is hidden. False otherwise. | |
| """ | |
| return False | |
| def get_function_name(self) -> Optional[str]: | |
| """Get the scripted frame function name. | |
| Returns: | |
| str: The function name of the scripted frame. | |
| """ | |
| return self.name | |
| def get_display_function_name(self) -> Optional[str]: | |
| """Get the scripted frame display function name. | |
| Returns: | |
| str: The display function name of the scripted frame. | |
| """ | |
| return self.get_function_name() | |
| def get_variables( | |
| self, filters: lldb.SBVariablesOptions | |
| ) -> Optional[lldb.SBValueList]: | |
| """Get the scripted thread state type. | |
| Args: | |
| filter (lldb.SBVariablesOptions): The filter used to resolve the variables | |
| Returns: | |
| lldb.SBValueList: The SBValueList containing the SBValue for each resolved variable. | |
| Returns None by default. | |
| """ | |
| return None | |
| def get_register_info(self) -> dict[str, Any]: | |
| """Get the register info dictionary describing the scripted frame's | |
| registers. Delegates to the originating scripted thread when there | |
| is one; otherwise lazily populates a per-architecture | |
| general-purpose register layout keyed off `self.arch`. | |
| Returns: | |
| Dict: The register info dictionary with `sets` and `registers` | |
| keys. `sets` is a list of register set names and `registers` | |
| is a list of register descriptions. | |
| Raises: | |
| ValueError: If `self.arch` is not one of the architectures | |
| the base class ships a register layout for. | |
| """ | |
| if self.register_info is None: | |
| if isinstance(self.originating_thread, ScriptedThread): | |
| self.register_info = self.originating_thread.get_register_info() | |
| elif isinstance(self.originating_thread, lldb.SBThread): | |
| self.register_info = dict() | |
| if "x86_64" in self.arch: | |
| self.register_info["sets"] = ["General Purpose Registers"] | |
| self.register_info["registers"] = INTEL64_GPR | |
| elif "arm64" in self.arch or self.arch == "aarch64": | |
| self.register_info["sets"] = ["General Purpose Registers"] | |
| self.register_info["registers"] = ARM64_GPR | |
| elif "arm" in self.arch or "thumb" in self.arch: | |
| self.register_info["sets"] = ["General Purpose Registers"] | |
| self.register_info["registers"] = ARM32_GPR | |
| elif "hexagon" in self.arch: | |
| self.register_info["sets"] = ["General Purpose Registers"] | |
| self.register_info["registers"] = HEXAGON_GPR | |
| elif "wasm" in self.arch: | |
| # WebAssembly is a stack machine with no general-purpose | |
| # register file, so there is no GPR layout to expose. Leave | |
| # the register info empty rather than raising, which would | |
| # otherwise prevent the scripted frame from constructing. | |
| self.register_info["sets"] = [] | |
| self.register_info["registers"] = [] | |
| else: | |
| raise ValueError("Unknown architecture", self.arch) | |
| return self.register_info | |
| @abstractmethod | |
| def get_register_context(self) -> str: | |
| """Get the scripted thread register context | |
| Returns: | |
| str: A byte representing all register's value. | |
| """ | |
| pass | |
| # def get_plan_spec_for_step_type(self, step_type : lldb.StepType): | |
| # """Optional method. If this ScriptedFrame can produce a ThreadPlan | |
| # that implements the given step_type, then it should return a Python | |
| # dictionary with the `class_name` key giving the name of a class that | |
| # implements the step plan, and an optional extra_args dictionary that | |
| # will be passed to the constructor of your step-plan class. If the | |
| # class name is an empty string, that means use the standard stepping | |
| # algorithms for this step. | |
| # The body below tells lldb to fall back to the standard stepping | |
| # algorithm. However, the method is commented out in the base class, | |
| # since if you really don't intend to provide stepping support, | |
| # it's simpler to just not implement this API.""" | |
| # | |
| # dict = {"class_name" : "", extra_args : {"step_type" : str(step_type)} | |
| # return dict | |
| class PassthroughScriptedProcess(ScriptedProcess): | |
| """A reference `ScriptedProcess` subclass that forwards every request to | |
| a "driving" process running in another target of the same debugger. | |
| Useful as a starting point when the extension only needs to reshape or | |
| filter data from a real underlying process.""" | |
| driving_target = None | |
| driving_process = None | |
| def __init__( | |
| self, | |
| exe_ctx: lldb.SBExecutionContext, | |
| args: lldb.SBStructuredData, | |
| launched_driving_process: bool = True, | |
| ): | |
| """Construct a passthrough scripted process by looking up the driving | |
| target's index in `args["driving_target_idx"]` and (unless | |
| `launched_driving_process` is `False`) mirroring its threads and | |
| loaded images into `self`. | |
| """ | |
| super().__init__(exe_ctx, args) | |
| self.driving_target = None | |
| self.driving_process = None | |
| self.driving_target_idx = args.GetValueForKey("driving_target_idx") | |
| if self.driving_target_idx and self.driving_target_idx.IsValid(): | |
| idx = self.driving_target_idx.GetUnsignedIntegerValue(42) | |
| self.driving_target = self.target.GetDebugger().GetTargetAtIndex(idx) | |
| if launched_driving_process: | |
| self.driving_process = self.driving_target.GetProcess() | |
| for driving_thread in self.driving_process: | |
| structured_data = lldb.SBStructuredData() | |
| structured_data.SetFromJSON( | |
| json.dumps( | |
| { | |
| "driving_target_idx": idx, | |
| "thread_idx": driving_thread.GetIndexID(), | |
| } | |
| ) | |
| ) | |
| self.threads[driving_thread.GetThreadID()] = ( | |
| PassthroughScriptedThread(self, structured_data) | |
| ) | |
| for module in self.driving_target.modules: | |
| path = module.file.fullpath | |
| load_addr = module.GetObjectFileHeaderAddress().GetLoadAddress( | |
| self.driving_target | |
| ) | |
| self.loaded_images.append({"path": path, "load_addr": load_addr}) | |
| def get_memory_region_containing_address( | |
| self, addr: int | |
| ) -> Optional[lldb.SBMemoryRegionInfo]: | |
| mem_region = lldb.SBMemoryRegionInfo() | |
| error = self.driving_process.GetMemoryRegionInfo(addr, mem_region) | |
| if error.Fail(): | |
| return None | |
| return mem_region | |
| def read_memory_at_address( | |
| self, addr: int, size: int, error: lldb.SBError | |
| ) -> lldb.SBData: | |
| data = lldb.SBData() | |
| bytes_read = self.driving_process.ReadMemory(addr, size, error) | |
| if error.Fail(): | |
| return data | |
| data.SetDataWithOwnership( | |
| error, | |
| bytes_read, | |
| self.driving_target.GetByteOrder(), | |
| self.driving_target.GetAddressByteSize(), | |
| ) | |
| return data | |
| def write_memory_at_address( | |
| self, addr: int, data: lldb.SBData, error: lldb.SBError | |
| ) -> int: | |
| return self.driving_process.WriteMemory( | |
| addr, bytearray(data.uint8.all()), error | |
| ) | |
| def get_process_id(self) -> int: | |
| return self.driving_process.GetProcessID() | |
| def is_alive(self) -> bool: | |
| return True | |
| def get_scripted_thread_plugin(self) -> str: | |
| return f"{PassthroughScriptedThread.__module__}.{PassthroughScriptedThread.__name__}" | |
| class PassthroughScriptedThread(ScriptedThread): | |
| """A reference `ScriptedThread` subclass that forwards every request to | |
| a specific thread of a driving process. See `PassthroughScriptedProcess` | |
| for the process-side counterpart.""" | |
| def __init__( | |
| self, | |
| process: Union["lldb.plugins.scripted_process.ScriptedProcess", lldb.SBProcess], | |
| args: lldb.SBStructuredData, | |
| ): | |
| super().__init__(process, args) | |
| driving_target_idx = args.GetValueForKey("driving_target_idx") | |
| thread_idx = args.GetValueForKey("thread_idx") | |
| # TODO: Change to Walrus operator (:=) with oneline if assignment | |
| # Requires python 3.8 | |
| val = thread_idx.GetUnsignedIntegerValue() | |
| if val is not None: | |
| self.idx = val | |
| self.driving_target = None | |
| self.driving_process = None | |
| self.driving_thread = None | |
| # TODO: Change to Walrus operator (:=) with oneline if assignment | |
| # Requires python 3.8 | |
| val = driving_target_idx.GetUnsignedIntegerValue() | |
| if val is not None: | |
| self.driving_target = self.target.GetDebugger().GetTargetAtIndex(val) | |
| self.driving_process = self.driving_target.GetProcess() | |
| self.driving_thread = self.driving_process.GetThreadByIndexID(self.idx) | |
| if self.driving_thread: | |
| self.id = self.driving_thread.GetThreadID() | |
| def get_thread_id(self) -> int: | |
| return self.id | |
| def get_name(self) -> str: | |
| return f"{PassthroughScriptedThread.__name__}.thread-{self.idx}" | |
| def get_stop_reason(self) -> dict: | |
| stop_reason = {"type": lldb.eStopReasonInvalid, "data": {}} | |
| if ( | |
| self.driving_thread | |
| and self.driving_thread.IsValid() | |
| and self.get_thread_id() == self.driving_thread.GetThreadID() | |
| ): | |
| stop_reason["type"] = lldb.eStopReasonNone | |
| # TODO: Passthrough stop reason from driving process | |
| if self.driving_thread.GetStopReason() != lldb.eStopReasonNone: | |
| if "arm64" in self.arch: | |
| stop_reason["type"] = lldb.eStopReasonException | |
| stop_reason["data"]["desc"] = ( | |
| self.driving_thread.GetStopDescription(100) | |
| ) | |
| elif self.arch == "x86_64": | |
| stop_reason["type"] = lldb.eStopReasonSignal | |
| stop_reason["data"]["signal"] = signal.SIGTRAP | |
| else: | |
| stop_reason["type"] = self.driving_thread.GetStopReason() | |
| return stop_reason | |
| def get_register_context(self) -> Optional[str]: | |
| if not self.driving_thread or self.driving_thread.GetNumFrames() == 0: | |
| return None | |
| frame = self.driving_thread.GetFrameAtIndex(0) | |
| GPRs = None | |
| registerSet = frame.registers # Returns an SBValueList. | |
| for regs in registerSet: | |
| if "general purpose" in regs.name.lower(): | |
| GPRs = regs | |
| break | |
| if not GPRs: | |
| return None | |
| for reg in GPRs: | |
| self.register_ctx[reg.name] = int(reg.value, base=16) | |
| return struct.pack(f"{len(self.register_ctx)}Q", *self.register_ctx.values()) | |
| ARM32_GPR = [ | |
| { | |
| "name": "r0", | |
| "bitsize": 32, | |
| "offset": 0, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| "generic": "arg0", | |
| "alt-name": "arg0", | |
| }, | |
| { | |
| "name": "r1", | |
| "bitsize": 32, | |
| "offset": 4, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 1, | |
| "dwarf": 1, | |
| "generic": "arg1", | |
| "alt-name": "arg1", | |
| }, | |
| { | |
| "name": "r2", | |
| "bitsize": 32, | |
| "offset": 8, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 2, | |
| "dwarf": 2, | |
| "generic": "arg2", | |
| "alt-name": "arg2", | |
| }, | |
| { | |
| "name": "r3", | |
| "bitsize": 32, | |
| "offset": 12, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 3, | |
| "dwarf": 3, | |
| "generic": "arg3", | |
| "alt-name": "arg3", | |
| }, | |
| { | |
| "name": "r4", | |
| "bitsize": 32, | |
| "offset": 16, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 4, | |
| "dwarf": 4, | |
| }, | |
| { | |
| "name": "r5", | |
| "bitsize": 32, | |
| "offset": 20, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 5, | |
| "dwarf": 5, | |
| }, | |
| { | |
| "name": "r6", | |
| "bitsize": 32, | |
| "offset": 24, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 6, | |
| "dwarf": 6, | |
| }, | |
| { | |
| "name": "r7", | |
| "bitsize": 32, | |
| "offset": 28, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 7, | |
| "dwarf": 7, | |
| }, | |
| { | |
| "name": "r8", | |
| "bitsize": 32, | |
| "offset": 32, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 8, | |
| "dwarf": 8, | |
| }, | |
| { | |
| "name": "r9", | |
| "bitsize": 32, | |
| "offset": 36, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 9, | |
| "dwarf": 9, | |
| }, | |
| { | |
| "name": "r10", | |
| "bitsize": 32, | |
| "offset": 40, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 10, | |
| "dwarf": 10, | |
| }, | |
| { | |
| "name": "r11", | |
| "bitsize": 32, | |
| "offset": 44, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 11, | |
| "dwarf": 11, | |
| "generic": "fp", | |
| "alt-name": "fp", | |
| }, | |
| { | |
| "name": "r12", | |
| "bitsize": 32, | |
| "offset": 48, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 12, | |
| "dwarf": 12, | |
| }, | |
| { | |
| "name": "sp", | |
| "bitsize": 32, | |
| "offset": 52, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 13, | |
| "dwarf": 13, | |
| "generic": "sp", | |
| "alt-name": "r13", | |
| }, | |
| { | |
| "name": "lr", | |
| "bitsize": 32, | |
| "offset": 56, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 14, | |
| "dwarf": 14, | |
| "generic": "lr", | |
| "alt-name": "r14", | |
| }, | |
| { | |
| "name": "pc", | |
| "bitsize": 32, | |
| "offset": 60, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 15, | |
| "dwarf": 15, | |
| "generic": "pc", | |
| "alt-name": "r15", | |
| }, | |
| { | |
| "name": "cpsr", | |
| "bitsize": 32, | |
| "offset": 64, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "dwarf": 128, | |
| }, | |
| ] | |
| ARM64_GPR = [ | |
| { | |
| "name": "x0", | |
| "bitsize": 64, | |
| "offset": 0, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| "generic": "arg0", | |
| "alt-name": "arg0", | |
| }, | |
| { | |
| "name": "x1", | |
| "bitsize": 64, | |
| "offset": 8, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 1, | |
| "dwarf": 1, | |
| "generic": "arg1", | |
| "alt-name": "arg1", | |
| }, | |
| { | |
| "name": "x2", | |
| "bitsize": 64, | |
| "offset": 16, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 2, | |
| "dwarf": 2, | |
| "generic": "arg2", | |
| "alt-name": "arg2", | |
| }, | |
| { | |
| "name": "x3", | |
| "bitsize": 64, | |
| "offset": 24, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 3, | |
| "dwarf": 3, | |
| "generic": "arg3", | |
| "alt-name": "arg3", | |
| }, | |
| { | |
| "name": "x4", | |
| "bitsize": 64, | |
| "offset": 32, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 4, | |
| "dwarf": 4, | |
| "generic": "arg4", | |
| "alt-name": "arg4", | |
| }, | |
| { | |
| "name": "x5", | |
| "bitsize": 64, | |
| "offset": 40, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 5, | |
| "dwarf": 5, | |
| "generic": "arg5", | |
| "alt-name": "arg5", | |
| }, | |
| { | |
| "name": "x6", | |
| "bitsize": 64, | |
| "offset": 48, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 6, | |
| "dwarf": 6, | |
| "generic": "arg6", | |
| "alt-name": "arg6", | |
| }, | |
| { | |
| "name": "x7", | |
| "bitsize": 64, | |
| "offset": 56, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 7, | |
| "dwarf": 7, | |
| "generic": "arg7", | |
| "alt-name": "arg7", | |
| }, | |
| { | |
| "name": "x8", | |
| "bitsize": 64, | |
| "offset": 64, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 8, | |
| "dwarf": 8, | |
| }, | |
| { | |
| "name": "x9", | |
| "bitsize": 64, | |
| "offset": 72, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 9, | |
| "dwarf": 9, | |
| }, | |
| { | |
| "name": "x10", | |
| "bitsize": 64, | |
| "offset": 80, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 10, | |
| "dwarf": 10, | |
| }, | |
| { | |
| "name": "x11", | |
| "bitsize": 64, | |
| "offset": 88, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 11, | |
| "dwarf": 11, | |
| }, | |
| { | |
| "name": "x12", | |
| "bitsize": 64, | |
| "offset": 96, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 12, | |
| "dwarf": 12, | |
| }, | |
| { | |
| "name": "x13", | |
| "bitsize": 64, | |
| "offset": 104, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 13, | |
| "dwarf": 13, | |
| }, | |
| { | |
| "name": "x14", | |
| "bitsize": 64, | |
| "offset": 112, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 14, | |
| "dwarf": 14, | |
| }, | |
| { | |
| "name": "x15", | |
| "bitsize": 64, | |
| "offset": 120, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 15, | |
| "dwarf": 15, | |
| }, | |
| { | |
| "name": "x16", | |
| "bitsize": 64, | |
| "offset": 128, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 16, | |
| "dwarf": 16, | |
| }, | |
| { | |
| "name": "x17", | |
| "bitsize": 64, | |
| "offset": 136, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 17, | |
| "dwarf": 17, | |
| }, | |
| { | |
| "name": "x18", | |
| "bitsize": 64, | |
| "offset": 144, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 18, | |
| "dwarf": 18, | |
| }, | |
| { | |
| "name": "x19", | |
| "bitsize": 64, | |
| "offset": 152, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 19, | |
| "dwarf": 19, | |
| }, | |
| { | |
| "name": "x20", | |
| "bitsize": 64, | |
| "offset": 160, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 20, | |
| "dwarf": 20, | |
| }, | |
| { | |
| "name": "x21", | |
| "bitsize": 64, | |
| "offset": 168, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 21, | |
| "dwarf": 21, | |
| }, | |
| { | |
| "name": "x22", | |
| "bitsize": 64, | |
| "offset": 176, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 22, | |
| "dwarf": 22, | |
| }, | |
| { | |
| "name": "x23", | |
| "bitsize": 64, | |
| "offset": 184, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 23, | |
| "dwarf": 23, | |
| }, | |
| { | |
| "name": "x24", | |
| "bitsize": 64, | |
| "offset": 192, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 24, | |
| "dwarf": 24, | |
| }, | |
| { | |
| "name": "x25", | |
| "bitsize": 64, | |
| "offset": 200, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 25, | |
| "dwarf": 25, | |
| }, | |
| { | |
| "name": "x26", | |
| "bitsize": 64, | |
| "offset": 208, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 26, | |
| "dwarf": 26, | |
| }, | |
| { | |
| "name": "x27", | |
| "bitsize": 64, | |
| "offset": 216, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 27, | |
| "dwarf": 27, | |
| }, | |
| { | |
| "name": "x28", | |
| "bitsize": 64, | |
| "offset": 224, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 28, | |
| "dwarf": 28, | |
| }, | |
| { | |
| "name": "x29", | |
| "bitsize": 64, | |
| "offset": 232, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 29, | |
| "dwarf": 29, | |
| "generic": "fp", | |
| "alt-name": "fp", | |
| }, | |
| { | |
| "name": "x30", | |
| "bitsize": 64, | |
| "offset": 240, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 30, | |
| "dwarf": 30, | |
| "generic": "lr", | |
| "alt-name": "lr", | |
| }, | |
| { | |
| "name": "sp", | |
| "bitsize": 64, | |
| "offset": 248, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 31, | |
| "dwarf": 31, | |
| "generic": "sp", | |
| "alt-name": "sp", | |
| }, | |
| { | |
| "name": "pc", | |
| "bitsize": 64, | |
| "offset": 256, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 32, | |
| "dwarf": 32, | |
| "generic": "pc", | |
| "alt-name": "pc", | |
| }, | |
| { | |
| "name": "cpsr", | |
| "bitsize": 32, | |
| "offset": 264, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 33, | |
| "dwarf": 33, | |
| }, | |
| ] | |
| HEXAGON_GPR = [ | |
| { | |
| "name": "r0", | |
| "bitsize": 32, | |
| "offset": 0, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r1", | |
| "bitsize": 32, | |
| "offset": 4, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r2", | |
| "bitsize": 32, | |
| "offset": 8, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r3", | |
| "bitsize": 32, | |
| "offset": 12, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r4", | |
| "bitsize": 32, | |
| "offset": 16, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r5", | |
| "bitsize": 32, | |
| "offset": 20, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r6", | |
| "bitsize": 32, | |
| "offset": 24, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r7", | |
| "bitsize": 32, | |
| "offset": 28, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r8", | |
| "bitsize": 32, | |
| "offset": 32, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r9", | |
| "bitsize": 32, | |
| "offset": 36, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r10", | |
| "bitsize": 32, | |
| "offset": 40, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r11", | |
| "bitsize": 32, | |
| "offset": 44, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r12", | |
| "bitsize": 32, | |
| "offset": 48, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r13", | |
| "bitsize": 32, | |
| "offset": 52, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r14", | |
| "bitsize": 32, | |
| "offset": 56, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r15", | |
| "bitsize": 32, | |
| "offset": 60, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r16", | |
| "bitsize": 32, | |
| "offset": 64, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r17", | |
| "bitsize": 32, | |
| "offset": 68, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r18", | |
| "bitsize": 32, | |
| "offset": 72, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r19", | |
| "bitsize": 32, | |
| "offset": 76, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r20", | |
| "bitsize": 32, | |
| "offset": 80, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r21", | |
| "bitsize": 32, | |
| "offset": 84, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r22", | |
| "bitsize": 32, | |
| "offset": 88, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r23", | |
| "bitsize": 32, | |
| "offset": 92, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r24", | |
| "bitsize": 32, | |
| "offset": 96, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r25", | |
| "bitsize": 32, | |
| "offset": 100, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r26", | |
| "bitsize": 32, | |
| "offset": 104, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r27", | |
| "bitsize": 32, | |
| "offset": 108, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r28", | |
| "bitsize": 32, | |
| "offset": 112, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "r29", | |
| "bitsize": 32, | |
| "offset": 116, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| "alt-name": "sp", | |
| }, | |
| { | |
| "name": "r30", | |
| "bitsize": 32, | |
| "offset": 120, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| "alt-name": "fp", | |
| }, | |
| { | |
| "name": "r31", | |
| "bitsize": 32, | |
| "offset": 124, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| "alt-name": "lr", | |
| }, | |
| { | |
| "name": "sa0", | |
| "bitsize": 32, | |
| "offset": 128, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "lc0", | |
| "bitsize": 32, | |
| "offset": 132, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "sa1", | |
| "bitsize": 32, | |
| "offset": 136, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "lc1", | |
| "bitsize": 32, | |
| "offset": 140, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "p3_0", | |
| "bitsize": 32, | |
| "offset": 144, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "m0", | |
| "bitsize": 32, | |
| "offset": 148, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "m1", | |
| "bitsize": 32, | |
| "offset": 152, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "usr", | |
| "bitsize": 32, | |
| "offset": 156, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "pc", | |
| "bitsize": 32, | |
| "offset": 160, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| "generic": "pc", | |
| "alt-name": "pc", | |
| }, | |
| { | |
| "name": "ugp", | |
| "bitsize": 32, | |
| "offset": 164, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "gp", | |
| "bitsize": 32, | |
| "offset": 168, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "cs0", | |
| "bitsize": 32, | |
| "offset": 172, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "cs1", | |
| "bitsize": 32, | |
| "offset": 176, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "framelimit", | |
| "bitsize": 32, | |
| "offset": 180, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "framekey", | |
| "bitsize": 32, | |
| "offset": 184, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| ] | |
| INTEL64_GPR = [ | |
| { | |
| "name": "rax", | |
| "bitsize": 64, | |
| "offset": 0, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 0, | |
| "dwarf": 0, | |
| }, | |
| { | |
| "name": "rbx", | |
| "bitsize": 64, | |
| "offset": 8, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 3, | |
| "dwarf": 3, | |
| }, | |
| { | |
| "name": "rcx", | |
| "bitsize": 64, | |
| "offset": 16, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 2, | |
| "dwarf": 2, | |
| "generic": "arg4", | |
| "alt-name": "arg4", | |
| }, | |
| { | |
| "name": "rdx", | |
| "bitsize": 64, | |
| "offset": 24, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 1, | |
| "dwarf": 1, | |
| "generic": "arg3", | |
| "alt-name": "arg3", | |
| }, | |
| { | |
| "name": "rdi", | |
| "bitsize": 64, | |
| "offset": 32, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 5, | |
| "dwarf": 5, | |
| "generic": "arg1", | |
| "alt-name": "arg1", | |
| }, | |
| { | |
| "name": "rsi", | |
| "bitsize": 64, | |
| "offset": 40, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 4, | |
| "dwarf": 4, | |
| "generic": "arg2", | |
| "alt-name": "arg2", | |
| }, | |
| { | |
| "name": "rbp", | |
| "bitsize": 64, | |
| "offset": 48, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 6, | |
| "dwarf": 6, | |
| "generic": "fp", | |
| "alt-name": "fp", | |
| }, | |
| { | |
| "name": "rsp", | |
| "bitsize": 64, | |
| "offset": 56, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 7, | |
| "dwarf": 7, | |
| "generic": "sp", | |
| "alt-name": "sp", | |
| }, | |
| { | |
| "name": "r8", | |
| "bitsize": 64, | |
| "offset": 64, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 8, | |
| "dwarf": 8, | |
| "generic": "arg5", | |
| "alt-name": "arg5", | |
| }, | |
| { | |
| "name": "r9", | |
| "bitsize": 64, | |
| "offset": 72, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 9, | |
| "dwarf": 9, | |
| "generic": "arg6", | |
| "alt-name": "arg6", | |
| }, | |
| { | |
| "name": "r10", | |
| "bitsize": 64, | |
| "offset": 80, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 10, | |
| "dwarf": 10, | |
| }, | |
| { | |
| "name": "r11", | |
| "bitsize": 64, | |
| "offset": 88, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 11, | |
| "dwarf": 11, | |
| }, | |
| { | |
| "name": "r12", | |
| "bitsize": 64, | |
| "offset": 96, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 12, | |
| "dwarf": 12, | |
| }, | |
| { | |
| "name": "r13", | |
| "bitsize": 64, | |
| "offset": 104, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 13, | |
| "dwarf": 13, | |
| }, | |
| { | |
| "name": "r14", | |
| "bitsize": 64, | |
| "offset": 112, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 14, | |
| "dwarf": 14, | |
| }, | |
| { | |
| "name": "r15", | |
| "bitsize": 64, | |
| "offset": 120, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 15, | |
| "dwarf": 15, | |
| }, | |
| { | |
| "name": "rip", | |
| "bitsize": 64, | |
| "offset": 128, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "gcc": 16, | |
| "dwarf": 16, | |
| "generic": "pc", | |
| "alt-name": "pc", | |
| }, | |
| { | |
| "name": "rflags", | |
| "bitsize": 64, | |
| "offset": 136, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| "generic": "flags", | |
| "alt-name": "flags", | |
| }, | |
| { | |
| "name": "cs", | |
| "bitsize": 64, | |
| "offset": 144, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| }, | |
| { | |
| "name": "fs", | |
| "bitsize": 64, | |
| "offset": 152, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| }, | |
| { | |
| "name": "gs", | |
| "bitsize": 64, | |
| "offset": 160, | |
| "encoding": "uint", | |
| "format": "hex", | |
| "set": 0, | |
| }, | |
| ] |